gapic-generator-cloud 0.3.1

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 (40) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +81 -0
  3. data/CONTRIBUTING.md +28 -0
  4. data/LICENSE +202 -0
  5. data/README.md +84 -0
  6. data/bin/protoc-gen-ruby_cloud +33 -0
  7. data/bin/ruby-cloud-docker-entrypoint +103 -0
  8. data/cloud-rubocop.yml +14 -0
  9. data/lib/gapic/generator/cloud/version.rb +23 -0
  10. data/lib/gapic/generators/cloud_generator.rb +119 -0
  11. data/lib/gapic/presenters/wrapper_gem_presenter.rb +123 -0
  12. data/lib/gapic/presenters/wrapper_service_presenter.rb +49 -0
  13. data/templates/cloud/gem/authentication.erb +172 -0
  14. data/templates/cloud/gem/gemspec.erb +38 -0
  15. data/templates/cloud/gem/gitignore.erb +23 -0
  16. data/templates/cloud/gem/license.erb +204 -0
  17. data/templates/cloud/gem/rakefile.erb +156 -0
  18. data/templates/cloud/gem/readme.erb +93 -0
  19. data/templates/cloud/gem/repo-metadata.erb +6 -0
  20. data/templates/cloud/gem/rubocop.erb +36 -0
  21. data/templates/cloud/gem/yardopts.erb +13 -0
  22. data/templates/cloud/service/client/_credentials.erb +30 -0
  23. data/templates/cloud/service/client/_requires.erb +2 -0
  24. data/templates/cloud/service/client/_self_configure.erb +15 -0
  25. data/templates/cloud/service/client/method/def/_rescue.erb +3 -0
  26. data/templates/cloud/service/client/method/docs/_error.erb +2 -0
  27. data/templates/cloud/shared/_license.erb +13 -0
  28. data/templates/cloud/wrapper_gem/_main.erb +90 -0
  29. data/templates/cloud/wrapper_gem/client_test.erb +22 -0
  30. data/templates/cloud/wrapper_gem/entrypoint.erb +4 -0
  31. data/templates/cloud/wrapper_gem/gemfile.erb +17 -0
  32. data/templates/cloud/wrapper_gem/gemspec.erb +40 -0
  33. data/templates/cloud/wrapper_gem/main.erb +5 -0
  34. data/templates/cloud/wrapper_gem/rakefile.erb +190 -0
  35. data/templates/cloud/wrapper_gem/readme.erb +95 -0
  36. data/templates/cloud/wrapper_gem/rubocop.erb +23 -0
  37. data/templates/cloud/wrapper_gem/test_helper.erb +9 -0
  38. data/templates/cloud/wrapper_gem/version_test.erb +11 -0
  39. data/templates/cloud/wrapper_gem/yardopts.erb +15 -0
  40. metadata +227 -0
