knife-oneandone 1.0.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.
Files changed (37) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +26 -0
  5. data/.travis.yml +5 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE +201 -0
  8. data/README.md +278 -0
  9. data/Rakefile +6 -0
  10. data/knife-oneandone.gemspec +31 -0
  11. data/lib/1and1/helpers.rb +29 -0
  12. data/lib/chef/knife/oneandone_appliance_list.rb +39 -0
  13. data/lib/chef/knife/oneandone_base.rb +32 -0
  14. data/lib/chef/knife/oneandone_datacenter_list.rb +33 -0
  15. data/lib/chef/knife/oneandone_firewall_create.rb +97 -0
  16. data/lib/chef/knife/oneandone_firewall_delete.rb +59 -0
  17. data/lib/chef/knife/oneandone_firewall_list.rb +33 -0
  18. data/lib/chef/knife/oneandone_ip_list.rb +39 -0
  19. data/lib/chef/knife/oneandone_loadbalancer_create.rb +147 -0
  20. data/lib/chef/knife/oneandone_loadbalancer_delete.rb +59 -0
  21. data/lib/chef/knife/oneandone_loadbalancer_list.rb +39 -0
  22. data/lib/chef/knife/oneandone_mp_list.rb +37 -0
  23. data/lib/chef/knife/oneandone_server_create.rb +163 -0
  24. data/lib/chef/knife/oneandone_server_delete.rb +63 -0
  25. data/lib/chef/knife/oneandone_server_hdd_add.rb +60 -0
  26. data/lib/chef/knife/oneandone_server_hdd_delete.rb +55 -0
  27. data/lib/chef/knife/oneandone_server_hdd_list.rb +44 -0
  28. data/lib/chef/knife/oneandone_server_hdd_resize.rb +59 -0
  29. data/lib/chef/knife/oneandone_server_list.rb +35 -0
  30. data/lib/chef/knife/oneandone_server_modify.rb +80 -0
  31. data/lib/chef/knife/oneandone_server_reboot.rb +41 -0
  32. data/lib/chef/knife/oneandone_server_rename.rb +37 -0
  33. data/lib/chef/knife/oneandone_server_size_list.rb +39 -0
  34. data/lib/chef/knife/oneandone_server_start.rb +35 -0
  35. data/lib/chef/knife/oneandone_server_stop.rb +41 -0
  36. data/lib/knife-oneandone/version.rb +5 -0
  37. metadata +191 -0
