diff --git a/lib/puppet/provider/elastic_parsedfile.rb b/lib/puppet/provider/elastic_parsedfile.rb index e4f7334..285119d 100644 --- a/lib/puppet/provider/elastic_parsedfile.rb +++ b/lib/puppet/provider/elastic_parsedfile.rb @@ -1,26 +1,19 @@ require 'puppet/provider/parsedfile' # Parent class for Elasticsearch-based providers that need to access # specific configuration directories. class Puppet::Provider::ElasticParsedFile < Puppet::Provider::ParsedFile - # Find/set a shield configuration file. - # - # @return String - def self.shield_config(val) - @default_target ||= "/etc/elasticsearch/shield/#{val}" - end - # Find/set an x-pack configuration file. # # @return String def self.xpack_config(val) - @default_target ||= "/etc/elasticsearch/x-pack/#{val}" + @default_target ||= "/etc/elasticsearch/#{val}" end # Find/set an oss x-pack configuration file. # # @return String def self.oss_xpack_config(val) @default_target ||= "/etc/elasticsearch/#{val}" end end diff --git a/lib/puppet/provider/elastic_user_roles.rb b/lib/puppet/provider/elastic_user_roles.rb index f7a6a68..ee86a4c 100644 --- a/lib/puppet/provider/elastic_user_roles.rb +++ b/lib/puppet/provider/elastic_user_roles.rb @@ -1,49 +1,49 @@ require 'puppet/provider/elastic_yaml' -# Provider to help manage file-based Shield/X-Pack user/role configuration +# Provider to help manage file-based X-Pack user/role configuration # files. class Puppet::Provider::ElasticUserRoles < Puppet::Provider::ElasticYaml # Override the ancestor `parse` method to process a users/roles file # managed by the Elasticsearch user tools. def self.parse(text) text.split("\n").map(&:strip).select do |line| # Strip comments not line.start_with? '#' and not line.empty? end.map do |line| # Turn array of roles into array of users that have the role role, users = line.split(':') users.split(',').map do |user| { user => [role] } end end.flatten.inject({}) do |hash, user| # Gather up user => role hashes by append-merging role lists hash.merge(user) { |_, o, n| o + n } end.map do |user, roles| # Map those hashes into what the provider expects { :name => user, :roles => roles } end.to_a end # Represent this user/role record as a correctly-formatted config file. def self.to_file(records) debug "Flushing: #{records.inspect}" records.map do |record| record[:roles].map do |r| { [record[:name]] => r } end end.flatten.map(&:invert).inject({}) do |acc, role| acc.merge(role) { |_, o, n| o + n } end.delete_if do |_, users| users.empty? end.map do |role, users| "#{role}:#{users.join(',')}" end.join("\n") + "\n" end def self.skip_record?(_record) false end end diff --git a/lib/puppet/provider/elasticsearch_license/x-pack.rb b/lib/puppet/provider/elasticsearch_license/ruby.rb similarity index 100% rename from lib/puppet/provider/elasticsearch_license/x-pack.rb rename to lib/puppet/provider/elasticsearch_license/ruby.rb diff --git a/lib/puppet/provider/elasticsearch_license/shield.rb b/lib/puppet/provider/elasticsearch_license/shield.rb deleted file mode 100644 index 19e0bbc..0000000 --- a/lib/puppet/provider/elasticsearch_license/shield.rb +++ /dev/null @@ -1,31 +0,0 @@ -require 'puppet/provider/elastic_rest' - -Puppet::Type.type(:elasticsearch_license).provide( - :shield, - :api_resource_style => :bare, - :parent => Puppet::Provider::ElasticREST, - :metadata => :content, - :metadata_pipeline => [ - lambda { |data| Puppet_X::Elastic.deep_to_s data }, - lambda { |data| Puppet_X::Elastic.deep_to_i data } - ], - :api_uri => '_license', - :query_string => { - 'acknowledge' => 'true' - } -) do - desc 'A REST API based provider to manage Elasticsearch Shield licenses.' - - mk_resource_methods - - def self.process_body(body) - JSON.parse(body).map do |_object_name, api_object| - { - :name => name.to_s, - :ensure => :present, - metadata => { 'license' => process_metadata(api_object) }, - :provider => name - } - end - end -end diff --git a/lib/puppet/provider/elasticsearch_role/shield.rb b/lib/puppet/provider/elasticsearch_role/shield.rb deleted file mode 100644 index bd465a0..0000000 --- a/lib/puppet/provider/elasticsearch_role/shield.rb +++ /dev/null @@ -1,12 +0,0 @@ -require 'puppet/provider/elastic_yaml' - -Puppet::Type.type(:elasticsearch_role).provide( - :shield, - :parent => Puppet::Provider::ElasticYaml, - :metadata => :privileges -) do - desc 'Provider for Shield role resources.' - - shield_config 'roles.yml' - confine :exists => default_target -end diff --git a/lib/puppet/provider/elasticsearch_role_mapping/shield.rb b/lib/puppet/provider/elasticsearch_role_mapping/shield.rb deleted file mode 100644 index 0a1775e..0000000 --- a/lib/puppet/provider/elasticsearch_role_mapping/shield.rb +++ /dev/null @@ -1,12 +0,0 @@ -require 'puppet/provider/elastic_yaml' - -Puppet::Type.type(:elasticsearch_role_mapping).provide( - :shield, - :parent => Puppet::Provider::ElasticYaml, - :metadata => :mappings -) do - desc 'Provider for Shield role mappings.' - - shield_config 'role_mapping.yml' - confine :exists => default_target -end diff --git a/lib/puppet/provider/elasticsearch_service_file/ruby.rb b/lib/puppet/provider/elasticsearch_service_file/ruby.rb deleted file mode 100644 index 08cd19a..0000000 --- a/lib/puppet/provider/elasticsearch_service_file/ruby.rb +++ /dev/null @@ -1,90 +0,0 @@ -$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', '..', '..')) - -require 'pathname' -require 'puppet/util/filetype' - -require 'puppet_x/elastic/es_versioning' - -Puppet::Type.type(:elasticsearch_service_file).provide(:ruby) do - desc <<-ENDHEREDOC - Provides management of elasticsearch service files. - ENDHEREDOC - - mk_resource_methods - - def initialize(value = {}) - super(value) - @property_flush = {} - end - - def self.services - [ - '/usr/lib/systemd/system/elasticsearch-', - '/lib/systemd/system/elasticsearch-', - '/etc/init.d/elasticsearch.', - '/etc/init.d/elasticsearch-', - '/etc/rc.d/elasticsearch_' - ].map do |path| - Pathname.glob(path + '*').map do |service| - { - :name => service.to_s, - :ensure => :present, - :provider => :ruby, - :content => Puppet::Util::FileType.filetype(:flat).new(service.to_s).read - } - end - end.flatten.compact - end - - def self.instances - services.map do |instance| - new instance - end - end - - def self.prefetch(resources) - instances.each do |prov| - if (resource = resources[prov.name]) - resource.provider = prov - end - end - end - - def create - @property_flush[:ensure] = :present - end - - def exists? - @property_hash[:ensure] == :present - end - - def destroy? - @property_flush[:ensure] = :absent - end - - def flush - begin - opt_flag, opt_flags = Puppet_X::Elastic::EsVersioning.opt_flags( - resource[:package_name], resource.catalog - ) - rescue ElasticsearchPackageNotFoundError - # If the Elasticsearch package is not present at all, we don't know what - # version is present, so we just set these as empty values for the - # template. - opt_flag = '' - opt_flags = [] - end - - # This should only be present on systemd systems. - opt_flags.delete('--quiet') unless resource[:name].include?('systemd') - - template = ERB.new(resource[:content], 0, '-') - result = template.result(binding) - - Puppet::Util::FileType.filetype(:flat).new(resource[:name]).write(result) - - @property_hash = self.class.services.detect do |t| - t[:name] == resource[:name] - end - end -end # of .provide diff --git a/lib/puppet/provider/elasticsearch_user_file/shield.rb b/lib/puppet/provider/elasticsearch_user_file/shield.rb deleted file mode 100644 index a6f15f6..0000000 --- a/lib/puppet/provider/elasticsearch_user_file/shield.rb +++ /dev/null @@ -1,29 +0,0 @@ -require 'puppet/provider/elastic_parsedfile' - -Puppet::Type.type(:elasticsearch_user_file).provide( - :shield, - :parent => Puppet::Provider::ElasticParsedFile -) do - desc 'Provider for Shield esusers using plain files.' - - shield_config 'users' - confine :exists => default_target - - has_feature :manages_encrypted_passwords - - text_line :comment, - :match => /^\s*#/ - - record_line :shield, - :fields => %w[name hashed_password], - :separator => ':', - :joiner => ':' - - def self.valid_attr?(klass, attr_name) - if klass.respond_to? :parameters - klass.parameters.include?(attr_name) - else - true - end - end -end diff --git a/lib/puppet/provider/elasticsearch_user_roles/shield.rb b/lib/puppet/provider/elasticsearch_user_roles/shield.rb deleted file mode 100644 index 52bd8a0..0000000 --- a/lib/puppet/provider/elasticsearch_user_roles/shield.rb +++ /dev/null @@ -1,11 +0,0 @@ -require 'puppet/provider/elastic_user_roles' - -Puppet::Type.type(:elasticsearch_user_roles).provide( - :shield, - :parent => Puppet::Provider::ElasticUserRoles -) do - desc 'Provider for Shield user roles (parsed file.)' - - shield_config 'users_roles' - confine :exists => default_target -end diff --git a/lib/puppet/type/elasticsearch_service_file.rb b/lib/puppet/type/elasticsearch_service_file.rb deleted file mode 100644 index 25b26a1..0000000 --- a/lib/puppet/type/elasticsearch_service_file.rb +++ /dev/null @@ -1,96 +0,0 @@ -$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', '..')) - -require 'puppet/util/checksums' - -require 'puppet_x/elastic/es_versioning' - -Puppet::Type.newtype(:elasticsearch_service_file) do - @doc = 'Manages elasticsearch service files.' - - ensurable - - newparam(:name, :namevar => true) do - desc 'Fully qualified path to the service file.' - end - - newproperty(:content) do - include Puppet::Util::Checksums - - desc 'Service file contents in erb template form.' - - # Interploate the erb source before comparing it to the on-disk - # init script - def insync?(is) - _opt_flag, opt_flags = Puppet_X::Elastic::EsVersioning.opt_flags( - resource[:package_name], resource.catalog - ) - # This should only be present on systemd systems. - opt_flags.delete('--quiet') unless resource[:name].include?('systemd') - - template = ERB.new(should, 0, '-') - is == template.result(binding) - rescue ElasticsearchPackageNotFoundError - # This behavior is extremely confusing because of the fact that while - # someone should be able to indicate that an instance should be absent, - # if there is no service file to query via Puppet providers, it can't - # determine this fact. If no package exists and thus `absent` has been - # instructed, indicate that the template contents are correct, because - # we don't really care what's in there anyway - the service file is for - # an absent instance of Elasticsearch anyway. - return true - end - - # Represent as a checksum, not the whole file - def change_to_s(currentvalue, newvalue) - algo = Puppet[:digest_algorithm].to_sym - - if currentvalue == :absent - return "defined content as '#{send(algo, newvalue)}'" - elsif newvalue == :absent - return "undefined content from '#{send(algo, currentvalue)}'" - else - return "content changed '#{send(algo, currentvalue)}' to '#{send(algo, newvalue)}'" - end - end - end - - newparam(:defaults_location) do - desc 'File path to defaults file.' - end - - newparam(:group) do - desc 'Group to run service under.' - end - - newparam(:homedir) do - desc 'Elasticsearch home directory.' - end - - newparam(:instance) do - desc 'Elasticsearch instance name.' - end - - newparam(:memlock) do - desc 'Memlock setting for service.' - end - - newparam(:nofile) do - desc 'Service NOFILE ulimit.' - end - - newparam(:nproc) do - desc 'Service NPROC ulimit.' - end - - newparam(:package_name) do - desc 'Name of the system Elasticsearch package.' - end - - newparam(:pid_dir) do - desc 'Directory to use for storing service PID.' - end - - newparam(:user) do - desc 'User to run service under.' - end -end diff --git a/manifests/license.pp b/manifests/license.pp index 84fc297..866b857 100644 --- a/manifests/license.pp +++ b/manifests/license.pp @@ -1,96 +1,88 @@ # A defined type to control Elasticsearch licenses. # # @param ensure # Controls whether the named pipeline should be present or absent in # the cluster. # # @param api_basic_auth_password # HTTP basic auth password to use when communicating over the Elasticsearch # API. # # @param api_basic_auth_username # HTTP basic auth username to use when communicating over the Elasticsearch # API. # # @param api_ca_file # Path to a CA file which will be used to validate server certs when # communicating with the Elasticsearch API over HTTPS. # # @param api_ca_path # Path to a directory with CA files which will be used to validate server # certs when communicating with the Elasticsearch API over HTTPS. # # @param api_host # Host name or IP address of the ES instance to connect to. # # @param api_port # Port number of the ES instance to connect to # # @param api_protocol # Protocol that should be used to connect to the Elasticsearch API. # # @param api_timeout # Timeout period (in seconds) for the Elasticsearch API. # # @param content # License content in hash or string form. # -# @param security_plugin -# Which security plugin will be used to manage users, roles, and -# certificates. -# # @param validate_tls # Determines whether the validity of SSL/TLS certificates received from the # Elasticsearch API should be verified or ignored. # # @author Tyler Langlois # class elasticsearch::license ( - Enum['absent', 'present'] $ensure = 'present', - Optional[String] $api_basic_auth_password = $elasticsearch::api_basic_auth_password, - Optional[String] $api_basic_auth_username = $elasticsearch::api_basic_auth_username, - Optional[Stdlib::Absolutepath] $api_ca_file = $elasticsearch::api_ca_file, - Optional[Stdlib::Absolutepath] $api_ca_path = $elasticsearch::api_ca_path, - String $api_host = $elasticsearch::api_host, - Integer[0, 65535] $api_port = $elasticsearch::api_port, - Enum['http', 'https'] $api_protocol = $elasticsearch::api_protocol, - Integer $api_timeout = $elasticsearch::api_timeout, - Variant[String, Hash] $content = $elasticsearch::license, - Optional[Enum['shield', 'x-pack']] $security_plugin = $elasticsearch::security_plugin, - Boolean $validate_tls = $elasticsearch::validate_tls, + Enum['absent', 'present'] $ensure = 'present', + Optional[String] $api_basic_auth_password = $elasticsearch::api_basic_auth_password, + Optional[String] $api_basic_auth_username = $elasticsearch::api_basic_auth_username, + Optional[Stdlib::Absolutepath] $api_ca_file = $elasticsearch::api_ca_file, + Optional[Stdlib::Absolutepath] $api_ca_path = $elasticsearch::api_ca_path, + String $api_host = $elasticsearch::api_host, + Integer[0, 65535] $api_port = $elasticsearch::api_port, + Enum['http', 'https'] $api_protocol = $elasticsearch::api_protocol, + Integer $api_timeout = $elasticsearch::api_timeout, + Variant[String, Hash] $content = $elasticsearch::license, + Boolean $validate_tls = $elasticsearch::validate_tls, ) { if $content =~ String { $_content = parsejson($content) } else { $_content = $content } - $_security_plugin = regsubst($security_plugin, '-', '') - if $ensure == 'present' { Elasticsearch::Role <| |> -> Class['elasticsearch::license'] Elasticsearch::User <| |> -> Class['elasticsearch::license'] } es_instance_conn_validator { 'license-conn-validator': server => $api_host, port => $api_port, timeout => $api_timeout, } - -> elasticsearch_license { $_security_plugin: + -> elasticsearch_license { 'xpack': ensure => $ensure, content => $_content, protocol => $api_protocol, host => $api_host, port => $api_port, timeout => $api_timeout, username => $api_basic_auth_username, password => $api_basic_auth_password, ca_file => $api_ca_file, ca_path => $api_ca_path, validate_tls => $validate_tls, - provider => $_security_plugin, } } diff --git a/manifests/service.pp b/manifests/service.pp index b8d09e2..acf82a5 100644 --- a/manifests/service.pp +++ b/manifests/service.pp @@ -1,112 +1,85 @@ # This class exists to coordinate all service management related actions, # functionality and logical units in a central place. # # *Note*: "service" is the Puppet term and type for background processes # in general and is used in a platform-independent way. E.g. "service" means # "daemon" in relation to Unix-like systems. # # @param ensure # Controls if the managed resources shall be `present` or `absent`. # If set to `absent`, the managed software packages will be uninstalled, and # any traces of the packages will be purged as well as possible, possibly # including existing configuration files. # System modifications (if any) will be reverted as well as possible (e.g. # removal of created users, services, changed log settings, and so on). # This is a destructive parameter and should be used with care. # # @param init_defaults # Defaults file content in hash representation # # @param init_defaults_file # Defaults file as puppet resource # # @param init_template # Service file as a template # # @param service_flags # Flags to pass to the service. # # @param status # Defines the status of the service. If set to `enabled`, the service is # started and will be enabled at boot time. If set to `disabled`, the # service is stopped and will not be started at boot time. If set to `running`, # the service is started but will not be enabled at boot time. You may use # this to start a service on the first Puppet run instead of the system startup. # If set to `unmanaged`, the service will not be started at boot time and Puppet # does not care whether the service is running or not. For example, this may # be useful if a cluster management software is used to decide when to start # the service plus assuring it is running on the desired node. # # @author Richard Pijnenburg # @author Tyler Langlois # @author Gavin Williams # class elasticsearch::service { #### Service management if $::elasticsearch::ensure == 'present' { case $::elasticsearch::status { # make sure service is currently running, start it on boot 'enabled': { $_service_ensure = 'running' $_service_enable = true } # make sure service is currently stopped, do not start it on boot 'disabled': { $_service_ensure = 'stopped' $_service_enable = false } # make sure service is currently running, do not start it on boot 'running': { $_service_ensure = 'running' $_service_enable = false } # do not start service on boot, do not care whether currently running # or not 'unmanaged': { $_service_ensure = undef $_service_enable = false } default: { } } } else { # make sure the service is stopped and disabled (the removal itself will be # done by package.pp) $_service_ensure = 'stopped' $_service_enable = false } - # # TODO: Flesh this out - # $_service_require = undef - - # case $::elasticsearch::service_provider { - # 'init': { - - # $_service_provider = undef - # } - # 'openbsd': { - # # include elasticsearch::service::openbsd - # $_service_provider = undef - # } - # 'openrc': { - # # include elasticsearch::service::openrc - # $_service_provider = undef - # } - # 'systemd': { - # # include elasticsearch::service::systemd - # $_service_provider = 'systemd' - # } - # default: { - # fail("Unknown service provider ${::elasticsearch::service_provider}") - # } - # } - service { $::elasticsearch::service_name: ensure => $_service_ensure, enable => $_service_enable, - # provider => $_service_provider, - # require => $_service_require, } } diff --git a/spec/classes/000_elasticsearch_init_spec.rb b/spec/classes/000_elasticsearch_init_spec.rb index cbeb1f3..673aca7 100644 --- a/spec/classes/000_elasticsearch_init_spec.rb +++ b/spec/classes/000_elasticsearch_init_spec.rb @@ -1,397 +1,396 @@ require 'spec_helper' describe 'elasticsearch', :type => 'class' do default_params = { :config => { 'node.name' => 'foo' } } on_supported_os.each do |os, facts| context "on #{os}" do case facts[:os]['family'] when 'Debian' let(:defaults_path) { '/etc/default' } let(:system_service_folder) { '/lib/systemd/system' } let(:pkg_ext) { 'deb' } let(:pkg_prov) { 'dpkg' } let(:version_add) { '' } if (facts[:os]['name'] == 'Debian' and \ facts[:os]['release']['major'].to_i >= 8) or \ (facts[:os]['name'] == 'Ubuntu' and \ facts[:os]['release']['major'].to_i >= 15) let(:systemd_service_path) { '/lib/systemd/system' } test_pid = true else test_pid = false end when 'RedHat' let(:defaults_path) { '/etc/sysconfig' } let(:system_service_folder) { '/lib/systemd/system' } let(:pkg_ext) { 'rpm' } let(:pkg_prov) { 'rpm' } let(:version_add) { '-1' } if facts[:os]['release']['major'].to_i >= 7 let(:systemd_service_path) { '/lib/systemd/system' } test_pid = true else test_pid = false end when 'Suse' let(:defaults_path) { '/etc/sysconfig' } let(:pkg_ext) { 'rpm' } let(:pkg_prov) { 'rpm' } let(:version_add) { '-1' } if facts[:os]['name'] == 'OpenSuSE' and facts[:os]['release']['major'].to_i <= 12 let(:systemd_service_path) { '/lib/systemd/system' } else let(:systemd_service_path) { '/usr/lib/systemd/system' } end end let(:facts) do facts.merge('scenario' => '', 'common' => '') end let(:params) do default_params.merge({}) end # Varies depending on distro it { should contain_augeas("#{defaults_path}/elasticsearch") } it do should contain_file("#{defaults_path}/elasticsearch").with( :ensure => 'file', :group => 'elasticsearch', :owner => 'elasticsearch', :mode => '0640' ) end # Systemd-specific files if test_pid == true it { should contain_service('elasticsearch').with( :ensure => 'running', :enable => true ) } it { should contain_file('/usr/lib/tmpfiles.d/elasticsearch.conf') } end context 'java installation' do let(:pre_condition) do <<-MANIFEST include ::java MANIFEST end it { should contain_class('elasticsearch::config') .that_requires('Class[java]') } end context 'package installation' do context 'via repository' do context 'with specified version' do let(:params) do default_params.merge( :version => '1.0' ) end it { should contain_package('elasticsearch') .with(:ensure => "1.0#{version_add}") } end if facts[:os]['family'] == 'RedHat' context 'Handle special CentOS/RHEL package versioning' do let(:params) do default_params.merge( :version => '1.1-2' ) end it { should contain_package('elasticsearch') .with(:ensure => '1.1-2') } end end end context 'when setting package version and package_url' do let(:params) do default_params.merge( :version => '0.90.10', :package_url => "puppet:///path/to/some/es-0.90.10.#{pkg_ext}" ) end it { expect { should raise_error(Puppet::Error) } } end context 'via package_url setting' do ['file:/', 'ftp://', 'http://', 'https://', 'puppet:///'].each do |schema| context "using #{schema} schema" do let(:params) do default_params.merge( :package_url => "#{schema}domain-or-path/pkg.#{pkg_ext}" ) end unless schema.start_with? 'puppet' it { should contain_exec('create_package_dir_elasticsearch') .with(:command => 'mkdir -p /opt/elasticsearch/swdl') } it { should contain_file('/opt/elasticsearch/swdl') .with( :purge => false, :force => false, :require => 'Exec[create_package_dir_elasticsearch]' ) } end case schema when 'file:/' it { should contain_file( "/opt/elasticsearch/swdl/pkg.#{pkg_ext}" ).with( :source => "/domain-or-path/pkg.#{pkg_ext}", :backup => false ) } when 'puppet:///' it { should contain_file( "/opt/elasticsearch/swdl/pkg.#{pkg_ext}" ).with( :source => "#{schema}domain-or-path/pkg.#{pkg_ext}", :backup => false ) } else [true, false].each do |verify_certificates| context "with download_tool_verify_certificates '#{verify_certificates}'" do let(:params) do default_params.merge( :package_url => "#{schema}domain-or-path/pkg.#{pkg_ext}", :download_tool_verify_certificates => verify_certificates ) end flag = (not verify_certificates) ? ' --no-check-certificate' : '' it { should contain_exec('download_package_elasticsearch') .with( :command => "wget#{flag} -O /opt/elasticsearch/swdl/pkg.#{pkg_ext} #{schema}domain-or-path/pkg.#{pkg_ext} 2> /dev/null", :require => 'File[/opt/elasticsearch/swdl]' ) } end end end it { should contain_package('elasticsearch') .with( :ensure => 'present', :source => "/opt/elasticsearch/swdl/pkg.#{pkg_ext}", :provider => pkg_prov ) } end end context 'using http:// schema with proxy_url' do let(:params) do default_params.merge( :package_url => "http://www.domain.com/package.#{pkg_ext}", :proxy_url => 'http://proxy.example.com:12345/' ) end it { should contain_exec('download_package_elasticsearch') .with( :environment => [ 'use_proxy=yes', 'http_proxy=http://proxy.example.com:12345/', 'https_proxy=http://proxy.example.com:12345/' ] ) } end end end # package context 'when setting the module to absent' do let(:params) do default_params.merge( :ensure => 'absent' ) end case facts[:os]['family'] when 'Suse' it { should contain_package('elasticsearch') .with(:ensure => 'absent') } else it { should contain_package('elasticsearch') .with(:ensure => 'purged') } end it { should contain_file('/usr/share/elasticsearch/plugins') .with(:ensure => 'absent') } end context 'When managing the repository' do let(:params) do default_params.merge( :manage_repo => true ) end it { should contain_class('elastic_stack::repo') } end context 'When not managing the repository' do let(:params) do default_params.merge( :manage_repo => false ) end it { should compile.with_all_deps } end end end on_supported_os( :hardwaremodels => ['x86_64'], :supported_os => [ { 'operatingsystem' => 'CentOS', 'operatingsystemrelease' => ['7'] } ] ).each do |os, facts| context "on #{os}" do let(:facts) { facts.merge( :scenario => '', :common => '' ) } - context 'main class tests' do + describe 'main class tests' do # init.pp it { should compile.with_all_deps } it { should contain_class('elasticsearch') } it { should contain_class('elasticsearch::package') } it { should contain_class('elasticsearch::config') .that_requires('Class[elasticsearch::package]') } it { should contain_class('elasticsearch::service') .that_requires('Class[elasticsearch::config]') } # Base directories it { should contain_file('/etc/elasticsearch') } it { should contain_file('/usr/share/elasticsearch') } it { should contain_file('/usr/share/elasticsearch/lib') } it { should contain_file('/var/lib/elasticsearch') } it { should contain_exec('remove_plugin_dir') } end context 'package installation' do - context 'with default package' do + describe 'with default package' do it { should contain_package('elasticsearch') .with(:ensure => 'present') } it { should_not contain_package('my-elasticsearch') .with(:ensure => 'present') } end - context 'with specified package name' do + describe 'with specified package name' do let(:params) do default_params.merge( :package_name => 'my-elasticsearch' ) end it { should contain_package('elasticsearch') .with(:ensure => 'present', :name => 'my-elasticsearch') } it { should_not contain_package('elasticsearch') .with(:ensure => 'present', :name => 'elasticsearch') } end - context 'with auto upgrade enabled' do + describe 'with auto upgrade enabled' do let(:params) do default_params.merge( :autoupgrade => true ) end it { should contain_package('elasticsearch') .with(:ensure => 'latest') } end end - context 'running a a different user' do + describe 'running a a different user' do let(:params) do default_params.merge( :elasticsearch_user => 'myesuser', :elasticsearch_group => 'myesgroup' ) end it { should contain_file('/etc/elasticsearch') .with(:owner => 'root', :group => 'myesgroup') } it { should contain_file('/var/log/elasticsearch') .with(:owner => 'myesuser') } it { should contain_file('/usr/share/elasticsearch') .with(:owner => 'myesuser', :group => 'myesgroup') } it { should contain_file('/var/lib/elasticsearch') .with(:owner => 'myesuser', :group => 'myesgroup') } it { should contain_file('/var/run/elasticsearch') .with(:owner => 'myesuser') if facts[:os]['family'] == 'RedHat' } end # This check helps catch dependency cycles. context 'create_resource' do # Helper for these tests def singular(s) case s when 'indices' 'index' when 'snapshot_repositories' 'snapshot_repository' else s[0..-2] end end { 'indices' => { 'test-index' => {} }, # 'instances' => { 'es-instance' => {} }, 'pipelines' => { 'testpipeline' => { 'content' => {} } }, 'plugins' => { 'head' => {} }, 'roles' => { 'elastic_role' => {} }, 'scripts' => { 'foo' => { 'source' => 'puppet:///path/to/foo.groovy' } }, 'snapshot_repositories' => { 'backup' => { 'location' => '/backups' } }, 'templates' => { 'foo' => { 'content' => {} } }, 'users' => { 'elastic' => { 'password' => 'foobar' } } }.each_pair do |deftype, params| describe deftype do let(:params) do default_params.merge( - deftype => params, - :security_plugin => 'x-pack' + deftype => params ) end it { should compile } it { should send( "contain_elasticsearch__#{singular(deftype)}", params.keys.first ) } end end end describe 'oss' do let(:params) do default_params.merge(:oss => true) end it do should contain_package('elasticsearch').with( :name => 'elasticsearch-oss' ) end end end end end diff --git a/spec/classes/001_hiera_spec.rb b/spec/classes/001_hiera_spec.rb index 9f9daea..59484db 100644 --- a/spec/classes/001_hiera_spec.rb +++ b/spec/classes/001_hiera_spec.rb @@ -1,217 +1,217 @@ require 'spec_helper' describe 'elasticsearch', :type => 'class' do default_params = { :config => { 'node.name' => 'foo' } } let(:params) do default_params.merge({}) end on_supported_os( :hardwaremodels => ['x86_64'], :supported_os => [ { 'operatingsystem' => 'CentOS', 'operatingsystemrelease' => ['7'] } ] ).each do |os, facts| context "on #{os}" do context 'hiera' do describe 'indices' do context 'single indices' do let(:facts) { facts.merge(:scenario => 'singleindex') } it { should contain_elasticsearch__index('baz') .with( :ensure => 'present', :settings => { 'index' => { 'number_of_shards' => 1 } } ) } it { should contain_elasticsearch_index('baz') } it { should contain_es_instance_conn_validator( 'baz-index-conn-validator' ) } end context 'no indices' do let(:facts) { facts.merge(:scenario => '') } it { should_not contain_elasticsearch__index('baz') } end end context 'config' do let(:facts) { facts.merge(:scenario => 'singleinstance') } # TODO: Fix this # it { should contain_augeas('defaults') } it { should contain_datacat('/etc/elasticsearch/elasticsearch.yml') } it { should contain_datacat_fragment('main_config') } it { should contain_service('elasticsearch').with( :ensure => 'running', :enable => true ) } %w[elasticsearch.yml jvm.options log4j2.properties].each do |file| it { should contain_file("/etc/elasticsearch/#{file}") } end end # of config describe 'pipelines' do context 'single pipeline' do let(:facts) { facts.merge(:scenario => 'singlepipeline') } it { should contain_elasticsearch__pipeline('testpipeline') .with( :ensure => 'present', :content => { 'description' => 'Add the foo field', 'processors' => [ { 'set' => { 'field' => 'foo', 'value' => 'bar' } } ] } ) } it { should contain_elasticsearch_pipeline('testpipeline') } end context 'no pipelines' do let(:facts) { facts.merge(:scenario => '') } it { should_not contain_elasticsearch__pipeline('testpipeline') } end end describe 'plugins' do context 'single plugin' do let(:facts) { facts.merge(:scenario => 'singleplugin') } it { should contain_elasticsearch__plugin('mobz/elasticsearch-head') .with( :ensure => 'present', :module_dir => 'head' ) } it { should contain_elasticsearch_plugin('mobz/elasticsearch-head') } end context 'no plugins' do let(:facts) { facts.merge(:scenario => '') } it { should_not contain_elasticsearch__plugin( 'mobz/elasticsearch-head/1.0.0' ) } end end describe 'roles' do context 'single roles' do let(:facts) { facts.merge(:scenario => 'singlerole') } let(:params) do - default_params.merge(:security_plugin => 'x-pack') + default_params end it { should contain_elasticsearch__role('admin') .with( :ensure => 'present', :privileges => { 'cluster' => 'monitor', 'indices' => { '*' => 'all' } }, :mappings => [ 'cn=users,dc=example,dc=com' ] ) } it { should contain_elasticsearch_role('admin') } it { should contain_elasticsearch_role_mapping('admin') } end context 'no roles' do let(:facts) { facts.merge(:scenario => '') } it { should_not contain_elasticsearch__role('admin') } end end describe 'scripts' do context 'single scripts' do let(:facts) { facts.merge(:scenario => 'singlescript') } it { should contain_elasticsearch__script('myscript') .with( :ensure => 'present', :source => 'puppet:///file/here' ) } it { should contain_file('/usr/share/elasticsearch/scripts/here') } end context 'no roles' do let(:facts) { facts.merge(:scenario => '') } it { should_not contain_elasticsearch__script('myscript') } end end describe 'templates' do context 'single template' do let(:facts) { facts.merge(:scenario => 'singletemplate') } it { should contain_elasticsearch__template('foo') .with( :ensure => 'present', :content => { 'template' => 'foo-*', 'settings' => { 'index' => { 'number_of_replicas' => 0 } } } ) } it { should contain_elasticsearch_template('foo') } end context 'no templates' do let(:facts) { facts.merge(:scenario => '') } it { should_not contain_elasticsearch__template('foo') } end end describe 'users' do context 'single users' do let(:facts) { facts.merge(:scenario => 'singleuser') } let(:params) do - default_params.merge(:security_plugin => 'x-pack') + default_params end it { should contain_elasticsearch__user('elastic') .with( :ensure => 'present', :roles => ['admin'], :password => 'password' ) } it { should contain_elasticsearch_user('elastic') } end context 'no users' do let(:facts) { facts.merge(:scenario => '') } it { should_not contain_elasticsearch__user('elastic') } end end end end end end diff --git a/spec/classes/006_elasticsearch_license_spec.rb b/spec/classes/006_elasticsearch_license_spec.rb index 88da031..c5df878 100644 --- a/spec/classes/006_elasticsearch_license_spec.rb +++ b/spec/classes/006_elasticsearch_license_spec.rb @@ -1,85 +1,85 @@ require 'spec_helper' describe 'elasticsearch::license', :type => 'class' do # First, randomly select one of our supported OSes to run tests that apply # to any distro on_supported_os.to_a.sample(1).to_h.each do |os, facts| context "on #{os}" do let(:facts) do facts.merge('scenario' => '', 'common' => '') end - %w[shield x-pack].each do |plugin| - context "with #{plugin} plugin" do - let(:params) do - { - :security_plugin => plugin, - :content => { - 'license' => { - 'uid' => 'cbff45e7-c553-41f7-ae4f-9205eabd80xx', - 'type' => 'trial', - 'issue_date_in_millis' => 1_519_341_125_550, - 'expiry_date_in_millis' => 1_521_933_125_550, - 'max_nodes' => 1000, - 'issued_to' => 'test', - 'issuer' => 'elasticsearch', - 'signature' => 'secretvalue', - 'start_date_in_millis' => 1_513_814_400_000 - } + context 'when managing x-pack license' do + let(:params) do + { + :content => { + 'license' => { + 'uid' => 'cbff45e7-c553-41f7-ae4f-9205eabd80xx', + 'type' => 'trial', + 'issue_date_in_millis' => 1_519_341_125_550, + 'expiry_date_in_millis' => 1_521_933_125_550, + 'max_nodes' => 1000, + 'issued_to' => 'test', + 'issuer' => 'elasticsearch', + 'signature' => 'secretvalue', + 'start_date_in_millis' => 1_513_814_400_000 } } - end + } + end - let(:pre_condition) do - <<-EOS - class { 'elasticsearch' : - api_protocol => 'https', - api_host => '127.0.0.1', - api_port => 9201, - api_timeout => 11, - api_basic_auth_username => 'elastic', - api_basic_auth_password => 'password', - api_ca_file => '/foo/bar.pem', - api_ca_path => '/foo/', - validate_tls => false, - } - EOS - end + let(:pre_condition) do + <<-EOS + class { 'elasticsearch' : + api_protocol => 'https', + api_host => '127.0.0.1', + api_port => 9201, + api_timeout => 11, + api_basic_auth_username => 'elastic', + api_basic_auth_password => 'password', + api_ca_file => '/foo/bar.pem', + api_ca_path => '/foo/', + validate_tls => false, + } + EOS + end - it do - should contain_class('elasticsearch::license') - should contain_es_instance_conn_validator( - 'license-conn-validator' - ).that_comes_before("elasticsearch_license[#{plugin.delete('-')}]") - should contain_elasticsearch_license(plugin.delete('-')).with( - :ensure => 'present', - :content => { - 'license' => { - 'uid' => 'cbff45e7-c553-41f7-ae4f-9205eabd80xx', - 'type' => 'trial', - 'issue_date_in_millis' => 1_519_341_125_550, - 'expiry_date_in_millis' => 1_521_933_125_550, - 'max_nodes' => 1000, - 'issued_to' => 'test', - 'issuer' => 'elasticsearch', - 'signature' => 'secretvalue', - 'start_date_in_millis' => 1_513_814_400_000 - } - }, - :protocol => 'https', - :host => '127.0.0.1', - :port => 9201, - :timeout => 11, - :username => 'elastic', - :password => 'password', - :ca_file => '/foo/bar.pem', - :ca_path => '/foo/', - :validate_tls => false, - :provider => plugin.delete('-') - ) - end + it do + should contain_class('elasticsearch::license') + end + it do + should contain_es_instance_conn_validator( + 'license-conn-validator' + ).that_comes_before("elasticsearch_license[xpack]") + end + it do + should contain_elasticsearch_license('xpack').with( + :ensure => 'present', + :content => { + 'license' => { + 'uid' => 'cbff45e7-c553-41f7-ae4f-9205eabd80xx', + 'type' => 'trial', + 'issue_date_in_millis' => 1_519_341_125_550, + 'expiry_date_in_millis' => 1_521_933_125_550, + 'max_nodes' => 1000, + 'issued_to' => 'test', + 'issuer' => 'elasticsearch', + 'signature' => 'secretvalue', + 'start_date_in_millis' => 1_513_814_400_000 + } + }, + :protocol => 'https', + :host => '127.0.0.1', + :port => 9201, + :timeout => 11, + :username => 'elastic', + :password => 'password', + :ca_file => '/foo/bar.pem', + :ca_path => '/foo/', + :validate_tls => false + ) end end end end end diff --git a/spec/unit/provider/elasticsearch_license/all_spec.rb b/spec/unit/provider/elasticsearch_license/all_spec.rb deleted file mode 100644 index 8018274..0000000 --- a/spec/unit/provider/elasticsearch_license/all_spec.rb +++ /dev/null @@ -1,66 +0,0 @@ -require_relative '../../../helpers/unit/provider/elasticsearch_rest_shared_examples' - -{ - 'shield' => 'license', - 'xpack' => 'xpack/license' -}.each_pair do |plugin, endpoint| - describe Puppet::Type.type(:elasticsearch_license).provider(plugin.to_sym) do - let(:name) { plugin } - - let(:example_1) do - { - :name => plugin, - :ensure => :present, - :provider => plugin.to_sym, - :content => { - 'license' => { - 'status' => 'active', - 'uid' => 'cbff45e7-c553-41f7-ae4f-9205eabd80xx', - 'type' => 'trial', - 'issue_date' => '2018-02-22T23:12:05.550Z', - 'issue_date_in_millis' => 1_519_341_125_550, - 'expiry_date' => '2018-03-24T23:12:05.550Z', - 'expiry_date_in_millis' => 1_521_933_125_550, - 'max_nodes' => 1_000, - 'issued_to' => 'test', - 'issuer' => 'elasticsearch', - 'start_date_in_millis' => 1_513_814_400_000 - } - } - } - end - - let(:json_1) do - { - 'license' => { - 'status' => 'active', - 'uid' => 'cbff45e7-c553-41f7-ae4f-9205eabd80xx', - 'type' => 'trial', - 'issue_date' => '2018-02-22T23:12:05.550Z', - 'issue_date_in_millis' => '1519341125550', - 'expiry_date' => '2018-03-24T23:12:05.550Z', - 'expiry_date_in_millis' => '1521933125550', - 'max_nodes' => '1000', - 'issued_to' => 'test', - 'issuer' => 'elasticsearch', - 'start_date_in_millis' => '1513814400000' - } - } - end - - let(:resource) { Puppet::Type::Elasticsearch_index.new props } - let(:provider) { described_class.new resource } - let(:props) do - { - :name => name, - :settings => { - 'index' => { - 'number_of_replicas' => 0 - } - } - } - end - - include_examples 'REST API', endpoint, nil, true - end -end diff --git a/spec/unit/provider/elasticsearch_license/x-pack_spec.rb b/spec/unit/provider/elasticsearch_license/x-pack_spec.rb new file mode 100644 index 0000000..1bfcd01 --- /dev/null +++ b/spec/unit/provider/elasticsearch_license/x-pack_spec.rb @@ -0,0 +1,61 @@ +require_relative '../../../helpers/unit/provider/elasticsearch_rest_shared_examples' + +describe Puppet::Type.type(:elasticsearch_license).provider(:xpack) do + let(:name) { 'xpack' } + + let(:example_1) do + { + :name => 'xpack', + :ensure => :present, + :provider => :xpack, + :content => { + 'license' => { + 'status' => 'active', + 'uid' => 'cbff45e7-c553-41f7-ae4f-9205eabd80xx', + 'type' => 'trial', + 'issue_date' => '2018-02-22T23:12:05.550Z', + 'issue_date_in_millis' => 1_519_341_125_550, + 'expiry_date' => '2018-03-24T23:12:05.550Z', + 'expiry_date_in_millis' => 1_521_933_125_550, + 'max_nodes' => 1_000, + 'issued_to' => 'test', + 'issuer' => 'elasticsearch', + 'start_date_in_millis' => 1_513_814_400_000 + } + } + } + end + + let(:json_1) do + { + 'license' => { + 'status' => 'active', + 'uid' => 'cbff45e7-c553-41f7-ae4f-9205eabd80xx', + 'type' => 'trial', + 'issue_date' => '2018-02-22T23:12:05.550Z', + 'issue_date_in_millis' => '1519341125550', + 'expiry_date' => '2018-03-24T23:12:05.550Z', + 'expiry_date_in_millis' => '1521933125550', + 'max_nodes' => '1000', + 'issued_to' => 'test', + 'issuer' => 'elasticsearch', + 'start_date_in_millis' => '1513814400000' + } + } + end + + let(:resource) { Puppet::Type::Elasticsearch_index.new props } + let(:provider) { described_class.new resource } + let(:props) do + { + :name => name, + :settings => { + 'index' => { + 'number_of_replicas' => 0 + } + } + } + end + + include_examples 'REST API', 'xpack/license', nil, true +end diff --git a/spec/unit/provider/elasticsearch_role/all_spec.rb b/spec/unit/provider/elasticsearch_role/all_spec.rb index 7ce018c..fe026b4 100644 --- a/spec/unit/provider/elasticsearch_role/all_spec.rb +++ b/spec/unit/provider/elasticsearch_role/all_spec.rb @@ -1,61 +1,61 @@ require 'spec_helper_rspec' -[:oss_xpack, :shield, :xpack].each do |provider| +[:oss_xpack, :xpack].each do |provider| describe Puppet::Type.type(:elasticsearch_role).provider(provider) do describe 'instances' do it 'should have an instance method' do expect(described_class).to respond_to :instances end context 'with no roles' do it 'should return no resources' do expect(described_class.parse("\n")).to eq([]) end end context 'with one role' do it 'should return one resource' do expect(described_class.parse(%( admin: cluster: all indices: '*': all ))[0]).to eq( :ensure => :present, :name => 'admin', :privileges => { 'cluster' => 'all', 'indices' => { '*' => 'all' } } ) end end context 'with multiple roles' do it 'should return three resources' do expect(described_class.parse(%( admin: cluster: all indices: '*': all user: indices: '*': read power_user: cluster: monitor indices: '*': all )).length).to eq(3) end end end # of describe instances describe 'prefetch' do it 'should have a prefetch method' do expect(described_class).to respond_to :prefetch end end end # of describe puppet type end diff --git a/spec/unit/provider/elasticsearch_role_mapping/all_spec.rb b/spec/unit/provider/elasticsearch_role_mapping/all_spec.rb index 095f5ef..53e1891 100644 --- a/spec/unit/provider/elasticsearch_role_mapping/all_spec.rb +++ b/spec/unit/provider/elasticsearch_role_mapping/all_spec.rb @@ -1,53 +1,53 @@ require 'spec_helper_rspec' -[:oss_xpack, :shield, :xpack].each do |provider| +[:oss_xpack, :xpack].each do |provider| describe Puppet::Type.type(:elasticsearch_role_mapping).provider(provider) do describe 'instances' do it 'should have an instance method' do expect(described_class).to respond_to :instances end context 'with no roles' do it 'should return no resources' do expect(described_class.parse("\n")).to eq([]) end end context 'with one role' do it 'should return one resource' do expect(described_class.parse(%( admin: - "cn=users,dc=example,dc=com" ))[0]).to eq( :ensure => :present, :name => 'admin', :mappings => [ 'cn=users,dc=example,dc=com' ] ) end end context 'with multiple roles' do it 'should return three resources' do expect(described_class.parse(%( admin: - "cn=users,dc=example,dc=com" user: - "cn=users,dc=example,dc=com" - "cn=admins,dc=example,dc=com" - "cn=John Doe,cn=other users,dc=example,dc=com" power_user: - "cn=admins,dc=example,dc=com" )).length).to eq(3) end end end # of describe instances describe 'prefetch' do it 'should have a prefetch method' do expect(described_class).to respond_to :prefetch end end end # of describe puppet type end diff --git a/spec/unit/provider/elasticsearch_user_file/all_spec.rb b/spec/unit/provider/elasticsearch_user_file/all_spec.rb index 8bd1ea9..83bab2e 100644 --- a/spec/unit/provider/elasticsearch_user_file/all_spec.rb +++ b/spec/unit/provider/elasticsearch_user_file/all_spec.rb @@ -1,46 +1,46 @@ require 'spec_helper_rspec' -[:oss_xpack, :shield, :xpack].each do |provider| +[:oss_xpack, :xpack].each do |provider| describe Puppet::Type.type(:elasticsearch_user_file).provider(provider) do describe 'instances' do it 'should have an instance method' do expect(described_class).to respond_to :instances end context 'without users' do it 'should return no resources' do expect(described_class.parse("\n")).to eq([]) end end context 'with one user' do it 'should return one resource' do expect(described_class.parse(%( elastic:$2a$10$DddrTs0PS3qNknUTq0vpa.g.0JpU.jHDdlKp1xox1W5ZHX.w8Cc8C ).gsub(/^\s+/, ''))[0]).to eq( :name => 'elastic', :hashed_password => '$2a$10$DddrTs0PS3qNknUTq0vpa.g.0JpU.jHDdlKp1xox1W5ZHX.w8Cc8C', :record_type => provider ) end end context 'with multiple users' do it 'should return three resources' do expect(described_class.parse(%( admin:$2a$10$DddrTs0PS3qNknUTq0vpa.g.0JpU.jHDdlKp1xox1W5ZHX.w8Cc8C user:$2a$10$caYr8GhYeJ2Yo0yEhQhQvOjLSwt8Lm6MKQWx8WSnZ/L/IL5sGdQFu kibana:$2a$10$daYr8GhYeJ2Yo0yEhQhQvOjLSwt8Lm6MKQWx8WSnZ/L/IL5sGdQFu ).gsub(/^\s+/, '')).length).to eq(3) end end end # of describe instances describe 'prefetch' do it 'should have a prefetch method' do expect(described_class).to respond_to :prefetch end end end # of describe puppet type end diff --git a/spec/unit/provider/elasticsearch_user_roles/all_spec.rb b/spec/unit/provider/elasticsearch_user_roles/all_spec.rb index e79808a..7b74ace 100644 --- a/spec/unit/provider/elasticsearch_user_roles/all_spec.rb +++ b/spec/unit/provider/elasticsearch_user_roles/all_spec.rb @@ -1,46 +1,46 @@ require 'spec_helper_rspec' -[:oss_xpack, :shield, :xpack].each do |provider| +[:oss_xpack, :xpack].each do |provider| describe Puppet::Type.type(:elasticsearch_user_roles) .provider(provider) do describe 'instances' do it 'should have an instance method' do expect(described_class).to respond_to :instances end context 'without roles' do it 'should return no resources' do expect(described_class.parse("\n")).to eq([]) end end context 'with one user' do it 'should return one resource' do expect(described_class.parse(%( admin:elastic power_user:elastic ))[0]).to eq( :name => 'elastic', :roles => %w[admin power_user] ) end end context 'with multiple users' do it 'should return three resources' do expect(described_class.parse(%( admin:elastic logstash:user kibana:kibana )).length).to eq(3) end end end # of describe instances describe 'prefetch' do it 'should have a prefetch method' do expect(described_class).to respond_to :prefetch end end end # of describe puppet type end diff --git a/spec/unit/type/elasticsearch_service_file_spec.rb b/spec/unit/type/elasticsearch_service_file_spec.rb deleted file mode 100644 index 930d9c9..0000000 --- a/spec/unit/type/elasticsearch_service_file_spec.rb +++ /dev/null @@ -1,73 +0,0 @@ -require 'spec_helper_rspec' - -describe Puppet::Type.type(:elasticsearch_service_file) do - let(:resource_name) { '/usr/lib/systemd/system/elasticsearch-es-01.service' } - - describe 'attribute validation' do - [ - :name, - :defaults_location, - :group, - :instance, - :homedir, - :memlock, - :nofile, - :nproc, - :package_name, - :pid_dir, - :user - ].each do |param| - it "should have a #{param} parameter" do - expect(described_class.attrtype(param)).to eq(:param) - end - end - - [:content, :ensure].each do |prop| - it "should have a #{prop} property" do - expect(described_class.attrtype(prop)).to eq(:property) - end - end - - describe 'namevar validation' do - it 'should have :name as its namevar' do - expect(described_class.key_attributes).to eq([:name]) - end - end - - describe 'content' do - it 'should accept simple strings' do - expect(described_class.new( - :name => resource_name, - :content => "Test\n" - )[:content]).to eq( - "Test\n" - ) - end - end - - describe 'ensure' do - it 'should support present as a value for ensure' do - expect { described_class.new( - :name => resource_name, - :ensure => :present, - :content => {} - ) }.to_not raise_error - end - - it 'should support absent as a value for ensure' do - expect { described_class.new( - :name => resource_name, - :ensure => :absent - ) }.to_not raise_error - end - - it 'should not support other values' do - expect { described_class.new( - :name => resource_name, - :ensure => :foo, - :content => {} - ) }.to raise_error(Puppet::Error, /Invalid value/) - end - end - end # of describing when validing values -end # of describe Puppet::Type