diff --git a/REFERENCE.md b/REFERENCE.md
index 2333c744..f29c8492 100644
--- a/REFERENCE.md
+++ b/REFERENCE.md
@@ -40,6 +40,7 @@
* [`Rundeck::Loglevel`](#Rundeck--Loglevel): Rundeck log level type.
* [`Rundeck::Mail_config`](#Rundeck--Mail_config): Rundeck mail config type.
* [`Rundeck::Project`](#Rundeck--Project): Rundeck project type.
+* [`Rundeck::Scm`](#Rundeck--Scm): Rundeck scm type.
## Classes
@@ -1008,6 +1009,63 @@ rundeck::config::project { 'MyProject':
}
```
+##### Advanced usage with jobs.
+
+```puppet
+rundeck::config::project { 'MyProject':
+ config => {
+ 'project.description' => 'My test project',
+ 'project.disable.schedule' => 'false',
+ },
+ jobs => {
+ 'MyJob1' => {
+ 'path' => '/etc/myjob1',
+ 'format' => 'yaml',
+ },
+ 'MyJob2' => {
+ 'path' => '/etc/myjob2',
+ 'format' => 'xml',
+ },
+ 'DeleteJob1' => {
+ 'ensure' => 'absent',
+ 'path' => '/etc/testjob1',
+ 'format' => 'yaml',
+ },
+ },
+}
+```
+
+##### Advanced usage with scm_config.
+
+```puppet
+rundeck::config::project { 'MyProject':
+ config => {
+ 'project.description' => 'My test project',
+ 'project.disable.schedule' => 'false',
+ },
+ scm_config => {
+ 'import' => {
+ 'type' => 'git-import',
+ 'config' => {
+ 'strictHostKeyChecking' => 'yes',
+ 'gitPasswordPath' => 'keys/example-access-token',
+ 'format' => 'xml',
+ 'dir' => '/var/lib/rundeck/projects/MyProject/ScmImport',
+ 'branch' => 'master',
+ 'url' => 'https://myuser@example.com/example/example.git',
+ 'filePattern' => '*.xml',
+ 'useFilePattern' => 'true',
+ 'pathTemplate' => "\${job.id}.\${config.format}",
+ 'importUuidBehavior' => 'preserve',
+ 'sshPrivateKeyPath' => '',
+ 'fetchAutomatically' => 'true',
+ 'pullAutomatically' => 'true',
+ },
+ },
+ },
+}
+```
+
#### Parameters
The following parameters are available in the `rundeck::config::project` defined type:
@@ -1016,6 +1074,10 @@ The following parameters are available in the `rundeck::config::project` defined
* [`config`](#-rundeck--config--project--config)
* [`update_method`](#-rundeck--config--project--update_method)
* [`jobs`](#-rundeck--config--project--jobs)
+* [`owner`](#-rundeck--config--project--owner)
+* [`group`](#-rundeck--config--project--group)
+* [`projects_dir`](#-rundeck--config--project--projects_dir)
+* [`scm_config`](#-rundeck--config--project--scm_config)
##### `ensure`
@@ -1065,6 +1127,38 @@ Rundeck jobs related to a project.
Default value: `{}`
+##### `owner`
+
+Data type: `String[1]`
+
+The user that rundeck is installed as.
+
+Default value: `'rundeck'`
+
+##### `group`
+
+Data type: `String[1]`
+
+The group permission that rundeck is installed as.
+
+Default value: `'rundeck'`
+
+##### `projects_dir`
+
+Data type: `Stdlib::Absolutepath`
+
+Directory where some project config will be stored.
+
+Default value: `'/var/lib/rundeck/projects'`
+
+##### `scm_config`
+
+Data type: `Optional[Rundeck::Scm]`
+
+A hash of name value pairs representing properties for the scm.json file.
+
+Default value: `undef`
+
### `rundeck::config::secret`
This define will manage secrets in key storage.
@@ -1261,3 +1355,31 @@ Struct[{
}]
```
+### `Rundeck::Scm`
+
+Rundeck scm type.
+
+Alias of
+
+```puppet
+Variant[Struct[{
+ 'import' => Struct[{
+ 'type' => String[1],
+ 'config' => Hash[String[1], String],
+ }],
+ Optional['export'] => Struct[{
+ 'type' => String[1],
+ 'config' => Hash[String[1], String],
+ }],
+ }], Struct[{
+ 'export' => Struct[{
+ 'type' => String[1],
+ 'config' => Hash[String[1], String],
+ }],
+ Optional['import'] => Struct[{
+ 'type' => String[1],
+ 'config' => Hash[String[1], String],
+ }],
+ }]]
+```
+
diff --git a/files/rd_scm_diff.sh b/files/rd_scm_diff.sh
new file mode 100644
index 00000000..6ae8eaa6
--- /dev/null
+++ b/files/rd_scm_diff.sh
@@ -0,0 +1,8 @@
+#!/bin/sh
+# THIS FILE IS MANAGED BY PUPPET
+
+projects_dir="$1"
+project="$2"
+interaction="$3"
+
+bash -c "diff <(rd projects scm config -p '$project' -i $interaction | jq .config -S) <(cat $projects_dir/$project/scm-import.json | jq .config -S)"
diff --git a/manifests/cli.pp b/manifests/cli.pp
index c01903e9..586242fb 100644
--- a/manifests/cli.pp
+++ b/manifests/cli.pp
@@ -106,6 +106,9 @@
'/usr/local/bin/rd_job_diff.sh':
content => file('rundeck/rd_job_diff.sh'),
;
+ '/usr/local/bin/rd_scm_diff.sh':
+ content => file('rundeck/rd_scm_diff.sh'),
+ ;
}
$_default_env_vars = [
diff --git a/manifests/config.pp b/manifests/config.pp
index af5225e6..70969930 100644
--- a/manifests/config.pp
+++ b/manifests/config.pp
@@ -15,6 +15,7 @@
'framework.var.dir' => '/var/lib/rundeck/var',
'framework.tmp.dir' => '/var/lib/rundeck/var/tmp',
'framework.logs.dir' => '/var/lib/rundeck/logs',
+ 'framework.projects.dir' => '/var/lib/rundeck/projects',
'framework.libext.dir' => '/var/lib/rundeck/libext',
'framework.ssh.keypath' => '/var/lib/rundeck/.ssh/id_rsa',
'framework.ssh.user' => 'rundeck',
diff --git a/manifests/config/project.pp b/manifests/config/project.pp
index 9dba1e79..c9b55a3a 100644
--- a/manifests/config/project.pp
+++ b/manifests/config/project.pp
@@ -8,6 +8,57 @@
# },
# }
#
+# @example Advanced usage with jobs.
+# rundeck::config::project { 'MyProject':
+# config => {
+# 'project.description' => 'My test project',
+# 'project.disable.schedule' => 'false',
+# },
+# jobs => {
+# 'MyJob1' => {
+# 'path' => '/etc/myjob1',
+# 'format' => 'yaml',
+# },
+# 'MyJob2' => {
+# 'path' => '/etc/myjob2',
+# 'format' => 'xml',
+# },
+# 'DeleteJob1' => {
+# 'ensure' => 'absent',
+# 'path' => '/etc/testjob1',
+# 'format' => 'yaml',
+# },
+# },
+# }
+#
+# @example Advanced usage with scm_config.
+# rundeck::config::project { 'MyProject':
+# config => {
+# 'project.description' => 'My test project',
+# 'project.disable.schedule' => 'false',
+# },
+# scm_config => {
+# 'import' => {
+# 'type' => 'git-import',
+# 'config' => {
+# 'strictHostKeyChecking' => 'yes',
+# 'gitPasswordPath' => 'keys/example-access-token',
+# 'format' => 'xml',
+# 'dir' => '/var/lib/rundeck/projects/MyProject/ScmImport',
+# 'branch' => 'master',
+# 'url' => 'https://myuser@example.com/example/example.git',
+# 'filePattern' => '*.xml',
+# 'useFilePattern' => 'true',
+# 'pathTemplate' => "\${job.id}.\${config.format}",
+# 'importUuidBehavior' => 'preserve',
+# 'sshPrivateKeyPath' => '',
+# 'fetchAutomatically' => 'true',
+# 'pullAutomatically' => 'true',
+# },
+# },
+# },
+# }
+#
# @param ensure
# Whether or not the project should be present.
# @param config
@@ -17,6 +68,14 @@
# update: Modify configuration properties for a project. Only the specified keys will be updated.
# @param jobs
# Rundeck jobs related to a project.
+# @param owner
+# The user that rundeck is installed as.
+# @param group
+# The group permission that rundeck is installed as.
+# @param projects_dir
+# Directory where some project config will be stored.
+# @param scm_config
+# A hash of name value pairs representing properties for the scm.json file.
#
define rundeck::config::project (
Enum['absent', 'present'] $ensure = 'present',
@@ -34,6 +93,10 @@
},
Enum['set', 'update'] $update_method = 'update',
Hash[String, Rundeck::Job] $jobs = {},
+ String[1] $owner = 'rundeck',
+ String[1] $group = 'rundeck',
+ Stdlib::Absolutepath $projects_dir = '/var/lib/rundeck/projects',
+ Optional[Rundeck::Scm] $scm_config = undef,
) {
include rundeck::cli
@@ -92,5 +155,42 @@
}
}
}
+
+ if $scm_config {
+ ensure_resource('file', "${projects_dir}/${name}",
+ {
+ 'ensure' => 'directory',
+ 'owner' => $owner,
+ 'group' => $group,
+ 'mode' => '0755'
+ }
+ )
+
+ $scm_config.each |$integration, $config| {
+ file { "${projects_dir}/${name}/scm-${integration}.json":
+ ensure => file,
+ owner => $owner,
+ group => $group,
+ mode => '0644',
+ content => stdlib::to_json($config),
+ }
+
+ $_command = [
+ 'rd projects scm setup',
+ "-p '${name}'",
+ "-i ${integration}",
+ "-t ${config['type']}",
+ "-f ${projects_dir}/${name}/scm-${integration}.json",
+ ].join(' ')
+
+ exec { "Setup/update SCM ${integration} config for rundeck project: ${name}":
+ command => $_command,
+ path => ['/bin', '/usr/bin', '/usr/local/bin'],
+ environment => $rundeck::cli::environment,
+ unless => "rd_scm_diff.sh ${projects_dir} '${name}' ${integration}",
+ require => File["${projects_dir}/${name}/scm-${integration}.json"],
+ }
+ }
+ }
}
}
diff --git a/spec/classes/cli_spec.rb b/spec/classes/cli_spec.rb
index eb9c7af5..15ef8101 100644
--- a/spec/classes/cli_spec.rb
+++ b/spec/classes/cli_spec.rb
@@ -42,6 +42,7 @@
it { is_expected.to contain_package('rundeck-cli').with(ensure: 'installed') }
it { is_expected.to contain_file('/usr/local/bin/rd_project_diff.sh').with(ensure: 'file', mode: '0755') }
it { is_expected.to contain_file('/usr/local/bin/rd_job_diff.sh').with(ensure: 'file', mode: '0755') }
+ it { is_expected.to contain_file('/usr/local/bin/rd_scm_diff.sh').with(ensure: 'file', mode: '0755') }
end
it do
diff --git a/spec/classes/config_spec.rb b/spec/classes/config_spec.rb
index d0e90e02..e7483511 100644
--- a/spec/classes/config_spec.rb
+++ b/spec/classes/config_spec.rb
@@ -19,6 +19,7 @@
it { is_expected.to contain_file('/var/lib/rundeck/var').with(ensure: 'directory') }
it { is_expected.to contain_file('/var/lib/rundeck/var/tmp').with(ensure: 'directory') }
it { is_expected.to contain_file('/var/lib/rundeck/logs').with(ensure: 'directory') }
+ it { is_expected.to contain_file('/var/lib/rundeck/projects').with(ensure: 'directory') }
it { is_expected.to contain_file('/var/log/rundeck').with(ensure: 'directory') }
diff --git a/spec/defines/config/project_spec.rb b/spec/defines/config/project_spec.rb
index 2ca98a6a..c0094328 100644
--- a/spec/defines/config/project_spec.rb
+++ b/spec/defines/config/project_spec.rb
@@ -149,6 +149,74 @@
it { is_expected.to contain_exec('(MyJobProject) Create/update job: TestJob1') }
it { is_expected.to contain_exec('(MyJobProject) Remove job: DeleteJob1') }
end
+
+ context 'Add rundeck project: TestSCM with scm config' do
+ name = 'TestSCM'
+
+ let(:title) { name }
+ let(:params) do
+ {
+ scm_config: {
+ 'import' => {
+ 'type' => 'git-import',
+ 'config' => {
+ 'strictHostKeyChecking' => 'yes',
+ 'gitPasswordPath' => 'keys/example-access-token',
+ 'format' => 'xml',
+ 'dir' => '/var/lib/rundeck/projects/MyProject/ScmImport',
+ 'branch' => 'master',
+ 'url' => 'https://myuser@example.com/example/example.git',
+ 'filePattern' => '*.xml',
+ 'useFilePattern' => 'true',
+ 'pathTemplate' => '${job.id}.${config.format}',
+ 'importUuidBehavior' => 'preserve',
+ 'sshPrivateKeyPath' => '',
+ 'fetchAutomatically' => 'true',
+ 'pullAutomatically' => 'true',
+ },
+ },
+ },
+ }
+ end
+
+ it { is_expected.to contain_exec('Create rundeck project: TestSCM') }
+ it { is_expected.to contain_exec('Manage rundeck project: TestSCM') }
+ it { is_expected.to contain_file('/var/lib/rundeck/projects/TestSCM').with(ensure: 'directory', owner: 'rundeck', group: 'rundeck', mode: '0755') }
+ it { is_expected.to contain_file('/var/lib/rundeck/projects/TestSCM/scm-import.json').with(ensure: 'file', owner: 'rundeck', group: 'rundeck', mode: '0644') }
+ it { is_expected.to contain_exec('Setup/update SCM import config for rundeck project: TestSCM').that_requires('File[/var/lib/rundeck/projects/TestSCM/scm-import.json]') }
+ end
+
+ context 'Add rundeck project: TestWrongSCM with wrong scm config' do
+ name = 'TestWrongSCM'
+
+ let(:title) { name }
+ let(:params) do
+ {
+ scm_config: {
+ 'wrong_key' => {
+ 'type' => 'git-import',
+ 'config' => {
+ 'strictHostKeyChecking' => 'yes',
+ 'gitPasswordPath' => 'keys/example-access-token',
+ 'format' => 'xml',
+ 'dir' => '/var/lib/rundeck/projects/MyProject/ScmImport',
+ 'branch' => 'master',
+ 'url' => 'https://myuser@example.com/example/example.git',
+ 'filePattern' => '*.xml',
+ 'useFilePattern' => 'true',
+ 'pathTemplate' => '${job.id}.${config.format}',
+ 'importUuidBehavior' => 'preserve',
+ 'sshPrivateKeyPath' => '',
+ 'fetchAutomatically' => 'true',
+ 'pullAutomatically' => 'true',
+ },
+ },
+ },
+ }
+ end
+
+ it { is_expected.not_to compile }
+ end
end
end
end
diff --git a/types/scm.pp b/types/scm.pp
new file mode 100644
index 00000000..5b2268be
--- /dev/null
+++ b/types/scm.pp
@@ -0,0 +1,23 @@
+# @summary Rundeck scm type.
+type Rundeck::Scm = Variant[
+ Struct[{
+ 'import' => Struct[{
+ 'type' => String[1],
+ 'config' => Hash[String[1], String],
+ }],
+ Optional['export'] => Struct[{
+ 'type' => String[1],
+ 'config' => Hash[String[1], String],
+ }],
+ }],
+ Struct[{
+ 'export' => Struct[{
+ 'type' => String[1],
+ 'config' => Hash[String[1], String],
+ }],
+ Optional['import'] => Struct[{
+ 'type' => String[1],
+ 'config' => Hash[String[1], String],
+ }],
+ }],
+]