modules/mu/config.rb in cloud-mu-3.0.0 vs modules/mu/config.rb in cloud-mu-3.0.1
- old
+ new
@@ -315,21 +315,28 @@
@@refs << newref
return newref
}
end
+ # A way of dynamically defining +attr_reader+ without leaking memory
+ def self.define_reader(name)
+ define_method(name) {
+ instance_variable_get("@#{name.to_s}")
+ }
+ end
+
# @param cfg [Hash]: A Basket of Kittens configuration hash containing
# lookup information for a cloud object
def initialize(cfg)
cfg.keys.each { |field|
next if field == "tag"
if !cfg[field].nil?
self.instance_variable_set("@#{field}".to_sym, cfg[field])
elsif !cfg[field.to_sym].nil?
self.instance_variable_set("@#{field.to_s}".to_sym, cfg[field.to_sym])
end
- self.singleton_class.instance_eval { attr_reader field.to_sym }
+ MU::Config::Ref.define_reader(field)
}
if cfg['tag'] and cfg['tag']['key'] and
!cfg['tag']['key'].empty? and cfg['tag']['value']
@tag_key = cfg['tag']['key']
@tag_value = cfg['tag']['value']
@@ -983,10 +990,19 @@
]
end
@config['credentials'] ||= @default_credentials
+ if @config['cloud'] and !MU::Cloud.availableClouds.include?(@config['cloud'])
+ if MU::Cloud.supportedClouds.include?(@config['cloud'])
+ MU.log "Cloud provider #{@config['cloud']} declared, but no #{@config['cloud']} credentials available", MU::ERR
+ else
+ MU.log "Cloud provider #{@config['cloud']} is not supported", MU::ERR, details: MU::Cloud.supportedClouds
+ end
+ exit 1
+ end
+
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|
@@ -1272,10 +1288,20 @@
return true
end
}
ok = true
+ if descriptor['cloud'] and
+ !MU::Cloud.availableClouds.include?(descriptor['cloud'])
+ if MU::Cloud.supportedClouds.include?(descriptor['cloud'])
+ MU.log "#{cfg_name} #{descriptor['name']} is configured with cloud #{descriptor['cloud']}, but no #{descriptor['cloud']} credentials available", MU::ERR
+ else
+ MU.log "#{cfg_name} #{descriptor['name']}: Cloud provider #{descriptor['cloud']} is not supported", MU::ERR, details: MU::Cloud.supportedClouds
+ end
+ return false
+ end
+
descriptor["#MU_CLOUDCLASS"] = classname
applyInheritedDefaults(descriptor, cfg_plural)
# Meld defaults from our global schema and, if applicable, from our
@@ -1973,11 +1999,11 @@
end
elsif schema_chunk["type"] == "array" and conf_chunk.kind_of?(Array)
conf_chunk.map! { |item|
# If we're working on a resource type, go get implementation-specific
# schema information so that we set those defaults correctly.
- realschema = if type and schema_chunk["items"] and schema_chunk["items"]["properties"] and item["cloud"]
+ realschema = if type and schema_chunk["items"] and schema_chunk["items"]["properties"] and item["cloud"] and MU::Cloud.supportedClouds.include?(item['cloud'])
cloudclass = Object.const_get("MU").const_get("Cloud").const_get(item["cloud"]).const_get(type)
toplevel_required, cloudschema = cloudclass.schema(self)
newschema = schema_chunk["items"].dup
@@ -2124,10 +2150,14 @@
# @param type [String]: The type of resource this is ("servers" etc)
def applyInheritedDefaults(kitten, type)
kitten['cloud'] ||= @config['cloud']
kitten['cloud'] ||= MU::Config.defaultCloud
+ if !MU::Cloud.supportedClouds.include?(kitten['cloud'])
+ return
+ end
+
cloudclass = Object.const_get("MU").const_get("Cloud").const_get(kitten['cloud'])
shortclass, cfg_name, cfg_plural, classname = MU::Cloud.getResourceNames(type)
resclass = Object.const_get("MU").const_get("Cloud").const_get(kitten['cloud']).const_get(shortclass)
schema_fields = ["us_only", "scrub_mu_isms", "credentials", "billing_acct"]
@@ -2196,10 +2226,11 @@
applyInheritedDefaults(k, type)
}
count = count + @kittens[type].size
}
+
if count == 0
MU.log "You must declare at least one resource to create", MU::ERR
ok = false
end
@@ -2435,12 +2466,14 @@
# Emit our Basket of Kittens schema in a format that YARD can comprehend
# and turn into documentation.
def self.printSchema(kitten_rb, class_hierarchy, schema, in_array = false, required = false, prefix: nil)
return if schema.nil?
+
if schema["type"] == "object"
- printme = Array.new
+ printme = []
+
if !schema["properties"].nil?
# order sub-elements by whether they're required, so we can use YARD's
# grouping tags on them
if !schema["required"].nil? and schema["required"].size > 0
prop_list = schema["properties"].keys.sort_by { |name|
@@ -2451,9 +2484,56 @@
end
req = false
printme << "# @!group Optional parameters" if schema["required"].nil? or schema["required"].size == 0
prop_list.each { |name|
prop = schema["properties"][name]
+
+ if class_hierarchy.size == 1
+
+ _shortclass, cfg_name, cfg_plural, _classname = MU::Cloud.getResourceNames(name)
+ if cfg_name
+ example_path = MU.myRoot+"/modules/mu/config/"+cfg_name+".yml"
+ if File.exist?(example_path)
+ example = "#\n# Examples:\n#\n"
+ # XXX these variables are all parameters from the BoKs in
+ # modules/tests. A really clever implementation would read
+ # and parse them to get default values, perhaps, instead of
+ # hard-coding them here.
+ instance_type = "t2.medium"
+ db_size = "db.t2.medium"
+ vpc_name = "some_vpc"
+ logs_name = "some_loggroup"
+ queues_name = "some_queue"
+ server_pools_name = "some_server_pool"
+ ["simple", "complex"].each { |complexity|
+ erb = ERB.new(File.read(example_path), nil, "<>")
+ example += "# !!!yaml\n"
+ example += "# ---\n"
+ example += "# appname: #{complexity}\n"
+ example += "# #{cfg_plural}:\n"
+ firstline = true
+ erb.result(binding).split(/\n/).each { |l|
+ l.sub!(/#.*/, "")
+ next if l.empty? or l.match(/^\s+$/)
+ if firstline
+ l = "- "+l
+ firstline = false
+ else
+ l = " "+l
+ end
+ example += "# "+l+" "+"\n"
+ }
+ example += "# \n#\n" if complexity == "simple"
+ }
+ schema["properties"][name]["items"]["description"] ||= ""
+ if !schema["properties"][name]["items"]["description"].empty?
+ schema["properties"][name]["items"]["description"] += "\n"
+ end
+ schema["properties"][name]["items"]["description"] += example
+ end
+ end
+ end
+
if !schema["required"].nil? and schema["required"].include?(name)
printme << "# @!group Required parameters" if !req
req = true
else
if req