Module: Puppet_X::EnterpriseModules::Oci::Type
- Defined in:
- lib/puppet_x/enterprisemodules/oci/type.rb
Overview
Add Documentation
Defined Under Namespace
Modules: ClassMethods
Class Method Summary collapse
Instance Method Summary collapse
- #before_create ⇒ Object
- #before_modify ⇒ Object
-
#handle_oci_request(oci_object_type = nil, oci_synchronized = nil, id = nil) ⇒ Object
Generates a nice error when an OCI error is raised in the yield.
-
#oci_api_data ⇒ Object
rubocop: enable Lint/OrAssignmentToConstant.
- #on_create ⇒ Object
- #on_destroy ⇒ Object
- #on_modify ⇒ Object
- #validate_reference_propery(property, resource) ⇒ Object
- #wait_for_state(oci_object_type, id, type) ⇒ Object
- #wait_for_work_request(wait_for_resource_id) ⇒ Object
Class Method Details
.included(parent) ⇒ Object
8 9 10 11 12 13 14 15 |
# File 'lib/puppet_x/enterprisemodules/oci/type.rb', line 8 def self.included(parent) parent.send(:include, EasyType) parent.send(:include, Settings) parent.send(:include, Config) parent.extend(Config) parent.extend(ClassMethods) parent.extend(Settings) end |
Instance Method Details
#before_create ⇒ Object
49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
# File 'lib/puppet_x/enterprisemodules/oci/type.rb', line 49 def before_create @oci_api_data = to_hash # # In Puppet the name is the full name. OCI needs just the name. # Also sometimes OCI doesn't have a name but just a display_name. So we # fill this in too. # @oci_api_data[:name] = @oci_api_data[:display_name] = # # If the compartment_id is nil, it means we are at the root and use the tenant ocid # @oci_api_data[:compartment_id] ||= client.api_client.config.tenancy # end |
#before_modify ⇒ Object
118 119 120 121 122 123 124 125 126 |
# File 'lib/puppet_x/enterprisemodules/oci/type.rb', line 118 def before_modify @oci_api_data = to_hash # # Although OCI allows renaming, Puppet doesn't, so we delete the name and display_name # attributes # @oci_api_data.delete(:name) @oci_api_data.delete(:display_name) end |
#handle_oci_request(oci_object_type = nil, oci_synchronized = nil, id = nil) ⇒ Object
Generates a nice error when an OCI error is raised in the yield. Also waits for the state specified in the type parameter.
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 |
# File 'lib/puppet_x/enterprisemodules/oci/type.rb', line 248 def handle_oci_request(oci_object_type = nil, oci_synchronized = nil, id = nil) oci_object_type ||= object_type oci_synchronized = synchronized if oci_synchronized.nil? begin operation_result = yield rescue OCI::Errors::ServiceError => e fail "#{path}: OCI raised error: #{e.}" end wait_for_resource_id = operation_result.headers['opc-work-request-id'] # See if we can do a synchronize return operation_result unless oci_synchronized # # We can synchronize, so do it.Although the post on oci_core_instance returns # an wait_for_resource_id, the API somehow doesn't support the wait_for_state call. # So that's why we just use the wait_for state call here. # if wait_for_resource_id && oci_object_type != 'instance' wait_for_work_request(wait_for_resource_id) elsif %w[bucket tag].include?(oci_object_type) # Do nothing. We can't sync bucket or tag operations elsif id.nil? # We need the id from the operation and the operation is a create or update operation wait_for_state(oci_object_type, operation_result.data.id, :create) else wait_for_state(oci_object_type, id, :destroy) end operation_result end |
#oci_api_data ⇒ Object
rubocop: enable Lint/OrAssignmentToConstant
39 40 41 |
# File 'lib/puppet_x/enterprisemodules/oci/type.rb', line 39 def oci_api_data @oci_api_data end |
#on_create ⇒ Object
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/puppet_x/enterprisemodules/oci/type.rb', line 64 def on_create Puppet.debug "create #{object_type} #{name} " # # In Puppet we use underscored names, but OCI needs camel case with a lowecase # first character. # @oci_api_data = @oci_api_data.to_oci handle_oci_request do @oci_api_data = case object_type when 'tag' tag_namespace_id = resolver.name_to_ocid(tenant, tag_namespace_name, :tagnamespace) create_details = create_class.new(@oci_api_data) client.create_tag(tag_namespace_id, create_details) when 'instance' launch_details = launch_class.new(@oci_api_data) creation_data = client.launch_instance(launch_details) # # The creation of an instance also create's a boot image. To allow searching for it # in the cache, invalidate the cache of boot volumes. This is not very efficient. Specialy # in large environments. # TODO: Find a way to make this more effecient # resolver.invalidate(tenant, :bootvolume) creation_data when 'bucket' namespace = client.get_namespace.data create_details = create_class.new(@oci_api_data) client.send("create_#{object_type}", namespace, create_details) when 'vcn' # # Version 2.18 of the sdk always sets the is_oracle_gua_allocation_enabled property. This causes the # API to fail that why we set it to nil when it isn't explicitly set to true # create_details = create_class.new(@oci_api_data) create_details.is_oracle_gua_allocation_enabled = nil unless is_oracle_gua_allocation_enabled.to_s == 'true' client.send("create_#{object_type}", create_details) else create_details = create_class.new(@oci_api_data) client.send("create_#{object_type}", create_details) end end # # Add the created resource to the name cache so new Puppet resources can find it # resolver.add_to_cache(tenant, @oci_api_data.data) # # Report the information back to the provide # hash = @oci_api_data.data.to_hash.to_puppet hash['tenant'] = tenant hash['name'] = name self[:provider] = self.class.defaultprovider.map_raw_to_resource(hash) end |
#on_destroy ⇒ Object
155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 |
# File 'lib/puppet_x/enterprisemodules/oci/type.rb', line 155 def on_destroy Puppet.debug "destroy #{object_type} #{name} " handle_oci_request(object_type, synchronized, provider.id) do case object_type when 'tag' tag_namespace_id = resolver.name_to_ocid(tenant, tag_namespace_name, :tagnamespace) # # We can only remove the tag after it has been retired. So we make # it one kind of operation. Maybe in the future, we can add ensure > 'retired' # client.update_tag(tag_namespace_id, tag_name, { 'isRetired' => true }) client.delete_tag(tag_namespace_id, tag_name) when 'bucket' bucket_name = name.split('/').last client.send("delete_#{object_type}", provider.namespace, bucket_name) when 'instance' client.terminate_instance(provider.id) when 'instance_pool' client.terminate_instance_pool(provider.id) when 'vault' details = OCI::KeyManagement::Models::ScheduleVaultDeletionDetails.new client.send('schedule_vault_deletion', provider.id, details) when 'key' client.disable_key(provider.id) else client.send("delete_#{object_type}", provider.id) end end nil end |
#on_modify ⇒ Object
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/puppet_x/enterprisemodules/oci/type.rb', line 128 def on_modify Puppet.debug "modify #{object_type} #{name}" # # In Puppet we use underscored names, but OCI needs camel case with a lowecase # first character. # @oci_api_data = @oci_api_data.to_oci update_details = update_class.new(@oci_api_data) if update_details.to_hash == {} # There are changes here Puppet.debug 'No changes in main data. Defering changes to specific properties.' else handle_oci_request do case object_type when 'tag' tag_namespace_id = resolver.name_to_ocid(tenant, tag_namespace_name, :tagnamespace) client.update_tag(tag_namespace_id, tag_name, update_details) when 'bucket' bucket_name = name.split('/').last client.send("update_#{object_type}", provider.namespace, bucket_name, update_details) else client.send("update_#{object_type}", provider.id, update_details) end end end nil end |
#validate_reference_propery(property, resource) ⇒ Object
43 44 45 46 47 |
# File 'lib/puppet_x/enterprisemodules/oci/type.rb', line 43 def validate_reference_propery(property, resource) reference_property = property.to_s.scan(/(.*)_id(s)?$/).first.join fail "You cannot use both #{property} and #{reference_property} together. Choose either one." \ if resource.send(reference_property.to_sym) && resource.send(property.to_sym) end |
#wait_for_state(oci_object_type, id, type) ⇒ Object
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 |
# File 'lib/puppet_x/enterprisemodules/oci/type.rb', line 209 def wait_for_state(oci_object_type, id, type) ready_states = type == :create ? present_states : absent_states ready_states << 'UNKNOWN' # Some objects don't have a state. So they are ready directly eval_proc = ->(response) do state = response.data.respond_to?(:lifecycle_state) ? response.data.lifecycle_state : 'UNKNOWN' if response.data.respond_to?(:puppet_name) Puppet.debug "Waiting for resource #{object_type} with name #{response.data.puppet_name} to become ready; Now in state #{state}." else Puppet.debug "Waiting for resource #{object_type} to become ready; Now in state #{state}." end ready_states.include?(state) end local_retry_config = case type when :destroy nil when :create # # When creating a resource we allow more time and retries before we signal an error # For now we use hardcoded values that are large. Means we have maximum 30 seconds for a # create before we return an error. # retry_config(tenant, 'sleep_calc_millis' => 1500, 'max_attempts' => 20) else retry_config(tenant) end waiter_result = client.send("get_#{oci_object_type}", id, :retry_config => local_retry_config) waiter_result.wait_until( :eval_proc => eval_proc, :max_interval_seconds => oci_wait_interval, :max_wait_seconds => oci_timeout ) rescue OCI::Errors::ServiceError => e fail "#{path}: OCI raised error: #{e.}" unless e.status_code == 404 && type == :destroy end |
#wait_for_work_request(wait_for_resource_id) ⇒ Object
186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 |
# File 'lib/puppet_x/enterprisemodules/oci/type.rb', line 186 def wait_for_work_request(wait_for_resource_id) Puppet.debug "Wait on work-request with id #{wait_for_resource_id}..." OCI::Waiter::WorkRequest.wait_for_state( client, wait_for_resource_id, lambda do |work_request| Puppet.debug "Wait on work-request with id #{wait_for_resource_id}. Current status is #{work_request.status}" work_request.status == 'SUCCEEDED' end, lambda do |work_request| fail if work_request.status == 'FAILED' end, :max_interval_seconds => oci_wait_interval, :max_wait_seconds => oci_timeout ) rescue OCI::Errors::ServiceError => e # # If we are not autorized or the resource is not found, infer the work request # is done and we are finished # raise unless e.service_code == 'NotAuthorizedOrNotFound' end |