module MotherBrain::Mixin::AttributeSetting
Public Instance Methods
Set the appropriate attributes at the environment level to the desired version for each component given
@param [String] env_id
the name identifier of the environment to modify
@param [MB::Plugin] plugin
the plugin to use for finding the appropriate version attributes
@param [Hash] component_versions
Hash of components and the versions to set them to
@raise [MB::EnvironmentNotFound] if the environment does not exist
@example setting the versions of multiple components on an environment
set_component_versions("test-environment", "component_one" => "1.0.0", "component_two" => "2.3.0" )
# File lib/mb/mixin/attribute_setting.rb, line 28 def set_component_versions(env_id, plugin, component_versions) default_attributes = Hash.new component_versions.each do |component_name, version| version_hash = Hash.from_dotted_path(version_attribute(plugin, component_name), version) default_attributes.deep_merge!(version_hash) end log.info "Setting component versions #{component_versions}" unless env = chef_connection.environment.find(env_id) raise EnvironmentNotFound.new(env_id) end env.default_attributes.merge!(default_attributes) env.save end
Lock the cookbook versions on the target environment from the given hash of cookbooks and versions
@param [String] env_id
the name identifier of the environment to modify
@param [Hash] cookbook_versions
Hash of cookbooks and the versions to set them to
@raise [MB::EnvironmentNotFound] if the environment does not exist
@example setting cookbook versions on an environment
set_cookbook_versions("test-environment", "league" => "1.74.2", "pvpnet" => "3.2.0" )
@raise [ArgumentError] if given invalid version constraints
# File lib/mb/mixin/attribute_setting.rb, line 64 def set_cookbook_versions(env_id, cookbook_versions) cookbook_versions = expand_constraints(expand_latest_versions(cookbook_versions)) satisfies_constraints?(cookbook_versions) log.info "Setting cookbook versions #{cookbook_versions}" unless env = chef_connection.environment.find(env_id) raise EnvironmentNotFound.new(env_id) end env.cookbook_versions.merge!(cookbook_versions) env.save end
Set environment level attributes on an environment from a hash containing keys identifying attributes using the dot notation syntax and values of those attributes as values.
@param [String] env_id
the name identifier of the environment to modify
@param [Hash] new_attributes
Hash of attributes and values
@example setting multiple attributes on an environment
set_environment_attributes("test-environment", "foo" => "bar", "baz.quux" => 42 )
# File lib/mb/mixin/attribute_setting.rb, line 92 def set_environment_attributes(env_id, new_attributes) default_attributes = Hash.new new_attributes.each do |attribute, value| attribute_hash = Hash.from_dotted_path(attribute.to_s, value.to_s) default_attributes.deep_merge!(attribute_hash) end set_environment_attributes_from_hash(env_id, default_attributes) end
Set environment level attributes on an environment from the contents of the file at the given filepath
@param [String] env_id
the name of the environment to modify
@param [String] filepath
path to the file to read attributes from
@param [Symbol] type
the type of the contents found within the file
@raise [InvalidAttributesFile]
if the contents of the attributes file are missing or not well formed
@raise [ArgumentError]
if an unknown value for the 'type' parameter is specified
# File lib/mb/mixin/attribute_setting.rb, line 145 def set_environment_attributes_from_file(env_id, filepath, type = :json) contents = File.read(filepath) case type when :json set_environment_attributes_from_json(env_id, contents) else raise ArgumentError, "cannot read attributes from files of type: #{type}" end rescue MultiJson::DecodeError => ex raise InvalidAttributesFile, "Invalid JSON in #{filepath}: #{ex}" end
Set arbitrary attributes at the environment level
@param [String] env_id
the name of the environment to modify
@param [Hash] new_attributes
Hash of attributes to set on the environment
@raise [MB::EnvironmentNotFound] if the environment does not exist
@example setting multiple attributes on an environment
set_environment_attributes_from_hash("test-environment", "foo" => "bar", "baz => { "quux" => 42 } )
# File lib/mb/mixin/attribute_setting.rb, line 120 def set_environment_attributes_from_hash(env_id, new_attributes) log.info "Setting environment attributes: #{new_attributes}" unless env = chef_connection.environment.find(env_id) raise EnvironmentNotFound.new(env_id) end env.default_attributes.deep_merge!(new_attributes) env.save end
Set environment level attributes on an environment from the given JSON string
@param [String] env_id
the name of the environment to modify
@param [String] json
the json to use as attributes
# File lib/mb/mixin/attribute_setting.rb, line 164 def set_environment_attributes_from_json(env_id, json) set_environment_attributes_from_hash(env_id, MultiJson.decode(json)) end
Private Instance Methods
Expand constraints strings given to their fully qualified constraint operators
@param [Hash] cookbook_versions
Hash of cookbooks and the versions
@raise [ArgumentError] if the array of constraints contains an entry which is not in the
correct version constraint format
@example
expand_constraints( "league" => "1.74.2", "pvpnet" => ">= 1.2.3" ) # => { "league" => "= 1.74.2", "pvpnet" => ">= 1.2.3" }
@return [Hash]
# File lib/mb/mixin/attribute_setting.rb, line 234 def expand_constraints(cookbook_versions) expanded = cookbook_versions.collect do |name, constraint| [name, Semverse::Constraint.new(constraint).to_s] end Hash[expanded] rescue Semverse::InvalidConstraintFormat => ex raise ArgumentError, ex end
Expand the “latest” cookbook versions to the latest verison number for the cookbook
@param [Hash] cookbook_versions
Hash of cookbooks and the versions
@example expanding versions when 3.1.0 is the latest pvpnet cookbook
expand_latest_versions( "league" => "1.74.2", "pvpnet" => "latest" ) # => {"league" => "1.74.2", "pvpnet" => "3.1.0"}
# File lib/mb/mixin/attribute_setting.rb, line 205 def expand_latest_versions(cookbook_versions) expanded_cookbook_versions = cookbook_versions.map do |name, version| if version.downcase == "latest" version = chef_connection.cookbook.latest_version(name) end [name, version] end Hash[expanded_cookbook_versions] end
Ensure the chef server can satisfy the desired cookbook version constraints
@param [Hash] cookbook_versions
Hash of cookbooks and the versions
@raise [MB::CookbookConstraintNotSatisfied]
if the constraints cannot be satisfied
# File lib/mb/mixin/attribute_setting.rb, line 251 def satisfies_constraints?(cookbook_versions) failures = cookbook_versions.concurrent_map do |name, constraint| if chef_connection.cookbook.satisfy(name, constraint).nil? "#{name} (#{constraint})" end end.compact unless failures.empty? raise MB::CookbookConstraintNotSatisfied, "couldn't satisfy constraints for cookbook version(s): #{failures.join(', ')}" end end
retrieve the version attribute of a given component and raise if the component is not versioned
@param [MB::Plugin] plugin @param [#to_s] component_name
@raise [ComponentNotVersioned]
@return [String]
# File lib/mb/mixin/attribute_setting.rb, line 179 def version_attribute(plugin, component_name) result = plugin.component!(component_name).version_attribute unless result raise ComponentNotVersioned.new component_name end log.info "Component '#{component_name}' versioned with '#{result}'" result end