ovh-provisioner 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/.gitlab-ci.yml +23 -0
- data/.rspec +2 -0
- data/.ruby-version +1 -0
- data/CHANGELOG +7 -0
- data/CONTRIBUTING.md +62 -0
- data/Gemfile +6 -0
- data/LICENSE +202 -0
- data/README.md +107 -0
- data/Rakefile +24 -0
- data/bin/console +32 -0
- data/bin/ovh_provisioner +27 -0
- data/bin/setup +23 -0
- data/lib/ovh/provisioner.rb +43 -0
- data/lib/ovh/provisioner/api_list.rb +158 -0
- data/lib/ovh/provisioner/api_object/api_object.rb +125 -0
- data/lib/ovh/provisioner/api_object/dedicated_server.rb +225 -0
- data/lib/ovh/provisioner/api_object/domain_zone.rb +115 -0
- data/lib/ovh/provisioner/api_object/ip.rb +83 -0
- data/lib/ovh/provisioner/api_object/record.rb +48 -0
- data/lib/ovh/provisioner/api_object/vrack.rb +92 -0
- data/lib/ovh/provisioner/cli.rb +173 -0
- data/lib/ovh/provisioner/cli_domain.rb +138 -0
- data/lib/ovh/provisioner/cli_ip.rb +64 -0
- data/lib/ovh/provisioner/cli_vrack.rb +71 -0
- data/lib/ovh/provisioner/init.rb +77 -0
- data/lib/ovh/provisioner/self_cli.rb +81 -0
- data/lib/ovh/provisioner/spawner.rb +63 -0
- data/lib/ovh/provisioner/version.rb +24 -0
- data/ovh-provisioner.gemspec +53 -0
- data/spec/config.yml +53 -0
- data/spec/helpers/highline_helper.rb +36 -0
- data/spec/ovh/provisioner/cli_domain_spec.rb +140 -0
- data/spec/ovh/provisioner/cli_ip_spec.rb +90 -0
- data/spec/ovh/provisioner/cli_spec.rb +186 -0
- data/spec/ovh/provisioner/cli_vrack_spec.rb +83 -0
- data/spec/ovh/provisioner/stubs/domain_stubs.rb +204 -0
- data/spec/ovh/provisioner/stubs/ip_stubs.rb +152 -0
- data/spec/ovh/provisioner/stubs/server_stubs.rb +146 -0
- data/spec/ovh/provisioner/stubs/vrack_stubs.rb +87 -0
- data/spec/ovh/provisioner_spec.rb +25 -0
- data/spec/spec_helper.rb +47 -0
- metadata +350 -0
@@ -0,0 +1,115 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# Copyright (c) 2015-2016 Sam4Mobile, 2017-2018 Make.org
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
module OVH
|
20
|
+
module Provisioner
|
21
|
+
module APIObject
|
22
|
+
# Represent a Domain
|
23
|
+
class DomainZone < APIObject
|
24
|
+
attr_reader :nameservers, :dnssec_supported, :dnssec, :records
|
25
|
+
|
26
|
+
def to_s
|
27
|
+
"#{id}, dnssec #{dnssec_to_s}, #{records.list.size} records"
|
28
|
+
end
|
29
|
+
|
30
|
+
def details(record_lists = records)
|
31
|
+
"#{id} - dnssec: #{dnssec_to_s}\n"\
|
32
|
+
"#{(record_lists.format('type').lines[1..-1] || []).join('')}"
|
33
|
+
end
|
34
|
+
|
35
|
+
def add_record(subdomain, type, target, ttl = 0)
|
36
|
+
body = {
|
37
|
+
'fieldType' => type.upcase,
|
38
|
+
'target' => target,
|
39
|
+
'ttl' => ttl.to_i
|
40
|
+
}
|
41
|
+
sub = subdomain
|
42
|
+
body['subDomain'] = sub unless sub.nil? || sub.empty?
|
43
|
+
answer = post('record', body)
|
44
|
+
post('refresh')
|
45
|
+
format(answer)
|
46
|
+
end
|
47
|
+
|
48
|
+
def rm_record(record)
|
49
|
+
out = delete("record/#{record.id}")
|
50
|
+
post('refresh')
|
51
|
+
" #{record}#{out.nil? ? '' : ": #{out}"}"
|
52
|
+
end
|
53
|
+
|
54
|
+
def rm_records(records)
|
55
|
+
outputs = records.parallel_map(:rm_record, [], Actor.current)
|
56
|
+
(["#{id}, remove records:"] + outputs.sort).join("\n")
|
57
|
+
end
|
58
|
+
|
59
|
+
def filter_records(config)
|
60
|
+
filter = generate_filter(
|
61
|
+
config['subdomain'] || '',
|
62
|
+
config['type'] || '',
|
63
|
+
config['target'] || '',
|
64
|
+
config['ttl'] || ''
|
65
|
+
)
|
66
|
+
targets = records.list.dup.keep_if do |record|
|
67
|
+
filter.call(record)
|
68
|
+
end.map(&:id)
|
69
|
+
Actor[Spawner::NAME].get('Record', *targets, parent: @url)
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def set_general
|
75
|
+
general = get
|
76
|
+
@nameservers = general['nameServers']
|
77
|
+
@dnssec_supported = general['dnssecSupported']
|
78
|
+
end
|
79
|
+
|
80
|
+
def set_dnssec
|
81
|
+
@dnssec = get('dnssec')['status']
|
82
|
+
end
|
83
|
+
|
84
|
+
def set_records
|
85
|
+
@records = Actor[Spawner::NAME].get('Record', '', parent: @url)
|
86
|
+
end
|
87
|
+
|
88
|
+
def dnssec_to_s
|
89
|
+
dnssec_supported ? dnssec : 'not supported'
|
90
|
+
end
|
91
|
+
|
92
|
+
def generate_filter(subdomain, type, target, ttl)
|
93
|
+
lambda do |record|
|
94
|
+
record.subdomain.include?(subdomain) &&
|
95
|
+
(type.empty? || record.type == type.upcase) &&
|
96
|
+
record.target.include?(target) &&
|
97
|
+
(ttl == '' || record.ttl == ttl.to_i)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def format(answer)
|
102
|
+
return answer if answer.is_a? String
|
103
|
+
|
104
|
+
zone = answer['zone']
|
105
|
+
sub = answer['subDomain'] || ''
|
106
|
+
ttl = answer['ttl']
|
107
|
+
type = answer['fieldType']
|
108
|
+
target = answer['target']
|
109
|
+
"#{id}, add record:\n"\
|
110
|
+
" #{Record.print(zone, sub, ttl, type, target)}"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# Copyright (c) 2015-2016 Sam4Mobile, 2017-2018 Make.org
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
module OVH
|
20
|
+
module Provisioner
|
21
|
+
module APIObject
|
22
|
+
# Represent an OVH IP
|
23
|
+
class IP < APIObject
|
24
|
+
attr_reader :organisation_id, :country
|
25
|
+
attr_reader :routed_to, :can_be_terminated, :type
|
26
|
+
attr_reader :description
|
27
|
+
attr_reader :reverse
|
28
|
+
attr_reader :kind
|
29
|
+
|
30
|
+
def add_reverse(reverse)
|
31
|
+
body = {
|
32
|
+
'ipReverse' => id.split('/').first,
|
33
|
+
'reverse' => reverse
|
34
|
+
}
|
35
|
+
response = post('reverse', body)
|
36
|
+
unless response['reverse'].nil?
|
37
|
+
response = "#{id} - reverse #{reverse} has been added"
|
38
|
+
@reverse = reverse['reverse']
|
39
|
+
end
|
40
|
+
response
|
41
|
+
end
|
42
|
+
|
43
|
+
def rm_reverse
|
44
|
+
response = delete("reverse/#{id.split('/').first}")
|
45
|
+
response ||= "#{id} - reverse #{reverse} has been removed"
|
46
|
+
response
|
47
|
+
end
|
48
|
+
|
49
|
+
def to_s
|
50
|
+
base = "#{id} - #{routed_to}(#{type}) - #{endable}"
|
51
|
+
%i[organisation_id country reverse description].each do |key|
|
52
|
+
value = send(key)
|
53
|
+
base += "\n #{key}: #{value}" unless value.nil?
|
54
|
+
end
|
55
|
+
base
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def set_general
|
61
|
+
general = get
|
62
|
+
@organisation_id = general['organisationId']
|
63
|
+
@country = general['country']
|
64
|
+
routed = general['routedTo']
|
65
|
+
@routed_to = routed.nil? ? nil : routed['serviceName']
|
66
|
+
@can_be_terminated = general['canBeTerminated']
|
67
|
+
@type = general['type']
|
68
|
+
@description = general['description']
|
69
|
+
@kind = id.include?(':') ? 'ipv6' : 'ipv4'
|
70
|
+
end
|
71
|
+
|
72
|
+
def set_reverse
|
73
|
+
reverse = get("reverse/#{id.split('/').first}")
|
74
|
+
@reverse = reverse['reverse']
|
75
|
+
end
|
76
|
+
|
77
|
+
def endable
|
78
|
+
can_be_terminated ? 'endable' : 'non endable'
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# Copyright (c) 2015-2016 Sam4Mobile, 2017-2018 Make.org
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
module OVH
|
20
|
+
module Provisioner
|
21
|
+
module APIObject
|
22
|
+
# Represent a record in a domain zone
|
23
|
+
class Record < APIObject
|
24
|
+
attr_reader :target, :ttl, :zone, :type, :subdomain
|
25
|
+
|
26
|
+
def self.print(zone, subdomain, ttl, type, target)
|
27
|
+
"#{subdomain.empty? ? "#{zone}." : subdomain} "\
|
28
|
+
"#{ttl} #{type} #{target}".strip
|
29
|
+
end
|
30
|
+
|
31
|
+
def to_s
|
32
|
+
self.class.print(zone, subdomain, ttl, type, target)
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def set_general
|
38
|
+
general = get
|
39
|
+
@target = general['target']
|
40
|
+
@ttl = general['ttl']
|
41
|
+
@zone = general['zone']
|
42
|
+
@type = general['fieldType']
|
43
|
+
@subdomain = general['subDomain']
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# Copyright (c) 2015-2016 Sam4Mobile, 2017-2018 Make.org
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
module OVH
|
20
|
+
module Provisioner
|
21
|
+
module APIObject
|
22
|
+
# Represent a VRack
|
23
|
+
class Vrack < APIObject
|
24
|
+
attr_reader :name, :description, :dedicated_servers, :tasks
|
25
|
+
|
26
|
+
def add(api_object)
|
27
|
+
path = path_from(api_object)
|
28
|
+
ok, msg = parse_task(post(path, path => api_object.id))
|
29
|
+
"#{api_object.id}: #{ok ? 'ok' : 'failed'}\n #{msg}"
|
30
|
+
end
|
31
|
+
|
32
|
+
def remove(api_object)
|
33
|
+
path = "#{path_from(api_object)}/#{api_object.id}"
|
34
|
+
ok, msg = parse_task(delete(path))
|
35
|
+
"#{api_object.id}: #{ok ? 'ok' : 'failed'}\n #{msg}"
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_s
|
39
|
+
"#{name}: #{id}#{" - #{description}" unless description.empty?}" \
|
40
|
+
"#{list_to_s(:dedicated_servers)}" \
|
41
|
+
"#{list_to_s(:tasks)}"
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def set_general
|
47
|
+
general = get
|
48
|
+
@name = general['name']
|
49
|
+
@description = general['description']
|
50
|
+
end
|
51
|
+
|
52
|
+
def set_dedicated_server
|
53
|
+
@dedicated_servers = get('dedicatedServer')
|
54
|
+
end
|
55
|
+
|
56
|
+
def set_tasks
|
57
|
+
tasks = get('task')
|
58
|
+
futures = tasks.map { |t| future.get("task/#{t}") }
|
59
|
+
@tasks = futures.map do |future|
|
60
|
+
_ok, msg = parse_task(future.value)
|
61
|
+
msg
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def list_to_s(list_sym)
|
66
|
+
list = send(list_sym)
|
67
|
+
return '' if list.nil? || list.empty?
|
68
|
+
|
69
|
+
header = ["\n #{list_sym}:"]
|
70
|
+
tail = list.map { |i| " #{i}" }.sort
|
71
|
+
(header + tail).join("\n")
|
72
|
+
end
|
73
|
+
|
74
|
+
def path_from(api_object)
|
75
|
+
name = api_object.class.classname
|
76
|
+
"#{name[0..0].downcase}#{name[1..-1]}"
|
77
|
+
end
|
78
|
+
|
79
|
+
def parse_task(msg)
|
80
|
+
return [false, msg] if msg.is_a?(String)
|
81
|
+
|
82
|
+
method = /^[[:lower:]]+/.match(msg['function']).to_a.first
|
83
|
+
[
|
84
|
+
true,
|
85
|
+
"#{msg['status']} #{msg['serviceName']}.#{method}" \
|
86
|
+
"(#{msg['targetDomain']})"
|
87
|
+
]
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,173 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
#
|
4
|
+
# Copyright (c) 2015-2016 Sam4Mobile, 2017-2018 Make.org
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'thor'
|
20
|
+
require 'pp'
|
21
|
+
require 'ruby-progressbar'
|
22
|
+
require 'highline/import'
|
23
|
+
Dir[File.dirname(__FILE__) + '/cli*.rb'].each { |file| require file }
|
24
|
+
|
25
|
+
# Monkey patch Thor to fix #261
|
26
|
+
module ThorPatching
|
27
|
+
def banner(command, namespace = nil, subcommand = false)
|
28
|
+
array = super.split(' ')
|
29
|
+
array[1] = array[1].tr('_', '')[3..-1] if array[1].start_with?('cli_')
|
30
|
+
array.join(' ')
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# Prepending the patch
|
35
|
+
class Thor
|
36
|
+
class << self
|
37
|
+
prepend ThorPatching
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
module OVH
|
42
|
+
module Provisioner
|
43
|
+
# The command line runner
|
44
|
+
class Cli < Thor # rubocop:disable Metrics/ClassLength
|
45
|
+
desc 'version', 'print OVH Provisioner\'s version information'
|
46
|
+
def version
|
47
|
+
say "OVH Provisioner version #{OVH::Provisioner::VERSION}"
|
48
|
+
end
|
49
|
+
map %w[-v --version] => :version
|
50
|
+
|
51
|
+
desc 'list targets', 'print the list of your dedicated servers'
|
52
|
+
def list(*targets)
|
53
|
+
spawner = Provisioner.init(options)
|
54
|
+
puts spawner
|
55
|
+
.get('DedicatedServer', *self.class.all(targets))
|
56
|
+
.format('vrack', 'flavor')
|
57
|
+
end
|
58
|
+
|
59
|
+
option(
|
60
|
+
:force,
|
61
|
+
type: :boolean,
|
62
|
+
desc: 'Force the installation even if the server is already installed',
|
63
|
+
default: false,
|
64
|
+
aliases: ['-f']
|
65
|
+
)
|
66
|
+
option(
|
67
|
+
:template,
|
68
|
+
desc: 'Template to install',
|
69
|
+
aliases: ['-t']
|
70
|
+
)
|
71
|
+
option(
|
72
|
+
:ssh_key_name,
|
73
|
+
desc: 'Name of the ssh key to install',
|
74
|
+
aliases: ['-n']
|
75
|
+
)
|
76
|
+
option(
|
77
|
+
:use_distrib_kernel,
|
78
|
+
type: :boolean,
|
79
|
+
desc: 'Use official kernel instead of OVH\'s (default = false)',
|
80
|
+
aliases: ['-d']
|
81
|
+
)
|
82
|
+
option(
|
83
|
+
:custom_hostname,
|
84
|
+
desc: 'Hostname of the server (default = reverse)',
|
85
|
+
aliases: ['-h']
|
86
|
+
)
|
87
|
+
desc 'install targets', 'install/reinstall one or more dedicated servers'
|
88
|
+
def install(*targets)
|
89
|
+
spawner = Provisioner.init(options)
|
90
|
+
servers = spawner.get('DedicatedServer', *self.class.all(targets))
|
91
|
+
self.class.ask_validation(
|
92
|
+
'You are going to (re)install those servers:',
|
93
|
+
servers.format('install_status', 'flavor')
|
94
|
+
)
|
95
|
+
servers.puts_each(:install)
|
96
|
+
end
|
97
|
+
|
98
|
+
NAME_SCHEME = [
|
99
|
+
:name_scheme,
|
100
|
+
desc: 'Name scheme to use for the servers, ex: %<flavor_tag>s-%<id>s',
|
101
|
+
aliases: ['-n']
|
102
|
+
].freeze
|
103
|
+
NAME_DOMAIN = [
|
104
|
+
:name_domain,
|
105
|
+
desc: 'Domain of the servers, ex: test.com',
|
106
|
+
aliases: ['-d']
|
107
|
+
].freeze
|
108
|
+
|
109
|
+
option(*NAME_SCHEME)
|
110
|
+
option(*NAME_DOMAIN)
|
111
|
+
desc 'rename targets', 'rename one or more dedicated servers'
|
112
|
+
def rename(*targets)
|
113
|
+
servers, domain = init_rename(targets)
|
114
|
+
# Add check on duplication?
|
115
|
+
self.class.ask_validation(
|
116
|
+
'You are going to rename those servers:',
|
117
|
+
servers.list.map do |s|
|
118
|
+
" #{s.reverse} => #{s.newname}.#{domain.id}"
|
119
|
+
end.join("\n")
|
120
|
+
)
|
121
|
+
servers.puts_each(:rename, [domain])
|
122
|
+
puts 'To complete renaming, call "set_reverse" in a few minute'
|
123
|
+
end
|
124
|
+
|
125
|
+
option(*NAME_SCHEME)
|
126
|
+
option(*NAME_DOMAIN)
|
127
|
+
desc 'set_reverse targets', 'set the reverse for a server'
|
128
|
+
def set_reverse(*targets) # rubocop:disable Style/AccessorMethodName
|
129
|
+
servers, domain = init_rename(targets)
|
130
|
+
servers.puts_each(:define_reverse, [domain])
|
131
|
+
end
|
132
|
+
|
133
|
+
# TODO: test it!
|
134
|
+
desc 'ipmi target', 'create ipmi interface and launch javaws on it'
|
135
|
+
def ipmi(*targets)
|
136
|
+
spawner = Provisioner.init(options)
|
137
|
+
servers = spawner.get('DedicatedServer', *self.class.all(targets))
|
138
|
+
list = servers.list
|
139
|
+
unless list.size == 1
|
140
|
+
puts 'Please select one and only one target! You have targeted:'
|
141
|
+
puts servers.format('flavor')
|
142
|
+
exit 1
|
143
|
+
end
|
144
|
+
list.first.ipmi
|
145
|
+
end
|
146
|
+
|
147
|
+
desc 'get url', 'execute a get on url'
|
148
|
+
def get(url)
|
149
|
+
Provisioner.init(options)
|
150
|
+
puts Provisioner.client.get url
|
151
|
+
end
|
152
|
+
|
153
|
+
desc 'vrack SUBCOMMAND ...ARGS', 'Manage Vracks'
|
154
|
+
subcommand 'vrack', CliVrack
|
155
|
+
|
156
|
+
desc 'domain SUBCOMMAND ...ARGS', 'Manage Domains'
|
157
|
+
subcommand 'domain', CliDomain
|
158
|
+
|
159
|
+
desc 'ip SUBCOMMAND ...ARGS', 'Manage IPs'
|
160
|
+
subcommand 'ip', CliIP
|
161
|
+
|
162
|
+
no_commands do
|
163
|
+
def init_rename(targets)
|
164
|
+
spawner = Provisioner.init(options)
|
165
|
+
servers = spawner.get('DedicatedServer', *self.class.all(targets))
|
166
|
+
name_domain = Provisioner.config['name_domain']
|
167
|
+
domain = spawner.get('DomainZone', id: name_domain)
|
168
|
+
[servers, domain]
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|