knife-oneandone 1.0.0 → 1.2.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 +12 -12
- data/.rspec +2 -2
- data/.rubocop.yml +29 -26
- data/.travis.yml +5 -5
- data/Gemfile +4 -4
- data/LICENSE +201 -201
- data/README.md +358 -278
- data/Rakefile +6 -6
- data/knife-oneandone.gemspec +30 -31
- data/lib/1and1/helpers.rb +29 -29
- data/lib/chef/knife/oneandone_appliance_list.rb +39 -39
- data/lib/chef/knife/oneandone_base.rb +32 -32
- data/lib/chef/knife/oneandone_block_storage_attach.rb +33 -0
- data/lib/chef/knife/oneandone_block_storage_create.rb +64 -0
- data/lib/chef/knife/oneandone_block_storage_delete.rb +59 -0
- data/lib/chef/knife/oneandone_block_storage_detach.rb +28 -0
- data/lib/chef/knife/oneandone_block_storage_list.rb +42 -0
- data/lib/chef/knife/oneandone_block_storage_rename.rb +38 -0
- data/lib/chef/knife/oneandone_datacenter_list.rb +33 -33
- data/lib/chef/knife/oneandone_firewall_create.rb +97 -97
- data/lib/chef/knife/oneandone_firewall_delete.rb +59 -59
- data/lib/chef/knife/oneandone_firewall_list.rb +33 -33
- data/lib/chef/knife/oneandone_ip_list.rb +39 -39
- data/lib/chef/knife/oneandone_loadbalancer_create.rb +147 -147
- data/lib/chef/knife/oneandone_loadbalancer_delete.rb +59 -59
- data/lib/chef/knife/oneandone_loadbalancer_list.rb +39 -39
- data/lib/chef/knife/oneandone_mp_list.rb +37 -37
- data/lib/chef/knife/oneandone_server_baremetal_model_list.rb +31 -0
- data/lib/chef/knife/oneandone_server_create.rb +193 -163
- data/lib/chef/knife/oneandone_server_delete.rb +63 -63
- data/lib/chef/knife/oneandone_server_hdd_add.rb +60 -60
- data/lib/chef/knife/oneandone_server_hdd_delete.rb +55 -55
- data/lib/chef/knife/oneandone_server_hdd_list.rb +44 -44
- data/lib/chef/knife/oneandone_server_hdd_resize.rb +59 -59
- data/lib/chef/knife/oneandone_server_list.rb +35 -35
- data/lib/chef/knife/oneandone_server_modify.rb +80 -80
- data/lib/chef/knife/oneandone_server_reboot.rb +41 -41
- data/lib/chef/knife/oneandone_server_rename.rb +37 -37
- data/lib/chef/knife/oneandone_server_size_list.rb +39 -39
- data/lib/chef/knife/oneandone_server_start.rb +35 -35
- data/lib/chef/knife/oneandone_server_stop.rb +41 -41
- data/lib/chef/knife/oneandone_ssh_key_create.rb +54 -0
- data/lib/chef/knife/oneandone_ssh_key_delete.rb +59 -0
- data/lib/chef/knife/oneandone_ssh_key_list.rb +44 -0
- data/lib/chef/knife/oneandone_ssh_key_rename.rb +37 -0
- data/lib/knife-oneandone/version.rb +5 -5
- metadata +24 -13
data/Rakefile
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
require 'bundler/gem_tasks'
|
2
|
-
require 'rspec/core/rake_task'
|
3
|
-
|
4
|
-
RSpec::Core::RakeTask.new(:spec)
|
5
|
-
|
6
|
-
task default: :spec
|
1
|
+
require 'bundler/gem_tasks'
|
2
|
+
require 'rspec/core/rake_task'
|
3
|
+
|
4
|
+
RSpec::Core::RakeTask.new(:spec)
|
5
|
+
|
6
|
+
task default: :spec
|
data/knife-oneandone.gemspec
CHANGED
@@ -1,31 +1,30 @@
|
|
1
|
-
|
2
|
-
lib
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
spec.
|
8
|
-
spec.
|
9
|
-
spec.
|
10
|
-
|
11
|
-
|
12
|
-
spec.
|
13
|
-
spec.
|
14
|
-
spec.
|
15
|
-
|
16
|
-
|
17
|
-
spec.
|
18
|
-
spec.
|
19
|
-
spec.
|
20
|
-
|
21
|
-
|
22
|
-
spec.add_runtime_dependency '
|
23
|
-
|
24
|
-
|
25
|
-
spec.add_development_dependency '
|
26
|
-
spec.add_development_dependency '
|
27
|
-
spec.add_development_dependency '
|
28
|
-
spec.add_development_dependency '
|
29
|
-
spec.add_development_dependency 'webmock', '~> 1.24'
|
30
|
-
|
31
|
-
end
|
1
|
+
lib = File.expand_path('lib', __dir__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require 'knife-oneandone/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = 'knife-oneandone'
|
7
|
+
spec.version = Knife::Oneandone::VERSION
|
8
|
+
spec.authors = ['Nurfet Becirevic']
|
9
|
+
spec.email = ['nurfet@stackpointcloud.com']
|
10
|
+
|
11
|
+
spec.summary = 'Chef Knife plugin for 1&1 Cloud server'
|
12
|
+
spec.description = 'Official Chef Knife plugin for managing 1&1 Cloud servers'
|
13
|
+
spec.homepage = 'https://github.com/1and1/oneandone-cloudserver-chef'
|
14
|
+
spec.license = 'Apache-2.0'
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
17
|
+
spec.bindir = 'exe'
|
18
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
19
|
+
spec.require_paths = ['lib']
|
20
|
+
|
21
|
+
spec.add_runtime_dependency '1and1', '~> 1.2'
|
22
|
+
spec.add_runtime_dependency 'chef', '~> 12'
|
23
|
+
|
24
|
+
spec.add_development_dependency 'bundler', '~> 1.12'
|
25
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
26
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
27
|
+
spec.add_development_dependency 'rubocop', '~> 0.58'
|
28
|
+
spec.add_development_dependency 'vcr', '~> 3.0'
|
29
|
+
spec.add_development_dependency 'webmock', '~> 1.24'
|
30
|
+
end
|
data/lib/1and1/helpers.rb
CHANGED
@@ -1,29 +1,29 @@
|
|
1
|
-
module Oneandone
|
2
|
-
module Helpers
|
3
|
-
def split_delimited_input(input)
|
4
|
-
return [] if input.nil?
|
5
|
-
|
6
|
-
if input.is_a? String
|
7
|
-
input.strip!
|
8
|
-
|
9
|
-
delimiter = ','
|
10
|
-
# Knife is reading --option value1,value2 as "value1 value2"
|
11
|
-
# on Windows PowerShell interface
|
12
|
-
delimiter = ' ' if input.include? ' '
|
13
|
-
|
14
|
-
values = input.split(delimiter)
|
15
|
-
values
|
16
|
-
else
|
17
|
-
# return array of whatever
|
18
|
-
[input]
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def validate(param, msg)
|
23
|
-
if param.nil? || param.empty?
|
24
|
-
ui.error("You must supply #{msg}!")
|
25
|
-
exit 1
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
1
|
+
module Oneandone
|
2
|
+
module Helpers
|
3
|
+
def split_delimited_input(input)
|
4
|
+
return [] if input.nil?
|
5
|
+
|
6
|
+
if input.is_a? String
|
7
|
+
input.strip!
|
8
|
+
|
9
|
+
delimiter = ','
|
10
|
+
# Knife is reading --option value1,value2 as "value1 value2"
|
11
|
+
# on Windows PowerShell interface
|
12
|
+
delimiter = ' ' if input.include? ' '
|
13
|
+
|
14
|
+
values = input.split(delimiter)
|
15
|
+
values
|
16
|
+
else
|
17
|
+
# return array of whatever
|
18
|
+
[input]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def validate(param, msg)
|
23
|
+
if param.nil? || param.empty?
|
24
|
+
ui.error("You must supply #{msg}!")
|
25
|
+
exit 1
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -1,39 +1,39 @@
|
|
1
|
-
require 'chef/knife/oneandone_base'
|
2
|
-
|
3
|
-
class Chef
|
4
|
-
class Knife
|
5
|
-
class OneandoneApplianceList < Knife
|
6
|
-
include Knife::OneandoneBase
|
7
|
-
|
8
|
-
banner 'knife oneandone appliance list'
|
9
|
-
|
10
|
-
def run
|
11
|
-
$stdout.sync = true
|
12
|
-
|
13
|
-
init_client
|
14
|
-
|
15
|
-
response = OneAndOne::ServerAppliance.new.list
|
16
|
-
formated_output(response, true)
|
17
|
-
|
18
|
-
sizes = [
|
19
|
-
ui.color('ID', :bold),
|
20
|
-
ui.color('Name', :bold),
|
21
|
-
ui.color('Type', :bold),
|
22
|
-
ui.color('OS', :bold),
|
23
|
-
ui.color('Version', :bold),
|
24
|
-
ui.color('Architecture', :bold)
|
25
|
-
]
|
26
|
-
response.each do |fs|
|
27
|
-
sizes << fs['id']
|
28
|
-
sizes << fs['name']
|
29
|
-
sizes << fs['type']
|
30
|
-
sizes << fs['os']
|
31
|
-
sizes << fs['version']
|
32
|
-
sizes << fs['os_architecture'].to_s
|
33
|
-
end
|
34
|
-
|
35
|
-
puts ui.list(sizes, :uneven_columns_across, 6)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
1
|
+
require 'chef/knife/oneandone_base'
|
2
|
+
|
3
|
+
class Chef
|
4
|
+
class Knife
|
5
|
+
class OneandoneApplianceList < Knife
|
6
|
+
include Knife::OneandoneBase
|
7
|
+
|
8
|
+
banner 'knife oneandone appliance list'
|
9
|
+
|
10
|
+
def run
|
11
|
+
$stdout.sync = true
|
12
|
+
|
13
|
+
init_client
|
14
|
+
|
15
|
+
response = OneAndOne::ServerAppliance.new.list
|
16
|
+
formated_output(response, true)
|
17
|
+
|
18
|
+
sizes = [
|
19
|
+
ui.color('ID', :bold),
|
20
|
+
ui.color('Name', :bold),
|
21
|
+
ui.color('Type', :bold),
|
22
|
+
ui.color('OS', :bold),
|
23
|
+
ui.color('Version', :bold),
|
24
|
+
ui.color('Architecture', :bold)
|
25
|
+
]
|
26
|
+
response.each do |fs|
|
27
|
+
sizes << fs['id']
|
28
|
+
sizes << fs['name']
|
29
|
+
sizes << fs['type']
|
30
|
+
sizes << fs['os']
|
31
|
+
sizes << fs['version']
|
32
|
+
sizes << fs['os_architecture'].to_s
|
33
|
+
end
|
34
|
+
|
35
|
+
puts ui.list(sizes, :uneven_columns_across, 6)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -1,32 +1,32 @@
|
|
1
|
-
require 'chef/knife'
|
2
|
-
|
3
|
-
class Chef
|
4
|
-
class Knife
|
5
|
-
module OneandoneBase
|
6
|
-
def self.included(includer)
|
7
|
-
includer.class_eval do
|
8
|
-
deps do
|
9
|
-
require 'oneandone'
|
10
|
-
end
|
11
|
-
|
12
|
-
option :oneandone_api_key,
|
13
|
-
short: '-A API_KEY',
|
14
|
-
long: '--oneandone-api-key API_KEY',
|
15
|
-
description: 'Your 1&1 API access key',
|
16
|
-
proc: proc { |api_token| Chef::Config[:knife][:oneandone_api_key] = api_token }
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
def init_client
|
21
|
-
OneAndOne.start(Chef::Config[:knife][:oneandone_api_key])
|
22
|
-
end
|
23
|
-
|
24
|
-
def formated_output(data, is_exit)
|
25
|
-
if config[:format] != default_config[:format]
|
26
|
-
ui.output(data)
|
27
|
-
exit 0 if is_exit
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
32
|
-
end
|
1
|
+
require 'chef/knife'
|
2
|
+
|
3
|
+
class Chef
|
4
|
+
class Knife
|
5
|
+
module OneandoneBase
|
6
|
+
def self.included(includer)
|
7
|
+
includer.class_eval do
|
8
|
+
deps do
|
9
|
+
require 'oneandone'
|
10
|
+
end
|
11
|
+
|
12
|
+
option :oneandone_api_key,
|
13
|
+
short: '-A API_KEY',
|
14
|
+
long: '--oneandone-api-key API_KEY',
|
15
|
+
description: 'Your 1&1 API access key',
|
16
|
+
proc: proc { |api_token| Chef::Config[:knife][:oneandone_api_key] = api_token }
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def init_client
|
21
|
+
OneAndOne.start(Chef::Config[:knife][:oneandone_api_key])
|
22
|
+
end
|
23
|
+
|
24
|
+
def formated_output(data, is_exit)
|
25
|
+
if config[:format] != default_config[:format]
|
26
|
+
ui.output(data)
|
27
|
+
exit 0 if is_exit
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'chef/knife/oneandone_base'
|
2
|
+
|
3
|
+
class Chef
|
4
|
+
class Knife
|
5
|
+
class OneandoneBlockStorageAttach < Knife
|
6
|
+
include Knife::OneandoneBase
|
7
|
+
|
8
|
+
banner 'knife oneandone block storage attach (options)'
|
9
|
+
|
10
|
+
option :id,
|
11
|
+
short: '-I ID',
|
12
|
+
long: '--id ID',
|
13
|
+
description: 'Block storage ID'
|
14
|
+
|
15
|
+
option :server_id,
|
16
|
+
short: '-SI SERVER-ID',
|
17
|
+
long: '--server-id SERVER-ID',
|
18
|
+
description: 'ID of the server that the block storage will be attached to'
|
19
|
+
|
20
|
+
def run
|
21
|
+
$stdout.sync = true
|
22
|
+
|
23
|
+
init_client
|
24
|
+
|
25
|
+
block_storage = OneAndOne::BlockStorage.new
|
26
|
+
response = block_storage.attach_server(block_storage_id: config[:id], server_id: config[:server_id])
|
27
|
+
|
28
|
+
formated_output(response, true)
|
29
|
+
puts "Block storage attached to server #{ui.color('updated', :bold)}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'chef/knife/oneandone_base'
|
2
|
+
require '1and1/helpers'
|
3
|
+
|
4
|
+
class Chef
|
5
|
+
class Knife
|
6
|
+
class OneandoneBlockStorageCreate < Knife
|
7
|
+
include Knife::OneandoneBase
|
8
|
+
include Oneandone::Helpers
|
9
|
+
|
10
|
+
banner 'knife oneandone block storage create (options)'
|
11
|
+
|
12
|
+
option :name,
|
13
|
+
short: '-n NAME',
|
14
|
+
long: '--name NAME',
|
15
|
+
description: 'Name of the block storage (required)'
|
16
|
+
|
17
|
+
option :size,
|
18
|
+
short: '-s SIZE',
|
19
|
+
long: '--size SIZE',
|
20
|
+
description: 'Size of the block storage (required, min:20, max:500, multipleOf:10)'
|
21
|
+
|
22
|
+
option :description,
|
23
|
+
long: '--description DESCRIPTION',
|
24
|
+
description: 'Description of the block storage'
|
25
|
+
|
26
|
+
option :datacenter_id,
|
27
|
+
short: '-D DATACENTER_ID',
|
28
|
+
long: '--datacenter-id DATACENTER_ID',
|
29
|
+
description: 'ID of the virtual data center where the block storage will be created',
|
30
|
+
proc: proc { |datacenter_id| Chef::Config[:knife][:datacenter_id] = datacenter_id }
|
31
|
+
|
32
|
+
option :server_id,
|
33
|
+
long: '--server_id SERVER_ID',
|
34
|
+
description: 'ID of the server that the block storage will be attached to'
|
35
|
+
|
36
|
+
option :wait,
|
37
|
+
short: '-W',
|
38
|
+
long: '--wait',
|
39
|
+
description: 'Wait for the operation to complete.'
|
40
|
+
|
41
|
+
def run
|
42
|
+
$stdout.sync = true
|
43
|
+
|
44
|
+
validate(config[:name], '-n NAME')
|
45
|
+
validate(config[:size], '-s SIZE')
|
46
|
+
|
47
|
+
init_client
|
48
|
+
|
49
|
+
block_storage = OneAndOne::BlockStorage.new
|
50
|
+
response = block_storage.create(name: config[:name], description: config[:description], size: config[:size],
|
51
|
+
datacenter_id: config[:datacenter_id], server_id: config[:server_id])
|
52
|
+
|
53
|
+
if config[:wait]
|
54
|
+
block_storage.wait_for
|
55
|
+
formated_output(block_storage.get, true)
|
56
|
+
puts "Block storage #{response['id']} is #{ui.color('created', :bold)}"
|
57
|
+
else
|
58
|
+
formated_output(response, true)
|
59
|
+
puts "Block storage #{response['id']} is #{ui.color('being created', :bold)}"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'chef/knife/oneandone_base'
|
2
|
+
|
3
|
+
class Chef
|
4
|
+
class Knife
|
5
|
+
class OneandoneBlockStorageDelete < Knife
|
6
|
+
include Knife::OneandoneBase
|
7
|
+
|
8
|
+
banner 'knife oneandone block storage delete BLOCK_STORAGE_ID [BLOCK_STORAGE_ID] (options)'
|
9
|
+
|
10
|
+
option :wait,
|
11
|
+
short: '-W',
|
12
|
+
long: '--wait',
|
13
|
+
description: 'Wait for the operation to complete.'
|
14
|
+
|
15
|
+
def run
|
16
|
+
$stdout.sync = true
|
17
|
+
|
18
|
+
init_client
|
19
|
+
|
20
|
+
name_args.each do |block_storage_id|
|
21
|
+
block_storage = OneAndOne::BlockStorage.new
|
22
|
+
|
23
|
+
begin
|
24
|
+
block_storage.get(block_storage_id: block_storage_id)
|
25
|
+
rescue StandardError => e
|
26
|
+
if e.message.include? 'NOT_FOUND'
|
27
|
+
ui.error("Block storage ID #{block_storage_id} not found. Skipping.")
|
28
|
+
else
|
29
|
+
ui.error(e.message)
|
30
|
+
end
|
31
|
+
next
|
32
|
+
end
|
33
|
+
|
34
|
+
block_storage_name = block_storage.specs['name']
|
35
|
+
|
36
|
+
confirm("Do you really want to delete block storage '#{block_storage_name}'")
|
37
|
+
|
38
|
+
block_storage.delete
|
39
|
+
|
40
|
+
if config[:wait]
|
41
|
+
begin
|
42
|
+
puts ui.color('Deleting, wait for the operation to complete...', :cyan).to_s
|
43
|
+
block_storage.wait_for
|
44
|
+
puts "Block storage '#{block_storage_name}' is #{ui.color('deleted', :bold)}"
|
45
|
+
rescue StandardError => e
|
46
|
+
if e.message.include? 'NOT_FOUND'
|
47
|
+
puts "Block storage '#{block_storage_name}' is #{ui.color('deleted', :bold)}"
|
48
|
+
else
|
49
|
+
ui.error(e.message)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
else
|
53
|
+
puts "Block storage '#{block_storage_name}' is #{ui.color('being deleted', :bold)}"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'chef/knife/oneandone_base'
|
2
|
+
|
3
|
+
class Chef
|
4
|
+
class Knife
|
5
|
+
class OneandoneBlockStorageDetach < Knife
|
6
|
+
include Knife::OneandoneBase
|
7
|
+
|
8
|
+
banner 'knife oneandone block storage detach (options)'
|
9
|
+
|
10
|
+
option :id,
|
11
|
+
short: '-I ID',
|
12
|
+
long: '--id ID',
|
13
|
+
description: 'Block storage ID'
|
14
|
+
|
15
|
+
def run
|
16
|
+
$stdout.sync = true
|
17
|
+
|
18
|
+
init_client
|
19
|
+
|
20
|
+
block_storage = OneAndOne::BlockStorage.new
|
21
|
+
response = block_storage.detach_server(block_storage_id: config[:id])
|
22
|
+
|
23
|
+
formated_output(response, true)
|
24
|
+
puts "Block storage detached from server #{ui.color('updated', :bold)}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|