require 'json' require 'yaml' require 'vagrant-skytap/environment_properties' require 'vagrant-skytap/api/resource' require 'vagrant-skytap/api/vm' require 'vagrant-skytap/api/network' require 'vagrant-skytap/api/publish_set' require_relative 'runstate_operations' module VagrantPlugins module Skytap module API class Environment < Resource include RunstateOperations RESOURCE_ROOT = '/configurations' class << self def create!(env, vm_url) vm = Vm.fetch(env, vm_url) check_vm_before_adding(env, vm) resp = env[:api_client].post(RESOURCE_ROOT, JSON.dump(template_id: vm.template_id, vm_ids: [vm.id])) fetch(env, resp['Location']) end def fetch(env, url) resp = env[:api_client].get(url) new(JSON.load(resp.body), env) end def properties(env) EnvironmentProperties.read(env[:machine].env.local_data_path) end def check_vm_before_adding(env, vm) raise Errors::NotTemplateVm, url: vm.url unless vm.from_template? raise Errors::SourceVmNotStopped, name: env[:machine].name, url: vm.url unless vm.stopped? end end attr_reader :provider_config attr_reader :vms, :networks reads :id, :name, :vms, :networks, :region, :runstate, :url def initialize(attrs, env) super @provider_config = env[:machine].provider_config end def vms @vms ||= (get_api_attribute('vms') || []).collect do |vm_attrs| Vm.new(vm_attrs, self, env) end end def get_vms_by_id(ids=[]) vms.select{|vm| ids.include?(vm.id)} end def get_vm_by_id(id) get_vms_by_id([id]).first end def current_vm vms.find(&:current_machine?) end def networks @networks ||= (get_api_attribute('networks') || []).collect do |network_attrs| Network.new(network_attrs, self, env) end end def publish_sets @publish_sets ||= (get_api_attribute('publish_sets') || []).collect do |ps_attrs| PublishSet.new(ps_attrs, self, env) end end def region get_api_attribute('region') end def refresh(attrs) @vms = nil @networks = nil @publish_sets = nil super end def run!(vm_ids = nil) set_runstate :running, vm_ids: vm_ids end def delete retry_while_resource_busy do api_client.delete(url) break end end def add_vm(vm_url) vm = Vm.fetch(env, vm_url) check_vm_before_adding(env, vm) vm_ids = vms.collect(&:id) update_with_retry(template_id: vm.template_id, vm_ids: [vm.id]) new_vm_ids = vms.collect(&:id) - vm_ids get_vm_by_id(new_vm_ids.last) end def check_vm_before_adding(env, vm) raise Errors::RegionMismatch, environment_region: region, vm_region: vm.region unless vm.region == region self.class.check_vm_before_adding(env, vm) end def create_publish_set(attrs={}) resp = api_client.post("#{url}/publish_sets", JSON.dump(attrs)) PublishSet.new(JSON.load(resp.body), self, env) end def properties @properties ||= EnvironmentProperties.new(env[:machine].env.local_data_path) end end end end end