knife-google 1.3.1 → 2.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 (111) hide show
  1. checksums.yaml +5 -13
  2. data/.gitignore +1 -0
  3. data/.travis.yml +15 -3
  4. data/CHANGELOG.md +4 -6
  5. data/Gemfile +3 -9
  6. data/README.md +208 -355
  7. data/RELEASE_NOTES.md +8 -17
  8. data/Rakefile +8 -49
  9. data/knife-google.gemspec +20 -17
  10. data/lib/chef/knife/cloud/google_service.rb +491 -0
  11. data/lib/chef/knife/cloud/google_service_helpers.rb +62 -0
  12. data/lib/chef/knife/cloud/google_service_options.rb +58 -0
  13. data/lib/chef/knife/google_disk_create.rb +40 -44
  14. data/lib/chef/knife/google_disk_delete.rb +22 -40
  15. data/lib/chef/knife/google_disk_list.rb +57 -51
  16. data/lib/chef/knife/google_project_quotas.rb +59 -0
  17. data/lib/chef/knife/google_region_list.rb +43 -102
  18. data/lib/chef/knife/google_region_quotas.rb +77 -0
  19. data/lib/chef/knife/google_server_create.rb +224 -505
  20. data/lib/chef/knife/google_server_delete.rb +20 -78
  21. data/lib/chef/knife/google_server_list.rb +42 -53
  22. data/lib/chef/knife/google_server_show.rb +44 -0
  23. data/lib/chef/knife/google_zone_list.rb +39 -50
  24. data/lib/knife-google/version.rb +3 -2
  25. data/spec/cloud/google_service_helpers_spec.rb +120 -0
  26. data/spec/cloud/google_service_spec.rb +832 -0
  27. data/spec/google_disk_create_spec.rb +72 -0
  28. data/spec/google_disk_delete_spec.rb +64 -0
  29. data/spec/google_disk_list_spec.rb +93 -0
  30. data/spec/google_project_quotas_spec.rb +63 -0
  31. data/spec/google_region_list_spec.rb +65 -0
  32. data/spec/google_region_quotas_spec.rb +108 -0
  33. data/spec/google_server_create_spec.rb +177 -0
  34. data/spec/google_server_delete_spec.rb +39 -0
  35. data/spec/google_server_list_spec.rb +77 -0
  36. data/spec/google_server_show_spec.rb +60 -0
  37. data/spec/google_zone_list_spec.rb +59 -0
  38. metadata +91 -114
  39. data/CONTRIB.md +0 -64
  40. data/lib/chef/knife/google_base.rb +0 -76
  41. data/lib/chef/knife/google_project_list.rb +0 -178
  42. data/lib/chef/knife/google_setup.rb +0 -31
  43. data/lib/google/compute.rb +0 -47
  44. data/lib/google/compute/client.rb +0 -216
  45. data/lib/google/compute/config.rb +0 -23
  46. data/lib/google/compute/creatable_resource_collection.rb +0 -55
  47. data/lib/google/compute/deletable_resource_collection.rb +0 -51
  48. data/lib/google/compute/disk.rb +0 -38
  49. data/lib/google/compute/exception.rb +0 -30
  50. data/lib/google/compute/firewall.rb +0 -65
  51. data/lib/google/compute/global_operation.rb +0 -60
  52. data/lib/google/compute/image.rb +0 -29
  53. data/lib/google/compute/listable_resource_collection.rb +0 -33
  54. data/lib/google/compute/machine_type.rb +0 -36
  55. data/lib/google/compute/mixins/utils.rb +0 -58
  56. data/lib/google/compute/network.rb +0 -29
  57. data/lib/google/compute/project.rb +0 -76
  58. data/lib/google/compute/region.rb +0 -31
  59. data/lib/google/compute/region_operation.rb +0 -62
  60. data/lib/google/compute/resource.rb +0 -81
  61. data/lib/google/compute/resource_collection.rb +0 -78
  62. data/lib/google/compute/server.rb +0 -88
  63. data/lib/google/compute/server/attached_disk.rb +0 -39
  64. data/lib/google/compute/server/network_interface.rb +0 -38
  65. data/lib/google/compute/server/network_interface/access_config.rb +0 -35
  66. data/lib/google/compute/server/serial_port_output.rb +0 -31
  67. data/lib/google/compute/snapshot.rb +0 -30
  68. data/lib/google/compute/version.rb +0 -19
  69. data/lib/google/compute/zone.rb +0 -34
  70. data/lib/google/compute/zone_operation.rb +0 -62
  71. data/spec/chef/knife/google_base_spec.rb +0 -46
  72. data/spec/chef/knife/google_disk_create_spec.rb +0 -37
  73. data/spec/chef/knife/google_disk_delete_spec.rb +0 -64
  74. data/spec/chef/knife/google_disk_list_spec.rb +0 -36
  75. data/spec/chef/knife/google_region_list_spec.rb +0 -32
  76. data/spec/chef/knife/google_server_create_spec.rb +0 -138
  77. data/spec/chef/knife/google_server_delete_spec.rb +0 -127
  78. data/spec/chef/knife/google_server_list_spec.rb +0 -39
  79. data/spec/chef/knife/google_setup_spec.rb +0 -24
  80. data/spec/chef/knife/google_zone_list_spec.rb +0 -32
  81. data/spec/data/client.json +0 -14
  82. data/spec/data/compute-v1.json +0 -6734
  83. data/spec/data/disk.json +0 -14
  84. data/spec/data/firewall.json +0 -13
  85. data/spec/data/global_operation.json +0 -36
  86. data/spec/data/image.json +0 -12
  87. data/spec/data/machine_type.json +0 -24
  88. data/spec/data/network.json +0 -10
  89. data/spec/data/project.json +0 -21
  90. data/spec/data/region.json +0 -23
  91. data/spec/data/serial_port_output.json +0 -5
  92. data/spec/data/server.json +0 -46
  93. data/spec/data/snapshot.json +0 -12
  94. data/spec/data/zone.json +0 -22
  95. data/spec/data/zone_operation.json +0 -36
  96. data/spec/google/compute/disk_spec.rb +0 -115
  97. data/spec/google/compute/firewall_spec.rb +0 -129
  98. data/spec/google/compute/global_operation_spec.rb +0 -62
  99. data/spec/google/compute/image_spec.rb +0 -75
  100. data/spec/google/compute/machine_type_spec.rb +0 -53
  101. data/spec/google/compute/network_spec.rb +0 -68
  102. data/spec/google/compute/project_spec.rb +0 -71
  103. data/spec/google/compute/region_spec.rb +0 -51
  104. data/spec/google/compute/server_spec.rb +0 -118
  105. data/spec/google/compute/snapshot_spec.rb +0 -57
  106. data/spec/google/compute/zone_operation_spec.rb +0 -62
  107. data/spec/google/compute/zone_spec.rb +0 -51
  108. data/spec/spec_helper.rb +0 -45
  109. data/spec/support/mocks.rb +0 -62
  110. data/spec/support/resource_examples.rb +0 -70
  111. data/spec/support/spec_google_base.rb +0 -60
