Class: GeoEngineer::Environment
- Inherits:
-
Object
- Object
- GeoEngineer::Environment
- Includes:
- HasAttributes, HasLifecycle, HasProjects, HasResources, HasSubResources, HasTemplates, HasValidations
- Defined in:
- lib/geoengineer/environment.rb
Overview
An Environment is a group of projects, resources and attributes, build to create a terraform file. The goal of GeoEngineer is to build an environment that can be created.
An environment has resources, has arbitrary attributes, validations and lifecycle hooks
Constant Summary
Constants included from HasValidations
HasValidations::MAX_POLICY_LENGTH
Instance Attribute Summary collapse
-
#name ⇒ Object
readonly
Returns the value of attribute name.
Instance Method Summary collapse
- #all_resources ⇒ Object
-
#codified_resources(type) ⇒ Object
This method looks into AWS for resources that are not yet codified.
- #depends_on(res) ⇒ Object
-
#extract_dependencies(x) ⇒ Object
DOT Methods Given an attribute it tries to identify a dependency and return it.
- #find_provider(id_alias) ⇒ Object
-
#initialize(name, &block) ⇒ Environment
constructor
A new instance of Environment.
- #json_resources ⇒ Object
- #output(id, value, &block) ⇒ Object
- #project(org, name, &block) ⇒ Object
- #provider(id, &block) ⇒ Object
- #resource(type, id, &block) ⇒ Object
- #to_dot ⇒ Object
-
#to_terraform ⇒ Object
Terraform Methods.
- #to_terraform_json ⇒ Object
- #to_terraform_state ⇒ Object
- #uncodified_resources(type) ⇒ Object
Methods included from HasLifecycle
Methods included from HasValidations
#errors, included, #validate_at_least_one_present, #validate_cidr_block, #validate_only_one_present, #validate_policy_length, #validate_required_attributes
Methods included from HasTemplates
#all_template_resources, #find_template, #from_template, #templates
Methods included from HasProjects
#all_project_resources, #create_project, #projects
Methods included from HasResources
#create_resource, #find_resource, #find_resource_by_ref, included, #resources, #resources_grouped_by, #resources_of_type, #resources_of_type_grouped_by
Methods included from HasSubResources
#assign_block, #attribute_missing, #delete_all_subresources, #delete_subresources_where, #subresources
Methods included from HasAttributes
#[], #[]=, #assign_attribute, #assign_block, #attribute_missing, #attribute_procs, #attributes, #delete, #eager_load_attributes, #method_missing, #reset_attributes, #retrieve_attribute, #terraform_attribute_ref, #terraform_attributes, #timeout
Constructor Details
#initialize(name, &block) ⇒ Environment
Returns a new instance of Environment.
56 57 58 59 60 61 62 |
# File 'lib/geoengineer/environment.rb', line 56 def initialize(name, &block) @name = name @outputs = [] @providers = [] self.send("#{name}?=", true) # e.g. staging? instance_exec(self, &block) if block_given? end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method in the class HasAttributes
Instance Attribute Details
#name ⇒ Object (readonly)
Returns the value of attribute name.
19 20 21 |
# File 'lib/geoengineer/environment.rb', line 19 def name @name end |
Instance Method Details
#all_resources ⇒ Object
97 98 99 |
# File 'lib/geoengineer/environment.rb', line 97 def all_resources [resources, all_template_resources, all_project_resources].flatten end |
#codified_resources(type) ⇒ Object
This method looks into AWS for resources that are not yet codified
194 195 196 197 198 |
# File 'lib/geoengineer/environment.rb', line 194 def codified_resources(type) # managed resources have a remote resource res = self.resources_of_type(type).select { |r| !r.remote_resource.nil? } res.sort_by(&:terraform_name) end |
#depends_on(res) ⇒ Object
115 116 117 118 119 120 121 122 123 |
# File 'lib/geoengineer/environment.rb', line 115 def depends_on(res) all_attributes = [res.attributes.values] all_attributes .concat(res.subresources.map { |sr| sr.attributes.values }) .map { |attr| extract_dependencies(attr) } .flatten .compact .uniq end |
#extract_dependencies(x) ⇒ Object
DOT Methods Given an attribute it tries to identify a dependency and return it
103 104 105 106 107 108 109 110 111 112 113 |
# File 'lib/geoengineer/environment.rb', line 103 def extract_dependencies(x) return x.map { |y| extract_dependencies(y) }.flatten if x.is_a? Array return [x] if x.is_a?(GeoEngineer::Resource) if x.is_a?(String) res = find_resource_by_ref(x) return [res] if res end [] end |
#find_provider(id_alias) ⇒ Object
87 88 89 |
# File 'lib/geoengineer/environment.rb', line 87 def find_provider(id_alias) @providers.find { |p| p.terraform_id == id_alias } end |
#json_resources ⇒ Object
165 166 167 168 169 170 171 |
# File 'lib/geoengineer/environment.rb', line 165 def json_resources all_resources.each_with_object({}) do |r, c| c[r.type] ||= {} c[r.type][r.id] = r.to_terraform_json c end end |
#output(id, value, &block) ⇒ Object
91 92 93 94 95 |
# File 'lib/geoengineer/environment.rb', line 91 def output(id, value, &block) output = GeoEngineer::Output.new(id, value, &block) @outputs << output output end |
#project(org, name, &block) ⇒ Object
64 65 66 67 68 69 70 71 |
# File 'lib/geoengineer/environment.rb', line 64 def project(org, name, &block) project = create_project(org, name, &block) supported_environments = [project.environments].flatten # do not add the project if the project is not supported by this environment return NullObject.new unless supported_environments.include?(@name) project end |
#provider(id, &block) ⇒ Object
81 82 83 84 85 |
# File 'lib/geoengineer/environment.rb', line 81 def provider(id, &block) provider = GeoEngineer::Provider.new(id, &block) @providers << provider provider end |
#resource(type, id, &block) ⇒ Object
73 74 75 76 77 78 79 |
# File 'lib/geoengineer/environment.rb', line 73 def resource(type, id, &block) return find_resource(type, id) unless block_given? resource = create_resource(type, id, &block) resource.environment = self resource end |
#to_dot ⇒ Object
125 126 127 128 129 130 131 132 |
# File 'lib/geoengineer/environment.rb', line 125 def to_dot str = ["digraph {", projects.values.map(&:to_dot)] all_resources.each do |res| str << depends_on(res).map { |r| " #{res.to_ref.inspect} -> #{r.to_ref.inspect}" } end str << " }" str.join("\n") end |
#to_terraform ⇒ Object
Terraform Methods
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 |
# File 'lib/geoengineer/environment.rb', line 135 def to_terraform # Force preventing the destruction of any resource unless explicitly set # Hopefully this will stop accidentally the environment unless self.allow_destroy all_resources.each { |r| r.lifecycle {} unless r.lifecycle r.lifecycle.prevent_destroy = true } end tf_resources = all_resources.map(&:to_terraform) tf_resources += @providers.compact.map(&:to_terraform) tf_resources += @outputs.compact.map(&:to_terraform) tf_resources.join("\n\n") end |
#to_terraform_json ⇒ Object
151 152 153 154 155 156 157 158 159 160 161 162 163 |
# File 'lib/geoengineer/environment.rb', line 151 def to_terraform_json unless self.allow_destroy all_resources.each { |r| r.lifecycle {} unless r.lifecycle r.lifecycle.prevent_destroy = true } end h = { resource: json_resources } h[:output] = @outputs.map(&:to_terraform_json) unless @outputs.empty? h[:provider] = @providers.map(&:to_terraform_json) unless @providers.empty? h end |
#to_terraform_state ⇒ Object
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/geoengineer/environment.rb', line 173 def to_terraform_state reses = all_resources.select(&:_terraform_id) # _terraform_id must not be nil reses = Parallel.map(reses, { in_threads: Parallel.processor_count }) do |r| { "#{r.type}.#{r.id}" => r.to_terraform_state() } end.reduce({}, :merge) { version: 1, serial: 1, modules: [ { path: [:root], outputs: {}, resources: reses } ] } end |
#uncodified_resources(type) ⇒ Object
200 201 202 203 204 205 |
# File 'lib/geoengineer/environment.rb', line 200 def uncodified_resources(type) # unmanaged resources have a remote resource without local_resource clazz = self.class.get_resource_class_from_type(type) res = clazz.fetch_remote_resources(nil).select { |r| r.local_resource.nil? } res.sort_by(&:terraform_name) end |