avst-cloud 0.1.35 → 0.1.40
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/.travis.yml +4 -0
- data/avst-cloud.gemspec +9 -6
- data/bin/avst-cloud-azure-rm +1 -1
- data/bin/avst-cloud-gcp +124 -0
- data/lib/avst-cloud/aws_connection.rb +90 -11
- data/lib/avst-cloud/gcp_connection.rb +310 -0
- data/lib/avst-cloud/gcp_server.rb +55 -0
- data/lib/avst-cloud/rackspace_connection.rb +1 -2
- data/lib/capistrano/tasks/prepare_puppet_and_execute.rake +0 -4
- metadata +27 -39
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 46cf2e686b412006cb9a4cbd2ae7fb624f5dbadf800bc05db414e7b2718e98e0
|
|
4
|
+
data.tar.gz: b56b12c41540f2d787fb80db59cc9cc6d1017721b327fa9bfd48adb0bab75afa
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 25461b2620b01cfd5e82909a00ad833787df06ef96729ce76e476cfddc9eb83189add2a324c2c7b51fb5c5e3d8428fd19e0d9520315ea76f868b23966c40b6cf
|
|
7
|
+
data.tar.gz: 388417ecbce19754583fb90c0b3e884e4d1d8ef1b585d8feef8b1e908dee98e8615914571584a7ce8c61ebfc4e5f58180ea1bd266649802d91d8132e5406072d
|
data/.travis.yml
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
language: ruby
|
|
2
|
+
before_install:
|
|
3
|
+
# https://github.com/travis-ci/travis-rubies/issues/57#issuecomment-458981237
|
|
4
|
+
- "find /home/travis/.rvm/rubies -wholename '*default/bundler-*.gemspec' -delete"
|
|
5
|
+
- gem install bundler --version 1.17.3
|
|
2
6
|
notifications:
|
|
3
7
|
email: false
|
|
4
8
|
hipchat:
|
data/avst-cloud.gemspec
CHANGED
|
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
|
4
4
|
|
|
5
5
|
Gem::Specification.new do |spec|
|
|
6
6
|
spec.name = "avst-cloud"
|
|
7
|
-
spec.version = '0.1.
|
|
7
|
+
spec.version = '0.1.40'
|
|
8
8
|
spec.authors = ["Martin Brehovsky", "Jon Bevan", "Matthew Hope"]
|
|
9
9
|
spec.email = ["mbrehovsky@adaptavist.com", "jbevan@adaptavist.com", "mhope@adaptavist.com"]
|
|
10
10
|
spec.summary = %q{Automated creation, bootstrapping and provisioning of servers }
|
|
@@ -15,13 +15,14 @@ Gem::Specification.new do |spec|
|
|
|
15
15
|
spec.executables = ["avst-cloud", "avst-cloud-puppet", "avst-cloud-rackspace", "avst-cloud-azure", "avst-cloud-azure-rm"]
|
|
16
16
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
17
17
|
spec.require_paths = ["lib"]
|
|
18
|
-
spec.add_development_dependency "bundler", "~> 1.
|
|
18
|
+
spec.add_development_dependency "bundler", "~> 1.17.3"
|
|
19
19
|
spec.add_development_dependency "rake"
|
|
20
20
|
spec.add_dependency "fog"
|
|
21
21
|
spec.add_dependency "fog-core", "1.43.0"
|
|
22
|
-
spec.add_dependency "fog-azure"
|
|
23
|
-
spec.add_dependency "fog-azure-rm", "0.0.3"
|
|
24
|
-
spec.add_dependency "
|
|
22
|
+
###spec.add_dependency "fog-azure"
|
|
23
|
+
###spec.add_dependency "fog-azure-rm", "0.0.3"
|
|
24
|
+
spec.add_dependency "fog-google", "1.8.2"
|
|
25
|
+
###spec.add_dependency "azure"
|
|
25
26
|
spec.add_dependency "rvm-capistrano"
|
|
26
27
|
spec.add_dependency "capistrano", "3.4.1"
|
|
27
28
|
spec.add_dependency "capistrano-rvm"
|
|
@@ -30,6 +31,8 @@ Gem::Specification.new do |spec|
|
|
|
30
31
|
spec.add_dependency "derelict"
|
|
31
32
|
spec.add_dependency "docopt", ">= 0.5.0"
|
|
32
33
|
spec.add_dependency "rainbow", '3.0.0'
|
|
33
|
-
spec.add_dependency "nokogiri",
|
|
34
|
+
spec.add_dependency "nokogiri", "~> 1.8.5"
|
|
35
|
+
spec.add_dependency "signet", "0.14.1"
|
|
34
36
|
end
|
|
35
37
|
|
|
38
|
+
|
data/bin/avst-cloud-azure-rm
CHANGED
|
@@ -39,7 +39,7 @@ platform = nil # defaults to Linux
|
|
|
39
39
|
server_name = "hostname1"
|
|
40
40
|
user = "ubuntu"
|
|
41
41
|
# Must comply to Azure pass guidelines
|
|
42
|
-
password = "
|
|
42
|
+
password = ""
|
|
43
43
|
location = nil # Will default to West Europe
|
|
44
44
|
resource_group = "new_resource_group" # if RG does not exists it will create it
|
|
45
45
|
vm_size = nil # Defaults to Basic_A0
|
data/bin/avst-cloud-gcp
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
# Copyright 2015 Adaptavist.com Ltd.
|
|
4
|
+
#
|
|
5
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
# you may not use this file except in compliance with the License.
|
|
7
|
+
# You may obtain a copy of the License at
|
|
8
|
+
#
|
|
9
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
#
|
|
11
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
# See the License for the specific language governing permissions and
|
|
15
|
+
# limitations under the License.
|
|
16
|
+
|
|
17
|
+
require 'avst-cloud'
|
|
18
|
+
require 'avst-cloud/gcp_connection'
|
|
19
|
+
require 'avst-cloud/gcp_server'
|
|
20
|
+
|
|
21
|
+
avst_cloud_base="#{File.expand_path("../../", __FILE__)}"
|
|
22
|
+
|
|
23
|
+
# FILL IN YOUR GCP ACCOUNT DETAILS (Access Key ID and Secret Access Key), GIT REPO AND MAKE SURE
|
|
24
|
+
# FILES IN files FOLDER HAS CORRECT CONTENT
|
|
25
|
+
provider_user=''
|
|
26
|
+
provider_pass=''
|
|
27
|
+
project=''
|
|
28
|
+
region='europe-west1'
|
|
29
|
+
|
|
30
|
+
# Initiate connector object
|
|
31
|
+
conn = AvstCloud::GcpConnection.new(provider_user, provider_pass, region, project)
|
|
32
|
+
|
|
33
|
+
server_name = 'hostname1'
|
|
34
|
+
|
|
35
|
+
flavour = nil # defaults to t2.micro
|
|
36
|
+
hdd_device_path = nil # defaults to '/dev/sda1'
|
|
37
|
+
machine_type_id = nil
|
|
38
|
+
os = "centos-7"
|
|
39
|
+
|
|
40
|
+
key_name = 'admin' # key name, e.g. admin
|
|
41
|
+
ssh_public_key = "path/to/your/admin.pem.pub" # Full path to ssh public key, e.g. /tmp/admin.pem.pub
|
|
42
|
+
ssh_private_key = "path/to/your/admin.pem" # Full path to ssh private key, e.g. /tmp/admin.pem
|
|
43
|
+
subnet_id = nil # Your subnet
|
|
44
|
+
security_group_ids = [''] # List of security groups
|
|
45
|
+
root_disk_size = nil # In GB
|
|
46
|
+
additional_hdds = {}
|
|
47
|
+
vpc = nil
|
|
48
|
+
created_by = nil
|
|
49
|
+
root_username = nil
|
|
50
|
+
custom_tags = []
|
|
51
|
+
availability_zone = 'europe-west1-b'
|
|
52
|
+
delete_root_disk = true
|
|
53
|
+
|
|
54
|
+
# display server status
|
|
55
|
+
##server_detail = conn.server_status(server_name)
|
|
56
|
+
##puts server_detail.inspect
|
|
57
|
+
##conn.list_zones
|
|
58
|
+
##conn.list_flavours(availability_zone)
|
|
59
|
+
##conn.list_images
|
|
60
|
+
##conn.list_networks
|
|
61
|
+
##conn.list_disk_types(availability_zone)
|
|
62
|
+
|
|
63
|
+
server = conn.create_server(server_name, flavour, os, key_name, ssh_public_key, ssh_private_key, subnet_id, security_group_ids, root_disk_size, machine_type_id, availability_zone, additional_hdds, vpc, created_by, custom_tags, root_username, delete_root_disk)
|
|
64
|
+
|
|
65
|
+
# server = conn.server(server_name, root_username, ssh_private_key, os)
|
|
66
|
+
# server.destroy
|
|
67
|
+
|
|
68
|
+
# puts conn.server_status(server_name)
|
|
69
|
+
# exit
|
|
70
|
+
|
|
71
|
+
pre_upload_commands = [
|
|
72
|
+
"echo 'pre_upload_command was here' >> /tmp/pre_upload",
|
|
73
|
+
]
|
|
74
|
+
|
|
75
|
+
custom_file_uploads = {
|
|
76
|
+
"#{avst_cloud_base}/files/id_rsa" => "/tmp/.",
|
|
77
|
+
"#{avst_cloud_base}/files/known_hosts" => "/tmp/."
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
# Uploading ssh keys to access git repo in provisioning stage, make sure you provide correct keys
|
|
81
|
+
post_upload_commands = [
|
|
82
|
+
"mkdir /home/ubuntu/.ssh",
|
|
83
|
+
"mv /tmp/id_rsa /home/ubuntu/.ssh/.",
|
|
84
|
+
"mv /tmp/known_hosts /home/ubuntu/.ssh/.",
|
|
85
|
+
"chmod 0600 /home/ubuntu/.ssh/known_hosts",
|
|
86
|
+
"chmod 0600 /home/ubuntu/.ssh/id_rsa",
|
|
87
|
+
"mkdir /var/opt/puppet",
|
|
88
|
+
"chown ubuntu /var/opt/puppet",
|
|
89
|
+
"apt-get update && apt-get install -o Dpkg::Options::='--force-confold' -f -y git puppet-common puppet"
|
|
90
|
+
]
|
|
91
|
+
|
|
92
|
+
remote_server_debug = true
|
|
93
|
+
debug_structured_log = false
|
|
94
|
+
|
|
95
|
+
##!##server.bootstrap(pre_upload_commands, custom_file_uploads, post_upload_commands, remote_server_debug, debug_structured_log, false)
|
|
96
|
+
|
|
97
|
+
git = "ssh://git@you_repo.git"
|
|
98
|
+
branch = "master"
|
|
99
|
+
reference = nil # Tag
|
|
100
|
+
# In this example we do not use puppet-runner, check doco
|
|
101
|
+
puppet_runner = nil
|
|
102
|
+
puppet_runner_prepare = nil
|
|
103
|
+
avst_cloud_config_dir = nil
|
|
104
|
+
download_dependencies_command = nil
|
|
105
|
+
custom_provisioning_commands = ["echo 'done' >> /tmp/done", "echo 'done' >> /tmp/done1"]
|
|
106
|
+
server_tmp_folder="/tmp/avst_cloud_tmp_#{Time.now.to_i}"
|
|
107
|
+
|
|
108
|
+
destination_folder = nil # defaults to /var/opt/puppet
|
|
109
|
+
##!##server.provision(git, branch, server_tmp_folder, reference, custom_provisioning_commands, puppet_runner, puppet_runner_prepare, destination_folder, avst_cloud_config_dir, download_dependencies_command)
|
|
110
|
+
|
|
111
|
+
# puts conn.server_status(server_name)
|
|
112
|
+
# server.stop
|
|
113
|
+
|
|
114
|
+
# puts conn.server_status(server_name)
|
|
115
|
+
# server.start
|
|
116
|
+
|
|
117
|
+
# puts conn.server_status(server_name)
|
|
118
|
+
|
|
119
|
+
# custom_commands=nil
|
|
120
|
+
# server_tmp_folder="/tmp/done"
|
|
121
|
+
# server.post_provisioning_cleanup(custom_commands, os, remote_server_debug, server_tmp_folder)
|
|
122
|
+
|
|
123
|
+
# server.destroy
|
|
124
|
+
# puts conn.server_status(server_name)
|
|
@@ -33,7 +33,7 @@ module AvstCloud
|
|
|
33
33
|
AvstCloud::AwsServer.new(server, server_name, server.public_ip_address, root_user, root_password)
|
|
34
34
|
end
|
|
35
35
|
|
|
36
|
-
def create_server(server_name, flavour, os, key_name, ssh_key, subnet_id, security_group_ids, ebs_size, hdd_device_path, ami_image_id, availability_zone, additional_hdds={}, vpc=nil, created_by=nil, custom_tags={}, root_username=nil)
|
|
36
|
+
def create_server(server_name, flavour, os, key_name, ssh_key, subnet_id, security_group_ids, ebs_size, hdd_device_path, ami_image_id, availability_zone, additional_hdds={}, vpc=nil, created_by=nil, custom_tags={}, root_username=nil, create_elastic_ip=false, encrypt_root=false ,root_encryption_key=nil, delete_root_disk=true, root_disk_type='gp2', root_disk_iops=0, private_ip=nil)
|
|
37
37
|
# Permit named instances from DEFAULT_FLAVOURS
|
|
38
38
|
flavour = flavour || "t2.micro"
|
|
39
39
|
os = os || "ubuntu-14"
|
|
@@ -87,26 +87,62 @@ module AvstCloud
|
|
|
87
87
|
logger.debug "hdd_device_path - #{device_name}"
|
|
88
88
|
logger.debug "additional_hdds - #{additional_hdds}"
|
|
89
89
|
logger.debug "vpc - #{vpc}"
|
|
90
|
+
logger.debug "create_elastic_ip - #{create_elastic_ip}"
|
|
91
|
+
logger.debug "custom_private_ip - #{private_ip}"
|
|
90
92
|
|
|
91
93
|
create_ebs_volume = nil
|
|
92
94
|
if ebs_size
|
|
93
95
|
# in case of centos ami we need to use /dev/xvda this is ami dependent
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
96
|
+
root_disk = {
|
|
97
|
+
:DeviceName => device_name,
|
|
98
|
+
'Ebs.VolumeType' => root_disk_type,
|
|
99
|
+
'Ebs.VolumeSize' => ebs_size,
|
|
100
|
+
}
|
|
101
|
+
# if the root disk is to be encrypted set te "Encrypted" flag to true, if there is an optional KMS Key ID send that,
|
|
102
|
+
# if not set to nil and thereby defalt to the default key for EBS
|
|
103
|
+
if encrypt_root
|
|
104
|
+
root_disk.merge!('Ebs.Encrypted' => true, 'Ebs.KmsKeyId' => root_encryption_key||nil )
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# if we do not want to delete the root disk with the VM set the flag
|
|
108
|
+
if delete_root_disk == false || delete_root_disk == 'false'
|
|
109
|
+
root_disk.merge!('Ebs.DeleteOnTermination' => false)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# if this is a provisioned IOPS disk set the iops value
|
|
113
|
+
if root_disk_type == 'io1'
|
|
114
|
+
root_disk.merge!('Ebs.Iops' => root_disk_iops)
|
|
115
|
+
end
|
|
116
|
+
# add the root disk as the first entry in the array of disks to create/attach
|
|
117
|
+
create_ebs_volume = [ root_disk ]
|
|
118
|
+
|
|
101
119
|
if additional_hdds and additional_hdds.is_a?(Hash)
|
|
102
120
|
additional_hdds.each_value do |disk|
|
|
103
121
|
volume_type = disk['volume_type'] || 'gp2'
|
|
104
122
|
if disk['device_name'] && disk['ebs_size']
|
|
105
|
-
|
|
123
|
+
disk_hash = {
|
|
106
124
|
:DeviceName => disk['device_name'],
|
|
107
125
|
'Ebs.VolumeType' => volume_type,
|
|
108
126
|
'Ebs.VolumeSize' => disk['ebs_size']
|
|
109
127
|
}
|
|
128
|
+
# if the additional disk is to be encrypted set te "Encrypted" flag to true, if there is an optional KMS Key ID send that,
|
|
129
|
+
# if not set to nil and thereby defalt to the default key for EBS
|
|
130
|
+
if disk['encrypted']
|
|
131
|
+
disk_hash.merge!('Ebs.Encrypted' => true, 'Ebs.KmsKeyId' => disk['encryption_key_id'] || nil)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# if we do not want to delete the additional disk with the VM set the flag
|
|
135
|
+
if disk['delete_disk_with_vm'] == false || disk['delete_disk_with_vm'] == 'false'
|
|
136
|
+
disk_hash.merge!('Ebs.DeleteOnTermination' => false)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# if the additional disk is an provisioned IOPS disk set the iops value
|
|
140
|
+
if volume_type == 'io1'
|
|
141
|
+
disk_hash.merge!('Ebs.Iops' => disk['volume_iops'] || 0)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
# add this disk to the array of all disks to create/attach
|
|
145
|
+
create_ebs_volume << disk_hash
|
|
110
146
|
else
|
|
111
147
|
logger.warn "Failed to create additional hdd, required params device_name (e.g. /dev/sda1) or ebs_size missing: #{disk}"
|
|
112
148
|
end
|
|
@@ -122,6 +158,7 @@ module AvstCloud
|
|
|
122
158
|
tags['created_by'] = created_by
|
|
123
159
|
end
|
|
124
160
|
tags.merge!(custom_tags)
|
|
161
|
+
|
|
125
162
|
# create server
|
|
126
163
|
server = connect.servers.create :tags => tags,
|
|
127
164
|
:flavor_id => flavour,
|
|
@@ -132,8 +169,8 @@ module AvstCloud
|
|
|
132
169
|
:security_group_ids => security_group_ids,
|
|
133
170
|
:availability_zone => availability_zone,
|
|
134
171
|
:block_device_mapping => create_ebs_volume,
|
|
135
|
-
:vpc => vpc
|
|
136
|
-
|
|
172
|
+
:vpc => vpc,
|
|
173
|
+
:private_ip_address => private_ip
|
|
137
174
|
|
|
138
175
|
result_server = AvstCloud::AwsServer.new(server, server_name, nil, root_user, ssh_key)
|
|
139
176
|
# result_server.logger = logger
|
|
@@ -143,6 +180,27 @@ module AvstCloud
|
|
|
143
180
|
|
|
144
181
|
logger.debug "[DONE]\n\n"
|
|
145
182
|
|
|
183
|
+
# create Elastic IP Address if required
|
|
184
|
+
if create_elastic_ip
|
|
185
|
+
logger.debug("Attempting to create elastic IP address")
|
|
186
|
+
elastic_ip = connect.allocate_address("vpc").body
|
|
187
|
+
elastic_ip_address = elastic_ip['publicIp']
|
|
188
|
+
# if we have a server id and an Elastic public IP attempt to join the two togehter
|
|
189
|
+
if server.id and elastic_ip_address
|
|
190
|
+
logger.debug ("Elastic IP #{elastic_ip_address} created, attempting to allocate to server")
|
|
191
|
+
connect.associate_address(server.id, elastic_ip_address)
|
|
192
|
+
# reacquire server object as IP has, probably, changed
|
|
193
|
+
server = find_fog_server(server_name)
|
|
194
|
+
|
|
195
|
+
# create tag on the Elastic IP
|
|
196
|
+
# TODO: add ability for other tags to be defined by the user
|
|
197
|
+
logger.debug("Creating tags on Elastic IP Address #{elastic_ip}\n\n")
|
|
198
|
+
connect.tags.create(:resource_id => elastic_ip['allocationId'], :key => "Name", :value => server_name)
|
|
199
|
+
else
|
|
200
|
+
logger.warn("Elastic IP creation failed, proceeding with non Elastic IP\n\n")
|
|
201
|
+
end
|
|
202
|
+
end
|
|
203
|
+
|
|
146
204
|
logger.debug "The server has been successfully created, to login onto the server:\n"
|
|
147
205
|
logger.debug "\t ssh -i #{ssh_key} #{root_user}@#{server.public_ip_address}\n"
|
|
148
206
|
if create_ebs_volume
|
|
@@ -201,6 +259,18 @@ module AvstCloud
|
|
|
201
259
|
servers.first
|
|
202
260
|
end
|
|
203
261
|
|
|
262
|
+
def delete_elastic_ip(ip_address)
|
|
263
|
+
address = is_elastic_ip(ip_address)
|
|
264
|
+
if address
|
|
265
|
+
logger.debug "Found Elastic IP #{address.public_ip}, attempting to delete"
|
|
266
|
+
logger.debug "Elastic IP #{ip_address} deleted" if address.destroy
|
|
267
|
+
return true
|
|
268
|
+
else
|
|
269
|
+
logger.debug "IP #{ip_address} does NOT appear to be an Elastic IP"
|
|
270
|
+
end
|
|
271
|
+
return false
|
|
272
|
+
end
|
|
273
|
+
|
|
204
274
|
private
|
|
205
275
|
def user_from_os(os)
|
|
206
276
|
case os.to_s
|
|
@@ -233,5 +303,14 @@ module AvstCloud
|
|
|
233
303
|
def all_named_servers(server_name)
|
|
234
304
|
connect.servers.all({'tag:Name' => server_name})
|
|
235
305
|
end
|
|
306
|
+
|
|
307
|
+
def is_elastic_ip(ip_address)
|
|
308
|
+
connect.addresses.each do |address|
|
|
309
|
+
if address.public_ip == ip_address
|
|
310
|
+
return address
|
|
311
|
+
end
|
|
312
|
+
end
|
|
313
|
+
return false
|
|
314
|
+
end
|
|
236
315
|
end
|
|
237
316
|
end
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
# Copyright 2015 Adaptavist.com Ltd.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
require_relative './cloud_connection.rb'
|
|
16
|
+
require 'fog/google'
|
|
17
|
+
using Rainbow
|
|
18
|
+
module AvstCloud
|
|
19
|
+
|
|
20
|
+
class GcpConnection < AvstCloud::CloudConnection
|
|
21
|
+
|
|
22
|
+
attr_accessor :region
|
|
23
|
+
|
|
24
|
+
def initialize(provider_user, provider_pass, region, project)
|
|
25
|
+
super('Google', provider_user, provider_pass)
|
|
26
|
+
@region = region
|
|
27
|
+
@project = project
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def server(server_name, root_user, root_password, os=nil)
|
|
31
|
+
server = find_fog_server(server_name)
|
|
32
|
+
if !root_user and os
|
|
33
|
+
root_user = user_from_key(os)
|
|
34
|
+
end
|
|
35
|
+
AvstCloud::GcpServer.new(server, server_name, server.public_ip_address, root_user, root_password)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def create_server(server_name, flavour, os, key_name, ssh_public_key, ssh_private_key, subnet_id, security_group_ids, root_disk_size, root_disk_type, machine_type_id, availability_zone, additional_hdds={}, vpc=nil, created_by=nil, custom_tags=[], root_username=nil, delete_root_disk=true)
|
|
39
|
+
flavour = flavour || "g1-small"
|
|
40
|
+
os = os || "centos-7"
|
|
41
|
+
vpc_name = vpc || "default"
|
|
42
|
+
subnet_name = subnet_id || "default"
|
|
43
|
+
machine_type_id = machine_type_id || get_image_name(os)
|
|
44
|
+
if machine_type_id.nil? or machine_type_id.empty?
|
|
45
|
+
machine_type_id = "centos-7-v20190312"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
unless File.file?(ssh_public_key)
|
|
49
|
+
logger.error "Could not find local public SSH key '#{ssh_public_key}'".red
|
|
50
|
+
raise "Could not find local SSH public key '#{ssh_public_key}'"
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
unless File.file?(ssh_private_key)
|
|
54
|
+
logger.error "Could not find local private SSH key '#{ssh_public_key}'".red
|
|
55
|
+
raise "Could not find local SSH private key '#{ssh_public_key}'"
|
|
56
|
+
end
|
|
57
|
+
root_user = root_username || user_from_key(os)
|
|
58
|
+
|
|
59
|
+
existing_servers = all_named_servers(server_name)
|
|
60
|
+
restartable_servers = existing_servers.select{ |serv| serv.status == 'TERMINATED' }
|
|
61
|
+
#TODO, status is a guess, need to work out if "DELETED" is valid for GCP
|
|
62
|
+
running_servers = existing_servers.select{ |serv| serv.status != 'TERMINATED' && serv.status != 'DELETED' }
|
|
63
|
+
|
|
64
|
+
if running_servers.length > 0
|
|
65
|
+
running_servers.each do |server|
|
|
66
|
+
logger.error "Server #{server_name} with id #{server.id} found in state: #{server.status}".yellow
|
|
67
|
+
end
|
|
68
|
+
raise "Server with the same name found!"
|
|
69
|
+
|
|
70
|
+
elsif restartable_servers.length > 0
|
|
71
|
+
if restartable_servers.length > 1
|
|
72
|
+
running_servers.each do |server|
|
|
73
|
+
logger.error "Server #{server_name} with id #{server.id} found in state: #{server.status}. Can not restart".yellow
|
|
74
|
+
end
|
|
75
|
+
raise "Too many servers can be restarted."
|
|
76
|
+
end
|
|
77
|
+
server = restartable_servers.first
|
|
78
|
+
server.start
|
|
79
|
+
result_server = AvstCloud::GcpServer.new(server, server_name, server.public_ip_address, root_user, ssh_private_key)
|
|
80
|
+
result_server.wait_for_state() {|serv| serv.ready?}
|
|
81
|
+
logger.debug "[DONE]\n\n"
|
|
82
|
+
logger.debug "The server was successfully re-started.\n\n"
|
|
83
|
+
result_server
|
|
84
|
+
else
|
|
85
|
+
logger.debug "Creating GCP server:"
|
|
86
|
+
logger.debug "Server name - #{server_name}"
|
|
87
|
+
logger.debug "Operating system - #{os}"
|
|
88
|
+
logger.debug "image_template_id - #{machine_type_id}"
|
|
89
|
+
logger.debug "flavour - #{flavour}"
|
|
90
|
+
logger.debug "key_name - #{key_name}"
|
|
91
|
+
logger.debug "Public ssh_key - #{ssh_public_key}"
|
|
92
|
+
logger.debug "Private ssh_key - #{ssh_private_key}"
|
|
93
|
+
logger.debug "root user - #{root_user}"
|
|
94
|
+
logger.debug "subnet_id - #{subnet_name}"
|
|
95
|
+
logger.debug "security_group_ids - #{security_group_ids}"
|
|
96
|
+
logger.debug "region - #{@region}"
|
|
97
|
+
logger.debug "availability_zone - #{availability_zone}"
|
|
98
|
+
logger.debug "root_disk_size - #{root_disk_size}"
|
|
99
|
+
logger.debug "additional_hdds - #{additional_hdds}"
|
|
100
|
+
logger.debug "vpc - #{vpc_name}"
|
|
101
|
+
|
|
102
|
+
# Create root disk
|
|
103
|
+
# TODO check if this exists and exit politely, or catch the exception and exit politely
|
|
104
|
+
root_disk_type = root_disk_type || 'pd-standard'
|
|
105
|
+
logger.debug "Creating root disk with type #{root_disk_type}"
|
|
106
|
+
root_disk_url="https://www.googleapis.com/compute/v1/projects/#{@project}/zones/#{availability_zone}/diskTypes/#{root_disk_type}"
|
|
107
|
+
disk = connect.disks.create :name => "#{server_name}-root",
|
|
108
|
+
:size_gb => root_disk_size,
|
|
109
|
+
:zone => availability_zone,
|
|
110
|
+
:source_image => machine_type_id,
|
|
111
|
+
:type => root_disk_url
|
|
112
|
+
|
|
113
|
+
# wait for the disk to be ready
|
|
114
|
+
logger.debug "Waiting for root disk to be ready"
|
|
115
|
+
disk.wait_for { ready? }
|
|
116
|
+
|
|
117
|
+
disk_to_attach=[disk.attached_disk_obj(boot: true, auto_delete: delete_root_disk)]
|
|
118
|
+
|
|
119
|
+
# create additional HDD's if required
|
|
120
|
+
if additional_hdds and additional_hdds.is_a?(Hash)
|
|
121
|
+
disk_count=1
|
|
122
|
+
additional_hdds.each_value do |disk|
|
|
123
|
+
#TODO wortk out how to set disk type!
|
|
124
|
+
if disk['disk_size'] || disk['ebs_size']
|
|
125
|
+
disk_type = disk['disk_type'] || 'pd-standard'
|
|
126
|
+
logger.debug "Creating additional disk #{disk_count} with type #{disk_type}"
|
|
127
|
+
disk_url="https://www.googleapis.com/compute/v1/projects/#{@project}/zones/#{availability_zone}/diskTypes/#{disk_type}"
|
|
128
|
+
delete_disk_with_vm = disk['delete_disk_with_vm'] || false
|
|
129
|
+
additional_disk = connect.disks.create :name => "#{server_name}-disk#{disk_count}",
|
|
130
|
+
:size_gb => disk['disk_size'] || disk['ebs_size'],
|
|
131
|
+
:zone => availability_zone,
|
|
132
|
+
:type => disk_url
|
|
133
|
+
# wait for additional disk
|
|
134
|
+
logger.debug "Waiting for additional disk #{disk_count}"
|
|
135
|
+
additional_disk.wait_for { ready? }
|
|
136
|
+
|
|
137
|
+
# add disk to array of those to be mounted
|
|
138
|
+
disk_to_attach.push additional_disk.attached_disk_obj(boot: false, auto_delete: delete_disk_with_vm)
|
|
139
|
+
|
|
140
|
+
#blank the additional disk object for the next time around
|
|
141
|
+
attached_disk = nil
|
|
142
|
+
|
|
143
|
+
# increment disk counter
|
|
144
|
+
disk_count = disk_count +1
|
|
145
|
+
else
|
|
146
|
+
logger.warn "Failed to create additional hdd, required param disk_size missing: #{disk}"
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
## GCP tags are not key value pairs
|
|
152
|
+
tags = [server_name, os] + custom_tags
|
|
153
|
+
|
|
154
|
+
# work out the URK for the subnetwork
|
|
155
|
+
subnet_url = "https://www.googleapis.com/compute/v1/projects/#{@project}/regions/#{region}/subnetworks/#{subnet_name}"
|
|
156
|
+
|
|
157
|
+
# create server
|
|
158
|
+
logger.debug "Creating Server"
|
|
159
|
+
server = connect.servers.create :name => server_name,
|
|
160
|
+
:disks => disk_to_attach,
|
|
161
|
+
:machine_type => flavour,
|
|
162
|
+
:private_key_path => ssh_private_key,
|
|
163
|
+
:public_key_path => ssh_public_key,
|
|
164
|
+
:zone => availability_zone,
|
|
165
|
+
:network_interfaces => [{ :network => "global/networks/#{vpc_name}",
|
|
166
|
+
:subnetwork => subnet_url,
|
|
167
|
+
:access_configs => [{
|
|
168
|
+
:name => "External NAT",
|
|
169
|
+
:type => "ONE_TO_ONE_NAT" }]
|
|
170
|
+
}],
|
|
171
|
+
:username => root_user,
|
|
172
|
+
:tags => tags
|
|
173
|
+
|
|
174
|
+
result_server = AvstCloud::GcpServer.new(server, server_name, nil, root_user, ssh_private_key)
|
|
175
|
+
# result_server.logger = logger
|
|
176
|
+
# Check every 5 seconds to see if server is in the active state (ready?).
|
|
177
|
+
# If the server has not been built in 5 minutes (600 seconds) an exception will be raised.
|
|
178
|
+
result_server.wait_for_state() {|serv| serv.ready?}
|
|
179
|
+
|
|
180
|
+
logger.debug "[DONE]\n\n"
|
|
181
|
+
logger.debug "The server has been successfully created, to login onto the server:\n"
|
|
182
|
+
logger.debug "\t ssh -i #{ssh_private_key} #{root_user}@#{server.public_ip_address}\n"
|
|
183
|
+
result_server.ip_address = server.public_ip_address
|
|
184
|
+
result_server
|
|
185
|
+
end
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def server_status(server_name)
|
|
189
|
+
#TODO, status is a guess, need to work out if this is valid for GCP
|
|
190
|
+
servers = all_named_servers(server_name).select{|serv| serv.status != 'DELETED'}
|
|
191
|
+
if servers.length > 0
|
|
192
|
+
servers.each do |server|
|
|
193
|
+
logger.debug "Server #{server.id} with name '#{server_name}' exists and has state: #{server.status}"
|
|
194
|
+
end
|
|
195
|
+
else
|
|
196
|
+
logger.debug "Server not found for name: #{server_name}"
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def list_zones
|
|
201
|
+
logger.debug connect.list_zones
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def list_flavours(zone)
|
|
205
|
+
logger.debug connect.list_machine_types(zone)
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def list_images
|
|
209
|
+
# Only list current images, not deprecated ones
|
|
210
|
+
get_images.each do |im|
|
|
211
|
+
logger.debug im.inspect
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
|
|
215
|
+
def list_networks
|
|
216
|
+
logger.debug connect.list_networks
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
def list_disk_types(availability_zone)
|
|
220
|
+
logger.debug connect.list_disk_types(availability_zone)
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
# Returns list of servers from fog
|
|
224
|
+
def list_known_servers
|
|
225
|
+
connect.servers.all
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
def find_fog_server(server_name, should_fail=true)
|
|
229
|
+
#TODO, status is a guess, need to work out if this is valid for GCP
|
|
230
|
+
servers = all_named_servers(server_name).select{|serv| serv.status != 'DELETED'}
|
|
231
|
+
unless servers.length == 1
|
|
232
|
+
logger.debug "Found #{servers.length} servers for name: #{server_name}".yellow
|
|
233
|
+
if should_fail
|
|
234
|
+
raise "Found #{servers.length} servers for name: #{server_name}"
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
servers.first
|
|
238
|
+
end
|
|
239
|
+
|
|
240
|
+
private
|
|
241
|
+
# attempt to workout the user from the key comments! - TODO
|
|
242
|
+
def user_from_key(os)
|
|
243
|
+
raise "Function to extract username from key comment not yet implemented"
|
|
244
|
+
end
|
|
245
|
+
def connect
|
|
246
|
+
unless @connection
|
|
247
|
+
logger.debug "Creating new connection to GCP"
|
|
248
|
+
@connection = Fog::Compute.new({
|
|
249
|
+
:provider => 'Google',
|
|
250
|
+
:google_project => @project,
|
|
251
|
+
:google_client_email => @provider_access_user,
|
|
252
|
+
:google_json_key_location => @provider_access_pass
|
|
253
|
+
})
|
|
254
|
+
end
|
|
255
|
+
@connection
|
|
256
|
+
end
|
|
257
|
+
# get a list of images,
|
|
258
|
+
def get_images(family=nil, deprecated=false)
|
|
259
|
+
# if we are looking to include depreacted images get them all
|
|
260
|
+
if deprecated
|
|
261
|
+
images = connect.images.all
|
|
262
|
+
# if not just get the current ones
|
|
263
|
+
else
|
|
264
|
+
images = connect.images.current
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
# if we are to filter on a list of families do so
|
|
268
|
+
if family
|
|
269
|
+
final_images = Array.new
|
|
270
|
+
images.each do |image|
|
|
271
|
+
if image.family == family
|
|
272
|
+
final_images.push image
|
|
273
|
+
end
|
|
274
|
+
end
|
|
275
|
+
# return the filtered list
|
|
276
|
+
final_images
|
|
277
|
+
# if not just return all results
|
|
278
|
+
else
|
|
279
|
+
# return the results
|
|
280
|
+
images
|
|
281
|
+
end
|
|
282
|
+
end
|
|
283
|
+
# get a single machine image by family
|
|
284
|
+
def get_image_name(family)
|
|
285
|
+
image = get_images(family, false)
|
|
286
|
+
if image.length != 1
|
|
287
|
+
raise "Too many images returned for family #{family}, #{image.length} were returned"
|
|
288
|
+
end
|
|
289
|
+
# return the image name
|
|
290
|
+
image.first.name
|
|
291
|
+
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
def all_named_servers(server_name)
|
|
295
|
+
# ***connect.servers.all does not accept any arguments in GCP***
|
|
296
|
+
|
|
297
|
+
# create empty array
|
|
298
|
+
named_servers=Array.new
|
|
299
|
+
# get all servers
|
|
300
|
+
connect.servers.all.each do | returned_server |
|
|
301
|
+
# if the server name matches what we are looking for add to the result array
|
|
302
|
+
if returned_server.name == server_name
|
|
303
|
+
named_servers.push(returned_server)
|
|
304
|
+
end
|
|
305
|
+
end
|
|
306
|
+
# return the list of servers
|
|
307
|
+
named_servers
|
|
308
|
+
end
|
|
309
|
+
end
|
|
310
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Copyright 2015 Adaptavist.com Ltd.
|
|
2
|
+
#
|
|
3
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
# you may not use this file except in compliance with the License.
|
|
5
|
+
# You may obtain a copy of the License at
|
|
6
|
+
#
|
|
7
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
#
|
|
9
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
# See the License for the specific language governing permissions and
|
|
13
|
+
# limitations under the License.
|
|
14
|
+
|
|
15
|
+
require_relative './cloud_server.rb'
|
|
16
|
+
using Rainbow
|
|
17
|
+
module AvstCloud
|
|
18
|
+
class GcpServer < AvstCloud::CloudServer
|
|
19
|
+
|
|
20
|
+
def stop
|
|
21
|
+
if @server
|
|
22
|
+
logger.debug "Stopping #{@server_name}"
|
|
23
|
+
@server.stop
|
|
24
|
+
wait_for_state() {|serv| serv.status == 'TERMINATED'}
|
|
25
|
+
logger.debug "[DONE]\n\n"
|
|
26
|
+
logger.debug "Server #{@server_name} stopped...".green
|
|
27
|
+
else
|
|
28
|
+
raise "Server #{@server_name} does not exist!".red
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def start
|
|
33
|
+
if @server
|
|
34
|
+
logger.debug "Starting #{@server_name}"
|
|
35
|
+
@server.start
|
|
36
|
+
wait_for_state() {|serv| serv.ready?}
|
|
37
|
+
logger.debug "[DONE]\n\n"
|
|
38
|
+
logger.debug "Server #{@server_name} started...".green
|
|
39
|
+
else
|
|
40
|
+
raise "Server #{@server_name} does not exist!".red
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def destroy
|
|
45
|
+
if @server
|
|
46
|
+
logger.debug "Killing #{@server_name}"
|
|
47
|
+
@server.destroy
|
|
48
|
+
logger.debug "Server #{@server_name} destroying...".green
|
|
49
|
+
else
|
|
50
|
+
raise "Server #{@server_name} does not exist!".red
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -54,10 +54,6 @@ task :prepare_puppet_and_execute do
|
|
|
54
54
|
execute :link_puppet
|
|
55
55
|
execute :link_hiera
|
|
56
56
|
|
|
57
|
-
if File.exist?("#{ENV["avst_cloud_config_dir"]}/keys")
|
|
58
|
-
upload! "#{ENV["avst_cloud_config_dir"]}/keys", "/etc/puppet/config", recursive: true
|
|
59
|
-
end
|
|
60
|
-
|
|
61
57
|
within '/etc/puppet' do
|
|
62
58
|
begin
|
|
63
59
|
execute :execute_puppet_runner
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: avst-cloud
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.40
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Martin Brehovsky
|
|
@@ -10,7 +10,7 @@ authors:
|
|
|
10
10
|
autorequire:
|
|
11
11
|
bindir: bin
|
|
12
12
|
cert_chain: []
|
|
13
|
-
date:
|
|
13
|
+
date: 2021-04-19 00:00:00.000000000 Z
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|
|
16
16
|
name: bundler
|
|
@@ -18,14 +18,14 @@ dependencies:
|
|
|
18
18
|
requirements:
|
|
19
19
|
- - "~>"
|
|
20
20
|
- !ruby/object:Gem::Version
|
|
21
|
-
version: 1.
|
|
21
|
+
version: 1.17.3
|
|
22
22
|
type: :development
|
|
23
23
|
prerelease: false
|
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
|
25
25
|
requirements:
|
|
26
26
|
- - "~>"
|
|
27
27
|
- !ruby/object:Gem::Version
|
|
28
|
-
version: 1.
|
|
28
|
+
version: 1.17.3
|
|
29
29
|
- !ruby/object:Gem::Dependency
|
|
30
30
|
name: rake
|
|
31
31
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -69,47 +69,19 @@ dependencies:
|
|
|
69
69
|
- !ruby/object:Gem::Version
|
|
70
70
|
version: 1.43.0
|
|
71
71
|
- !ruby/object:Gem::Dependency
|
|
72
|
-
name: fog-
|
|
73
|
-
requirement: !ruby/object:Gem::Requirement
|
|
74
|
-
requirements:
|
|
75
|
-
- - ">="
|
|
76
|
-
- !ruby/object:Gem::Version
|
|
77
|
-
version: '0'
|
|
78
|
-
type: :runtime
|
|
79
|
-
prerelease: false
|
|
80
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
81
|
-
requirements:
|
|
82
|
-
- - ">="
|
|
83
|
-
- !ruby/object:Gem::Version
|
|
84
|
-
version: '0'
|
|
85
|
-
- !ruby/object:Gem::Dependency
|
|
86
|
-
name: fog-azure-rm
|
|
72
|
+
name: fog-google
|
|
87
73
|
requirement: !ruby/object:Gem::Requirement
|
|
88
74
|
requirements:
|
|
89
75
|
- - '='
|
|
90
76
|
- !ruby/object:Gem::Version
|
|
91
|
-
version:
|
|
77
|
+
version: 1.8.2
|
|
92
78
|
type: :runtime
|
|
93
79
|
prerelease: false
|
|
94
80
|
version_requirements: !ruby/object:Gem::Requirement
|
|
95
81
|
requirements:
|
|
96
82
|
- - '='
|
|
97
83
|
- !ruby/object:Gem::Version
|
|
98
|
-
version:
|
|
99
|
-
- !ruby/object:Gem::Dependency
|
|
100
|
-
name: azure
|
|
101
|
-
requirement: !ruby/object:Gem::Requirement
|
|
102
|
-
requirements:
|
|
103
|
-
- - ">="
|
|
104
|
-
- !ruby/object:Gem::Version
|
|
105
|
-
version: '0'
|
|
106
|
-
type: :runtime
|
|
107
|
-
prerelease: false
|
|
108
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
109
|
-
requirements:
|
|
110
|
-
- - ">="
|
|
111
|
-
- !ruby/object:Gem::Version
|
|
112
|
-
version: '0'
|
|
84
|
+
version: 1.8.2
|
|
113
85
|
- !ruby/object:Gem::Dependency
|
|
114
86
|
name: rvm-capistrano
|
|
115
87
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -224,18 +196,32 @@ dependencies:
|
|
|
224
196
|
version: 3.0.0
|
|
225
197
|
- !ruby/object:Gem::Dependency
|
|
226
198
|
name: nokogiri
|
|
199
|
+
requirement: !ruby/object:Gem::Requirement
|
|
200
|
+
requirements:
|
|
201
|
+
- - "~>"
|
|
202
|
+
- !ruby/object:Gem::Version
|
|
203
|
+
version: 1.8.5
|
|
204
|
+
type: :runtime
|
|
205
|
+
prerelease: false
|
|
206
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
207
|
+
requirements:
|
|
208
|
+
- - "~>"
|
|
209
|
+
- !ruby/object:Gem::Version
|
|
210
|
+
version: 1.8.5
|
|
211
|
+
- !ruby/object:Gem::Dependency
|
|
212
|
+
name: signet
|
|
227
213
|
requirement: !ruby/object:Gem::Requirement
|
|
228
214
|
requirements:
|
|
229
215
|
- - '='
|
|
230
216
|
- !ruby/object:Gem::Version
|
|
231
|
-
version:
|
|
217
|
+
version: 0.14.1
|
|
232
218
|
type: :runtime
|
|
233
219
|
prerelease: false
|
|
234
220
|
version_requirements: !ruby/object:Gem::Requirement
|
|
235
221
|
requirements:
|
|
236
222
|
- - '='
|
|
237
223
|
- !ruby/object:Gem::Version
|
|
238
|
-
version:
|
|
224
|
+
version: 0.14.1
|
|
239
225
|
description: Automated creation, bootstrapping and provisioning of servers
|
|
240
226
|
email:
|
|
241
227
|
- mbrehovsky@adaptavist.com
|
|
@@ -260,6 +246,7 @@ files:
|
|
|
260
246
|
- bin/avst-cloud
|
|
261
247
|
- bin/avst-cloud-azure
|
|
262
248
|
- bin/avst-cloud-azure-rm
|
|
249
|
+
- bin/avst-cloud-gcp
|
|
263
250
|
- bin/avst-cloud-puppet
|
|
264
251
|
- bin/avst-cloud-rackspace
|
|
265
252
|
- config/custom_system_config/hiera-configs/defaults/example.yaml
|
|
@@ -277,6 +264,8 @@ files:
|
|
|
277
264
|
- lib/avst-cloud/azure_server.rb
|
|
278
265
|
- lib/avst-cloud/cloud_connection.rb
|
|
279
266
|
- lib/avst-cloud/cloud_server.rb
|
|
267
|
+
- lib/avst-cloud/gcp_connection.rb
|
|
268
|
+
- lib/avst-cloud/gcp_server.rb
|
|
280
269
|
- lib/avst-cloud/logging.rb
|
|
281
270
|
- lib/avst-cloud/rackspace_connection.rb
|
|
282
271
|
- lib/avst-cloud/rackspace_server.rb
|
|
@@ -300,8 +289,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
300
289
|
- !ruby/object:Gem::Version
|
|
301
290
|
version: '0'
|
|
302
291
|
requirements: []
|
|
303
|
-
|
|
304
|
-
rubygems_version: 2.7.7
|
|
292
|
+
rubygems_version: 3.0.8
|
|
305
293
|
signing_key:
|
|
306
294
|
specification_version: 4
|
|
307
295
|
summary: Automated creation, bootstrapping and provisioning of servers
|