module Azure module Armrest # Base class for managing templates and deployments class TemplateDeploymentService < ResourceGroupBasedService def initialize(configuration, options = {}) super(configuration, 'deployments', 'Microsoft.Resources', options) end # Get names of all deployments in a resource group def list_names(resource_group = configuration.resource_group) list(resource_group).map(&:name) end # Get all deployments for the current subscription def list_all list_in_all_groups end # Get all operations of a deployment in a resource group def list_deployment_operations(deploy_name, resource_group = configuration.resource_group) validate_resource_group(resource_group) validate_resource(deploy_name) url = build_url(resource_group, deploy_name, 'operations') response = rest_get(url) JSON.parse(response)['value'].map { |hash| TemplateDeploymentOperation.new(hash) } end # Get the operation of a deployment in a resource group def get_deployment_operation(op_id, deploy_name, resource_group = configuration.resource_group) validate_resource_group(resource_group) validate_resource(deploy_name) raise ArgumentError, "must specify operation id" unless op_id url = build_url(resource_group, deploy_name, 'operations', op_id) response = rest_get(url) TemplateDeploymentOperation.new(response) end # Returns the json template as an object for the given deployment. # # If you want the plain JSON text then call .to_json on the returned object. # def get_template(deploy_name, resource_group = configuration.resource_group) validate_resource_group(resource_group) validate_resource(deploy_name) url = build_url(resource_group, deploy_name, 'exportTemplate') response = JSON.parse(rest_post(url))['template'] DeploymentTemplate.new(response) end # Delete a deployment and all associated resources that were generated by the # deployment. # # This is a synchronous call. It waits until all deletions complete def delete_associated_resources(deploy_name, resource_group = configuration.resource_group) operations = list_deployment_operations(deploy_name, resource_group) resource_ids = operations.collect do |op| if op.properties.provisioning_operation =~ /^create$/i op.properties.target_resource.id end end.compact resource_ids << build_id_string(resource_group, deploy_name) delete_resources(resource_ids, resource_ids.size) end private def delete_resources(ids, retry_cnt) if retry_cnt == 0 ids.each { |id| log("error", "Failed to delete #{id}") } return end remaining_ids = ids.collect { |id| delete_resource(id) }.compact delete_resources(remaining_ids, retry_cnt - 1) unless remaining_ids.empty? end def delete_resource(id_string) log("Deleting #{id_string}") wait(delete_by_id(id_string), 0) log("Deleted #{id_string}") nil rescue Azure::Armrest::BadRequestException => err log("debug", err.to_s) log("Resource #{id_string} cannot be deleted because of BadRequestException. Will try again.") id_string rescue Azure::Armrest::PreconditionFailedException, Azure::Armrest::ConflictException => err log("debug", err.to_s) log("Resource #{id_string} cannot be deleted because it is used by others. Will try again.") id_string rescue Azure::Armrest::ResourceNotFoundException => err log("debug", err.to_s) nil end end end end