knife-softlayer 0.1.3 → 0.2.0.pre.f0ba31b95
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 +8 -8
- data/knife-softlayer.gemspec +1 -1
- data/lib/chef/knife/flavor/base.rb +9 -134
- data/lib/chef/knife/softlayer_base.rb +31 -95
- data/lib/chef/knife/softlayer_datacenter_list.rb +28 -0
- data/lib/chef/knife/softlayer_datacenter_show.rb +45 -0
- data/lib/chef/knife/softlayer_flavor_list.rb +16 -7
- data/lib/chef/knife/softlayer_global_ip_list.rb +34 -0
- data/lib/chef/knife/softlayer_image_list.rb +26 -0
- data/lib/chef/knife/softlayer_server_create.rb +170 -77
- data/lib/chef/knife/softlayer_server_destroy.rb +5 -6
- data/lib/chef/knife/softlayer_vlan_create.rb +42 -0
- data/lib/chef/knife/softlayer_vlan_list.rb +28 -0
- data/lib/chef/knife/softlayer_vlan_show.rb +40 -0
- data/lib/knife-softlayer/version.rb +1 -1
- data/spec/unit/softlayer_base_spec.rb +5 -4
- data/spec/unit/softlayer_server_create_spec.rb +52 -84
- data/spec/unit/softlayer_server_destroy_spec.rb +29 -53
- metadata +14 -7
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
YTMxZDhhZDc1MWQ0Y2RkYWM4Y2IyYjJmY2FhNzY3MTg0ZGIxMTU2ZA==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MzY5ZTQ1YWMxYjAwNTkxYmJkMzEwNTMwZjYwMmUxOGQ5ZTZmMGJjOQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ZTRkYzNhNDQyNDdiMzkyMGE2YzI2MDBlYTNmZGJlOTc1NTNlY2VjNzBkMjZj
|
10
|
+
YmI5NWVhY2M0OWIyNjdiNTIyODFmMzU0NmJhODFlOGNhZjQ3ZjE0MGVmNjhl
|
11
|
+
MmFhNmZjYWEyMjRmODgxOGYwODlkYjA1ZWRmZWJmMTcwNTVkZDY=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
OTk4Yzc3OTRjMGM4ZmU3YmYzMWM4NmJiZTdjYmM2MTlkYzEwNmRhMzAyMmQ5
|
14
|
+
MDgxYTRhODM1NGIwMjgzNTBjYjVkMWUyZDhmZjA0OTdjMjA1NGNmODJkMDdk
|
15
|
+
YzA4OTQwMWJhMDIyNmUzYWM4OTE1YjExYmE1NTNjNjY2NDM0NWE=
|
data/knife-softlayer.gemspec
CHANGED
@@ -25,7 +25,7 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.test_files = spec.files.grep(%r{^(spec|spec|features)/})
|
26
26
|
spec.require_paths = ["lib"]
|
27
27
|
|
28
|
-
spec.add_dependency "
|
28
|
+
spec.add_dependency "fog-softlayer", "~> 0.3.14"
|
29
29
|
spec.add_dependency "knife-windows", "> 0.5.12"
|
30
30
|
spec.add_dependency "net-ssh", "> 2.8.0"
|
31
31
|
|
@@ -11,32 +11,22 @@ class Chef
|
|
11
11
|
class Knife
|
12
12
|
module SoftlayerFlavorBase
|
13
13
|
|
14
|
-
##
|
15
|
-
# Return the flavors table or the options table.
|
16
|
-
# @param [Boolean] show_all
|
17
|
-
# @return [Hash]
|
18
|
-
def table_info(show_all=false)
|
19
|
-
if show_all
|
20
|
-
options_table
|
21
|
-
else
|
22
|
-
flavors_table
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
14
|
##
|
27
15
|
# Build table of all VM configuration options.
|
28
16
|
# @return [Hash]
|
29
17
|
def options_table
|
30
18
|
columns = [
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
19
|
+
"| CORES",
|
20
|
+
"| RAM",
|
21
|
+
"| DISK",
|
22
|
+
"| OS",
|
23
|
+
"| NETWORK [MBS]",
|
24
|
+
"| DATACENTER",
|
37
25
|
]
|
38
26
|
|
39
|
-
|
27
|
+
6.times { columns << '| ========== ' }
|
28
|
+
|
29
|
+
opts = connection.request(:virtual_guest, :get_create_object_options).body
|
40
30
|
cpu = opts['processors']
|
41
31
|
ram = opts['memory']
|
42
32
|
disk = opts['blockDevices'].sort_by{|d| d['itemPrice']['item']['description'] unless d['itemPrice'].nil? }
|
@@ -57,121 +47,6 @@ class Chef
|
|
57
47
|
columns
|
58
48
|
end
|
59
49
|
|
60
|
-
##
|
61
|
-
# Build the VM "flavor" table.
|
62
|
-
# @return [Hash]
|
63
|
-
def flavors_table
|
64
|
-
# We don't have "flavors" actually, you can just pick from the menu.
|
65
|
-
# Let's shim in place the standard openstack flavors so people can get started without making loads of decisions.
|
66
|
-
|
67
|
-
columns = [
|
68
|
-
ui.color("| FLAVOR", :bold, :green),
|
69
|
-
ui.color("| CORES", :bold, :green),
|
70
|
-
ui.color("| RAM", :bold, :green),
|
71
|
-
ui.color("| DISK", :bold, :green)
|
72
|
-
]
|
73
|
-
|
74
|
-
# tiny
|
75
|
-
columns << "| tiny"
|
76
|
-
columns << "| 1"
|
77
|
-
columns << "| 1024"
|
78
|
-
columns << "| 25GB [LOCAL]"
|
79
|
-
|
80
|
-
# small
|
81
|
-
columns << "| small"
|
82
|
-
columns << "| 2"
|
83
|
-
columns << "| 2048"
|
84
|
-
columns << "| 100GB [LOCAL]"
|
85
|
-
|
86
|
-
|
87
|
-
# medium
|
88
|
-
columns << "| medium"
|
89
|
-
columns << "| 4"
|
90
|
-
columns << "| 4096"
|
91
|
-
columns << "| 150GB [LOCAL]"
|
92
|
-
|
93
|
-
|
94
|
-
# large
|
95
|
-
columns << "| large"
|
96
|
-
columns << "| 8"
|
97
|
-
columns << "| 8192"
|
98
|
-
columns << "| 200GB [LOCAL]"
|
99
|
-
|
100
|
-
|
101
|
-
# xlarge
|
102
|
-
columns << "| xlarge"
|
103
|
-
columns << "| 16"
|
104
|
-
columns << "| 16384"
|
105
|
-
columns << "| 300GB [LOCAL]"
|
106
|
-
end
|
107
|
-
|
108
|
-
def self.load_flavor(flavor)
|
109
|
-
self.send(flavor.to_s)
|
110
|
-
end
|
111
|
-
|
112
|
-
|
113
|
-
private
|
114
|
-
|
115
|
-
##
|
116
|
-
# Set options for a "tiny" instance.
|
117
|
-
# @return [Hash]
|
118
|
-
def self.tiny
|
119
|
-
{
|
120
|
-
'startCpus' => 1,
|
121
|
-
'maxMemory' => 1024,
|
122
|
-
'localDiskFlag' => true,
|
123
|
-
'blockDevices' => [{'device' => 0, 'diskImage' => {'capacity' => 25 } }]
|
124
|
-
}
|
125
|
-
end
|
126
|
-
|
127
|
-
##
|
128
|
-
# Set options for a "small" instance.
|
129
|
-
# @return [Hash]
|
130
|
-
def self.small
|
131
|
-
{
|
132
|
-
'startCpus' => 2,
|
133
|
-
'maxMemory' => 2048,
|
134
|
-
'localDiskFlag' => true,
|
135
|
-
'blockDevices' => [{'device' => 0, 'diskImage' => {'capacity' => 100 } }]
|
136
|
-
}
|
137
|
-
end
|
138
|
-
|
139
|
-
##
|
140
|
-
# Set options for a "medium" instance.
|
141
|
-
# @return [Hash]
|
142
|
-
def self.medium
|
143
|
-
{
|
144
|
-
'startCpus' => 4,
|
145
|
-
'maxMemory' => 4096,
|
146
|
-
'localDiskFlag' => true,
|
147
|
-
'blockDevices' => [{'device' => 0, 'diskImage' => {'capacity' => 25 } },{'device' => 2, 'diskImage' => {'capacity' => 150 } }]
|
148
|
-
}
|
149
|
-
end
|
150
|
-
|
151
|
-
##
|
152
|
-
# Set options for a "large" instance.
|
153
|
-
# @return [Hash]
|
154
|
-
def self.large
|
155
|
-
{
|
156
|
-
'startCpus' => 8,
|
157
|
-
'maxMemory' => 8192,
|
158
|
-
'localDiskFlag' => true,
|
159
|
-
'blockDevices' => [{'device' => 0, 'diskImage' => {'capacity' => 25 } },{'device' => 2, 'diskImage' => {'capacity' => 200 } }]
|
160
|
-
}
|
161
|
-
end
|
162
|
-
|
163
|
-
##
|
164
|
-
# Set options for an "xlarge" instance.
|
165
|
-
# @return [Hash]
|
166
|
-
def self.xlarge
|
167
|
-
{
|
168
|
-
'startCpus' => 16,
|
169
|
-
'maxMemory' => 16384,
|
170
|
-
'localDiskFlag' => true,
|
171
|
-
'blockDevices' => [{'device' => 0, 'diskImage' => {'capacity' => 25 } },{'device' => 2, 'diskImage' => {'capacity' => 300 } }]
|
172
|
-
}
|
173
|
-
end
|
174
|
-
|
175
50
|
end
|
176
51
|
end
|
177
52
|
end
|
@@ -19,11 +19,17 @@ class Chef
|
|
19
19
|
includer.class_eval do
|
20
20
|
|
21
21
|
deps do
|
22
|
-
require '
|
23
|
-
require 'readline'
|
24
|
-
require 'chef/json_compat'
|
22
|
+
require 'fog/softlayer'
|
25
23
|
require 'net/ssh'
|
26
24
|
require 'net/ssh/multi'
|
25
|
+
require 'chef/monkey_patches/net-ssh-multi'
|
26
|
+
require 'readline'
|
27
|
+
require 'chef/exceptions'
|
28
|
+
require 'chef/search/query'
|
29
|
+
require 'chef/mixin/command'
|
30
|
+
require 'chef/mixin/shell_out'
|
31
|
+
require 'mixlib/shellout'
|
32
|
+
require 'chef/json_compat'
|
27
33
|
end
|
28
34
|
|
29
35
|
option :softlayer_credential_file,
|
@@ -49,102 +55,26 @@ class Chef
|
|
49
55
|
# Returns a connection to a SoftLayer API Service Endpoint.
|
50
56
|
# @param [Symbol] service
|
51
57
|
# @return [SoftLayer::Service]
|
52
|
-
def connection(service=:
|
53
|
-
|
54
|
-
SoftlayerBase.send(service),
|
55
|
-
:username => Chef::Config[:knife][:softlayer_username],
|
56
|
-
:api_key => Chef::Config[:knife][:softlayer_api_key],
|
57
|
-
:user_agent => USER_AGENT
|
58
|
-
)
|
59
|
-
end
|
60
|
-
|
61
|
-
##
|
62
|
-
# Returns identifier string for the SoftLayer Virtual Guest service.
|
63
|
-
# @return [String]
|
64
|
-
def self.cci
|
65
|
-
'SoftLayer_Virtual_Guest'
|
66
|
-
end
|
67
|
-
|
68
|
-
##
|
69
|
-
# Returns identifier string for the SoftLayer Product Package service.
|
70
|
-
# @return [String]
|
71
|
-
def self.package
|
72
|
-
'SoftLayer_Product_Package'
|
73
|
-
end
|
74
|
-
|
75
|
-
##
|
76
|
-
# Returns identifier string for the SoftLayer Product Order service.
|
77
|
-
# @return [String]
|
78
|
-
def self.order
|
79
|
-
'SoftLayer_Product_Order'
|
58
|
+
def connection(service=:compute)
|
59
|
+
self.send(service)
|
80
60
|
end
|
81
61
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
# Returns identifier string for the SoftLayer User Account service.
|
91
|
-
# @return [String]
|
92
|
-
def self.account
|
93
|
-
'SoftLayer_Account'
|
94
|
-
end
|
95
|
-
|
96
|
-
##
|
97
|
-
# Returns identifier string for the SoftLayer Global IP service.
|
98
|
-
# @return [String]
|
99
|
-
def self.global_ip
|
100
|
-
'SoftLayer_Network_Subnet_IpAddress_Global'
|
101
|
-
end
|
102
|
-
|
103
|
-
##
|
104
|
-
# Returns id of a particular SoftLayer ordering package.
|
105
|
-
# @return [String]
|
106
|
-
def self.non_server_package_id
|
107
|
-
0 # this package contains everything that isn't a server on the SoftLayer API
|
108
|
-
end
|
109
|
-
|
110
|
-
##
|
111
|
-
# Queries the SoftLayer API and returns the "category code" required for ordering a Global IPv4 address.
|
112
|
-
# @return [Integer]
|
113
|
-
def self.global_ipv4_cat_code
|
114
|
-
SoftLayer::Service.new(
|
115
|
-
SoftlayerBase.send(:package),
|
116
|
-
:username => Chef::Config[:knife][:softlayer_username],
|
117
|
-
:api_key => Chef::Config[:knife][:softlayer_api_key],
|
118
|
-
:user_agent => USER_AGENT
|
119
|
-
).object_with_id(non_server_package_id).object_mask('isRequired', 'itemCategory').getConfiguration.map do |item|
|
120
|
-
item['itemCategory']['id'] if item['itemCategory']['categoryCode'] == 'global_ipv4'
|
121
|
-
end.compact.first
|
122
|
-
end
|
123
|
-
|
124
|
-
##
|
125
|
-
# Queries the SoftLayer API and returns the "price code" required for ordering a Global IPv4 address.
|
126
|
-
# @return [Integer]
|
127
|
-
def self.global_ipv4_price_code
|
128
|
-
SoftLayer::Service.new(
|
129
|
-
SoftlayerBase.send(:package),
|
130
|
-
:username => Chef::Config[:knife][:softlayer_username],
|
131
|
-
:api_key => Chef::Config[:knife][:softlayer_api_key],
|
132
|
-
:user_agent => USER_AGENT
|
133
|
-
).object_with_id(non_server_package_id).object_mask('id', 'item.description', 'categories.id').getItemPrices.map do |item|
|
134
|
-
item['id'] if item['categories'][0]['id'] == SoftlayerBase.global_ipv4_cat_code
|
135
|
-
end.compact.first
|
62
|
+
def compute
|
63
|
+
@compute_connection ||= Fog::Compute.new(
|
64
|
+
:provider => :softlayer,
|
65
|
+
:softlayer_username => Chef::Config[:knife][:softlayer_username],
|
66
|
+
:softlayer_api_key => Chef::Config[:knife][:softlayer_api_key],
|
67
|
+
:softlayer_default_datacenter => Chef::Config[:knife][:softlayer_default_datacenter],
|
68
|
+
:softlayer_default_domain => Chef::Config[:knife][:softlayer_default_domain],
|
69
|
+
)
|
136
70
|
end
|
137
71
|
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
"packageId" => non_server_package_id,
|
145
|
-
"prices" => [{"id"=>SoftlayerBase.global_ipv4_price_code}],
|
146
|
-
"quantity" => 1
|
147
|
-
}
|
72
|
+
def network
|
73
|
+
@network_connection ||= Fog::Network.new(
|
74
|
+
:provider => :softlayer,
|
75
|
+
:softlayer_username => Chef::Config[:knife][:softlayer_username],
|
76
|
+
:softlayer_api_key => Chef::Config[:knife][:softlayer_api_key],
|
77
|
+
)
|
148
78
|
end
|
149
79
|
|
150
80
|
##
|
@@ -171,3 +101,9 @@ class Chef
|
|
171
101
|
end
|
172
102
|
end
|
173
103
|
end
|
104
|
+
|
105
|
+
module OS
|
106
|
+
def OS.windows?
|
107
|
+
(/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM) != nil
|
108
|
+
end
|
109
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Matt Eldridge (<matt.eldridge@us.ibm.com>)
|
3
|
+
# © Copyright IBM Corporation 2014.
|
4
|
+
#
|
5
|
+
# LICENSE: Apache 2.0 (http://www.apache.org/licenses/)
|
6
|
+
#
|
7
|
+
|
8
|
+
require 'chef/knife/softlayer_base'
|
9
|
+
|
10
|
+
class Chef
|
11
|
+
class Knife
|
12
|
+
class SoftlayerDatacenterList < Knife
|
13
|
+
|
14
|
+
include Knife::SoftlayerBase
|
15
|
+
|
16
|
+
banner 'knife softlayer datacenter list (options)'
|
17
|
+
|
18
|
+
def run
|
19
|
+
$stdout.sync = true
|
20
|
+
table_data = connection(:network).datacenters.map do |dc|
|
21
|
+
{:name => dc.name, :long_name => dc.long_name }
|
22
|
+
end
|
23
|
+
puts Formatador.display_table(table_data, [:name, :long_name])
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Matt Eldridge (<matt.eldridge@us.ibm.com>)
|
3
|
+
# © Copyright IBM Corporation 2014.
|
4
|
+
#
|
5
|
+
# LICENSE: Apache 2.0 (http://www.apache.org/licenses/)
|
6
|
+
#
|
7
|
+
|
8
|
+
require 'chef/knife/softlayer_base'
|
9
|
+
|
10
|
+
class Chef
|
11
|
+
class Knife
|
12
|
+
class SoftlayerDatacenterShow < Knife
|
13
|
+
|
14
|
+
include Knife::SoftlayerBase
|
15
|
+
|
16
|
+
banner 'knife softlayer datacenter show DATACENTER'
|
17
|
+
|
18
|
+
option :dc,
|
19
|
+
:short => "-a",
|
20
|
+
:long => "--all",
|
21
|
+
:description => "Display all available configuration options for launching an instance.",
|
22
|
+
:default => false
|
23
|
+
|
24
|
+
|
25
|
+
def run
|
26
|
+
unless name_args.size == 1
|
27
|
+
puts ui.color("Specify exactly one datacenter to show.", :red)
|
28
|
+
show_usage
|
29
|
+
exit 1
|
30
|
+
end
|
31
|
+
|
32
|
+
$stdout.sync = true
|
33
|
+
dc = connection(:network).datacenters.by_name(name_args[0])
|
34
|
+
|
35
|
+
puts "#{ui.color("Long Name:", :green)} #{dc.long_name}"
|
36
|
+
puts "#{ui.color("Name:", :green)} #{dc.name}"
|
37
|
+
|
38
|
+
puts "#{ui.color("Routers:", :green)}"
|
39
|
+
puts Formatador.display_table(dc.routers)
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -18,21 +18,29 @@ class Chef
|
|
18
18
|
banner 'knife softlayer flavor list (options)'
|
19
19
|
|
20
20
|
option :all,
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
:short => "-a",
|
22
|
+
:long => "--all",
|
23
|
+
:description => "Display all available configuration options for launching an instance.",
|
24
|
+
:default => false
|
25
25
|
|
26
26
|
##
|
27
27
|
# Run the procedure to list softlayer VM flavors or display all available options.
|
28
28
|
# @return [nil]
|
29
29
|
def run
|
30
|
-
|
30
|
+
$stdout.sync = true
|
31
31
|
if config[:all]
|
32
|
-
|
32
|
+
|
33
|
+
if OS.windows?
|
34
|
+
puts ui.list(options_table, :uneven_columns_across, 6)
|
35
|
+
else
|
36
|
+
IO.popen('less', 'w') do |pipe|
|
37
|
+
pipe.puts ui.list(options_table, :uneven_columns_across, 6)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
33
41
|
msg = "These options can be used in place of 'flavors'; See `knife softlayer server create --help` for details.\n"
|
34
42
|
else
|
35
|
-
puts
|
43
|
+
puts connection.flavors.table([:id, :cpu, :ram, :disk,])
|
36
44
|
msg = "'flavors' provided here for convenience; SoftLayer allows you to choose a configuration a la carte.\nFor a full list of available instance options use --all with the `knife softlayer flavor list` subcommand."
|
37
45
|
end
|
38
46
|
puts ui.color("\nNOTICE: ", :yellow)
|
@@ -42,3 +50,4 @@ class Chef
|
|
42
50
|
end
|
43
51
|
end
|
44
52
|
end
|
53
|
+
|