@@ -0,0 +1,14 @@
1
+ # This file is to be used as the config for formatting the generated cloud files.
2
+ # We can't reference the generated .rubocop.yml file because Rubocop is so clevar
3
+ # that it won't find the google-style gem unless the file is referenced here.
4
+ inherit_gem:
5
+ google-style: google-style.yml
6
+
7
+ AllCops:
8
+ Exclude:
9
+ - "acceptance/**/*"
10
+ - "*.gemspec"
11
+ - "lib/**/*_pb.rb"
12
+ - "Rakefile"
13
+ - "support/**/*"
14
+ - "test/**/*"
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2018 Google LLC
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
+ # https://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
+ module Gapic
18
+ module Generator
19
+ module Cloud
20
+ VERSION = "0.3.1"
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,119 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2018 Google LLC
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
+ # https://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 "gapic/generators/default_generator"
18
+ require "gapic/presenters"
19
+ require "gapic/presenters/wrapper_gem_presenter"
20
+
21
+ module Gapic
22
+ module Generators
23
+ # The generator orchestrates the rendering of templates for Google Cloud
24
+ # projects.
25
+ class CloudGenerator < DefaultGenerator
26
+ # Initializes the generator.
27
+ #
28
+ # @param api [Gapic::Schema::Api] The API model/context to
29
+ # generate.
30
+ def initialize api
31
+ gem_config = api.configuration[:gem] ||= {}
32
+ gem_config[:homepage] ||= "https://github.com/googleapis/google-cloud-ruby"
33
+
34
+ super
35
+
36
+ # Configure to use prefer Google Cloud templates
37
+ use_templates! File.join __dir__, "../../../templates/cloud"
38
+ end
39
+
40
+ # Generates all the files for the API.
41
+ #
42
+ # @return [Array<
43
+ # Google::Protobuf::Compiler::CodeGeneratorResponse::File>]
44
+ # The files that were generated for the API.
45
+ def generate
46
+ gem_config = @api.configuration[:gem] ||= {}
47
+ return generate_wrapper if gem_config[:version_dependencies]
48
+
49
+ orig_files = super
50
+
51
+ cloud_files = []
52
+
53
+ gem = Gapic::Presenters.gem_presenter @api
54
+
55
+ # Additional Gem level files
56
+ cloud_files << g("gem/repo-metadata.erb", ".repo-metadata.json", gem: gem)
57
+ cloud_files << g("gem/authentication.erb", "AUTHENTICATION.md", gem: gem) unless gem.services.empty?
58
+
59
+ format_files cloud_files
60
+
61
+ orig_files + cloud_files
62
+ end
63
+
64
+ # Disable Rubocop because we expect generate to grow and violate more
65
+ # and more style rules.
66
+ # rubocop:disable all
67
+
68
+ # Generates the files for a wrapper.
69
+ #
70
+ # @return [Array<Google::Protobuf::Compiler::CodeGeneratorResponse::File>]
71
+ # The files that were generated for the API.
72
+ #
73
+ def generate_wrapper
74
+ files = []
75
+
76
+ gem = Gapic::Presenters.wrapper_gem_presenter @api
77
+
78
+ files << g("gem/gitignore.erb", ".gitignore", gem: gem)
79
+ files << g("gem/repo-metadata.erb", ".repo-metadata.json", gem: gem)
80
+ files << g("wrapper_gem/rubocop.erb", ".rubocop.yml", gem: gem)
81
+ files << g("wrapper_gem/yardopts.erb", ".yardopts", gem: gem)
82
+ files << g("gem/authentication.erb", "AUTHENTICATION.md", gem: gem)
83
+ files << g("gem/changelog.erb", "CHANGELOG.md", gem: gem)
84
+ files << g("wrapper_gem/gemfile.erb", "Gemfile", gem: gem)
85
+ files << g("gem/license.erb", "LICENSE.md", gem: gem)
86
+ files << g("wrapper_gem/rakefile.erb", "Rakefile", gem: gem)
87
+ files << g("wrapper_gem/readme.erb", "README.md", gem: gem)
88
+ files << g("wrapper_gem/gemspec.erb", "#{gem.name}.gemspec", gem: gem)
89
+ files << g("wrapper_gem/entrypoint.erb", "lib/#{gem.name}.rb", gem: gem) if gem.needs_entrypoint?
90
+ files << g("wrapper_gem/main.erb", "lib/#{gem.namespace_file_path}", gem: gem)
91
+ files << g("gem/version.erb", "lib/#{gem.version_file_path}", gem: gem)
92
+ files << g("wrapper_gem/test_helper.erb", "test/helper.rb", gem: gem)
93
+ files << g("wrapper_gem/client_test.erb", "test/#{gem.namespace_require}/client_test.rb", gem: gem)
94
+ files << g("wrapper_gem/version_test.erb", "test/#{gem.namespace_require}/version_test.rb", gem: gem)
95
+
96
+ format_files files
97
+
98
+ files
99
+ end
100
+
101
+ # rubocop:enable all
102
+
103
+ private
104
+
105
+ ##
106
+ # Override the default rubocop config file to be used.
107
+ def format_config
108
+ @api.configuration[:format_config] ||
109
+ google_style_config
110
+ end
111
+
112
+ ##
113
+ # Path to the rubocop file for this project, which uses google-style
114
+ def google_style_config
115
+ File.expand_path File.join __dir__, "../../../cloud-rubocop.yml"
116
+ end
117
+ end
118
+ end
119
+ end
@@ -0,0 +1,123 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2019 Google LLC
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
+ # https://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 "gapic/presenters"
18
+ require "gapic/presenters/wrapper_service_presenter"
19
+
20
+ module Gapic
21
+ module Presenters
22
+ ##
23
+ # A presenter for wrapper gems.
24
+ #
25
+ class WrapperGemPresenter < GemPresenter
26
+ def entrypoint_require
27
+ namespace_require
28
+ end
29
+
30
+ def services
31
+ @services ||= begin
32
+ files = @api.generate_files
33
+ files.map(&:services).flatten.map { |s| WrapperServicePresenter.new @api, s }
34
+ end
35
+ end
36
+
37
+ def namespace_require
38
+ ruby_file_path @api, namespace
39
+ end
40
+
41
+ def namespace_file_path
42
+ "#{namespace_require}.rb"
43
+ end
44
+
45
+ def needs_entrypoint?
46
+ name != namespace_file_path
47
+ end
48
+
49
+ def needs_default_config_block?
50
+ needs_entrypoint? && !google_cloud_short_name.nil?
51
+ end
52
+
53
+ def migration_version
54
+ gem_config :migration_version
55
+ end
56
+
57
+ def pre_migration_version
58
+ m = /^(\d)+\./.match migration_version.to_s
59
+ return nil unless m
60
+ "#{m[1].to_i - 1}.x"
61
+ end
62
+
63
+ def migration?
64
+ migration_version ? true : false
65
+ end
66
+
67
+ def extra_files
68
+ files = ["README.md", "AUTHENTICATION.md", "LICENSE.md", ".yardopts"]
69
+ files << "MIGRATING.md" if migration?
70
+ files
71
+ end
72
+
73
+ def factory_method_suffix
74
+ gem_config(:factory_method_suffix).to_s
75
+ end
76
+
77
+ def version_dependencies
78
+ gem_config(:version_dependencies).to_s.split(";").map { |str| str.split ":" }
79
+ end
80
+
81
+ def gem_version_dependencies
82
+ version_dependencies.sort_by { |version, _requirement| version }
83
+ .map { |version, requirement| ["#{name}-#{version}", requirement] }
84
+ end
85
+
86
+ def versioned_gems
87
+ gem_version_dependencies.map { |name, _requirement| name }
88
+ end
89
+
90
+ def default_version
91
+ version_dependencies.first&.first
92
+ end
93
+
94
+ def google_cloud_short_name
95
+ m = /^google-cloud-(.*)$/.match name
96
+ return nil unless m
97
+ m[1].tr "-", "_"
98
+ end
99
+
100
+ def docs_link version: nil, class_name: nil, text: nil
101
+ gem_name = version ? "#{name}-#{version}" : name
102
+ base_url = "https://googleapis.dev/ruby/#{gem_name}/latest"
103
+ if class_name
104
+ path = namespace.gsub "::", "/"
105
+ path = "#{path}/#{version.capitalize}" if version
106
+ class_path = class_name.gsub "::", "/"
107
+ text ||= namespaced_class class_name, version: version
108
+ return "[#{text}](#{base_url}/#{path}/#{class_path}.html)"
109
+ end
110
+ "[#{text || name}](#{base_url})"
111
+ end
112
+
113
+ def namespaced_class name, version: nil
114
+ base = version ? "#{namespace}::#{version.capitalize}" : namespace
115
+ "#{base}::#{name}"
116
+ end
117
+ end
118
+
119
+ def self.wrapper_gem_presenter api
120
+ WrapperGemPresenter.new api
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright 2019 Google LLC
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
+ # https://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 "gapic/presenters"
18
+
19
+ module Gapic
20
+ module Presenters
21
+ ##
22
+ # A presenter for wrapper services.
23
+ #
24
+ class WrapperServicePresenter < ServicePresenter
25
+ def gem
26
+ WrapperGemPresenter.new @api
27
+ end
28
+
29
+ def factory_method_name
30
+ method_name = ActiveSupport::Inflector.underscore name
31
+ suffix = gem.factory_method_suffix
32
+ method_name = "#{method_name}#{suffix}" unless method_name.end_with? suffix
33
+ method_name
34
+ end
35
+
36
+ def create_client_call
37
+ "#{gem.namespace}.#{factory_method_name}"
38
+ end
39
+
40
+ def configure_client_call
41
+ "#{gem.namespace}.configure"
42
+ end
43
+
44
+ def credentials_class_xref
45
+ "`#{credentials_name_full}`"
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,172 @@
1
+ <%- assert_locals gem -%>
2
+ <%- service = gem.services.first -%>
3
+ <%- assert_locals service -%>
4
+ # Authentication
5
+
6
+ In general, the <%= gem.name %> library uses
7
+ [Service Account](https://cloud.google.com/iam/docs/creating-managing-service-accounts)
8
+ credentials to connect to Google Cloud services. When running within
9
+ [Google Cloud Platform environments](#google-cloud-platform-environments) the
10
+ credentials will be discovered automatically. When running on other
11
+ environments, the Service Account credentials can be specified by providing the
12
+ path to the
13
+ [JSON keyfile](https://cloud.google.com/iam/docs/managing-service-account-keys)
14
+ for the account (or the JSON itself) in
15
+ [environment variables](#environment-variables). Additionally, Cloud SDK
16
+ credentials can also be discovered automatically, but this is only recommended
17
+ during development.
18
+
19
+ ## Quickstart
20
+
21
+ 1. [Create a service account and credentials](#creating-a-service-account).
22
+ 2. Set the [environment variable](#environment-variables).
23
+
24
+ ```sh
25
+ export <%= gem.env_prefix %>_CREDENTIALS=path/to/keyfile.json
26
+ ```
27
+
28
+ 3. Initialize the client.
29
+
30
+ ```ruby
31
+ require "<%= gem.entrypoint_require %>"
32
+
33
+ client = <%= service.create_client_call %>
34
+ ```
35
+
36
+ ## Credential Lookup
37
+
38
+ The <%= gem.name %> library aims to make authentication
39
+ as simple as possible, and provides several mechanisms to configure your system
40
+ without requiring **Service Account Credentials** directly in code.
41
+
42
+ **Credentials** are discovered in the following order:
43
+
44
+ 1. Specify credentials in method arguments
45
+ 2. Specify credentials in configuration
46
+ 3. Discover credentials path in environment variables
47
+ 4. Discover credentials JSON in environment variables
48
+ 5. Discover credentials file in the Cloud SDK's path
49
+ 6. Discover GCP credentials
50
+
51
+ ### Google Cloud Platform environments
52
+
53
+ When running on Google Cloud Platform (GCP), including Google Compute Engine
54
+ (GCE), Google Kubernetes Engine (GKE), Google App Engine (GAE), Google Cloud
55
+ Functions (GCF) and Cloud Run, **Credentials** are discovered automatically.
56
+ Code should be written as if already authenticated.
57
+
58
+ ### Environment Variables
59
+
60
+ The **Credentials JSON** can be placed in environment variables instead of
61
+ declaring them directly in code. Each service has its own environment variable,
62
+ allowing for different service accounts to be used for different services. (See
63
+ the READMEs for the individual service gems for details.) The path to the
64
+ **Credentials JSON** file can be stored in the environment variable, or the
65
+ **Credentials JSON** itself can be stored for environments such as Docker
66
+ containers where writing files is difficult or not encouraged.
67
+
68
+ The environment variables that <%= gem.name %>
69
+ checks for credentials are configured on the service Credentials class (such as
70
+ <%= service.credentials_class_xref %>):
71
+
72
+ 1. `<%= gem.env_prefix %>_CREDENTIALS` - Path to JSON file, or JSON contents
73
+ 2. `<%= gem.env_prefix %>_KEYFILE` - Path to JSON file, or JSON contents
74
+ 3. `GOOGLE_CLOUD_CREDENTIALS` - Path to JSON file, or JSON contents
75
+ 4. `GOOGLE_CLOUD_KEYFILE` - Path to JSON file, or JSON contents
76
+ 5. `GOOGLE_APPLICATION_CREDENTIALS` - Path to JSON file
77
+
78
+ ```ruby
79
+ require "<%= gem.entrypoint_require %>"
80
+
81
+ ENV["<%= gem.env_prefix %>_CREDENTIALS"] = "path/to/keyfile.json"
82
+
83
+ client = <%= service.create_client_call %>
84
+ ```
85
+
86
+ ### Configuration
87
+
88
+ The **Credentials JSON** can be configured instead of placing them in
89
+ environment variables. Either on an individual client initialization:
90
+
91
+ ```ruby
92
+ require "<%= gem.entrypoint_require %>"
93
+
94
+ client = <%= service.create_client_call %> do |config|
95
+ config.credentials = "path/to/keyfile.json"
96
+ end
97
+ ```
98
+
99
+ Or configured globally for all clients:
100
+
101
+ ```ruby
102
+ require "<%= gem.entrypoint_require %>"
103
+
104
+ <%= service.configure_client_call %> do |config|
105
+ config.credentials = "path/to/keyfile.json"
106
+ end
107
+
108
+ client = <%= service.create_client_call %>
109
+ ```
110
+
111
+ ### Cloud SDK
112
+
113
+ This option allows for an easy way to authenticate during development. If
114
+ credentials are not provided in code or in environment variables, then Cloud SDK
115
+ credentials are discovered.
116
+
117
+ To configure your system for this, simply:
118
+
119
+ 1. [Download and install the Cloud SDK](https://cloud.google.com/sdk)
120
+ 2. Authenticate using OAuth 2.0 `$ gcloud auth login`
121
+ 3. Write code as if already authenticated.
122
+
123
+ **NOTE:** This is _not_ recommended for running in production. The Cloud SDK
124
+ *should* only be used during development.
125
+
126
+ [gce-how-to]: https://cloud.google.com/compute/docs/authentication#using
127
+ [dev-console]: https://console.cloud.google.com/project
128
+
129
+ [enable-apis]: https://raw.githubusercontent.com/GoogleCloudPlatform/gcloud-common/master/authentication/enable-apis.png
130
+
131
+ [create-new-service-account]: https://raw.githubusercontent.com/GoogleCloudPlatform/gcloud-common/master/authentication/create-new-service-account.png
132
+ [create-new-service-account-existing-keys]: https://raw.githubusercontent.com/GoogleCloudPlatform/gcloud-common/master/authentication/create-new-service-account-existing-keys.png
133
+ [reuse-service-account]: https://raw.githubusercontent.com/GoogleCloudPlatform/gcloud-common/master/authentication/reuse-service-account.png
134
+
135
+ ## Creating a Service Account
136
+
137
+ Google Cloud requires **Service Account Credentials** to
138
+ connect to the APIs. You will use the **JSON key file** to
139
+ connect to most services with <%= gem.name %>.
140
+
141
+ If you are not running this client within
142
+ [Google Cloud Platform environments](#google-cloud-platform-environments), you
143
+ need a Google Developers service account.
144
+
145
+ 1. Visit the [Google Developers Console][dev-console].
146
+ 2. Create a new project or click on an existing project.
147
+ 3. Activate the slide-out navigation tray and select **API Manager**. From
148
+ here, you will enable the APIs that your application requires.
149
+
150
+ ![Enable the APIs that your application requires][enable-apis]
151
+
152
+ *Note: You may need to enable billing in order to use these services.*
153
+
154
+ 4. Select **Credentials** from the side navigation.
155
+
156
+ You should see a screen like one of the following.
157
+
158
+ ![Create a new service account][create-new-service-account]
159
+
160
+ ![Create a new service account With Existing Keys][create-new-service-account-existing-keys]
161
+
162
+ Find the "Add credentials" drop down and select "Service account" to be
163
+ guided through downloading a new JSON key file.
164
+
165
+ If you want to re-use an existing service account, you can easily generate a
166
+ new key file. Just select the account you wish to re-use, and click "Generate
167
+ new JSON key":
168
+
169
+ ![Re-use an existing service account][reuse-service-account]
170
+
171
+ The key file you download will be used by this library to authenticate API
172
+ requests and should be stored in a secure location.