cap-gce 1.1.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 6eef30cfd574fe40156cd90133d646c233fa99c6
4
+ data.tar.gz: bb80ec04fb247ce1a4c0905d2c3db9699e208e9d
5
+ SHA512:
6
+ metadata.gz: 3b7c36cb89fc86cd76a004d3776819050bf46e5b27896b7b6416b95ef059ca2f15eb8777d061d01fca9be846693d424c927f356ef96c69a9ae37853493cf1b20
7
+ data.tar.gz: d0443ab299a1dccd5a5c32ae6fe67ad8b6010655e27f89830192e0231946e08c506287eb2c2960b619f43952d79a7ea9434ae6d758d584f5673e2c59c1b27009
data/.gitignore ADDED
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in cap-gce.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Dean Lin
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,137 @@
1
+ # Cap::Gce
2
+
3
+ Cap-GCE is used to generate Capistrano namespaces and tasks from Google Cloud Compute Engine instance metadata, dynamically building the list of servers to be deployed to.
4
+
5
+ This documentation assumes familiarity with Capistrano 3.x.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'cap-gce'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install cap-gce
22
+
23
+ You also need to add the gem to your Capfile:
24
+
25
+ ```
26
+ require "cap-gce/capistrano"
27
+ ```
28
+
29
+ ## Configuration
30
+
31
+ Configurable options, shown here with defaults:
32
+
33
+ ```
34
+ set :gce_config, 'config/gce.yml'
35
+ set :gce_project_tag, 'Project'
36
+ set :gce_roles_tag, 'Roles'
37
+ set :gce_stages_tag, 'Stages'
38
+
39
+ set :gce_project_id, nil
40
+ set :gce_zone, %w[]
41
+ set :gce_filter, '(status eq "RUNNING")'
42
+ set :gce_fields, nil
43
+
44
+ set :gce_scope, %w[https://www.googleapis.com/auth/compute]
45
+ set :gce_secret_config, 'config/compute_engine_secret.json'
46
+ set :gce_contact_point, nil # nat_ip, network_ip
47
+ ```
48
+
49
+ ### Secret Config
50
+ :gce_secret_config is credential file of GCP, now it only accept Service account key json certificate.
51
+
52
+ ### Zones
53
+
54
+ :gce_zone is an array of GCP zones and is required. Only list zones which you wish to query for instances
55
+
56
+ ### Misc settings
57
+
58
+ * project_tag
59
+
60
+ Cap-GCE will look for a metadata with this name when searching for instances that belong to this project. The metadata name defaults to "Project".
61
+
62
+ * stages_tag
63
+
64
+ Cap-GCE will look for a metadata with this name to determine which instances belong to a given stage. The metadata name defaults to "Stages".
65
+
66
+ * roles_tag
67
+
68
+ Cap-GCE will look for a metadata with this name to determine which instances belong to a given role. The metadata name defaults to "Roles".
69
+
70
+ ## Usage
71
+
72
+ ## Utility tasks
73
+
74
+ Cap-GCE adds a few utility tasks to Capistrano for displaying information about the instances that you will be deploying to. Note that unlike Capistrano 2.x, all tasks require a stage.
75
+
76
+ ### View instances
77
+
78
+ This command will show you information all the instances your configuration matches for a given stage.
79
+
80
+ ```
81
+ cap [stage] gce:status
82
+ ```
83
+
84
+ Example:
85
+ ```
86
+ $ cap production gce:status
87
+
88
+ Num Name ID Type IP Zone Roles Stage
89
+ 00 machine-learning-01 3805131608224908200 g1-small 10.138.0.2 us-west1-a web,app production
90
+ 00 machine-learning-02 3805131608224908300 g1-small 10.138.0.3 us-west1-a web,app production
91
+ ```
92
+
93
+ ### View server names
94
+
95
+ This command will show you the server names of the instances matching the given stage:
96
+
97
+ ```
98
+ cap [stage] gce:server_names
99
+ ```
100
+
101
+ Example:
102
+ ```
103
+ $ cap production gce:server_names
104
+ machine-learning-01
105
+ machine-learning-02
106
+ ```
107
+
108
+ ### View server instance IDs
109
+
110
+ This command will show the instance IDs of the instances matching the given stage:
111
+ ```
112
+ cap [stage] gce:instance_ids
113
+ ```
114
+
115
+ Example:
116
+
117
+ ```
118
+ $ cap production gce:instance_ids
119
+ 3805131608224908200
120
+ 3805131608224908300
121
+ ```
122
+
123
+ ## Development
124
+
125
+ After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
126
+
127
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
128
+
129
+ ## Contributing
130
+
131
+ Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/cap-gce. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
132
+
133
+
134
+ ## License
135
+
136
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
137
+
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require 'bundler/gem_tasks'
data/bin/console ADDED
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "cap/gce"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start(__FILE__)
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/cap-gce.gemspec ADDED
@@ -0,0 +1,40 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'cap-gce/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'cap-gce'
8
+ spec.version = CapGCE::VERSION
9
+ spec.authors = ['Dean Lin']
10
+ spec.email = ['iscreen@gmail.com']
11
+
12
+ spec.summary = %q(Cap-GCE is used to generate Capistrano namespaces and tasks from Google Compute Engine instance metadatas, dynamically building the list of servers to be deployed to.)
13
+ spec.description = %q(Cap-GCE is used to generate Capistrano namespaces and tasks from Google Compute Engine instance metadatas, dynamically building the list of servers to be deployed to.)
14
+ spec.homepage = 'https://github.com/iscreen/cap-gce'
15
+ spec.license = 'MIT'
16
+
17
+ # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
18
+ # to allow pushing to a single host or delete this section to allow pushing to any host.
19
+ # if spec.respond_to?(:metadata)
20
+ # spec.metadata['allowed_push_host'] = 'https://github.com/iscreen/cap-gce'
21
+ # else
22
+ # raise 'RubyGems 2.0 or newer is required to protect against ' \
23
+ # 'public gem pushes.'
24
+ # end
25
+
26
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
27
+ f.match(%r{^(test|spec|features)/})
28
+ end
29
+ spec.bindir = 'exe'
30
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
31
+ spec.require_paths = ['lib']
32
+
33
+ spec.add_dependency 'google-api-client', '~> 0.11'
34
+ spec.add_dependency 'capistrano', '>= 3.0'
35
+ spec.add_dependency 'terminal-table'
36
+ spec.add_dependency 'colorize'
37
+
38
+ spec.add_development_dependency 'bundler', '~> 1.14'
39
+ spec.add_development_dependency 'rake', '~> 10.0'
40
+ end
data/lib/cap-gce.rb ADDED
File without changes
@@ -0,0 +1,43 @@
1
+ require 'google/apis/compute_v1'
2
+ require 'googleauth'
3
+ require 'googleauth/stores/file_token_store'
4
+ require 'colorize'
5
+ require 'terminal-table'
6
+ require 'yaml'
7
+ require_relative 'utils'
8
+ require_relative 'gce-handler'
9
+ require_relative 'status-table'
10
+
11
+ # Load extra tasks
12
+ load File.expand_path('../tasks/gce.rake', __FILE__)
13
+
14
+ module Capistrano
15
+ module DSL
16
+ module Gce
17
+ def gce_handler
18
+ @gce_handler ||= CapGCE::GCEHandler.new
19
+ end
20
+
21
+ def gce_role(name, options = {})
22
+ gce_handler.get_servers_for_role(name).each do |server|
23
+ env.role(name, CapGCE::Utils.contact_point(server),
24
+ options_with_instance_id(options, server))
25
+ end
26
+ end
27
+
28
+ def env
29
+ Configuration.env
30
+ end
31
+
32
+ private
33
+
34
+ def options_with_instance_id(options, server)
35
+ options.merge(instance_id: server.id)
36
+ end
37
+ end
38
+ end
39
+ end
40
+
41
+ extend Capistrano::DSL::Gce
42
+
43
+ Capistrano::Configuration::Server.send(:include, CapGCE::Utils::Server)
@@ -0,0 +1,87 @@
1
+ require 'google/apis/compute_v1'
2
+ require 'googleauth'
3
+ require 'googleauth/stores/file_token_store'
4
+
5
+ module CapGCE
6
+ class GCEHandler
7
+ include CapGCE::Utils
8
+
9
+ def initialize
10
+ load_config
11
+ @authorizer = fetch_authorizer
12
+ load_gce
13
+ end
14
+
15
+ def load_gce
16
+ compute = Google::Apis::ComputeV1::ComputeService.new
17
+ compute.authorization = @authorizer
18
+ configured_zones = get_zones(fetch(:gce_zone))
19
+ @gce = {}
20
+ configured_zones.each do |zone|
21
+ @gce[zone] = compute.list_instances(
22
+ fetch(:gce_project_id),
23
+ zone,
24
+ filter: fetch(:gce_filter)
25
+ )
26
+ end
27
+ end
28
+
29
+ def status_table
30
+ CapGCE::StatusTable.new(
31
+ defined_roles.map { |r| get_servers_for_role(r) }.flatten.uniq(&:id)
32
+ )
33
+ end
34
+
35
+ def server_names
36
+ puts defined_roles
37
+ .map { |r| get_servers_for_role(r) }
38
+ .flatten
39
+ .uniq(&:id)
40
+ .map(&:name)
41
+ .join("\n")
42
+ end
43
+
44
+ def instance_ids
45
+ puts defined_roles
46
+ .map { |r| get_servers_for_role(r) }
47
+ .flatten
48
+ .uniq(&:id)
49
+ .map(&:id)
50
+ .join("\n")
51
+ end
52
+
53
+ def defined_roles
54
+ roles(:all).flat_map(&:roles_array).uniq.sort
55
+ end
56
+
57
+ def stage
58
+ Capistrano::Configuration.env.fetch(:stage).to_s
59
+ end
60
+
61
+ def application
62
+ Capistrano::Configuration.env.fetch(:application).to_s
63
+ end
64
+
65
+ def tag(tag_name)
66
+ "tag:#{tag_name}"
67
+ end
68
+
69
+ def get_servers_for_role(role)
70
+ servers = []
71
+ @gce.each do |_, gce|
72
+ servers += gce.items.select do |i|
73
+ instance_has_tag?(i, roles_tag, role) &&
74
+ instance_has_tag?(i, stages_tag, stage) &&
75
+ instance_has_tag?(i, project_tag, application)
76
+ end
77
+ end
78
+ servers.sort_by(&:name)
79
+ end
80
+
81
+ private
82
+
83
+ def instance_has_tag?(instance, key, value)
84
+ (tag_value(instance, key) || '').split(',').map(&:strip).include?(value.to_s)
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,63 @@
1
+ module CapGCE
2
+ class StatusTable
3
+ include CapGCE::Utils
4
+
5
+ def initialize(instances)
6
+ @instances = instances
7
+ output
8
+ end
9
+
10
+ def header_row
11
+ [
12
+ bold('Num'),
13
+ bold('Name'),
14
+ bold('ID'),
15
+ bold('Type'),
16
+ bold('IP'),
17
+ bold('Zone'),
18
+ bold('Roles'),
19
+ bold('Stages')
20
+ ]
21
+ end
22
+
23
+ def output
24
+ table = Terminal::Table.new(
25
+ style: {
26
+ border_x: '',
27
+ border_i: '',
28
+ border_y: ''
29
+ }
30
+ )
31
+ table.add_row header_row
32
+ @instances.each_with_index do |instance, index|
33
+ table.add_row instance_to_row(instance, index)
34
+ end
35
+ puts table.to_s
36
+ end
37
+
38
+ def instance_to_row(instance, index)
39
+ [
40
+ '%02d' % index,
41
+ green(instance.name || ''),
42
+ red(instance.id.to_s),
43
+ cyan(instance.machine_type.split('/').last),
44
+ bold(blue(CapGCE::Utils.contact_point(instance).join(','))),
45
+ magenta(instance.zone.split('/').last),
46
+ yellow(tag_value(instance, roles_tag)),
47
+ yellow(tag_value(instance, stages_tag))
48
+ ]
49
+ end
50
+
51
+ private
52
+
53
+ (String.colors + String.modes).each do |format|
54
+ define_method(format) do |string|
55
+ if $stdout.tty?
56
+ string.__send__(format)
57
+ else
58
+ string
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,33 @@
1
+ namespace :gce do
2
+ desc 'Show all information about GCE instances that match this project'
3
+ task :status do
4
+ gce_handler.status_table
5
+ end
6
+
7
+ desc 'Show GCE server names that match this project'
8
+ task :server_names do
9
+ gce_handler.server_names
10
+ end
11
+
12
+ desc 'Show GCE instance IDs that match this project'
13
+ task :instance_ids do
14
+ gce_handler.instance_ids
15
+ end
16
+ end
17
+
18
+ namespace :load do
19
+ task :defaults do
20
+ set :gce_config, 'config/gce.yml'
21
+ set :gce_project_tag, 'Project'
22
+ set :gce_roles_tag, 'Roles'
23
+ set :gce_stages_tag, 'Stages'
24
+
25
+ set :gce_project_id, nil
26
+ set :gce_zone, %w[]
27
+ set :gce_filter, '(status eq "RUNNING")'
28
+ set :gce_fields, nil
29
+ set :gce_scope, %w[https://www.googleapis.com/auth/compute]
30
+ set :gce_secret_config, 'config/compute_engine_secret.json'
31
+ set :gce_contact_point, nil # public_ip_address, private_ip_address
32
+ end
33
+ end
@@ -0,0 +1,92 @@
1
+ module CapGCE
2
+ module Utils
3
+ module Server
4
+ def gce_tags
5
+ id = properties.fetch(:gce_instance_id)
6
+ gce_handler.get_server(id).tags
7
+ end
8
+ end
9
+
10
+ def project_tag
11
+ fetch(:gce_project_tag)
12
+ end
13
+
14
+ def roles_tag
15
+ fetch(:gce_roles_tag)
16
+ end
17
+
18
+ def stages_tag
19
+ fetch(:gce_stages_tag)
20
+ end
21
+
22
+ def tag_value(instance, key)
23
+ instance.metadata.items.find({}) { |t| t.key == key.to_s }.value
24
+ end
25
+
26
+ def self.contact_point_mapping
27
+ {
28
+ public_ip: :nat_ip,
29
+ private_ip: :network_ip
30
+ }
31
+ end
32
+
33
+ def self.contact_point(instance)
34
+ gce_interface = contact_point_mapping[fetch(:gce_contact_point)]
35
+ network_interfaces = all_network_interfaces(instance)
36
+ return network_interfaces[gce_interface] if gce_interface
37
+
38
+ !network_interfaces[:nat_ip].empty? && network_interfaces[:nat_ip] ||
39
+ !network_interfaces[:network_ip].empty? && network_interfaces[:network_ip]
40
+ end
41
+
42
+ def self.all_network_interfaces(instance)
43
+ {
44
+ network_ip: instance.network_interfaces.map(&:network_ip),
45
+ nat_ip: nat_ip(instance)
46
+ }
47
+ end
48
+
49
+ def self.nat_ip(instance)
50
+ instance.network_interfaces.map(&:access_configs).flatten.map(&:nat_ip) - [nil]
51
+ end
52
+
53
+ private
54
+
55
+ def load_config
56
+ secret_location = File.expand_path(fetch(:gce_secret_config), Dir.pwd)
57
+ unless secret_location && File.exist?(secret_location)
58
+ raise 'You must specify secret config file.'
59
+ end
60
+
61
+ config_location = File.expand_path(fetch(:gce_config), Dir.pwd)
62
+ return unless config_location && File.exist?(config_location)
63
+ config = YAML.load_file fetch(:gce_config)
64
+ return unless config
65
+
66
+ set :gce_project_tag, config['project_tag'] if config['project_tag']
67
+ set :gce_roles_tag, config['roles_tag'] if config['roles_tag']
68
+ set :gce_stages_tag, config['stages_tag'] if config['stages_tag']
69
+
70
+ set :gce_project_id, config['project_id'] if config['project_id']
71
+ set :gce_filter, config['filter'] if config['filter']
72
+ set :gce_zone, config['zones'] if config['zones']
73
+ set :gce_scope, config['scopes'] if config['scopes']
74
+ end
75
+
76
+ def fetch_authorizer
77
+ authorizer = Google::Auth::ServiceAccountCredentials.make_creds(
78
+ json_key_io: File.open(fetch(:gce_secret_config)),
79
+ scope: fetch(:gce_scope)
80
+ )
81
+ authorizer.fetch_access_token!
82
+ authorizer
83
+ end
84
+
85
+ def get_zones(zones_array = nil)
86
+ if zones_array.nil? || zones_array.empty?
87
+ return raise 'You must specify at least one GCE zone.'
88
+ end
89
+ zones_array
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,3 @@
1
+ module CapGCE
2
+ VERSION = '1.1.0'.freeze
3
+ end
metadata ADDED
@@ -0,0 +1,147 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cap-gce
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Dean Lin
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-08-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: google-api-client
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.11'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.11'
27
+ - !ruby/object:Gem::Dependency
28
+ name: capistrano
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '3.0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '3.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: terminal-table
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: colorize
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: bundler
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.14'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.14'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '10.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '10.0'
97
+ description: Cap-GCE is used to generate Capistrano namespaces and tasks from Google
98
+ Compute Engine instance metadatas, dynamically building the list of servers to be
99
+ deployed to.
100
+ email:
101
+ - iscreen@gmail.com
102
+ executables: []
103
+ extensions: []
104
+ extra_rdoc_files: []
105
+ files:
106
+ - ".gitignore"
107
+ - Gemfile
108
+ - LICENSE.txt
109
+ - README.md
110
+ - Rakefile
111
+ - bin/console
112
+ - bin/setup
113
+ - cap-gce.gemspec
114
+ - lib/cap-gce.rb
115
+ - lib/cap-gce/capistrano.rb
116
+ - lib/cap-gce/gce-handler.rb
117
+ - lib/cap-gce/status-table.rb
118
+ - lib/cap-gce/tasks/gce.rake
119
+ - lib/cap-gce/utils.rb
120
+ - lib/cap-gce/version.rb
121
+ homepage: https://github.com/iscreen/cap-gce
122
+ licenses:
123
+ - MIT
124
+ metadata: {}
125
+ post_install_message:
126
+ rdoc_options: []
127
+ require_paths:
128
+ - lib
129
+ required_ruby_version: !ruby/object:Gem::Requirement
130
+ requirements:
131
+ - - ">="
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ required_rubygems_version: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ requirements: []
140
+ rubyforge_project:
141
+ rubygems_version: 2.6.11
142
+ signing_key:
143
+ specification_version: 4
144
+ summary: Cap-GCE is used to generate Capistrano namespaces and tasks from Google Compute
145
+ Engine instance metadatas, dynamically building the list of servers to be deployed
146
+ to.
147
+ test_files: []