From c3236775e22739f78bac6277cf1e5e7ff7f4b2ce Mon Sep 17 00:00:00 2001 From: Tim Smith Date: Mon, 5 Feb 2018 10:27:00 +0100 Subject: Add new Redhat Subscription Manager resources Initial commit of new RHSM resources from the Chef managed cookbook for RHSM Signed-off-by: Tim Smith --- lib/chef/resource/rhsm_errata.rb | 45 ++++++ lib/chef/resource/rhsm_errata_level.rb | 53 +++++++ lib/chef/resource/rhsm_register.rb | 170 +++++++++++++++++++++++ lib/chef/resource/rhsm_repo.rb | 63 +++++++++ lib/chef/resource/rhsm_subscription.rb | 96 +++++++++++++ lib/chef/resources.rb | 5 + spec/unit/resource/rhsm_errata_level_spec.rb | 46 +++++++ spec/unit/resource/rhsm_errata_spec.rb | 35 +++++ spec/unit/resource/rhsm_register_spec.rb | 199 +++++++++++++++++++++++++++ spec/unit/resource/rhsm_repo_spec.rb | 59 ++++++++ spec/unit/resource/rhsm_subscription_spec.rb | 93 +++++++++++++ 11 files changed, 864 insertions(+) create mode 100644 lib/chef/resource/rhsm_errata.rb create mode 100644 lib/chef/resource/rhsm_errata_level.rb create mode 100644 lib/chef/resource/rhsm_register.rb create mode 100644 lib/chef/resource/rhsm_repo.rb create mode 100644 lib/chef/resource/rhsm_subscription.rb create mode 100644 spec/unit/resource/rhsm_errata_level_spec.rb create mode 100644 spec/unit/resource/rhsm_errata_spec.rb create mode 100644 spec/unit/resource/rhsm_register_spec.rb create mode 100644 spec/unit/resource/rhsm_repo_spec.rb create mode 100644 spec/unit/resource/rhsm_subscription_spec.rb diff --git a/lib/chef/resource/rhsm_errata.rb b/lib/chef/resource/rhsm_errata.rb new file mode 100644 index 0000000000..56779909f5 --- /dev/null +++ b/lib/chef/resource/rhsm_errata.rb @@ -0,0 +1,45 @@ +# +# Copyright:: 2015-2018 Chef Software, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require "chef/resource" + +class Chef + class Resource + class RhsmErrata < Chef::Resource + resource_name :rhsm_errata + + description "A resource for installing packages associated with a given Red"\ + " Hat Subscription Manager Errata ID. This is helpful if packages"\ + " to mitigate a single vulnerability must be installed on your hosts." + introduced "14.0" + + property :errata_id, + String, + description: "An optional property for specifying the errata ID if not using the resource's name.", + name_property: true + + action :install do + description "Installs a package for a specific errata ID" + + execute "Install errata packages for #{new_resource.errata_id}" do + command "yum update --advisory #{new_resource.errata_id} -y" + action :run + end + end + end + end +end diff --git a/lib/chef/resource/rhsm_errata_level.rb b/lib/chef/resource/rhsm_errata_level.rb new file mode 100644 index 0000000000..3aa289ac2e --- /dev/null +++ b/lib/chef/resource/rhsm_errata_level.rb @@ -0,0 +1,53 @@ +# +# Copyright:: 2015-2018 Chef Software, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require "chef/resource" + +class Chef + class Resource + class RhsmErrataLevel < Chef::Resource + resource_name :rhsm_errata_level + + description "A resource for installing all packages of a specified errata level"\ + " from the Red Hat Subscript Manager. For example, you can ensure"\ + " that all packages associated with errata marked at a 'Critical'"\ + " security level are installed." + introduced "14.0" + + property :errata_level, + String, + coerce: proc { |x| x.downcase }, + equal_to: %w{critical moderate important low}, + description: "The errata level of packages to install.", + name_property: true + + action :install do + descripton "Install all packages of the specified errata level" + + yum_package "yum-plugin-security" do + action :install + only_if { node["platform_version"].to_i == 6 } + end + + execute "Install any #{new_resource.errata_level} errata" do + command "yum update --sec-severity=#{new_resource.errata_level.capitalize} -y" + action :run + end + end + end + end +end diff --git a/lib/chef/resource/rhsm_register.rb b/lib/chef/resource/rhsm_register.rb new file mode 100644 index 0000000000..47fe67d1cf --- /dev/null +++ b/lib/chef/resource/rhsm_register.rb @@ -0,0 +1,170 @@ +# +# Copyright:: 2015-2018 Chef Software, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require "chef/resource" +require "shellwords" + +class Chef + class Resource + class RhsmRegister < Chef::Resource + resource_name :rhsm_register + + description "A resource for registering a node with the Red Hat Subscription Manager"\ + " or a local Red Hat Satellite server." + introduced "14.0" + + property :activation_key, + [String, Array], + coerce: proc { |x| Array(x) }, + description: "A String or array of the activation keys to use when registering. You must also specify the organization property if using activation_key." + + property :satellite_host, + String, + description: "The FQDN of the Satellite host to register with. If not specified, the host will be registered with Red Hat's public RHSM service." + + property :organization, + String, + description: "The organization to use when registering, required when using an activation key" + + property :environment, + String, + description: "The environment to use when registering, required when using username and password" + + property :username, + String, + description: "The username to use when registering. Not applicable if using an activation key. If specified, password and environment are also required." + + property :password, + String, + description: "The password to use when registering. Not applicable if using an activation key. If specified, username and environment are also required." + + property :auto_attach, + [TrueClass, FalseClass], + description: "If true, RHSM will attempt to automatically attach the host to applicable subscriptions. It is generally better to use an activation key with the subscriptions pre-defined.", + default: false + + property :install_katello_agent, + [TrueClass, FalseClass], + description: "If true, the 'katello-agent' RPM will be installed.", + default: true + + property :force, + [TrueClass, FalseClass], + description: "If true, the system will be registered even if it is already registered. Normally, any register operations will fail if the machine is has already registered.", + default: false + + action :register do + description "Register the node with RHSM" + + package "subscription-manager" + + unless new_resource.satellite_host.nil? || registered_with_rhsm? + remote_file "#{Chef::Config[:file_cache_path]}/katello-package.rpm" do + source "http://#{new_resource.satellite_host}/pub/katello-ca-consumer-latest.noarch.rpm" + action :create + notifies :install, "yum_package[katello-ca-consumer-latest]", :immediately + not_if { katello_cert_rpm_installed? } + end + + yum_package "katello-ca-consumer-latest" do + options "--nogpgcheck" + source "#{Chef::Config[:file_cache_path]}/katello-package.rpm" + action :nothing + end + + file "#{Chef::Config[:file_cache_path]}/katello-package.rpm" do + action :delete + end + end + + execute "Register to RHSM" do + sensitive new_resource.sensitive + command register_command + action :run + not_if { registered_with_rhsm? } + end + + yum_package "katello-agent" do + action :install + only_if { new_resource.install_katello_agent && !new_resource.satellite_host.nil? } + end + end + + action :unregister do + description "Unregister the node from RHSM" + + execute "Unregister from RHSM" do + command "subscription-manager unregister" + action :run + only_if { registered_with_rhsm? } + notifies :run, "execute[Clean RHSM Config]", :immediately + end + + execute "Clean RHSM Config" do + command "subscription-manager clean" + action :nothing + end + end + + action_class do + def registered_with_rhsm? + cmd = Mixlib::ShellOut.new("subscription-manager status", env: { LANG: "en_US" }) + cmd.run_command + !cmd.stdout.match(/Overall Status: Unknown/) + end + + def katello_cert_rpm_installed? + cmd = Mixlib::ShellOut.new("rpm -qa | grep katello-ca-consumer") + cmd.run_command + !cmd.stdout.match(/katello-ca-consumer/).nil? + end + + def register_command + command = %w{subscription-manager register} + + unless new_resource.activation_key.empty? + raise "Unable to register - you must specify organization when using activation keys" if new_resource.organization.nil? + + command << new_resource.activation_key.map { |key| "--activationkey=#{Shellwords.shellescape(key)}" } + command << "--org=#{Shellwords.shellescape(new_resource.organization)}" + command << "--force" if new_resource.force + + return command.join(" ") + end + + if new_resource.username && new_resource.password + raise "Unable to register - you must specify environment when using username/password" if new_resource.environment.nil? && using_satellite_host? + + command << "--username=#{Shellwords.shellescape(new_resource.username)}" + command << "--password=#{Shellwords.shellescape(new_resource.password)}" + command << "--environment=#{Shellwords.shellescape(new_resource.environment)}" if using_satellite_host? + command << "--auto-attach" if new_resource.auto_attach + command << "--force" if new_resource.force + + return command.join(" ") + end + + raise "Unable to create register command - you must specify activation_key or username/password" + end + + def using_satellite_host? + !new_resource.satellite_host.nil? + end + end + end + end +end diff --git a/lib/chef/resource/rhsm_repo.rb b/lib/chef/resource/rhsm_repo.rb new file mode 100644 index 0000000000..aef4dd43d6 --- /dev/null +++ b/lib/chef/resource/rhsm_repo.rb @@ -0,0 +1,63 @@ +# +# Copyright:: 2015-2018 Chef Software, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require "chef/resource" + +class Chef + class Resource + class RhsmRepo < Chef::Resource + resource_name :rhsm_repo + + description "A resource for enabling and disabling Red Hat Subscription Manager"\ + " repositories that are made available via attached subscriptions." + introduced "14.0" + + property :repo_name, + String, + description: "An optional property for specifying the repository name if not using the resource's name.", + name_property: true + + action :enable do + description "Enable a RHSM repository" + + execute "Enable repository #{repo_name}" do + command "subscription-manager repos --enable=#{repo_name}" + action :run + not_if { repo_enabled?(repo_name) } + end + end + + action :disable do + description "Disable a RHSM repository" + + execute "Enable repository #{repo_name}" do + command "subscription-manager repos --disable=#{repo_name}" + action :run + only_if { repo_enabled?(repo_name) } + end + end + + action_class do + def repo_enabled?(repo) + cmd = Mixlib::ShellOut.new("subscription-manager repos --list-enabled", env: { LANG: "en_US" }) + cmd.run_command + !cmd.stdout.match(/Repo ID:\s+#{repo}$/).nil? + end + end + end + end +end diff --git a/lib/chef/resource/rhsm_subscription.rb b/lib/chef/resource/rhsm_subscription.rb new file mode 100644 index 0000000000..41dd398cd5 --- /dev/null +++ b/lib/chef/resource/rhsm_subscription.rb @@ -0,0 +1,96 @@ +# +# Copyright:: 2015-2018 Chef Software, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require "chef/resource" + +class Chef + class Resource + class RhsmSubscription < Chef::Resource + resource_name :rhsm_subscription + + description "A resource for adding additional Redhat Subscription Manager subscriptions"\ + " to your host. This can be used when a host's activation_key"\ + " does not attach all necessary subscriptions to your host." + introduced "14.0" + + property :pool_id, + String, + description: "An optional property for specifying the Pool ID if not using the resource's name.", + name_property: true + + action :attach do + description "Attach the node to a subscription pool" + + execute "Attach subscription pool #{new_resource.pool_id}" do + command "subscription-manager attach --pool=#{new_resource.pool_id}" + action :run + not_if { subscription_attached?(new_resource.pool_id) } + end + end + + action :remove do + description "Remove the node from a subscription pool" + + execute "Remove subscription pool #{new_resource.pool_id}" do + command "subscription-manager remove --serial=#{pool_serial(new_resource.pool_id)}" + action :run + only_if { subscription_attached?(new_resource.pool_id) } + end + end + + action_class do + def subscription_attached?(subscription) + cmd = Mixlib::ShellOut.new("subscription-manager list --consumed | grep #{subscription}", env: { LANG: "en_US" }) + cmd.run_command + !cmd.stdout.match(/Pool ID:\s+#{subscription}$/).nil? + end + + def serials_by_pool + serials = {} + pool = nil + serial = nil + + cmd = Mixlib::ShellOut.new("subscription-manager list --consumed", env: { LANG: "en_US" }) + cmd.run_command + cmd.stdout.lines.each do |line| + line.strip! + key, value = line.split(/:\s+/, 2) + next unless ["Pool ID", "Serial"].include?(key) + + if key == "Pool ID" + pool = value + elsif key == "Serial" + serial = value + end + + next unless pool && serial + + serials[pool] = serial + pool = nil + serial = nil + end + + serials + end + + def pool_serial(pool_id) + serials_by_pool[pool_id] + end + end + end + end +end diff --git a/lib/chef/resources.rb b/lib/chef/resources.rb index b580a01c29..cc89de749f 100644 --- a/lib/chef/resources.rb +++ b/lib/chef/resources.rb @@ -67,6 +67,11 @@ require "chef/resource/reboot" require "chef/resource/registry_key" require "chef/resource/remote_directory" require "chef/resource/remote_file" +require "chef/resource/rhsm_errata_level" +require "chef/resource/rhsm_errata" +require "chef/resource/rhsm_register" +require "chef/resource/rhsm_repo" +require "chef/resource/rhsm_subscription" require "chef/resource/rpm_package" require "chef/resource/solaris_package" require "chef/resource/route" diff --git a/spec/unit/resource/rhsm_errata_level_spec.rb b/spec/unit/resource/rhsm_errata_level_spec.rb new file mode 100644 index 0000000000..3284107e75 --- /dev/null +++ b/spec/unit/resource/rhsm_errata_level_spec.rb @@ -0,0 +1,46 @@ +# +# Copyright:: Copyright 2018, Chef Software, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require "spec_helper" + +describe Chef::Resource::RhsmErrataLevel do + + let(:resource) { Chef::Resource::RhsmErrataLevel.new("moderate") } + + it "has a resource name of :rhsm_errata_level" do + expect(resource.resource_name).to eql(:rhsm_errata_level) + end + + it "has a default action of install" do + expect(resource.action).to eql([:install]) + end + + it "the errata_level property is the name property" do + expect(resource.errata_level).to eql("moderate") + end + + it "coerces the errata_level to be lowercase" do + resource.errata_level "Important" + expect(resource.errata_level).to eql("important") + end + + it "raises an exception if invalid errata_level is passed" do + expect do + resource.errata_level "FOO" + end.to raise_error(Chef::Exceptions::ValidationFailed) + end +end diff --git a/spec/unit/resource/rhsm_errata_spec.rb b/spec/unit/resource/rhsm_errata_spec.rb new file mode 100644 index 0000000000..8da7269ca8 --- /dev/null +++ b/spec/unit/resource/rhsm_errata_spec.rb @@ -0,0 +1,35 @@ +# +# Copyright:: Copyright 2018, Chef Software, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require "spec_helper" + +describe Chef::Resource::RhsmErrata do + + let(:resource) { Chef::Resource::RhsmErrata.new("foo") } + + it "has a resource name of :rhsm_errata" do + expect(resource.resource_name).to eql(:rhsm_errata) + end + + it "has a default action of install" do + expect(resource.action).to eql([:install]) + end + + it "the errata_id property is the name property" do + expect(resource.errata_id).to eql("foo") + end +end diff --git a/spec/unit/resource/rhsm_register_spec.rb b/spec/unit/resource/rhsm_register_spec.rb new file mode 100644 index 0000000000..2e360b5708 --- /dev/null +++ b/spec/unit/resource/rhsm_register_spec.rb @@ -0,0 +1,199 @@ +# +# Copyright:: Copyright 2018, Chef Software, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require "spec_helper" + +describe Chef::Resource::RhsmRegister do + + let(:resource) { Chef::Resource::RhsmRegister.new("foo") } + let(:provider) { resource.provider_for_action(:register) } + + it "has a resource name of :rhsm_register" do + expect(resource.resource_name).to eql(:rhsm_register) + end + + it "has a default action of register" do + expect(resource.action).to eql([:register]) + end + + it "coerces activation_key to an array" do + resource.activation_key "foo" + expect(resource.activation_key).to eql(["foo"]) + end + + describe "#katello_cert_rpm_installed?" do + let(:cmd) { double("cmd") } + + before do + allow(Mixlib::ShellOut).to receive(:new).and_return(cmd) + allow(cmd).to receive(:run_command) + end + + context "when the output contains katello-ca-consumer" do + it "returns true" do + allow(cmd).to receive(:stdout).and_return("katello-ca-consumer-somehostname-1.0-1") + expect(provider.katello_cert_rpm_installed?).to eq(true) + end + end + + context "when the output does not contain katello-ca-consumer" do + it "returns false" do + allow(cmd).to receive(:stdout).and_return("katello-agent-but-not-the-ca") + expect(provider.katello_cert_rpm_installed?).to eq(false) + end + end + end + + describe "#register_command" do + before do + allow(provider).to receive(:activation_key).and_return([]) + allow(provider).to receive(:auto_attach) + end + + context "when activation keys exist" do + before do + allow(resource).to receive(:activation_key).and_return(%w{key1 key2}) + end + + context "when no org exists" do + it "raises an exception" do + allow(resource).to receive(:organization).and_return(nil) + expect { provider.register_command }.to raise_error(RuntimeError) + end + end + + context "when an org exists" do + it "returns a command containing the keys and org" do + allow(resource).to receive(:organization).and_return("myorg") + + expect(provider.register_command).to match("--activationkey=key1 --activationkey=key2 --org=myorg") + end + end + + context "when auto_attach is true" do + it "does not return a command with --auto-attach since it is not supported with activation keys" do + allow(resource).to receive(:organization).and_return("myorg") + allow(resource).to receive(:auto_attach).and_return(true) + + expect(provider.register_command).not_to match("--auto-attach") + end + end + end + + context "when username and password exist" do + before do + allow(resource).to receive(:username).and_return("myuser") + allow(resource).to receive(:password).and_return("mypass") + allow(resource).to receive(:environment) + allow(resource).to receive(:using_satellite_host?) + allow(resource).to receive(:activation_key).and_return([]) + end + + context "when auto_attach is true" do + it "returns a command containing --auto-attach" do + allow(resource).to receive(:auto_attach).and_return(true) + + expect(provider.register_command).to match("--auto-attach") + end + end + + context "when auto_attach is false" do + it "returns a command that does not contain --auto-attach" do + allow(resource).to receive(:auto_attach).and_return(false) + + expect(provider.register_command).not_to match("--auto-attach") + end + end + + context "when auto_attach is nil" do + it "returns a command that does not contain --auto-attach" do + allow(resource).to receive(:auto_attach).and_return(nil) + + expect(provider.register_command).not_to match("--auto-attach") + end + end + + context "when environment does not exist" do + context "when registering to a satellite server" do + it "raises an exception" do + allow(provider).to receive(:using_satellite_host?).and_return(true) + allow(resource).to receive(:environment).and_return(nil) + expect { provider.register_command }.to raise_error(RuntimeError) + end + end + + context "when registering to RHSM proper" do + before do + allow(provider).to receive(:using_satellite_host?).and_return(false) + allow(resource).to receive(:environment).and_return(nil) + end + + it "does not raise an exception" do + expect { provider.register_command }.not_to raise_error + end + + it "returns a command containing the username and password and no environment" do + allow(resource).to receive(:environment).and_return("myenv") + expect(provider.register_command).to match("--username=myuser --password=mypass") + expect(provider.register_command).not_to match("--environment") + end + end + end + + context "when an environment exists" do + it "returns a command containing the username, password, and environment" do + allow(provider).to receive(:using_satellite_host?).and_return(true) + allow(resource).to receive(:environment).and_return("myenv") + expect(provider.register_command).to match("--username=myuser --password=mypass --environment=myenv") + end + end + end + + context "when no activation keys, username, or password exist" do + it "raises an exception" do + allow(resource).to receive(:activation_key).and_return([]) + allow(resource).to receive(:username).and_return(nil) + allow(resource).to receive(:password).and_return(nil) + + expect { provider.register_command }.to raise_error(RuntimeError) + end + end + end + + describe "#registered_with_rhsm?" do + let(:cmd) { double("cmd") } + + before do + allow(Mixlib::ShellOut).to receive(:new).and_return(cmd) + allow(cmd).to receive(:run_command) + end + + context "when the status is Unknown" do + it "returns false" do + allow(cmd).to receive(:stdout).and_return("Overall Status: Unknown") + expect(provider.registered_with_rhsm?).to eq(false) + end + end + + context "when the status is anything else" do + it "returns true" do + allow(cmd).to receive(:stdout).and_return("Overall Status: Insufficient") + expect(provider.registered_with_rhsm?).to eq(true) + end + end + end +end diff --git a/spec/unit/resource/rhsm_repo_spec.rb b/spec/unit/resource/rhsm_repo_spec.rb new file mode 100644 index 0000000000..97606a03c8 --- /dev/null +++ b/spec/unit/resource/rhsm_repo_spec.rb @@ -0,0 +1,59 @@ +# +# Copyright:: Copyright 2018, Chef Software, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require "spec_helper" + +describe Chef::Resource::RhsmRepo do + + let(:resource) { Chef::Resource::RhsmRepo.new("foo") } + let(:provider) { resource.provider_for_action(:enable) } + + it "has a resource name of :rhsm_repo" do + expect(resource.resource_name).to eql(:rhsm_repo) + end + + it "has a default action of enable" do + expect(resource.action).to eql([:enable]) + end + + it "the repo_name property is the name property" do + expect(resource.repo_name).to eql("foo") + end + + describe "#repo_enabled?" do + let(:cmd) { double("cmd") } + let(:output) { "Repo ID: repo123" } + + before do + allow(Mixlib::ShellOut).to receive(:new).and_return(cmd) + allow(cmd).to receive(:run_command) + allow(cmd).to receive(:stdout).and_return(output) + end + + context "when the repo provided matches the output" do + it "returns true" do + expect(provider.repo_enabled?("repo123")).to eq(true) + end + end + + context "when the repo provided does not match the output" do + it "returns false" do + expect(provider.repo_enabled?("differentrepo")).to eq(false) + end + end + end +end diff --git a/spec/unit/resource/rhsm_subscription_spec.rb b/spec/unit/resource/rhsm_subscription_spec.rb new file mode 100644 index 0000000000..0160624f39 --- /dev/null +++ b/spec/unit/resource/rhsm_subscription_spec.rb @@ -0,0 +1,93 @@ +# +# Copyright:: Copyright 2018, Chef Software, Inc. +# License:: Apache License, Version 2.0 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require "spec_helper" + +describe Chef::Resource::RhsmSubscription do + let(:resource) { Chef::Resource::RhsmSubscription.new("foo") } + let(:provider) { resource.provider_for_action(:attach) } + + it "has a resource name of :rhsm_subscription" do + expect(resource.resource_name).to eql(:rhsm_subscription) + end + + it "has a default action of attach" do + expect(resource.action).to eql([:attach]) + end + + it "the pool_id property is the name property" do + expect(resource.pool_id).to eql("foo") + end + + describe "#subscription_attached?" do + let(:cmd) { double("cmd") } + let(:output) { "Pool ID: pool123" } + + before do + allow(Mixlib::ShellOut).to receive(:new).and_return(cmd) + allow(cmd).to receive(:run_command) + allow(cmd).to receive(:stdout).and_return(output) + end + + context "when the pool provided matches the output" do + it "returns true" do + expect(provider.subscription_attached?("pool123")).to eq(true) + end + end + + context "when the pool provided does not match the output" do + it "returns false" do + expect(provider.subscription_attached?("differentpool")).to eq(false) + end + end + end + + describe "#serials_by_pool" do + let(:cmd) { double("cmd") } + let(:output) do + <<~EOL + Key1: value1 + Pool ID: pool1 + Serial: serial1 + Key2: value2 + + Key1: value1 + Pool ID: pool2 + Serial: serial2 + Key2: value2 +EOL + end + + it "parses the output correctly" do + allow(Mixlib::ShellOut).to receive(:new).and_return(cmd) + allow(cmd).to receive(:run_command) + allow(cmd).to receive(:stdout).and_return(output) + + expect(provider.serials_by_pool["pool1"]).to eq("serial1") + expect(provider.serials_by_pool["pool2"]).to eq("serial2") + end + end + + describe "#pool_serial" do + let(:serials) { { "pool1" => "serial1", "pool2" => "serial2" } } + + it "returns the serial for a given pool" do + allow(provider).to receive(:serials_by_pool).and_return(serials) + expect(provider.pool_serial("pool1")).to eq("serial1") + end + end +end -- cgit v1.2.1