pec 0.4.4 → 0.5.0
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.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/README.md +4 -1
- data/lib/pec.rb +35 -32
- data/lib/pec/builder/port.rb +120 -0
- data/lib/pec/builder/server.rb +28 -0
- data/lib/pec/builder/user_data.rb +39 -0
- data/lib/pec/cli.rb +3 -3
- data/lib/pec/configure.rb +17 -26
- data/lib/pec/director.rb +103 -44
- data/lib/pec/init.rb +1 -1
- data/lib/pec/logger.rb +21 -0
- data/lib/pec/version.rb +1 -1
- data/pec.gemspec +1 -1
- metadata +8 -24
- data/lib/pec/compute/flavor.rb +0 -7
- data/lib/pec/compute/image.rb +0 -7
- data/lib/pec/compute/server.rb +0 -30
- data/lib/pec/compute/tenant.rb +0 -16
- data/lib/pec/configure/ethernet.rb +0 -81
- data/lib/pec/configure/host.rb +0 -40
- data/lib/pec/configure/sample.rb +0 -55
- data/lib/pec/configure/user_data.rb +0 -36
- data/lib/pec/director/destroy_director.rb +0 -23
- data/lib/pec/director/helper.rb +0 -51
- data/lib/pec/director/make_director.rb +0 -35
- data/lib/pec/director/vm_status_director.rb +0 -41
- data/lib/pec/network/port.rb +0 -104
- data/lib/pec/network/port_state.rb +0 -40
- data/lib/pec/network/security_group.rb +0 -7
- data/lib/pec/network/subnet.rb +0 -14
- data/lib/pec/query.rb +0 -24
- data/lib/pec/resource.rb +0 -26
- data/lib/pec/resource/mock.rb +0 -172
- data/lib/pec/resource/openstack.rb +0 -60
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8a7355209a3c35e40ac68d514cae1e0ed75e8102
|
4
|
+
data.tar.gz: ea45ced7c65397076d2c7496eb5efe44ffa6d41a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3f40e9678fbd05ffeac16fac0ca9eb1832185a38526a188149a473dee6d8e397d1250b1c081a30b687262fb02e7ebab83b02c53dcca3d9b03f7cb4f15daffdb8
|
7
|
+
data.tar.gz: 57feae3668f00d475f1b1be8871294caa4fb7ac72ace25a78a9af76e57220cf1dd70dcf58e4aa7e5b5392e20db6c782cf49fd11459c664c44046697d56accc1d
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -37,6 +37,7 @@ _default_: &def
|
|
37
37
|
tenant: your_tenant
|
38
38
|
image: centos-7.1_chef-12.3_puppet-3.7
|
39
39
|
flavor: m1.small
|
40
|
+
availability_zone: nova
|
40
41
|
|
41
42
|
pyama-test001:
|
42
43
|
<<: *def
|
@@ -74,8 +75,10 @@ pyama-test002:
|
|
74
75
|
| flavor | フレーバー名 | ○ | m1.small |
|
75
76
|
| networks | ネットワーク定義 | - | [] |
|
76
77
|
| security_group | セキュリティグループ名 | - | [default,ssh] |
|
77
|
-
| templates | `user_data
|
78
|
+
| templates | `user_data`のテンプレート `./user_data` に配置 | - | [base.yaml,webserver.yaml] |
|
78
79
|
| user_data | cloud-init記法に準拠 | - | - |
|
80
|
+
| availability_zone | アベイラビリティゾーン | - | nova |
|
81
|
+
|
79
82
|
* 先頭が_で開始されるインスタンス名はyaml merge記法用途と認識し、スキップします
|
80
83
|
|
81
84
|
##### Networks
|
data/lib/pec.rb
CHANGED
@@ -2,42 +2,45 @@ require 'fog'
|
|
2
2
|
require 'ip'
|
3
3
|
require 'colorator'
|
4
4
|
require "pec/version"
|
5
|
-
require "pec/
|
6
|
-
require "pec/errors"
|
7
|
-
require "pec/init"
|
8
|
-
require "pec/resource"
|
9
|
-
require "pec/resource/openstack"
|
10
|
-
require "pec/resource/mock"
|
11
|
-
require "pec/director"
|
12
|
-
require "pec/director/helper"
|
13
|
-
require "pec/director/make_director"
|
14
|
-
require "pec/director/destroy_director"
|
15
|
-
require "pec/director/vm_status_director"
|
5
|
+
require "pec/logger"
|
16
6
|
require "pec/configure"
|
17
|
-
require "pec/
|
18
|
-
require "pec/
|
19
|
-
require "pec/
|
20
|
-
require "pec/
|
21
|
-
require "pec/compute/server"
|
22
|
-
require "pec/compute/flavor"
|
23
|
-
require "pec/compute/image"
|
24
|
-
require "pec/compute/tenant"
|
25
|
-
require "pec/network/security_group"
|
26
|
-
require "pec/network/port"
|
27
|
-
require "pec/network/port_state"
|
28
|
-
require "pec/network/subnet"
|
7
|
+
require "pec/director"
|
8
|
+
require "pec/builder/server"
|
9
|
+
require "pec/builder/port"
|
10
|
+
require "pec/builder/user_data"
|
29
11
|
require "pec/cli"
|
30
12
|
|
31
13
|
module Pec
|
32
|
-
|
14
|
+
def self.compute
|
15
|
+
@_compute ||= Fog::Compute.new({
|
16
|
+
provider: 'openstack'
|
17
|
+
})
|
18
|
+
@_compute
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.neutron
|
22
|
+
@_neutron ||= Fog::Network.new({
|
23
|
+
provider: 'openstack'
|
24
|
+
})
|
25
|
+
@_neutron
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.identity
|
29
|
+
@_identity ||= Fog::Identity.new({
|
30
|
+
provider: 'openstack'
|
31
|
+
})
|
32
|
+
@_identity
|
33
|
+
end
|
33
34
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
def deep_merge!(second)
|
40
|
-
merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : Array === v1 && Array === v2 ? v1 | v2 : [:undefined, nil, :nil].include?(v2) ? v1 : v2 }
|
41
|
-
self.merge!(second.to_h, &merger)
|
35
|
+
def self.load_config(file_name=nil)
|
36
|
+
file_name ||= 'Pec.yaml'
|
37
|
+
@_configure = []
|
38
|
+
YAML.load_file(file_name).to_hash.reject {|c| c[0].to_s.match(/^_/)}.each do |host|
|
39
|
+
@_configure << Pec::Configure.new(host)
|
42
40
|
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.configure
|
44
|
+
@_configure
|
45
|
+
end
|
43
46
|
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
module Pec
|
2
|
+
module Builder
|
3
|
+
class Port
|
4
|
+
attr_reader :user_data
|
5
|
+
def build(host)
|
6
|
+
ports = []
|
7
|
+
@user_data = []
|
8
|
+
|
9
|
+
host.networks.each do |network|
|
10
|
+
validate(network)
|
11
|
+
Pec::Logger.notice "port create start : #{network[0]}"
|
12
|
+
port = create_port(host, network)
|
13
|
+
Pec::Logger.notice "assgin ip : #{port.fixed_ips.first["ip_address"]}"
|
14
|
+
ports << port
|
15
|
+
@user_data << gen_user_data(network, port)
|
16
|
+
end
|
17
|
+
{
|
18
|
+
nics: ports.map {|port| { port_id: port.id }}
|
19
|
+
}
|
20
|
+
end
|
21
|
+
|
22
|
+
def validate(network)
|
23
|
+
%w(
|
24
|
+
bootproto
|
25
|
+
ip_address
|
26
|
+
).each do |k|
|
27
|
+
raise "network key #{k} is require" unless network[1][k]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def create_port(host, network)
|
32
|
+
ip = IP.new(network[1]['ip_address'])
|
33
|
+
subnet = Pec.neutron.subnets.find {|s|s.cidr == ip.network.to_s}
|
34
|
+
attribute = gen_port_attribute(host, network, subnet, ip)
|
35
|
+
Pec.neutron.ports.create(attribute)
|
36
|
+
end
|
37
|
+
|
38
|
+
def gen_port_attribute(host, network, subnet, ip)
|
39
|
+
attribute = {
|
40
|
+
name: network[0],
|
41
|
+
network_id: subnet.network_id
|
42
|
+
}
|
43
|
+
|
44
|
+
attribute.merge!(
|
45
|
+
fixed_ip(subnet, ip)
|
46
|
+
) if ip.to_s != subnet.cidr
|
47
|
+
|
48
|
+
attribute.merge!(
|
49
|
+
security_group(host)
|
50
|
+
) if host.security_group
|
51
|
+
|
52
|
+
attribute.merge!(
|
53
|
+
allowed_address_pairs(network)
|
54
|
+
) if network[1]['allowed_address_pairs']
|
55
|
+
attribute
|
56
|
+
end
|
57
|
+
|
58
|
+
def gen_user_data(network, port)
|
59
|
+
path = network[1]['path'] || "/etc/sysconfig/network-scripts/ifcfg-#{port.name}"
|
60
|
+
{
|
61
|
+
'content' => ifcfg_config(network, port),
|
62
|
+
'owner' => "root:root",
|
63
|
+
'path' => path,
|
64
|
+
'permissions' => "0644"
|
65
|
+
}
|
66
|
+
end
|
67
|
+
|
68
|
+
def ifcfg_config(network, port)
|
69
|
+
base = {
|
70
|
+
"name" => port.name,
|
71
|
+
"device" => port.name,
|
72
|
+
"type" => 'Ethernet',
|
73
|
+
"onboot" => 'yes',
|
74
|
+
"hwaddr" => port.mac_address
|
75
|
+
}
|
76
|
+
|
77
|
+
base.merge!(
|
78
|
+
{
|
79
|
+
"netmask" => IP.new(network[1]['ip_address']).netmask.to_s,
|
80
|
+
"ipaddr" => port.fixed_ips.first['ip_address'].split("/").first
|
81
|
+
}
|
82
|
+
) if network[1]['bootproto'] == "static"
|
83
|
+
|
84
|
+
# delete options
|
85
|
+
%w(allowed_address_pairs ip_address).each {|name| network[1].delete(name)}
|
86
|
+
|
87
|
+
base.merge!(
|
88
|
+
network[1]
|
89
|
+
)
|
90
|
+
|
91
|
+
base.map {|k,v| "#{k.upcase}=#{v}"}.join("\n")
|
92
|
+
end
|
93
|
+
|
94
|
+
#
|
95
|
+
# after port options
|
96
|
+
#
|
97
|
+
def fixed_ip(subnet, ip)
|
98
|
+
{
|
99
|
+
fixed_ips: [
|
100
|
+
{ subnet_id: subnet.id, ip_address: ip.to_addr}
|
101
|
+
]
|
102
|
+
}
|
103
|
+
end
|
104
|
+
|
105
|
+
def security_group(host)
|
106
|
+
ids = host.security_group.map do |name|
|
107
|
+
Pec.neutron.security_groups.find {|sg| sg.name == name}.id
|
108
|
+
end
|
109
|
+
{ security_groups: ids }
|
110
|
+
end
|
111
|
+
|
112
|
+
def allowed_address_pairs(network)
|
113
|
+
pairs = network[1]['allowed_address_pairs'].map do |pair|
|
114
|
+
{ ip_address: pair['ip_address'] }
|
115
|
+
end
|
116
|
+
{ allowed_address_pairs: pairs }
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module Pec
|
2
|
+
module Builder
|
3
|
+
class Server
|
4
|
+
def build(host)
|
5
|
+
Pec::Logger.notice "flavor is #{host.flavor}"
|
6
|
+
Pec::Logger.notice "image is #{host.image}"
|
7
|
+
hash = {
|
8
|
+
name: host.name,
|
9
|
+
flavor_ref: fetch_flavor(host).id,
|
10
|
+
image_ref: fetch_image(host).id
|
11
|
+
}
|
12
|
+
hash[:availability_zone] = host.availability_zone if host.availability_zone
|
13
|
+
hash
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.resource(name)
|
17
|
+
define_method("fetch_#{name}", -> (host) {
|
18
|
+
r = Pec.compute.send("#{name}s").find {|val|val.name == host.send(name)}
|
19
|
+
raise "not fond #{name} #{host.send(name)}" unless r
|
20
|
+
r
|
21
|
+
})
|
22
|
+
end
|
23
|
+
|
24
|
+
resource 'flavor'
|
25
|
+
resource 'image'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Pec
|
2
|
+
module Builder
|
3
|
+
class UserData
|
4
|
+
def build(host, port_user_data)
|
5
|
+
user_data = default(host)
|
6
|
+
user_data["write_files"] = port_user_data if port_user_data
|
7
|
+
if template = load_template(host)
|
8
|
+
user_data.deep_merge!(template)
|
9
|
+
end
|
10
|
+
{ user_data: "#cloud-config\n" + user_data.to_yaml }
|
11
|
+
end
|
12
|
+
|
13
|
+
def load_template(host)
|
14
|
+
host.templates.inject({}) do |merge_template, template|
|
15
|
+
template.to_s.concat('.yaml') unless template.to_s.match(/.*\.yaml/)
|
16
|
+
raise "#{template} not fond!" unless FileTest.exist?("user_data/#{template}")
|
17
|
+
merge_template.deep_merge!(YAML.load_file("user_data/#{template}").to_hash)
|
18
|
+
end if host.templates
|
19
|
+
end
|
20
|
+
|
21
|
+
def default(host)
|
22
|
+
_def = host.user_data || {}
|
23
|
+
_def['fqdn'] = host.name if host.user_data && !host.user_data['fqdn']
|
24
|
+
_def
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class ::Hash
|
31
|
+
def deep_merge(second)
|
32
|
+
merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : Array === v1 && Array === v2 ? v1 | v2 : [:undefined, nil, :nil].include?(v2) ? v1 : v2 }
|
33
|
+
self.merge(second.to_h, &merger)
|
34
|
+
end
|
35
|
+
def deep_merge!(second)
|
36
|
+
merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : Array === v1 && Array === v2 ? v1 | v2 : [:undefined, nil, :nil].include?(v2) ? v1 : v2 }
|
37
|
+
self.merge!(second.to_h, &merger)
|
38
|
+
end
|
39
|
+
end
|
data/lib/pec/cli.rb
CHANGED
@@ -12,19 +12,19 @@ module Pec
|
|
12
12
|
|
13
13
|
desc 'up', 'create vm by Pec.yaml'
|
14
14
|
def up(host_name = nil)
|
15
|
-
Pec::Director.
|
15
|
+
Pec::Director.make(host_name)
|
16
16
|
end
|
17
17
|
|
18
18
|
option :force , type: :boolean, aliases: "-f"
|
19
19
|
desc "destroy", "delete vm"
|
20
20
|
def destroy(host_name = nil)
|
21
|
-
Pec::Director.
|
21
|
+
Pec::Director.destroy(host_name, options)
|
22
22
|
end
|
23
23
|
|
24
24
|
desc "status", "vm status"
|
25
25
|
def status(host_name = nil)
|
26
26
|
say("Current machine stasus:", :yellow)
|
27
|
-
Pec::Director.
|
27
|
+
Pec::Director.status(host_name)
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
data/lib/pec/configure.rb
CHANGED
@@ -1,36 +1,27 @@
|
|
1
|
-
require 'yaml'
|
2
1
|
module Pec
|
3
2
|
class Configure
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
if file_name.is_a?(Hash)
|
10
|
-
hash = file_name
|
11
|
-
else
|
12
|
-
hash = YAML.load_file(file_name).to_hash
|
13
|
-
end
|
14
|
-
|
15
|
-
hash.reject {|c| c[0].to_s.match(/^_/)}.each do |config|
|
16
|
-
|
17
|
-
config[1]['user_data'] ||= {}
|
18
|
-
config[1]['user_data']['fqdn'] ||= config[0].to_s
|
3
|
+
def initialize(config)
|
4
|
+
validate(config)
|
5
|
+
@_config = config
|
6
|
+
end
|
19
7
|
|
20
|
-
|
21
|
-
|
22
|
-
end
|
23
|
-
rescue Psych::SyntaxError,NoMethodError => e
|
24
|
-
raise(Pec::Errors::Configure, e)
|
8
|
+
def name
|
9
|
+
@_config[0]
|
25
10
|
end
|
26
11
|
|
27
|
-
def
|
28
|
-
|
12
|
+
def method_missing(method, *args)
|
13
|
+
nil unless @_config[1][method.to_s]
|
14
|
+
@_config[1][method.to_s]
|
29
15
|
end
|
30
16
|
|
31
|
-
def
|
32
|
-
|
33
|
-
|
17
|
+
def validate(host)
|
18
|
+
%w(
|
19
|
+
tenant
|
20
|
+
image
|
21
|
+
flavor
|
22
|
+
networks
|
23
|
+
).each do |k|
|
24
|
+
raise "host key #{k} is require" unless host[1][k]
|
34
25
|
end
|
35
26
|
end
|
36
27
|
end
|
data/lib/pec/director.rb
CHANGED
@@ -1,57 +1,116 @@
|
|
1
1
|
module Pec
|
2
|
-
class Director
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
err_message(e)
|
2
|
+
class Director
|
3
|
+
def self.make(host_name)
|
4
|
+
Pec.load_config
|
5
|
+
Pec.configure.each do |host|
|
6
|
+
next if host_name && host.name != host_name
|
7
|
+
Pec::Logger.info "make start #{host.name}"
|
8
|
+
|
9
|
+
Pec.compute.set_tenant(host.tenant)
|
10
|
+
Pec.neutron.set_tenant_patch(host.tenant)
|
11
|
+
|
12
|
+
port_builder = Pec::Builder::Port.new
|
13
|
+
server_builder = Pec::Builder::Server.new
|
14
|
+
user_data_builder = Pec::Builder::UserData.new
|
15
|
+
|
16
|
+
attribute = {}
|
17
|
+
attribute.merge!(server_builder.build(host))
|
18
|
+
attribute.merge!(port_builder.build(host))
|
19
|
+
|
20
|
+
if user_data = user_data_builder.build(host, port_builder.user_data)
|
21
|
+
attribute.merge!(user_data)
|
22
|
+
end
|
23
|
+
|
24
|
+
Pec::Logger.info "create success! #{host.name}" if Pec.compute.servers.create(attribute)
|
26
25
|
end
|
27
26
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
27
|
+
rescue Excon::Errors::Error => e
|
28
|
+
excon_err_message(e)
|
29
|
+
rescue => e
|
30
|
+
Pec::Logger.critical(e)
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.destroy(host_name, options)
|
34
|
+
Pec.load_config
|
35
|
+
Pec.configure.each do |host|
|
36
|
+
next if host_name && host.name != host_name
|
37
|
+
Pec.compute.set_tenant(host.tenant)
|
38
|
+
|
39
|
+
server = Pec.compute.servers.find {|s|s.name == host.name}
|
40
|
+
unless server
|
41
|
+
Pec::Logger.notice "not be created #{host.name}"
|
42
|
+
next
|
43
|
+
end
|
44
|
+
|
45
|
+
if options[:force] || Thor.new.yes?("#{host.name}: Are you sure you want to destroy the '#{host.name}' VM? [y/N]")
|
46
|
+
Pec::Logger.info "#{host.name} is deleted!" if Pec.compute.servers.destroy(server.id)
|
38
47
|
end
|
39
48
|
end
|
49
|
+
rescue Excon::Errors::Error => e
|
50
|
+
excon_err_message(e)
|
51
|
+
rescue => e
|
52
|
+
Pec::Logger.critical(e)
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.status(host_name)
|
56
|
+
Pec.load_config
|
57
|
+
Pec.configure.each do |host|
|
58
|
+
next if host_name && host.name != host_name
|
59
|
+
server = Pec.compute.servers.find {|s|s.name == host.name}
|
60
|
+
if server
|
61
|
+
puts sprintf(" %-35s %-10s %-10s %-10s %-10s %-35s %-48s",
|
62
|
+
host.name,
|
63
|
+
server.state,
|
64
|
+
Pec.identity.tenants.find_by_id(server.tenant_id),
|
65
|
+
Pec.compute.flavors.get(server.flavor['id']).name,
|
66
|
+
server.availability_zone,
|
67
|
+
server.os_ext_srv_attr_host,
|
68
|
+
server.addresses.map do |net, ethers|
|
69
|
+
ethers.map do |ether|
|
70
|
+
ether["addr"]
|
71
|
+
end
|
72
|
+
end.flatten.join(",")
|
73
|
+
)
|
40
74
|
|
41
|
-
|
42
|
-
|
75
|
+
else
|
76
|
+
puts sprintf(" %-35s %-10s",
|
77
|
+
host.name,
|
78
|
+
"uncreated"
|
79
|
+
)
|
80
|
+
end
|
43
81
|
end
|
44
82
|
|
45
|
-
|
46
|
-
|
47
|
-
|
83
|
+
rescue Excon::Errors::Error => e
|
84
|
+
excon_err_message(e)
|
85
|
+
rescue => e
|
86
|
+
Pec::Logger.critical(e)
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.excon_err_message(e)
|
90
|
+
if e.response
|
91
|
+
JSON.parse(e.response[:body]).each { |e,m| Pec::Logger.critical("#{e}:#{m["message"]}") }
|
92
|
+
else
|
93
|
+
Pec::Logger.critical(e)
|
48
94
|
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
49
98
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
99
|
+
module Fog
|
100
|
+
module Network
|
101
|
+
class OpenStack
|
102
|
+
class Real
|
103
|
+
def set_tenant_patch(tenant)
|
104
|
+
@openstack_must_reauthenticate = true
|
105
|
+
@openstack_tenant = tenant.to_s
|
106
|
+
authenticate
|
107
|
+
@path.sub!(/\/$/, '')
|
108
|
+
unless @path.match(SUPPORTED_VERSIONS)
|
109
|
+
@path = "/" + Fog::OpenStack.get_supported_version(SUPPORTED_VERSIONS,
|
110
|
+
@openstack_management_uri,
|
111
|
+
@auth_token,
|
112
|
+
@connection_options)
|
113
|
+
end
|
55
114
|
end
|
56
115
|
end
|
57
116
|
end
|