diff --git a/manifests/config.pp b/manifests/config.pp index fe08431..a933212 100644 --- a/manifests/config.pp +++ b/manifests/config.pp @@ -1,276 +1,276 @@ # Private class. class keycloak::config { assert_private() file { '/opt/keycloak': ensure => 'link', target => $keycloak::install_base, } # Template uses: # - $keycloak::install_base # - $keycloak::admin_user # - $keycloak::admin_user_password file { 'kcadm-wrapper.sh': ensure => 'file', path => "${keycloak::install_base}/bin/kcadm-wrapper.sh", owner => $keycloak::user, group => $keycloak::group, mode => '0750', content => template('keycloak/kcadm-wrapper.sh.erb'), show_diff => false, } file { "${keycloak::install_base}/tmp": ensure => 'directory', owner => $keycloak::user, group => $keycloak::group, mode => '0755', } $_add_user_keycloak_cmd = "${keycloak::install_base}/bin/add-user-keycloak.sh" $_add_user_keycloak_state = "${keycloak::install_base}/.create-keycloak-admin-${keycloak::datasource_driver}" $_config_cli_content = template('keycloak/config.cli.erb') if $::keycloak::operating_mode != 'domain' { $_add_user_keycloak_args = "--user ${keycloak::admin_user} --password ${keycloak::admin_user_password} --realm master" $_subdir = 'standalone' $_java_opts_path = "${keycloak::install_base}/bin/standalone.conf" } else { $_server_conf_dir = "${keycloak::install_base}/domain/servers/${keycloak::server_name}/configuration" $_add_user_keycloak_args = "--user ${keycloak::admin_user} --password ${keycloak::admin_user_password} --realm master --sc ${_server_conf_dir}/" # lint:ignore:140chars $_subdir = 'domain' $_java_opts_path = "${keycloak::install_base}/bin/domain.conf" $_dirs = [ "${keycloak::install_base}/domain/servers", "${keycloak::install_base}/domain/servers/${keycloak::server_name}", "${keycloak::install_base}/domain/servers/${keycloak::server_name}/configuration", ] file { $_dirs: ensure => 'directory', owner => $keycloak::user, group => $keycloak::group, mode => '0755', } } exec { 'create-keycloak-admin': command => "${_add_user_keycloak_cmd} ${_add_user_keycloak_args} && touch ${_add_user_keycloak_state}", creates => $_add_user_keycloak_state, notify => Class['keycloak::service'], user => $keycloak::user, } concat { "${keycloak::install_base}/config.cli": owner => $keycloak::user, group => $keycloak::group, mode => '0600', notify => Exec['jboss-cli.sh --file=config.cli'], show_diff => false, } concat::fragment { 'config.cli-keycloak': target => "${keycloak::install_base}/config.cli", content => $_config_cli_content, order => '00', } if $keycloak::custom_config_content or $keycloak::custom_config_source { concat::fragment { 'config.cli-custom': target => "${keycloak::install_base}/config.cli", content => $keycloak::custom_config_content, source => $keycloak::custom_config_source, order => '01', } } exec { 'jboss-cli.sh --file=config.cli': command => "${keycloak::install_base}/bin/jboss-cli.sh --file=config.cli", cwd => $keycloak::install_base, user => $keycloak::user, group => $keycloak::group, refreshonly => true, logoutput => true, notify => Class['keycloak::service'], } create_resources('keycloak::truststore::host', $keycloak::truststore_hosts) if $keycloak::java_opts { $java_opts_ensure = 'present' } else { $java_opts_ensure = 'absent' } if $keycloak::java_opts =~ Array { $java_opts = join($keycloak::java_opts, ' ') } else { $java_opts = $keycloak::java_opts } if $keycloak::java_opts_append { $_java_opts = "\$JAVA_OPTS ${java_opts}" } else { $_java_opts = $java_opts } - file_line { 'JAVA_OPTS': + file_line { 'keycloak-JAVA_OPTS': ensure => $java_opts_ensure, path => $_java_opts_path, line => "JAVA_OPTS=\"${_java_opts}\"", match => '^JAVA_OPTS=', notify => Class['keycloak::service'], } file { "${keycloak::install_base}/${_subdir}/configuration": ensure => 'directory', owner => $keycloak::user, group => $keycloak::group, mode => '0750', } file { "${keycloak::install_base}/${_subdir}/configuration/profile.properties": ensure => 'file', owner => $keycloak::user, group => $keycloak::group, content => template('keycloak/profile.properties.erb'), mode => '0644', notify => Class['keycloak::service'], } if $::keycloak::operating_mode == 'domain' { $_add_user_wildfly_cmd = "${keycloak::install_base}/bin/add-user.sh" $_add_user_wildfly_args = "--user ${keycloak::wildfly_user} --password ${keycloak::wildfly_user_password} -e -s" $_add_user_wildfly_state = "${::keycloak::install_base}/.create-wildfly-user" exec { 'create-wildfly-user': command => "${_add_user_wildfly_cmd} ${_add_user_wildfly_args} && touch ${_add_user_wildfly_state}", creates => $_add_user_wildfly_state, notify => Class['keycloak::service'], } if $keycloak::role == 'master' { # Remove load balancer group # Rename the server # Set port offset to zero to run server on port 8080 augeas { 'ensure-servername': incl => "${keycloak::install_base}/domain/configuration/host-master.xml", context => "/files${keycloak::install_base}/domain/configuration/host-master.xml/host/servers", load_path => '/opt/puppetlabs/puppet/share/augeas/lenses/dist', lens => 'Xml.lns', changes => [ 'rm server[1]', 'rm server', "set server/#attribute/name ${keycloak::server_name}", 'set server/#attribute/group auth-server-group', 'set server/#attribute/auto-start true', 'set server/socket-bindings/#attribute/port-offset 0', ], notify => Class['keycloak::service'], } # Set up interface names and defaults in host-master.xml augeas { 'ensure-interface-names-defaults-master': incl => "${keycloak::install_base}/domain/configuration/host-master.xml", context => "/files${keycloak::install_base}/domain/configuration/host-master.xml/host/interfaces", load_path => '/opt/puppetlabs/puppet/share/augeas/lenses/dist', lens => 'Xml.lns', changes => [ # lint:ignore:single_quote_string_with_variables 'set interface[1]/#attribute/name management', 'set interface[1]/inet-address/#attribute/value ${jboss.bind.address.management:127.0.0.1}', 'set interface[2]/#attribute/name private', 'set interface[2]/inet-address/#attribute/value ${jboss.bind.address.private:127.0.0.1}', 'set interface[3]/#attribute/name public', 'set interface[3]/inet-address/#attribute/value ${jboss.bind.address:127.0.0.1}', # lint:endignore ], notify => Class['keycloak::service'], } # Assing management interfaces to logical interfaces augeas { 'assign-management-interaces-master': incl => "${keycloak::install_base}/domain/configuration/host-master.xml", context => "/files${keycloak::install_base}/domain/configuration/host-master.xml/host/management/management-interfaces", load_path => '/opt/puppetlabs/puppet/share/augeas/lenses/dist', lens => 'Xml.lns', changes => [ 'set native-interface/socket/#attribute/interface management', 'set http-interface/socket/#attribute/interface private', ], notify => Class['keycloak::service'], } } else { # Rename the server # Set port offset to zero, to run server in port 8080 augeas { 'ensure-servername': incl => "${keycloak::install_base}/domain/configuration/host-slave.xml", context => "/files${keycloak::install_base}/domain/configuration/host-slave.xml/host/servers", load_path => '/opt/puppetlabs/puppet/share/augeas/lenses/dist', lens => 'Xml.lns', changes => [ "set server/#attribute/name ${keycloak::server_name}", 'set server/socket-bindings/#attribute/port-offset 0' ], notify => Class['keycloak::service'], } # Set username for authentication to master augeas { 'ensure-username': incl => "${keycloak::install_base}/domain/configuration/host-slave.xml", context => "/files${keycloak::install_base}/domain/configuration/host-slave.xml/host/domain-controller/remote", load_path => '/opt/puppetlabs/puppet/share/augeas/lenses/dist', lens => 'Xml.lns', changes => [ "set #attribute/username ${keycloak::wildfly_user}" ], notify => Class['keycloak::service'], } # Set secret for authentication to master augeas { 'ensure-secret': incl => "${keycloak::install_base}/domain/configuration/host-slave.xml", context => "/files${keycloak::install_base}/domain/configuration/host-slave.xml/host/management/security-realms/security-realm[1]/server-identities/secret", # lint:ignore:140chars load_path => '/opt/puppetlabs/puppet/share/augeas/lenses/dist', lens => 'Xml.lns', changes => [ "set #attribute/value ${keycloak::wildfly_user_password_base64}" ], notify => Class['keycloak::service'], } # Set up interface names and default in host-slave.xml augeas { 'ensure-interface-names-defaults-slave': incl => "${keycloak::install_base}/domain/configuration/host-slave.xml", context => "/files${keycloak::install_base}/domain/configuration/host-slave.xml/host/interfaces", load_path => '/opt/puppetlabs/puppet/share/augeas/lenses/dist', lens => 'Xml.lns', changes => [ # lint:ignore:single_quote_string_with_variables 'set interface[1]/#attribute/name management', 'set interface[1]/inet-address/#attribute/value ${jboss.bind.address.management:127.0.0.1}', 'set interface[2]/#attribute/name private', 'set interface[2]/inet-address/#attribute/value ${jboss.bind.address.private:127.0.0.1}', 'set interface[3]/#attribute/name public', 'set interface[3]/inet-address/#attribute/value ${jboss.bind.address:127.0.0.1}', # lint:endignore ], notify => Class['keycloak::service'], } # Assing management interfaces to logical interfaces augeas { 'assign-management-interaces-slave': incl => "${keycloak::install_base}/domain/configuration/host-slave.xml", context => "/files${keycloak::install_base}/domain/configuration/host-slave.xml/host/management/management-interfaces", load_path => '/opt/puppetlabs/puppet/share/augeas/lenses/dist', lens => 'Xml.lns', changes => [ 'set native-interface/socket/#attribute/interface management', 'set http-interface/socket/#attribute/interface private', ], notify => Class['keycloak::service'], } } } } diff --git a/metadata.json b/metadata.json index 7d0ce63..b2e8d66 100644 --- a/metadata.json +++ b/metadata.json @@ -1,93 +1,93 @@ { "name": "treydock-keycloak", "version": "6.25.1", "author": "treydock", "summary": "Keycloak Puppet module", "license": "Apache-2.0", "source": "https://github.com/treydock/puppet-module-keycloak", "project_page": "https://github.com/treydock/puppet-module-keycloak", "issues_url": "https://github.com/treydock/puppet-module-keycloak/issues", "dependencies": [ { "name": "puppetlabs/stdlib", "version_requirement": ">= 4.25.0 <7.0.0" }, { "name": "puppetlabs/mysql", "version_requirement": ">= 10.2.0 <11.0.0" }, { "name": "puppetlabs/postgresql", "version_requirement": ">= 6.4.0 <7.0.0" }, { "name": "puppetlabs/java", "version_requirement": ">= 5.0.0 <7.0.0" }, { "name": "puppetlabs/java_ks", "version_requirement": ">= 1.0.0 <4.0.0" }, { "name": "puppetlabs/augeas_core", "version_requirement": ">= 1.0.0 <4.0.0" }, { "name": "puppetlabs/yumrepo_core", - "version_requirement": ">= 1.0.0 <4.0.0" + "version_requirement": ">= 1.0.0 <2.0.0" }, { "name": "puppet/archive", "version_requirement": ">= 0.5.1 <5.0.0" }, { "name": "camptocamp/systemd", "version_requirement": ">= 0.4.0 <3.0.0" } ], "operatingsystem_support": [ { "operatingsystem": "RedHat", "operatingsystemrelease": [ "7", "8" ] }, { "operatingsystem": "CentOS", "operatingsystemrelease": [ "7", "8" ] }, { "operatingsystem": "Scientific", "operatingsystemrelease": [ "7", "8" ] }, { "operatingsystem": "Debian", "operatingsystemrelease": [ "9", "10" ] }, { "operatingsystem": "Ubuntu", "operatingsystemrelease": [ "18.04" ] } ], "requirements": [ { "name": "puppet", "version_requirement": ">= 5.0.0 < 7.0.0" } ], "pdk-version": "1.17.0", "template-url": "https://github.com/treydock/pdk-templates.git#master", "template-ref": "heads/master-0-g1f52e6d" } diff --git a/spec/acceptance/1_domain_mode_cluster_spec.rb b/spec/acceptance/1_domain_mode_cluster_spec.rb index 60bb589..24cec70 100644 --- a/spec/acceptance/1_domain_mode_cluster_spec.rb +++ b/spec/acceptance/1_domain_mode_cluster_spec.rb @@ -1,136 +1,136 @@ require 'spec_helper_acceptance' # This check needs to be here or Beaker will try to run find_only_one on # non-domain-mode tests and fail miserably. -if RSpec.configuration.keycloak_domain_mode_cluster - describe 'keycloak domain mode cluster' do - domain_master = find_only_one('domain_master') - domain_slave = find_only_one('domain_slave') - db = find_only_one('db') +describe 'keycloak domain mode cluster' if RSpec.configuration.keycloak_domain_mode_cluster + +domain_master = find_only_one('domain_master') +domain_slave = find_only_one('domain_slave') +db = find_only_one('db') - context 'new cluster' do - it 'launches' do - db_pp = <<-EOS - class { '::postgresql::globals': - manage_package_repo => true, - version => '9.6', - } +context 'new cluster' do + it 'launches' do + db_pp = <<-EOS + class { '::postgresql::globals': + manage_package_repo => true, + version => '9.6', + } - class { '::postgresql::server': - listen_addresses => '*', - require => Class['::postgresql::globals'] - } + class { '::postgresql::server': + listen_addresses => '*', + require => Class['::postgresql::globals'] + } - ::postgresql::server::role { 'keycloak': - password_hash => postgresql_password('keycloak', 'keycloak'), - connection_limit => 300, - require => Class['::postgresql::server'] - } + ::postgresql::server::role { 'keycloak': + password_hash => postgresql_password('keycloak', 'keycloak'), + connection_limit => 300, + require => Class['::postgresql::server'] + } - ::postgresql::server::database_grant { 'Grant all to keycloak': - privilege => 'ALL', - db => 'keycloak', - role => 'keycloak', - } + ::postgresql::server::database_grant { 'Grant all to keycloak': + privilege => 'ALL', + db => 'keycloak', + role => 'keycloak', + } - ::postgresql::server::db { 'keycloak': - user => 'keycloak', - password => postgresql_password('keycloak', 'keycloak'), - } + ::postgresql::server::db { 'keycloak': + user => 'keycloak', + password => postgresql_password('keycloak', 'keycloak'), + } - postgresql::server::pg_hba_rule { 'Allow Keycloak instances network access to the database': - description => 'Open up PostgreSQL for access from anywhere', - type => 'host', - database => 'keycloak', - user => 'keycloak', - address => '0.0.0.0/0', - auth_method => 'md5', - require => Class['::postgresql::server'] - } - EOS + postgresql::server::pg_hba_rule { 'Allow Keycloak instances network access to the database': + description => 'Open up PostgreSQL for access from anywhere', + type => 'host', + database => 'keycloak', + user => 'keycloak', + address => '0.0.0.0/0', + auth_method => 'md5', + require => Class['::postgresql::server'] + } + EOS - master_pp = <<-EOS - class { '::keycloak': - operating_mode => 'domain', - role => 'master', - management_bind_address => $::ipaddress, - enable_jdbc_ping => true, - wildfly_user => 'wildfly', - wildfly_user_password => 'wildfly', - manage_install => true, - manage_datasource => false, - version => '10.0.1', - datasource_driver => 'postgresql', - datasource_host => 'centos-7-db', - datasource_port => 5432, - datasource_dbname => 'keycloak', - datasource_username => 'keycloak', - datasource_password => 'keycloak', - admin_user => 'admin', - admin_user_password => 'changeme', - service_bind_address => '0.0.0.0', - proxy_https => false, - } - EOS + master_pp = <<-EOS + class { '::keycloak': + operating_mode => 'domain', + role => 'master', + management_bind_address => $::ipaddress, + enable_jdbc_ping => true, + wildfly_user => 'wildfly', + wildfly_user_password => 'wildfly', + manage_install => true, + manage_datasource => false, + version => '10.0.1', + datasource_driver => 'postgresql', + datasource_host => 'centos-7-db', + datasource_port => 5432, + datasource_dbname => 'keycloak', + datasource_username => 'keycloak', + datasource_password => 'keycloak', + admin_user => 'admin', + admin_user_password => 'changeme', + service_bind_address => '0.0.0.0', + proxy_https => false, + } + EOS - slave_pp = <<-EOS - class { '::keycloak': - operating_mode => 'domain', - role => 'slave', - enable_jdbc_ping => true, - management_bind_address => $::ipaddress, - wildfly_user => 'wildfly', - wildfly_user_password => 'wildfly', - master_address => 'centos-7-master', - manage_install => true, - manage_datasource => false, - version => '10.0.1', - datasource_driver => 'postgresql', - datasource_host => 'centos-7-db', - datasource_port => 5432, - datasource_dbname => 'keycloak', - datasource_username => 'keycloak', - datasource_password => 'keycloak', - admin_user => 'admin', - admin_user_password => 'changeme', - service_bind_address => '0.0.0.0', - proxy_https => false, - } - EOS + slave_pp = <<-EOS + class { '::keycloak': + operating_mode => 'domain', + role => 'slave', + enable_jdbc_ping => true, + management_bind_address => $::ipaddress, + wildfly_user => 'wildfly', + wildfly_user_password => 'wildfly', + master_address => 'centos-7-master', + manage_install => true, + manage_datasource => false, + version => '10.0.1', + datasource_driver => 'postgresql', + datasource_host => 'centos-7-db', + datasource_port => 5432, + datasource_dbname => 'keycloak', + datasource_username => 'keycloak', + datasource_password => 'keycloak', + admin_user => 'admin', + admin_user_password => 'changeme', + service_bind_address => '0.0.0.0', + proxy_https => false, + } + EOS - apply_manifest_on(db, db_pp, catch_failures: true) - apply_manifest_on(domain_master, master_pp, catch_failures: true) - apply_manifest_on(domain_master, master_pp, catch_changes: true) - apply_manifest_on(domain_slave, slave_pp, catch_failures: true) - apply_manifest_on(domain_slave, slave_pp, catch_changes: true) - end - - describe service('keycloak'), node: domain_master do - it { is_expected.to be_enabled } - it { is_expected.to be_running } - end - - describe service('keycloak'), node: domain_slave do - it { is_expected.to be_enabled } - it { is_expected.to be_running } - end + apply_manifest_on(db, db_pp, catch_failures: true) + apply_manifest_on(domain_master, master_pp, catch_failures: true) + apply_manifest_on(domain_master, master_pp, catch_changes: true) + apply_manifest_on(domain_slave, slave_pp, catch_failures: true) + apply_manifest_on(domain_slave, slave_pp, catch_changes: true) + end - it 'data replicates from master to slave' do - on domain_master, '/opt/keycloak/bin/kcadm-wrapper.sh create roles -r master -s name=testrole' - on domain_slave, '/opt/keycloak/bin/kcadm-wrapper.sh get roles/testrole -r master' do - data = JSON.parse(stdout) - expect(data['name']).to eq('testrole') - end - end + describe service('keycloak'), node: domain_master do + it { is_expected.to be_enabled } + it { is_expected.to be_running } + end - it 'data replicates from slave to master' do - on domain_slave, '/opt/keycloak/bin/kcadm-wrapper.sh delete roles/testrole -r master' - on domain_master, '/opt/keycloak/bin/kcadm-wrapper.sh get roles -r master' do - data = JSON.parse(stdout) - match = data.select { |role| role['name'] == 'testrole' } - expect(match).to be_empty - end - end + describe service('keycloak'), node: domain_slave do + it { is_expected.to be_enabled } + it { is_expected.to be_running } + end + + it 'data replicates from master to slave' do + on domain_master, '/opt/keycloak/bin/kcadm-wrapper.sh create roles -r master -s name=testrole' + on domain_slave, '/opt/keycloak/bin/kcadm-wrapper.sh get roles/testrole -r master' do + data = JSON.parse(stdout) + expect(data['name']).to eq('testrole') + end + end + + it 'data replicates from slave to master' do + on domain_slave, '/opt/keycloak/bin/kcadm-wrapper.sh delete roles/testrole -r master' + on domain_master, '/opt/keycloak/bin/kcadm-wrapper.sh get roles -r master' do + data = JSON.parse(stdout) + match = data.select { |role| role['name'] == 'testrole' } + expect(match).to be_empty end end end + +