vagrant_abiquo 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,24 @@
1
+ require 'vagrant_abiquo/helpers/client'
2
+ require 'vagrant_abiquo/helpers/abiquo'
3
+
4
+ module VagrantPlugins
5
+ module Abiquo
6
+ module Actions
7
+ class CheckState
8
+ include Helpers::Client
9
+
10
+ def initialize(app, env)
11
+ @app = app
12
+ @machine = env[:machine]
13
+ @logger = Log4r::Logger.new('vagrant::abiquo::check_state')
14
+ end
15
+
16
+ def call(env)
17
+ env[:machine_state] = @machine.state.id
18
+ @logger.info "Machine state is '#{@machine.state.id}'"
19
+ @app.call(env)
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,120 @@
1
+ require 'vagrant_abiquo/helpers/client'
2
+ require 'vagrant_abiquo/helpers/abiquo'
3
+
4
+ module VagrantPlugins
5
+ module Abiquo
6
+ module Actions
7
+ class Create
8
+ include Helpers::Client
9
+ include Helpers::Abiquo
10
+ include Vagrant::Util::Retryable
11
+
12
+ def initialize(app, env)
13
+ @app = app
14
+ @machine = env[:machine]
15
+ @client = client
16
+ @env = env
17
+ @logger = Log4r::Logger.new('vagrant::abiquo::create')
18
+ end
19
+
20
+ def call(env)
21
+ # Find for selected virtual datacenter
22
+ vdc = get_vdc(@machine.provider_config.virtualdatacenter)
23
+ raise Abiquo::Errors::VDCNotFound, vdc: @machine.provider_config.virtualdatacenter if vdc.nil?
24
+
25
+ # Find for selected virtual appliance
26
+ vname = vapp_name(@machine)
27
+ vapp = get_vapp(vdc, vname)
28
+
29
+ # Find for selected vm template
30
+ template = get_template(vdc, @machine.provider_config.template)
31
+ raise Abiquo::Errors::TemplateNotFound, template: @machine.provider_config.template, vdc: vdc.name if template.nil?
32
+
33
+ # If everything is OK we can proceed to create the VM
34
+ # VM Template link
35
+ tmpl_link = template.link(:edit).clone.to_hash
36
+ tmpl_link['rel'] = "virtualmachinetemplate"
37
+
38
+ # Configured CPU and RAM
39
+ cpu_cores = @machine.provider_config.cpu_cores
40
+ ram_mb = @machine.provider_config.ram_mb
41
+
42
+ # VM entity
43
+ vm_definition = {}
44
+ vm_definition['cpu'] = cpu_cores || template.cpuRequired
45
+ vm_definition['ram'] = ram_mb || template.ramRequired
46
+ vm_definition['label'] = @machine.name
47
+ vm_definition['vdrpEnabled'] = true
48
+ vm_definition['links'] = [ tmpl_link ]
49
+
50
+ # Create VM
51
+ env[:ui].info I18n.t('vagrant_abiquo.info.create')
52
+ vm = create_vm(vm_definition, vapp)
53
+
54
+ # User Data
55
+ md = vm.link(:metadata).get
56
+ mdhash = JSON.parse(md.to_json)
57
+ if mdhash['metadata'].nil?
58
+ mdhash['metadata'] = { 'startup-script' => @machine.provider_config.user_data }
59
+ else
60
+ mdhash['metadata']['startup-script'] = @machine.provider_config.user_data
61
+ end
62
+ @client.put(vm.link(:metadata), mdhash.to_json)
63
+
64
+ # Check network
65
+ unless @machine.provider_config.network.nil?
66
+ # Network config is not nil, so we have
67
+ # to attach a specific net.
68
+ attach_net(vm, @machine.provider_config.network)
69
+ raise Abiquo::Errors::NetworkError if vm.nil?
70
+ end
71
+ vm = vm.link(:edit).get
72
+
73
+ # Deploying VM
74
+ env[:ui].info I18n.t('vagrant_abiquo.info.deploy')
75
+ task = deploy(vm)
76
+
77
+ if task.state == 'FINISHED_SUCCESSFULLY'
78
+ # Deploy successfully completed
79
+ env[:ui].info I18n.t('vagrant_abiquo.info.deploycompleted')
80
+
81
+ # Give time to the OS to boot.
82
+ retryable(:tries => 20, :sleep => 5) do
83
+ next if env[:interrupted]
84
+ raise 'not ready' if !@machine.communicate.ready?
85
+ end
86
+
87
+ # Find its IP
88
+ vm = vm.link(:edit).get
89
+ ip = vm.link(:nic0).title
90
+ env[:ui].info I18n.t('vagrant_abiquo.info.vm_ip', :ip => ip)
91
+ @machine.id = vm.url
92
+ else
93
+ # Deploy failed
94
+ env[:ui].error I18n.t('vagrant_abiquo.info.deployfailed')
95
+ end
96
+
97
+ @app.call(env)
98
+ end
99
+
100
+ # Both the recover and terminate are stolen almost verbatim from
101
+ # the Vagrant AWS provider up action
102
+ def recover(env)
103
+ return if env['vagrant.error'].is_a?(Vagrant::Errors::VagrantError)
104
+
105
+ if @machine.state.id != :not_created
106
+ terminate(env)
107
+ end
108
+ end
109
+
110
+ def terminate(env)
111
+ destroy_env = env.dup
112
+ destroy_env.delete(:interrupted)
113
+ destroy_env[:config_validate] = false
114
+ destroy_env[:force_confirm_destroy] = true
115
+ env[:action_runner].run(Actions.destroy, destroy_env)
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,38 @@
1
+ require 'vagrant_abiquo/helpers/client'
2
+ require 'vagrant_abiquo/helpers/abiquo'
3
+
4
+ module VagrantPlugins
5
+ module Abiquo
6
+ module Actions
7
+ class CreatevApp
8
+ include Helpers::Client
9
+ include Helpers::Abiquo
10
+
11
+ def initialize(app, env)
12
+ @app = app
13
+ @machine = env[:machine]
14
+ @logger = Log4r::Logger.new('vagrant::abiquo::create_vapp')
15
+ end
16
+
17
+ def call(env)
18
+ pconfig = env[:env].vagrantfile.config.finalize![:vm].get_provider_config(:abiquo)
19
+ @client ||= AbiquoAPI.new(pconfig.abiquo_connection_data)
20
+
21
+ @logger.info "Checking vApp '#{pconfig.virtualappliance}'"
22
+
23
+ @logger.info "Looking up VDC '#{pconfig.virtualdatacenter}'"
24
+ vdc = get_vdc(pconfig.virtualdatacenter)
25
+ raise Abiquo::Errors::VDCNotFound, vdc: pconfig.virtualdatacenter if vdc.nil?
26
+
27
+ vapp = get_vapp(vdc, pconfig.virtualappliance)
28
+ if vapp.nil?
29
+ @logger.info "vApp '#{pconfig.virtualappliance}' does not exist, creating."
30
+ create_vapp(vdc, pconfig.virtualappliance)
31
+ end
32
+
33
+ @app.call(env)
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,46 @@
1
+ require 'vagrant_abiquo/helpers/client'
2
+ require 'vagrant_abiquo/helpers/abiquo'
3
+
4
+ module VagrantPlugins
5
+ module Abiquo
6
+ module Actions
7
+ class Destroy
8
+ include Helpers::Client
9
+ include Helpers::Abiquo
10
+ include Vagrant::Util::Retryable
11
+
12
+ def initialize(app, env)
13
+ @app = app
14
+ @machine = env[:machine]
15
+ @client = client
16
+ @logger = Log4r::Logger.new('vagrant::abiquo::destroy')
17
+ end
18
+
19
+ def call(env)
20
+ env[:ui].info I18n.t('vagrant_abiquo.info.destroying', vm: @machine.name)
21
+ vm = get_vm(@machine.id)
22
+ vm.delete
23
+
24
+ # Check when task finishes. This may take a while
25
+ retryable(:tries => 120, :sleep => 5) do
26
+ begin
27
+ raise vm.label if vm.refresh
28
+ rescue AbiquoAPIClient::NotFound
29
+ env[:ui].info I18n.t('vagrant_abiquo.info.deleted', vm: @machine.name)
30
+ end
31
+ end
32
+
33
+ vapp = vm.link(:virtualappliance).get
34
+ vms = vapp.link(:virtualmachines).get.count
35
+ if vms == 0
36
+ vapp.delete
37
+ env[:ui].info I18n.t('vagrant_abiquo.info.deleted_vapp', vapp: vapp.name)
38
+ end
39
+
40
+ @machine.id = nil
41
+ @app.call(env)
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,30 @@
1
+ require 'vagrant_abiquo/helpers/client'
2
+ require 'vagrant_abiquo/helpers/abiquo'
3
+
4
+ module VagrantPlugins
5
+ module Abiquo
6
+ module Actions
7
+ class PowerOff
8
+ include Helpers::Client
9
+ include Helpers::Abiquo
10
+ include Vagrant::Util::Retryable
11
+
12
+ def initialize(app, env)
13
+ @app = app
14
+ @machine = env[:machine]
15
+ @client = AbiquoAPI.new(@machine.provider_config.abiquo_connection_data)
16
+ @logger = Log4r::Logger.new('vagrant::abiquo::power_off')
17
+ end
18
+
19
+ def call(env)
20
+ vm = get_vm(@machine.id)
21
+ vm = power_off(vm)
22
+ raise PowerOffError, vm: vm.label, state: vm.state if vm.state != 'OFF'
23
+
24
+ @app.call(env)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+
@@ -0,0 +1,30 @@
1
+ require 'vagrant_abiquo/helpers/client'
2
+ require 'vagrant_abiquo/helpers/abiquo'
3
+
4
+ module VagrantPlugins
5
+ module Abiquo
6
+ module Actions
7
+ class PowerOn
8
+ include Helpers::Client
9
+ include Helpers::Abiquo
10
+ include Vagrant::Util::Retryable
11
+
12
+ def initialize(app, env)
13
+ @app = app
14
+ @machine = env[:machine]
15
+ @client = AbiquoAPI.new(@machine.provider_config.abiquo_connection_data)
16
+ @logger = Log4r::Logger.new('vagrant::abiquo::power_off')
17
+ end
18
+
19
+ def call(env)
20
+ vm = get_vm(@machine.id)
21
+ vm = poweron(vm)
22
+ raise PowerOnError, vm: vm.label, state: vm.state if vm.state != 'ON'
23
+
24
+ @app.call(env)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+
@@ -0,0 +1,37 @@
1
+ require 'vagrant_abiquo/helpers/client'
2
+ require 'vagrant_abiquo/helpers/abiquo'
3
+
4
+ module VagrantPlugins
5
+ module Abiquo
6
+ module Actions
7
+ class Reset
8
+ include Helpers::Client
9
+ include Helpers::Abiquo
10
+ include Vagrant::Util::Retryable
11
+
12
+ def initialize(app, env)
13
+ @app = app
14
+ @machine = env[:machine]
15
+ @client = AbiquoAPI.new(@machine.provider_config.abiquo_connection_data)
16
+ @logger = Log4r::Logger.new('vagrant::abiquo::reset')
17
+ end
18
+
19
+ def call(env)
20
+ env[:ui].info I18n.t('vagrant_abiquo.info.reloading')
21
+ vm = get_vm(@machine.id)
22
+ vm = reset(vm)
23
+
24
+ # Give time to the OS to boot.
25
+ retryable(:tries => 120, :sleep => 10) do
26
+ next if env[:interrupted]
27
+ raise 'not ready' if !@machine.communicate.ready?
28
+ end
29
+
30
+ @app.call(env)
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+
@@ -0,0 +1,55 @@
1
+ module VagrantPlugins
2
+ module Abiquo
3
+ class Config < Vagrant.plugin('2', :config)
4
+ attr_accessor :abiquo_connection_data
5
+ attr_accessor :virtualdatacenter
6
+ attr_accessor :virtualappliance
7
+ attr_accessor :cpu_cores
8
+ attr_accessor :ram_mb
9
+ attr_accessor :template
10
+ attr_accessor :network
11
+ attr_accessor :user_data
12
+
13
+ def initialize
14
+ @abiquo_connection_data = UNSET_VALUE
15
+ @virtualdatacenter = UNSET_VALUE
16
+ @virtualappliance = UNSET_VALUE
17
+ @template = UNSET_VALUE
18
+ @cpu_cores = 0
19
+ @ram_mb = 0
20
+ @network = UNSET_VALUE
21
+ @user_data = UNSET_VALUE
22
+ end
23
+
24
+ def finalize!
25
+ @abiquo_connection_data[:abiquo_api_url] = ENV['ABQ_URL'] if @abiquo_connection_data[:abiquo_api_url].nil?
26
+ @abiquo_connection_data[:abiquo_username] = ENV['ABQ_USER'] if @abiquo_connection_data[:abiquo_username].nil?
27
+ @abiquo_connection_data[:abiquo_password] = ENV['ABQ_PASS'] if @abiquo_connection_data[:abiquo_password].nil?
28
+
29
+ @virtualdatacenter = ENV['ABQ_VDC'] if @virtualdatacenter == UNSET_VALUE
30
+ @virtualappliance = ENV['ABQ_VAPP'] if @virtualappliance == UNSET_VALUE
31
+ @template = ENV['ABQ_TMPL'] if @template == UNSET_VALUE
32
+
33
+ @cpu_cores = ENV['ABQ_CPU'] if @cpu_cores == 0
34
+ @ram_mb = ENV['ABQ_RAM'] if @ram_mb == 0
35
+ @ram_mb = nil if @ram_mb == 0
36
+
37
+ @network = { ENV['ABQ_NET'] => ENV['ABQ_IP'] } if @network == UNSET_VALUE
38
+
39
+ if @user_data == UNSET_VALUE
40
+ # We will make sure the SSH key is injected.
41
+ @user_data = '#!/bin/bash\necho "vagrant_abiquo :: making sure SSH key gets injected."'
42
+ end
43
+ end
44
+
45
+ def validate(machine)
46
+ errors = []
47
+ errors << I18n.t('vagrant_abiquo.config.abiquo_connection_data') if !@abiquo_connection_data
48
+ errors << I18n.t('vagrant_abiquo.config.virtualdatacenter') if !@virtualdatacenter
49
+ errors << I18n.t('vagrant_abiquo.config.template') if !@template
50
+
51
+ { 'Abiquo Provider' => errors }
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,45 @@
1
+ module VagrantPlugins
2
+ module Abiquo
3
+ module Errors
4
+ class AbiquoError < Vagrant::Errors::VagrantError
5
+ error_namespace("vagrant_abiquo.errors")
6
+ end
7
+
8
+ class VDCNotFound < AbiquoError
9
+ error_key(:vdc_not_found)
10
+ end
11
+
12
+ class TemplateNotFound < AbiquoError
13
+ error_key(:template_not_found)
14
+ end
15
+
16
+ class PowerOffError < AbiquoError
17
+ error_key(:poweroff_error)
18
+ end
19
+
20
+ class NetworkError < AbiquoError
21
+ error_key(:network_error)
22
+ end
23
+
24
+ class APIStatusError < AbiquoError
25
+ error_key(:api_status)
26
+ end
27
+
28
+ class APIFindError < AbiquoError
29
+ error_key(:apifind_error)
30
+ end
31
+
32
+ class JSONError < AbiquoError
33
+ error_key(:json)
34
+ end
35
+
36
+ class ResultMatchError < AbiquoError
37
+ error_key(:result_match)
38
+ end
39
+
40
+ class LocalIPError < AbiquoError
41
+ error_key(:local_ip)
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,173 @@
1
+ require 'abiquo-api'
2
+ require 'log4r'
3
+ include Log4r
4
+
5
+ module VagrantPlugins
6
+ module Abiquo
7
+ module Helpers
8
+ module Abiquo
9
+ include Helpers::Client
10
+
11
+ @logger = Log4r::Logger.new('vagrant::abiquo::helper')
12
+
13
+ def vapp_name(machine)
14
+ machine.provider_config.virtualappliance.nil? ? File.basename(machine.env.cwd) : machine.provider_config.virtualappliance
15
+ end
16
+
17
+ def get_vm(vm_url)
18
+ vm_lnk = AbiquoAPI::Link.new :href => vm_url,
19
+ :type => 'application/vnd.abiquo.virtualmachine+json',
20
+ :client => client
21
+ vm_lnk.get
22
+ end
23
+
24
+ def get_vdc(vdc_name)
25
+ vdcs_lnk = AbiquoAPI::Link.new :href => 'cloud/virtualdatacenters',
26
+ :type => "application/vnd.abiquo.virtualdatacenters+json",
27
+ :client => client
28
+ vdcs_lnk.get.select {|vd| vd.name == vdc_name }.first
29
+ end
30
+
31
+ def get_vapp(vdc, name)
32
+ vdc.link(:virtualappliances).get.select {|va| va.name == name }.first
33
+ end
34
+
35
+ def create_vapp(vdc, name)
36
+ vapp_hash = { 'name' => name }
37
+ client.post(vdc.link(:virtualappliances), vapp_hash.to_json,
38
+ accept: 'application/vnd.abiquo.virtualappliance+json',
39
+ content: 'application/vnd.abiquo.virtualappliance+json')
40
+ end
41
+
42
+ def get_template(vdc, template)
43
+ vdc.link(:templates).get.select {|tmpl| tmpl.name == template }.first
44
+ end
45
+
46
+ def get_network(vm, net_name)
47
+ vdc = vm.link(:virtualdatacenter).get
48
+
49
+ networks = []
50
+ %w(privatenetworks network externalnetworks).each do |nettype|
51
+ begin
52
+ vdc.link(nettype.to_sym).get.each {|n| networks << n}
53
+ rescue Exception => e
54
+ @logger.debug "Exception retrieving '#{nettype}' networks."
55
+ @logger.debug e.message
56
+ @logger.debug e.backtrace
57
+ end
58
+ end
59
+ networks.select {|n| n.name == net_name }.first
60
+ end
61
+
62
+ def create_vm(vm_def, vapp)
63
+ client.post(vapp.link(:virtualmachines), vm_def.to_json,
64
+ :content => "application/vnd.abiquo.virtualmachine+json",
65
+ :accept => "application/vnd.abiquo.virtualmachine+json" )
66
+ end
67
+
68
+ def attach_net(vm, net_data)
69
+ net_data.each do |net, ip|
70
+ network = get_network(vm, net)
71
+ return nil if network.nil?
72
+
73
+ if ip
74
+ abqip = network.link(:ips).get.select {|i| i.ip == ip }.first
75
+ else
76
+ abqip = network.link(:ips).get.select {|i| ! i.has_link? :virtualmachine }.first
77
+ end
78
+
79
+ if abqip.nil?
80
+ if network.type == "EXTERNAL" || network.type == "PUBLIC"
81
+ # Can't create IP in those nets
82
+ return nil
83
+ end
84
+
85
+ # We have the net, we don't have the IP, create it
86
+ ip_hash = {
87
+ "ipv6" => network.ipv6,
88
+ "available" => true,
89
+ "quarantine" => false,
90
+ "numips" => 1,
91
+ "ip" => ip
92
+ }
93
+ abqip = client.post(network.link(:ips), ip_hash.to_json,
94
+ :accept => 'application/vnd.abiquo.privateip+json',
95
+ :content => 'application/vnd.abiquo.privateip+json' )
96
+ end
97
+
98
+ ip_lnk = abqip.link(:self).clone
99
+ ip_lnk.rel = 'nic0'
100
+ vm.links << {:nic0 => ip_lnk}
101
+
102
+ update(vm)
103
+ end
104
+ end
105
+
106
+ def deploy(vm)
107
+ task_lnk = client.post(vm.link(:deploy), '').link(:status).href
108
+ task = AbiquoAPI::Link.new(:href => task_lnk,
109
+ :type => 'application/vnd.abiquo.task+json',
110
+ :client => client).get
111
+
112
+ # Check when deploy finishes. This may take a while
113
+ retryable(:tries => 120, :sleep => 15) do
114
+ task = task.link(:self).get
115
+ raise vm.label if task.state == 'STARTED'
116
+ end
117
+
118
+ task
119
+ end
120
+
121
+ def apply_state(vm, state)
122
+ task_lnk = client.put(vm.link(:state), {"state" => state}.to_json,
123
+ :accept => 'application/vnd.abiquo.acceptedrequest+json',
124
+ :content => 'application/vnd.abiquo.virtualmachinestate+json').link(:status)
125
+ task = task_lnk.get
126
+
127
+ # Check when task finishes. This may take a while
128
+ retryable(:tries => 120, :sleep => 5) do
129
+ task = task.link(:self).get
130
+ raise vm.label if task.state == 'STARTED'
131
+ end
132
+ vm.link(:edit).get
133
+ end
134
+
135
+ def poweroff(vm)
136
+ apply_state('OFF')
137
+ end
138
+
139
+ def poweron(vm)
140
+ apply_state('ON')
141
+ end
142
+
143
+ def reset(vm)
144
+ task = client.post(vm.link(:reset), '',
145
+ :accept => 'application/vnd.abiquo.acceptedrequest+json',
146
+ :content => 'application/json').link(:status).get
147
+
148
+ # Check when task finishes. This may take a while
149
+ retryable(:tries => 120, :sleep => 5) do
150
+ task = task.link(:self).get
151
+ raise vm.label if task.state == 'STARTED'
152
+ end
153
+ vm.link(:edit).get
154
+ end
155
+
156
+ def update(vm)
157
+ task = client.put(vm.link(:edit), vm.to_json,
158
+ :accept => 'application/vnd.abiquo.acceptedrequest+json',
159
+ :content => vm.link(:edit).type)
160
+ if task
161
+ task = task.link(:status).get
162
+ # Check when task finishes. This may take a while
163
+ retryable(:tries => 120, :sleep => 5) do
164
+ task = task.link(:self).get
165
+ raise vm.label if task.state == 'STARTED'
166
+ end
167
+ end
168
+ vm.link(:edit).get
169
+ end
170
+ end
171
+ end
172
+ end
173
+ end