data/CONTRIB.md DELETED
@@ -1,64 +0,0 @@
1
- # How to become a contributor and submit your own code
2
-
3
- ## Contributor License Agreements
4
-
5
- We'd love to accept your sample apps and patches! Before we can take them, we
6
- have to jump a couple of legal hurdles.
7
-
8
- Please fill out either the individual or corporate Contributor License Agreement
9
- (CLA).
10
-
11
- * If you are an individual writing original source code and you're sure you
12
- own the intellectual property, then you'll need to sign an [individual CLA]
13
- (http://code.google.com/legal/individual-cla-v1.0.html).
14
- * If you work for a company that wants to allow you to contribute your work,
15
- then you'll need to sign a [corporate CLA]
16
- (http://code.google.com/legal/corporate-cla-v1.0.html).
17
-
18
- Follow either of the two links above to access the appropriate CLA and
19
- instructions for how to sign and return it. Once we receive it, we'll be able to
20
- accept your pull requests.
21
-
22
- ## Contributing A Patch
23
-
24
- 1. Submit an issue describing your proposed change to the repo in question.
25
- 1. The repo owner will respond to your issue promptly.
26
- 1. If your proposed change is accepted, and you haven't already done so, sign a
27
- Contributor License Agreement (see details above).
28
- 1. Fork the desired repo, develop and test your code changes.
29
- 1. Ensure that your code adheres to the existing style in the sample to which
30
- you are contributing. Refer to the
31
- [Google Cloud Platform Samples Style Guide]
32
- (https://github.com/GoogleCloudPlatform/Template/wiki/style.html) for the
33
- recommended coding standards for this organization.
34
- 1. Ensure that your code has an appropriate set of unit tests which all pass.
35
- 1. Submit a pull request.
36
-
37
- ## Contributing A New Sample App
38
-
39
- 1. Submit an issue to the GoogleCloudPlatform/Template repo describing your
40
- proposed sample app.
41
- 1. The Template repo owner will respond to your enhancement issue promptly.
42
- Instructional value is the top priority when evaluating new app proposals for
43
- this collection of repos.
44
- 1. If your proposal is accepted, and you haven't already done so, sign a
45
- Contributor License Agreement (see details above).
46
- 1. Create your own repo for your app following this naming convention:
47
- * {product}-{app-name}-{language}
48
- * products: appengine, compute, storage, bigquery, prediction, cloudsql
49
- * example: appengine-guestbook-python
50
- * For multi-product apps, concatenate the primary products, like this:
51
- compute-appengine-demo-suite-python.
52
- * For multi-language apps, concatenate the primary languages like this:
53
- appengine-sockets-python-java-go.
54
-
55
- 1. Clone the README.md, CONTRIB.md and LICENSE files from the
56
- GoogleCloudPlatform/Template repo.
57
- 1. Ensure that your code adheres to the existing style in the sample to which
58
- you are contributing. Refer to the
59
- [Google Cloud Platform Samples Style Guide]
60
- (https://github.com/GoogleCloudPlatform/Template/wiki/style.html) for the
61
- recommended coding standards for this organization.
62
- 1. Ensure that your code has an appropriate set of unit tests which all pass.
63
- 1. Submit a request to fork your repo in GoogleCloudPlatform organizationt via
64
- your proposal issue.
@@ -1,76 +0,0 @@
1
- # Copyright 2013 Google Inc. All Rights Reserved.
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 'chef/knife'
16
- require 'google/compute'
17
-
18
- class Chef
19
- class Knife
20
- module GoogleBase
21
-
22
- # hack for mixlib-cli workaround
23
- # https://github.com/opscode/knife-ec2/blob/master/lib/chef/knife/ec2_base.rb
24
- def self.included(includer)
25
- includer.class_eval do
26
- deps do
27
- require 'google/compute'
28
- require 'chef/json_compat'
29
- end
30
-
31
- option :compute_credential_file,
32
- :short => "-f CREDENTIAL_FILE",
33
- :long => "--gce-credential-file CREDENTIAL_FILE",
34
- :description => "Google Compute credential file (google setup can create this)"
35
- end
36
- end
37
-
38
- def client
39
- @client ||= begin
40
- Google::Compute::Client.from_json(config[:compute_credential_file])
41
- end
42
- end
43
-
44
- def selflink2name(selflink)
45
- selflink.to_s == '' ? selflink.to_s : selflink.split('/').last
46
- end
47
-
48
- def msg_pair(label, value, color=:cyan)
49
- if value && !value.to_s.empty?
50
- ui.info("#{ui.color(label, color)}: #{value}")
51
- end
52
- end
53
-
54
- def disks(instance)
55
- instance.disks.collect{|d|d.device_name}.compact
56
- end
57
-
58
- def private_ips(instance)
59
- instance.network_interfaces.collect{|ni|ni.network_ip}.compact
60
- end
61
-
62
- def public_ips(instance)
63
- instance.network_interfaces.collect{|ni|
64
- ni.access_configs.map{|ac|
65
- ac.nat_ip
66
- }
67
- }.flatten.compact
68
- end
69
-
70
- def locate_config_value(key)
71
- key = key.to_sym
72
- config[key] || Chef::Config[:knife][key]
73
- end
74
- end
75
- end
76
- end
@@ -1,178 +0,0 @@
1
- # Copyright 2013 Google Inc. All Rights Reserved.
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 'chef/knife/google_base'
16
- require 'time'
17
-
18
- class Chef
19
- class Knife
20
- class GoogleProjectList < Knife
21
-
22
- include Knife::GoogleBase
23
-
24
- banner "knife google project list (options)"
25
-
26
- option :limits,
27
- :short => "-L",
28
- :long => "--with-limits",
29
- :description => "Additionally print the quota limit for each metric",
30
- :required => false,
31
- :boolean => true,
32
- :default => false
33
-
34
- def run
35
- $stdout.sync = true
36
-
37
- project_list = [
38
- ui.color("name", :bold),
39
- ui.color('snapshots', :bold),
40
- ui.color('networks', :bold),
41
- ui.color('firewalls', :bold),
42
- ui.color('images', :bold),
43
- ui.color('routes', :bold),
44
- ui.color('forwarding-rules', :bold),
45
- ui.color('target-pools', :bold),
46
- ui.color('health-checks', :bold)].flatten.compact
47
-
48
- output_column_count = project_list.length
49
-
50
- project = client.projects.project
51
-
52
- project_list << project
53
-
54
- snapshots_usage = "0"
55
- snapshots_limit = "0"
56
- client.projects.get(project).quotas.each do |quota|
57
- if quota["metric"] == "SNAPSHOTS"
58
- snapshots_usage = "#{quota["usage"].to_i}"
59
- snapshots_limit = "#{quota["limit"].to_i}"
60
- end
61
- end
62
- if config[:limits] == true
63
- snapshots_quota = "#{snapshots_usage}/#{snapshots_limit}"
64
- else
65
- snapshots_quota = "#{snapshots_usage}"
66
- end
67
- project_list << snapshots_quota
68
-
69
- networks_usage = "0"
70
- networks_limit = "0"
71
- client.projects.get(project).quotas.each do |quota|
72
- if quota["metric"] == "NETWORKS"
73
- networks_usage = "#{quota["usage"].to_i}"
74
- networks_limit = "#{quota["limit"].to_i}"
75
- end
76
- end
77
- if config[:limits] == true
78
- networks_quota = "#{networks_usage}/#{networks_limit}"
79
- else
80
- networks_quota = "#{networks_usage}"
81
- end
82
- project_list << networks_quota
83
-
84
- firewalls_usage = "0"
85
- firewalls_limit = "0"
86
- client.projects.get(project).quotas.each do |quota|
87
- if quota["metric"] == "FIREWALLS"
88
- firewalls_usage = "#{quota["usage"].to_i}"
89
- firewalls_limit = "#{quota["limit"].to_i}"
90
- end
91
- end
92
- if config[:limits] == true
93
- firewalls_quota = "#{firewalls_usage}/#{firewalls_limit}"
94
- else
95
- firewalls_quota = "#{firewalls_usage}"
96
- end
97
- project_list << firewalls_quota
98
-
99
- images_usage = "0"
100
- images_limit = "0"
101
- client.projects.get(project).quotas.each do |quota|
102
- if quota["metric"] == "IMAGES"
103
- images_usage = "#{quota["usage"].to_i}"
104
- images_limit = "#{quota["limit"].to_i}"
105
- end
106
- end
107
- if config[:limits] == true
108
- images_quota = "#{images_usage}/#{images_limit}"
109
- else
110
- images_quota = "#{images_usage}"
111
- end
112
- project_list << images_quota
113
-
114
- routes_usage = "0"
115
- routes_limit = "0"
116
- client.projects.get(project).quotas.each do |quota|
117
- if quota["metric"] == "ROUTES"
118
- routes_usage = "#{quota["usage"].to_i}"
119
- routes_limit = "#{quota["limit"].to_i}"
120
- end
121
- end
122
- if config[:limits] == true
123
- routes_quota = "#{routes_usage}/#{routes_limit}"
124
- else
125
- routes_quota = "#{routes_usage}"
126
- end
127
- project_list << routes_quota
128
-
129
- forwarding_usage = "0"
130
- forwarding_limit = "0"
131
- client.projects.get(project).quotas.each do |quota|
132
- if quota["metric"] == "FORWARDING_RULES"
133
- forwarding_usage = "#{quota["usage"].to_i}"
134
- forwarding_limit = "#{quota["limit"].to_i}"
135
- end
136
- end
137
- if config[:limits] == true
138
- forwarding_quota = "#{forwarding_usage}/#{forwarding_limit}"
139
- else
140
- forwarding_quota = "#{forwarding_usage}"
141
- end
142
- project_list << forwarding_quota
143
-
144
- target_usage = "0"
145
- target_limit = "0"
146
- client.projects.get(project).quotas.each do |quota|
147
- if quota["metric"] == "TARGET_POOLS"
148
- target_usage = "#{quota["usage"].to_i}"
149
- target_limit = "#{quota["limit"].to_i}"
150
- end
151
- end
152
- if config[:limits] == true
153
- target_quota = "#{target_usage}/#{target_limit}"
154
- else
155
- target_quota = "#{target_usage}"
156
- end
157
- project_list << target_quota
158
-
159
- health_usage = "0"
160
- health_limit = "0"
161
- client.projects.get(project).quotas.each do |quota|
162
- if quota["metric"] == "HEALTH_CHECKS"
163
- health_usage = "#{quota["usage"].to_i}"
164
- health_limit = "#{quota["limit"].to_i}"
165
- end
166
- end
167
- if config[:limits] == true
168
- health_quota = "#{health_usage}/#{health_limit}"
169
- else
170
- health_quota = "#{health_usage}"
171
- end
172
- project_list << health_quota
173
-
174
- ui.info(ui.list(project_list, :uneven_columns_across, output_column_count))
175
- end
176
- end
177
- end
178
- end
@@ -1,31 +0,0 @@
1
- # Copyright 2013 Google Inc. All Rights Reserved.
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 'chef/knife/google_base'
16
-
17
- class Chef
18
- class Knife
19
- class GoogleSetup < Knife
20
-
21
- include Knife::GoogleBase
22
-
23
- banner "knife google setup"
24
-
25
- def run
26
- Google::Compute::Client.setup
27
- end
28
- end
29
- end
30
- end
31
-
@@ -1,47 +0,0 @@
1
- # Copyright 2013 Google Inc. All Rights Reserved.
2
- #
3
- # Copyright 2013 Google Inc.
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 autoload :d 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
- module Google
18
- module Compute
19
- end
20
- end
21
-
22
- require 'google/compute/version'
23
- require 'google/compute/config'
24
- require 'google/compute/resource_collection'
25
- require 'google/compute/listable_resource_collection'
26
- require 'google/compute/deletable_resource_collection'
27
- require 'google/compute/creatable_resource_collection'
28
- require 'google/compute/resource'
29
- require 'google/compute/client'
30
- require 'google/compute/exception'
31
- require 'google/compute/disk'
32
- require 'google/compute/firewall'
33
- require 'google/compute/image'
34
- require 'google/compute/server'
35
- require 'google/compute/machine_type'
36
- require 'google/compute/network'
37
- require 'google/compute/project'
38
- require 'google/compute/snapshot'
39
- require 'google/compute/region'
40
- require 'google/compute/zone'
41
- require 'google/compute/global_operation'
42
- require 'google/compute/region_operation'
43
- require 'google/compute/zone_operation'
44
- require 'google/compute/server/attached_disk'
45
- require 'google/compute/server/network_interface'
46
- require 'google/compute/server/serial_port_output'
47
- require 'google/compute/server/network_interface/access_config'
@@ -1,216 +0,0 @@
1
- # Copyright 2013 Google Inc. All Rights Reserved.
2
- #
3
- # Copyright 2013 Google Inc.
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 'google/api_client'
18
- require 'multi_json'
19
- require 'google/compute/resource_collection'
20
- require 'knife-google/version'
21
-
22
- module Google
23
- module Compute
24
- class Client
25
-
26
- DEFAULT_FILE = '~/.google-compute.json'
27
-
28
- attr_reader :dispatcher
29
-
30
- def initialize(authorization, project, credential_file)
31
- api_client = Google::APIClient.new(:application_name => 'knife-google', :application_version => Knife::Google::VERSION)
32
- api_client.authorization = authorization
33
- api_client.auto_refresh_token = true
34
- @project = project
35
- if !credential_file
36
- @credential_file = File.expand_path(DEFAULT_FILE)
37
- else
38
- @credential_file = File.expand_path(credential_file)
39
- end
40
- @dispatcher = APIDispatcher.new(:project=>project, :api_client=>api_client, :credential_file=>@credential_file)
41
- end
42
-
43
- def self.from_json(filename = nil)
44
- filename ||= File.expand_path(DEFAULT_FILE)
45
- begin
46
- credential_data = MultiJson.load(File.read(filename))
47
- rescue
48
- $stdout.print "Error reading CREDENTIAL_FILE, please run 'knife google setup'\n"
49
- exit 1
50
- end
51
- authorization = Signet::OAuth2::Client.new(credential_data)
52
- self.new(authorization, credential_data['project'], filename)
53
- end
54
-
55
- def self.setup
56
- credential_file ||= File.expand_path(DEFAULT_FILE)
57
- $stdout.print "Enter Project ID (ex: my-gce-project): "
58
- project = $stdin.gets.chomp
59
- $stdout.print "Enter Client ID (ex: 123abc4.apps.googleusercontent.com): "
60
- client_id = $stdin.gets.chomp
61
- $stdout.print "Enter Client secret: "
62
- client_secret = $stdin.gets.chomp
63
- authorization_uri = "https://accounts.google.com/o/oauth2/auth"
64
- token_credential_uri ="https://accounts.google.com/o/oauth2/token"
65
- scope = ["https://www.googleapis.com/auth/compute",
66
- "https://www.googleapis.com/auth/compute.readonly",
67
- "https://www.googleapis.com/auth/devstorage.full_control",
68
- "https://www.googleapis.com/auth/devstorage.read_only",
69
- "https://www.googleapis.com/auth/devstorage.read_write",
70
- "https://www.googleapis.com/auth/devstorage.write_only",
71
- "https://www.googleapis.com/auth/userinfo.email"]
72
- redirect_uri = 'urn:ietf:wg:oauth:2.0:oob'
73
-
74
- api_client = Google::APIClient.new(:application_name => 'knife-google', :application_version => Knife::Google::VERSION)
75
-
76
- api_client.authorization.scope = scope
77
- api_client.authorization.client_id = client_id
78
- api_client.authorization.client_secret = client_secret
79
- api_client.authorization.redirect_uri = redirect_uri
80
- $stdout.puts "Copy and paste the following url in your brower and allow access. Enter the resulting authorization code below.\n\n"
81
- $stdout.puts api_client.authorization.authorization_uri
82
- $stdout.print "\n\nAuthorization code: "
83
- authorization_code = $stdin.gets.chomp
84
- api_client.authorization.code = authorization_code
85
-
86
- begin
87
- api_client.authorization.fetch_access_token!
88
- rescue Faraday::Error::ConnectionFailed => e
89
- raise ConnectionFail,
90
- "The SSL certificates validation may not configured for this system. Please refer README to configured SSL certificates validation"
91
- end
92
- save_credentials(project, api_client, credential_file)
93
- end
94
-
95
- def self.save_credentials(project, api_client, credential_file)
96
- scope = api_client.authorization.scope
97
- client_id = api_client.authorization.client_id
98
- client_secret = api_client.authorization.client_secret
99
- redirect_uri = api_client.authorization.redirect_uri
100
- authorization_uri = "https://accounts.google.com/o/oauth2/auth"
101
- access_token = api_client.authorization.access_token
102
- refresh_token = api_client.authorization.refresh_token
103
- id_token = api_client.authorization.id_token
104
- expires_in = api_client.authorization.expires_in
105
- issued_at = api_client.authorization.issued_at.to_s
106
-
107
- File.open(credential_file,'w+') do |f|
108
- f.write(MultiJson.dump({"authorization_uri" => authorization_uri,
109
- "token_credential_uri"=>"https://accounts.google.com/o/oauth2/token",
110
- "scope"=>scope,"redirect_uri"=>redirect_uri, "client_id"=>client_id,
111
- "client_secret"=>client_secret, "access_token"=>access_token,
112
- "expires_in"=>expires_in,"refresh_token"=> refresh_token, "id_token"=>id_token,
113
- "issued_at"=>issued_at,"project"=>project }, :pretty=>true))
114
- end
115
- end
116
-
117
- def projects
118
- ResourceCollection.new(:resource_class => Google::Compute::Project, :dispatcher => @dispatcher)
119
- end
120
-
121
- def disks
122
- CreatableResourceCollection.new(:resource_class => Google::Compute::Disk, :dispatcher=>@dispatcher)
123
- end
124
-
125
- def firewalls
126
- CreatableResourceCollection.new(:resource_class => Google::Compute::Firewall, :dispatcher => @dispatcher)
127
- end
128
-
129
- def images
130
- CreatableResourceCollection.new(:resource_class => Google::Compute::Image, :dispatcher => @dispatcher)
131
- end
132
-
133
- def instances
134
- CreatableResourceCollection.new(:resource_class => Google::Compute::Server, :dispatcher=>@dispatcher)
135
- end
136
-
137
- def machine_types
138
- ListableResourceCollection.new(:resource_class => Google::Compute::MachineType,:dispatcher=>@dispatcher)
139
- end
140
-
141
- def networks
142
- CreatableResourceCollection.new(:resource_class => Google::Compute::Network, :dispatcher=>@dispatcher)
143
- end
144
-
145
- def globalOperations
146
- DeletableResourceCollection.new(:resource_class => Google::Compute::GlobalOperation, :dispatcher=>@dispatcher)
147
- end
148
-
149
- def regionOperations
150
- DeletableResourceCollection.new(:resource_class => Google::Compute::RegionOperation, :dispatcher=>@dispatcher)
151
- end
152
-
153
- def zoneOperations
154
- DeletableResourceCollection.new(:resource_class => Google::Compute::ZoneOperation, :dispatcher=>@dispatcher)
155
- end
156
-
157
- def regions
158
- ListableResourceCollection.new(:resource_class => Google::Compute::Region, :dispatcher=>@dispatcher)
159
- end
160
-
161
- def zones
162
- ListableResourceCollection.new(:resource_class => Google::Compute::Zone, :dispatcher=>@dispatcher)
163
- end
164
-
165
- def snapshots
166
- CreatableResourceCollection.new(:resource_class => Google::Compute::Snapshot, :dispatcher=>@dispatcher)
167
- end
168
-
169
- class APIDispatcher
170
- attr_reader :project, :api_client, :credential_file
171
-
172
- def initialize(opts)
173
- @project= opts[:project]
174
- @api_client = opts[:api_client]
175
- @credential_file = opts[:credential_file]
176
- end
177
-
178
- def compute
179
- @compute ||= @api_client.discovered_api('compute','v1')
180
- end
181
-
182
- def dispatch(opts)
183
- begin
184
- unless opts[:parameters].has_key?(:project)
185
- opts[:parameters].merge!( :project => @project )
186
- end
187
- result = @api_client.execute(:api_method=>opts[:api_method],
188
- :parameters=>opts[:parameters],
189
- :body_object => opts[:body_object]
190
- )
191
- unless result.success?
192
- response = MultiJson.load(result.response.body)
193
- error_code = response["error"]["code"]
194
- if error_code == 404
195
- raise ResourceNotFound, result.response.body
196
- elsif error_code == 400
197
- raise BadRequest, result.response.body
198
- elsif error_code == 401
199
- # ok, our credentials aren't working, we need
200
- # to get a new refresh token and retry
201
- @api_client.authorization.fetch_access_token!
202
- Client.save_credentials(@project, @api_client, @credential_file)
203
- return dispatch(opts)
204
- else
205
- raise BadRequest, result.response.body
206
- end
207
- end
208
- return MultiJson.load(result.response.body) unless result.response.body.nil?
209
- rescue ArgumentError => e
210
- raise ParameterValidation, e.message
211
- end
212
- end
213
- end
214
- end
215
- end
216
- end