@@ -0,0 +1,59 @@
1
+ require 'chef/knife/oneandone_base'
2
+
3
+ class Chef
4
+ class Knife
5
+ class OneandoneLoadbalancerDelete < Knife
6
+ include Knife::OneandoneBase
7
+
8
+ banner 'knife oneandone loadbalancer delete LOAD_BALANCER_ID [LOAD_BALANCER_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 |load_balancer_id|
21
+ load_balancer = OneAndOne::LoadBalancer.new
22
+
23
+ begin
24
+ load_balancer.get(load_balancer_id: load_balancer_id)
25
+ rescue StandardError => e
26
+ if e.message.include? 'NOT_FOUND'
27
+ ui.error("Load balancer ID #{load_balancer_id} not found. Skipping.")
28
+ else
29
+ ui.error(e.message)
30
+ end
31
+ next
32
+ end
33
+
34
+ load_balancer_name = load_balancer.specs['name']
35
+
36
+ confirm("Do you really want to delete load_balancer policy '#{load_balancer_name}'")
37
+
38
+ load_balancer.delete
39
+
40
+ if config[:wait]
41
+ begin
42
+ puts ui.color('Deleting, wait for the operation to complete...', :cyan).to_s
43
+ load_balancer.wait_for
44
+ puts "Load balancer '#{load_balancer_name}' is #{ui.color('deleted', :bold)}"
45
+ rescue StandardError => e
46
+ if e.message.include? 'NOT_FOUND'
47
+ puts "Load balancer '#{load_balancer_name}' is #{ui.color('deleted', :bold)}"
48
+ else
49
+ ui.error(e.message)
50
+ end
51
+ end
52
+ else
53
+ puts "Load balancer '#{load_balancer_name}' is #{ui.color('being deleted', :bold)}"
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,39 @@
1
+ require 'chef/knife/oneandone_base'
2
+
3
+ class Chef
4
+ class Knife
5
+ class OneandoneLoadbalancerList < Knife
6
+ include Knife::OneandoneBase
7
+
8
+ banner 'knife oneandone loadbalancer list'
9
+
10
+ def run
11
+ $stdout.sync = true
12
+
13
+ init_client
14
+
15
+ response = OneAndOne::LoadBalancer.new.list
16
+ formated_output(response, true)
17
+
18
+ load_balancers = [
19
+ ui.color('ID', :bold),
20
+ ui.color('Name', :bold),
21
+ ui.color('IP Address', :bold),
22
+ ui.color('Method', :bold),
23
+ ui.color('State', :bold),
24
+ ui.color('Data Center', :bold)
25
+ ]
26
+ response.each do |lb|
27
+ load_balancers << lb['id']
28
+ load_balancers << lb['name']
29
+ load_balancers << lb['ip']
30
+ load_balancers << lb['method']
31
+ load_balancers << lb['state']
32
+ load_balancers << lb['datacenter']['country_code']
33
+ end
34
+
35
+ puts ui.list(load_balancers, :uneven_columns_across, 6)
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,37 @@
1
+ require 'chef/knife/oneandone_base'
2
+
3
+ class Chef
4
+ class Knife
5
+ class OneandoneMpList < Knife
6
+ include Knife::OneandoneBase
7
+
8
+ banner 'knife oneandone mp list'
9
+
10
+ def run
11
+ $stdout.sync = true
12
+
13
+ init_client
14
+
15
+ response = OneAndOne::MonitoringPolicy.new.list
16
+ formated_output(response, true)
17
+
18
+ mp_list = [
19
+ ui.color('ID', :bold),
20
+ ui.color('Name', :bold),
21
+ ui.color('Email', :bold),
22
+ ui.color('State', :bold),
23
+ ui.color('Agent', :bold)
24
+ ]
25
+ response.each do |mp|
26
+ mp_list << mp['id']
27
+ mp_list << mp['name']
28
+ mp_list << mp['email']
29
+ mp_list << mp['state']
30
+ mp_list << mp['agent'].to_s
31
+ end
32
+
33
+ puts ui.list(mp_list, :uneven_columns_across, 5)
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,163 @@
1
+ require 'chef/knife/oneandone_base'
2
+ require '1and1/helpers'
3
+
4
+ class Chef
5
+ class Knife
6
+ class OneandoneServerCreate < Knife
7
+ include Knife::OneandoneBase
8
+ include Oneandone::Helpers
9
+
10
+ banner 'knife oneandone server create (options)'
11
+
12
+ option :datacenter_id,
13
+ short: '-D DATACENTER_ID',
14
+ long: '--datacenter-id DATACENTER_ID',
15
+ description: 'ID of the virtual data center',
16
+ proc: proc { |datacenter_id| Chef::Config[:knife][:datacenter_id] = datacenter_id }
17
+
18
+ option :name,
19
+ short: '-n NAME',
20
+ long: '--name NAME',
21
+ description: 'Name of the server (required)'
22
+
23
+ option :description,
24
+ long: '--description DESCRIPTION',
25
+ description: 'Description of the server'
26
+
27
+ option :appliance_id,
28
+ short: '-I APPLIANCE_ID',
29
+ long: '--appliance-id APPLIANCE_ID',
30
+ description: 'ID of the server appliance (required)',
31
+ proc: proc { |appliance_id| Chef::Config[:knife][:appliance_id] = appliance_id }
32
+
33
+ option :fixed_size_id,
34
+ short: '-S FIXED_SIZE_ID',
35
+ long: '--fixed-size-id FIXED_SIZE_ID',
36
+ description: 'ID of the fixed instance size',
37
+ proc: proc { |fixed_size_id| Chef::Config[:knife][:fixed_size_id] = fixed_size_id }
38
+
39
+ option :cpu,
40
+ short: '-P PROCESSORS',
41
+ long: '--cpu PROCESSORS',
42
+ description: "The number of processors. Required, if '--fixed-size-id' is not specified."
43
+
44
+ option :cores,
45
+ short: '-C CORES',
46
+ long: '--cores CORES',
47
+ description: "The number of cores per processor. Required, if '--fixed-size-id' is not specified."
48
+
49
+ option :ram,
50
+ short: '-r RAM',
51
+ long: '--ram RAM',
52
+ description: "The amount of RAM in GB. Required, if '--fixed-size-id' is not specified."
53
+
54
+ option :hdd_size,
55
+ short: '-H HDD_SIZE',
56
+ long: '--hdd-size HDD_SIZE',
57
+ description: "The HDD size in GB. Required, if '--fixed-size-id' is not specified."
58
+
59
+ option :password,
60
+ short: '-p PASSWORD',
61
+ long: '--password PASSWORD',
62
+ description: "The password of the server's root/administrator user"
63
+
64
+ option :rsa_key,
65
+ long: '--rsa-key RSA_KEY',
66
+ description: 'Specify a valid public SSH Key to be copied into your 1&1 server during creation.',
67
+ proc: proc { |rsa_key| Chef::Config[:knife][:rsa_key] = rsa_key }
68
+
69
+ option :firewall_id,
70
+ long: '--firewall-id FIREWALL_ID',
71
+ description: 'ID of a firewall policy to be used for the server',
72
+ proc: proc { |firewall_id| Chef::Config[:knife][:firewall_id] = firewall_id }
73
+
74
+ option :power_on,
75
+ long: '--power-on BOOLEAN_VALUE',
76
+ description: 'Power on the server after creating (true by default).',
77
+ default: true
78
+
79
+ option :ip_id,
80
+ long: '--ip-id IP_ID',
81
+ description: 'ID of an IP address to be used for the server'
82
+
83
+ option :load_balancer_id,
84
+ long: '--load-balancer-id LOAD_BALANCER_ID',
85
+ description: 'ID of a load balancer to be used for the server',
86
+ proc: proc { |load_balancer_id| Chef::Config[:knife][:load_balancer_id] = load_balancer_id }
87
+
88
+ option :monitoring_policy_id,
89
+ long: '--monitoring-policy-id MONITORING_POLICY_ID',
90
+ description: 'ID of a monitoring policy to be used for the server',
91
+ proc: proc { |monitoring_policy_id| Chef::Config[:knife][:monitoring_policy_id] = monitoring_policy_id }
92
+
93
+ option :wait,
94
+ long: '--[no-]wait',
95
+ description: 'Wait for the server deployment to complete (true by default).',
96
+ boolean: true,
97
+ default: true
98
+
99
+ def run
100
+ $stdout.sync = true
101
+
102
+ validate(config[:name], '-n NAME')
103
+ validate(config[:appliance_id], '-I APPLIANCE_ID')
104
+
105
+ init_client
106
+
107
+ size_id = config[:fixed_size_id]
108
+ hdds = nil
109
+
110
+ if size_id.nil? || size_id.empty?
111
+ hdds = [
112
+ {
113
+ 'size' => config[:hdd_size],
114
+ 'is_main' => true
115
+ }
116
+ ]
117
+ end
118
+
119
+ server = OneAndOne::Server.new
120
+ response = server.create(
121
+ name: config[:name],
122
+ description: config[:description],
123
+ datacenter_id: config[:datacenter_id],
124
+ fixed_instance_id: size_id,
125
+ appliance_id: config[:appliance_id],
126
+ vcore: config[:cpu],
127
+ cores_per_processor: config[:cores],
128
+ ram: config[:ram],
129
+ hdds: hdds,
130
+ power_on: config[:power_on],
131
+ password: config[:password],
132
+ rsa_key: config[:rsa_key],
133
+ firewall_id: config[:firewall_id],
134
+ ip_id: config[:ip_id],
135
+ load_balancer_id: config[:load_balancer_id],
136
+ monitoring_policy_id: config[:monitoring_policy_id]
137
+ )
138
+
139
+ if config[:wait]
140
+ puts ui.color('Deploying, wait for the operation to complete...', :cyan).to_s
141
+
142
+ # wait for provisioning 30m max
143
+ server.wait_for(timeout: 30, interval: 15)
144
+
145
+ formated_output(server.get, true)
146
+
147
+ first_password = server.first_password.nil? ? config[:password] : server.first_password
148
+ first_ip = !server.specs['ips'].empty? ? server.specs['ips'][0]['ip'] : ''
149
+
150
+ puts "\t#{ui.color('ID', :cyan)}: #{server.id}"
151
+ puts "\t#{ui.color('Name', :cyan)}: #{server.specs['name']}"
152
+ puts "\t#{ui.color('First IP', :cyan)}: #{first_ip}"
153
+ puts "\t#{ui.color('First Password', :cyan)}: #{first_password}\n"
154
+
155
+ puts ui.color('done', :bold).to_s
156
+ else
157
+ formated_output(response, true)
158
+ puts "Server #{response['id']} is #{ui.color('being deployed', :bold)}"
159
+ end
160
+ end
161
+ end
162
+ end
163
+ end
@@ -0,0 +1,63 @@
1
+ require 'chef/knife/oneandone_base'
2
+
3
+ class Chef
4
+ class Knife
5
+ class OneandoneServerDelete < Knife
6
+ include Knife::OneandoneBase
7
+
8
+ banner 'knife oneandone server delete SERVER_ID [SERVER_ID] (options)'
9
+
10
+ option :keep_ips,
11
+ long: '--keep-ips',
12
+ description: 'Keep server IPs after deleting the server.'
13
+
14
+ option :wait,
15
+ short: '-W',
16
+ long: '--wait',
17
+ description: 'Wait for the operation to complete.'
18
+
19
+ def run
20
+ $stdout.sync = true
21
+
22
+ init_client
23
+
24
+ name_args.each do |server_id|
25
+ server = OneAndOne::Server.new
26
+
27
+ begin
28
+ server.get(server_id: server_id)
29
+ rescue StandardError => e
30
+ if e.message.include? 'NOT_FOUND'
31
+ ui.error("Server ID #{server_id} not found. Skipping.")
32
+ else
33
+ ui.error(e.message)
34
+ end
35
+ next
36
+ end
37
+
38
+ server_name = server.specs['name']
39
+
40
+ confirm("Do you really want to delete server '#{server_name}'")
41
+
42
+ server.delete(keep_ips: config[:keep_ips])
43
+
44
+ if config[:wait]
45
+ begin
46
+ puts ui.color('Deleting, wait for the operation to complete...', :cyan).to_s
47
+ server.wait_for
48
+ puts "Server '#{server_name}' is #{ui.color('deleted', :bold)}"
49
+ rescue StandardError => e
50
+ if e.message.include? 'NOT_FOUND'
51
+ puts "Server '#{server_name}' is #{ui.color('deleted', :bold)}"
52
+ else
53
+ ui.error(e.message)
54
+ end
55
+ end
56
+ else
57
+ puts "Server '#{server_name}' is #{ui.color('being deleted', :bold)}"
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,60 @@
1
+ require 'chef/knife/oneandone_base'
2
+
3
+ class Chef
4
+ class Knife
5
+ class OneandoneServerHddAdd < Knife
6
+ include Knife::OneandoneBase
7
+
8
+ banner 'knife oneandone server hdd add HDD_SIZE [HDD_SIZE] (options)'
9
+
10
+ option :id,
11
+ short: '-I ID',
12
+ long: '--server-id ID',
13
+ description: 'Server ID'
14
+
15
+ option :wait,
16
+ short: '-W',
17
+ long: '--wait',
18
+ description: 'Wait for the operation to complete.'
19
+
20
+ def run
21
+ $stdout.sync = true
22
+
23
+ init_client
24
+
25
+ server = OneAndOne::Server.new
26
+
27
+ begin
28
+ server.get(server_id: config[:id])
29
+ rescue StandardError => e
30
+ if e.message.include? 'NOT_FOUND'
31
+ ui.error("Server ID #{config[:id]} not found")
32
+ else
33
+ ui.error(e.message)
34
+ end
35
+ exit 1
36
+ end
37
+
38
+ hdds = []
39
+
40
+ name_args.each do |size|
41
+ hdds << { 'size' => size, 'is_main' => false }
42
+ end
43
+
44
+ if hdds.empty?
45
+ ui.error('At least one value for HDD size must be specified.')
46
+ else
47
+ server.add_hdds(hdds: hdds)
48
+
49
+ if config[:wait]
50
+ puts ui.color('Adding, wait for the operation to complete...', :cyan).to_s
51
+ server.wait_for
52
+ puts "New HDD(s) is/are #{ui.color('added', :bold)}"
53
+ else
54
+ puts "New HDD(s) is/are #{ui.color('being added', :bold)}"
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,55 @@
1
+ require 'chef/knife/oneandone_base'
2
+
3
+ class Chef
4
+ class Knife
5
+ class OneandoneServerHddDelete < Knife
6
+ include Knife::OneandoneBase
7
+
8
+ banner 'knife oneandone server hdd delete (options)'
9
+
10
+ option :disk_id,
11
+ short: '-D DISK_ID',
12
+ long: '--disk-id DISK_ID',
13
+ description: 'Disk ID'
14
+
15
+ option :server_id,
16
+ short: '-S SERVER_ID',
17
+ long: '--server-id SERVER_ID',
18
+ description: 'Server ID'
19
+
20
+ option :wait,
21
+ short: '-W',
22
+ long: '--wait',
23
+ description: 'Wait for the operation to complete.'
24
+
25
+ def run
26
+ $stdout.sync = true
27
+
28
+ init_client
29
+
30
+ server = OneAndOne::Server.new
31
+
32
+ begin
33
+ server.get(server_id: config[:server_id])
34
+ rescue StandardError => e
35
+ if e.message.include? 'NOT_FOUND'
36
+ ui.error("Server ID #{config[:server_id]} not found")
37
+ else
38
+ ui.error(e.message)
39
+ end
40
+ exit 1
41
+ end
42
+
43
+ server.delete_hdd(server_id: config[:server_id], hdd_id: config[:disk_id])
44
+
45
+ if config[:wait]
46
+ puts ui.color('Deleting, wait for the operation to complete...', :cyan).to_s
47
+ server.wait_for
48
+ puts "HDD #{config[:disk_id]} is #{ui.color('deleted', :bold)}"
49
+ else
50
+ puts "HDD #{config[:disk_id]} is #{ui.color('being deleted', :bold)}"
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end