# Copyright:: Copyright (c) 2019 eGlobalTech, Inc., all rights reserved # # Licensed under the BSD-3 license (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License in the root of the project or at # # http://egt-labs.com/mu/LICENSE.html # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. module MU class Cloud class Azure # Creates an Azure directory as configured in {MU::Config::BasketofKittens::habitats} class Habitat < MU::Cloud::Habitat # Placeholder method, just here to see which bits of the subscription # API actually work. Delete this once we actually have enough # functionality for a real implementation. def self.testcalls #pp MU::Cloud::Azure::Habitat.find pp MU::Cloud::Azure.billing.enrollment_accounts.list # pp MU::Cloud::Azure.subfactory.api.class.name # pp MU::Cloud::Azure.subfactory.subscription_factory.create_subscription_in_enrollment_account # this should barf end # Initialize this cloud resource object. Calling +super+ will invoke the initializer defined under {MU::Cloud}, which should set the attribtues listed in {MU::Cloud::PUBLIC_ATTRS} as well as applicable dependency shortcuts, like @vpc, for us. # @param args [Hash]: Hash of named arguments passed via Ruby's double-splat def initialize(**args) super cloud_desc if @cloud_id # XXX why don't I have this on regroom? if !@cloud_id and cloud_desc and cloud_desc.project_id @cloud_id = cloud_desc.project_id end if !mu_name.nil? @mu_name = mu_name elsif @config['scrub_mu_isms'] @mu_name = @config['name'] else @mu_name = @deploy.getResourceName(@config['name']) end end # Called automatically by {MU::Deploy#createResources} def create end # Called automatically by {MU::Deploy#createResources} def groom end # Return the cloud descriptor for the Habitat def cloud_desc @cached_cloud_desc ||= MU::Cloud::Azure::Habitat.find(cloud_id: @cloud_id).values.first # @habitat_id ||= @cached_cloud_desc.parent.id if @cached_cloud_desc @cached_cloud_desc end # Return the metadata for this project's configuration # @return [Hash] def notify # MU.structToHash(MU::Cloud::Google.resource_manager(credentials: @config['credentials']).get_project(@cloud_id)) {} end # Does this resource type exist as a global (cloud-wide) artifact, or # is it localized to a region/zone? # @return [Boolean] def self.isGlobal? true end # Denote whether this resource implementation is experiment, ready for # testing, or ready for production use. def self.quality MU::Cloud::ALPHA end # Check whether is in the +ACTIVE+ state and has billing enabled. # @param project_id [String] # @return [Boolean] def self.isLive?(project_id, credentials = nil) true end # Stub method. Azure resources are cleaned up by removing the parent # resource group. # @return [void] def self.cleanup(**args) end @@list_projects_cache = nil # Locate and return cloud provider descriptors of this resource type # which match the provided parameters, or all visible resources if no # filters are specified. At minimum, implementations of +find+ must # honor +credentials+ and +cloud_id+ arguments. We may optionally # support other search methods, such as +tag_key+ and +tag_value+, or # cloud-specific arguments like +project+. See also {MU::MommaCat.findStray}. # @param args [Hash]: Hash of named arguments passed via Ruby's double-splat # @return [Hash]: The cloud provider's complete descriptions of matching resources def self.find(**args) #MU.log "habitat.find called by #{caller[0]}", MU::WARN, details: args found = {} args[:cloud_id] ||= args[:project] # XXX we probably want to cache this # XXX but why are we being called over and over? if args[:cloud_id] found[args[:cloud_id]] = MU::Cloud::Azure.subs.subscriptions.get(args[:cloud_id]) else MU::Cloud::Azure.subs.subscriptions.list.each { |sub| found[sub.subscription_id] = sub } end found end # Reverse-map our cloud description into a runnable config hash. # We assume that any values we have in +@config+ are placeholders, and # calculate our own accordingly based on what's live in the cloud. def toKitten(rootparent: nil, billing: nil) bok = { "cloud" => "Azure", "credentials" => @config['credentials'] } bok end # Cloud-specific configuration properties. # @param config [MU::Config]: The calling MU::Config object # @return [Array]: List of required fields, and json-schema Hash of cloud-specific configuration parameters for this resource def self.schema(config) toplevel_required = [] schema = { } [toplevel_required, schema] end # Cloud-specific pre-processing of {MU::Config::BasketofKittens::habitats}, bare and unvalidated. # @param habitat [Hash]: The resource to process and validate # @param configurator [MU::Config]: The overall deployment configurator of which this resource is a member # @return [Boolean]: True if validation succeeded, False otherwise def self.validateConfig(habitat, configurator) ok = true habitat['region'] ||= MU::Cloud::Azure.myRegion(habitat['credentials']) ok end end end end end