modules/mu/config.rb in cloud-mu-3.0.2 vs modules/mu/config.rb in cloud-mu-3.1.0
- old
+ new
@@ -358,11 +358,11 @@
end
# Base configuration schema for declared kittens referencing other cloud objects. This is essentially a set of filters that we're going to pass to {MU::MommaCat.findStray}.
# @param aliases [Array<Hash>]: Key => value mappings to set backwards-compatibility aliases for attributes, such as the ubiquitous +vpc_id+ (+vpc_id+ => +id+).
# @return [Hash]
- def self.schema(aliases = [], type: nil, parent_obj: nil, desc: nil)
+ def self.schema(aliases = [], type: nil, parent_obj: nil, desc: nil, omit_fields: [])
parent_obj ||= caller[1].gsub(/.*?\/([^\.\/]+)\.rb:.*/, '\1')
desc ||= "Reference a #{type ? "'#{type}' resource" : "resource" } from this #{parent_obj ? "'#{parent_obj}'" : "" } resource"
schema = {
"type" => "object",
"#MU_REFERENCE" => true,
@@ -407,10 +407,16 @@
}
if !["folders", "habitats"].include?(type)
schema["properties"]["habitat"] = MU::Config::Habitat.reference
end
+ if omit_fields
+ omit_fields.each { |f|
+ schema["properties"].delete(f)
+ }
+ end
+
if !type.nil?
schema["required"] = ["type"]
schema["properties"]["type"]["default"] = type
schema["properties"]["type"]["enum"] = [type]
end
@@ -720,11 +726,11 @@
tail
end
# Load up our YAML or JSON and parse it through ERB, optionally substituting
# externally-supplied parameters.
- def resolveConfig(path: @@config_path, param_pass: false)
+ def resolveConfig(path: @@config_path, param_pass: false, cloud: nil)
config = nil
@param_pass = param_pass
# Catch calls to missing variables in Basket of Kittens files when being
# parsed by ERB, and replace with placeholders for parameters. This
@@ -809,10 +815,13 @@
raw_json = raw_text
end
begin
config = JSON.parse(raw_json)
+ if @@parameters['cloud']
+ config['cloud'] ||= @@parameters['cloud'].to_s
+ end
if param_pass and config.is_a?(Hash)
config.keys.each { |key|
if key != "parameters"
if key == "appname" and @@parameters["myAppName"].nil?
$myAppName = config["appname"].upcase.dup
@@ -848,12 +857,13 @@
# Load, resolve, and validate a configuration file ("Basket of Kittens").
# @param path [String]: The path to the master config file to load. Note that this can include other configuration files via ERB.
# @param skipinitialupdates [Boolean]: Whether to forcibly apply the *skipinitialupdates* flag to nodes created by this configuration.
# @param params [Hash]: Optional name-value parameter pairs, which will be passed to our configuration files as ERB variables.
+ # @param cloud [String]: Sets a parameter named 'cloud', and insert it as the default cloud platform if not already declared
# @return [Hash]: The complete validated configuration for a deployment.
- def initialize(path, skipinitialupdates = false, params: {}, updating: nil, default_credentials: nil)
+ def initialize(path, skipinitialupdates = false, params: {}, updating: nil, default_credentials: nil, cloud: nil)
$myPublicIp = MU::Cloud::AWS.getAWSMetaData("public-ipv4")
$myRoot = MU.myRoot
$myRoot.freeze
$myAZ = MU.myAZ.freeze
@@ -888,20 +898,31 @@
rescue RuntimeError, SyntaxError => e
ok = false
MU.log "Error setting $#{name}='#{value}': #{e.message}", MU::ERR
end
}
+
+ if cloud and !@@parameters["cloud"]
+ if !MU::Cloud.availableClouds.include?(cloud)
+ ok = false
+ MU.log "Provider '#{cloud}' is not listed as an available cloud", MU::ERR, details: MU::Cloud.availableClouds
+ else
+ @@parameters["cloud"] = getTail("cloud", value: cloud, pseudo: true)
+ @@user_supplied_parameters["cloud"] = cloud
+ eval("$cloud='#{cloud}'") # support old-style $global parameter refs
+ end
+ end
raise ValidationError if !ok
# Run our input through the ERB renderer, a first pass just to extract
# the parameters section so that we can resolve all of those to variables
# for the rest of the config to reference.
# XXX Figure out how to make include() add parameters for us. Right now
# you can't specify parameters in an included file, because ERB is what's
# doing the including, and parameters need to already be resolved so that
# ERB can use them.
- param_cfg, raw_erb_params_only = resolveConfig(path: @@config_path, param_pass: true)
+ param_cfg, raw_erb_params_only = resolveConfig(path: @@config_path, param_pass: true, cloud: cloud)
if param_cfg.has_key?("parameters")
param_cfg["parameters"].each { |param|
if param.has_key?("default") and param["default"].nil?
param["default"] = ""
end
@@ -953,11 +974,11 @@
}
raise DeployParamError, "One or more invalid parameters specified" if !ok
$parameters = @@parameters.dup
$parameters.freeze
- tmp_cfg, raw_erb = resolveConfig(path: @@config_path)
+ tmp_cfg, raw_erb = resolveConfig(path: @@config_path, cloud: cloud)
# Convert parameter entries that constitute whole config keys into
# {MU::Config::Tail} objects.
def resolveTails(tree, indent= "")
if tree.is_a?(Hash)
@@ -1004,10 +1025,11 @@
types = MU::Cloud.resource_types.values.map { |v| v[:cfg_plural] }
MU::Cloud.resource_types.values.map { |v| v[:cfg_plural] }.each { |type|
if @config[type]
@config[type].each { |k|
+ next if !k.is_a?(Hash)
applyInheritedDefaults(k, type)
}
end
}
applySchemaDefaults(@config, MU::Config.schema)
@@ -1472,11 +1494,12 @@
["optional_tags", "tags", "cloud", "project"].each { |param|
acl[param] = descriptor[param] if descriptor[param]
}
descriptor["add_firewall_rules"] ||= []
- descriptor["add_firewall_rules"] << {"rule_name" => fwname, "type" => "firewall_rules" } # XXX why the duck is there a type argument required here?
+ descriptor["add_firewall_rules"] << {"name" => fwname, "type" => "firewall_rules" } # XXX why the duck is there a type argument required here?
+ descriptor["add_firewall_rules"].uniq!
acl = resolveIntraStackFirewallRefs(acl, delay_validation)
ok = false if !insertKitten(acl, "firewall_rules", delay_validation, overwrite: already_exists)
end
@@ -1505,17 +1528,19 @@
end
# Does it declare association with first-class firewall_rules?
if !descriptor["add_firewall_rules"].nil?
descriptor["add_firewall_rules"].each { |acl_include|
- if haveLitterMate?(acl_include["rule_name"], "firewall_rules")
+ next if !acl_include["name"] and !acl_include["rule_name"]
+ acl_include["name"] ||= acl_include["rule_name"]
+ if haveLitterMate?(acl_include["name"], "firewall_rules")
descriptor["dependencies"] << {
"type" => "firewall_rule",
- "name" => acl_include["rule_name"]
+ "name" => acl_include["name"]
}
- elsif acl_include["rule_name"]
- MU.log shortclass.to_s+" #{descriptor['name']} depends on FirewallRule #{acl_include["rule_name"]}, but no such rule declared.", MU::ERR
+ elsif acl_include["name"]
+ MU.log shortclass.to_s+" #{descriptor['name']} depends on FirewallRule #{acl_include["name"]}, but no such rule declared.", MU::ERR
ok = false
end
}
end
@@ -1832,31 +1857,31 @@
YAML.load(raw.gsub(/<%.*?%>/, ""))
rescue Psych::SyntaxError => e
# Ok, well neither of those worked, let's assume that filenames are
# meaningful.
if path.match(/\.(yaml|yml)$/i)
- MU.log "Guessing that #{path} is YAML based on filename", MU::NOTICE
+ MU.log "Guessing that #{path} is YAML based on filename", MU::DEBUG
return :yaml
elsif path.match(/\.(json|jsn|js)$/i)
- MU.log "Guessing that #{path} is JSON based on filename", MU::NOTICE
+ MU.log "Guessing that #{path} is JSON based on filename", MU::DEBUG
return :json
else
# For real? Ok, let's try the dumbest possible method.
dashes = raw.match(/\-/)
braces = raw.match(/[{}]/)
if dashes.size > braces.size
- MU.log "Guessing that #{path} is YAML by... counting dashes.", MU::WARN
+ MU.log "Guessing that #{path} is YAML by... counting dashes.", MU::NOTICE
return :yaml
elsif braces.size > dashes.size
- MU.log "Guessing that #{path} is JSON by... counting braces.", MU::WARN
+ MU.log "Guessing that #{path} is JSON by... counting braces.", MU::NOTICE
return :json
else
raise "Unable to guess composition of #{path} by any means"
end
end
end
- MU.log "Guessing that #{path} is YAML based on parser", MU::NOTICE
+ MU.log "Guessing that #{path} is YAML based on parser", MU::DEBUG
return :yaml
end
MU.log "Guessing that #{path} is JSON based on parser", MU::NOTICE
return :json
end
@@ -2157,9 +2182,10 @@
# Given a bare hash describing a resource, insert default values which can
# be inherited from its parent or from the root of the BoK.
# @param kitten [Hash]: A resource descriptor
# @param type [String]: The type of resource this is ("servers" etc)
def applyInheritedDefaults(kitten, type)
+ return if !kitten.is_a?(Hash)
kitten['cloud'] ||= @config['cloud']
kitten['cloud'] ||= MU::Config.defaultCloud
if !MU::Cloud.supportedClouds.include?(kitten['cloud'])
return