google-ssl-cert 0.1.0 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2b8d9e0628aac83d0eb66c15b5e2c711949e50ba2716f370151227c39065010e
4
- data.tar.gz: 4dd9a50a62e9a658c537306f5530cdeefb96253fd64cdd47bfd574cf995bb6d8
3
+ metadata.gz: 1f56ae3e966d0cd58eb597d8321e74ca8f5131a00c0b0de0fff8b230760b0546
4
+ data.tar.gz: '0987b6b7ddeb9ce1b9e3a6b7979c29d6e665e271be82db0da8181ea4377284fc'
5
5
  SHA512:
6
- metadata.gz: 3e081cf7944e0e37e2b58e2e4985c1374b58206ce50a54737bdec410c83f69d42c0a4049e7e0604cf8429c59962d11c2d09e1d8c4ddd0b5b6ca7202a83ff3005
7
- data.tar.gz: bf7c86b74c5eb758d319f817fc6a5b5c79a9297d6db77d78c79c3cc169c2e8fad8f0d52171b2c4bb013e4d65907b5a94fd04a72840bd7da3f5ada8f604cbe48e
6
+ metadata.gz: 30dc68bef1c6d6590d4e8b691a2eb41e1719f053d6696ced2a848d9270ab2cfc4e4c794dfb69b1050e97bba1f30f59f864f89a7da830698d6be2904d922126fb
7
+ data.tar.gz: 2b0f8963a89952e71501171484c7ecffed8cd22c252d9e9e22b426b5fda74dcda83e89eb3ba9ee9aeb931ced7750876922bb68a20569a174bbd388df38704c09
data/CHANGELOG.md CHANGED
@@ -3,5 +3,10 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  This project *loosely tries* to adhere to [Semantic Versioning](http://semver.org/), even before v1.0.
5
5
 
6
+ ## [0.2.0] - 2021-10-31
7
+ - [#1](https://github.com/boltops-tools/google-ssl-cert/pull/1) Cert name
8
+ - require cert name in interface, conventionally name secret instead
9
+ - validate google ssl cert name
10
+
6
11
  ## [0.1.0] - 2021-10-23
7
12
  - Initial release
data/README.md CHANGED
@@ -24,7 +24,7 @@ kind: Ingress
24
24
  metadata:
25
25
  name: web
26
26
  annotations:
27
- ingress.gcp.kubernetes.io/pre-shared-cert: '<%= google_secret("cert_demo", base64: false) %>'
27
+ ingress.gcp.kubernetes.io/pre-shared-cert: '<%= google_secret("cert-app1", base64: false) %>'
28
28
  spec:
29
29
  defaultBackend:
30
30
  service:
@@ -48,49 +48,39 @@ Make sure you have the cert files in your current folder:
48
48
  $ ls
49
49
  private.key certificate.crt
50
50
 
51
- When no cert name is provided, one will be generated for you:
51
+ Command synopsys.
52
52
 
53
- $ google-ssl-cert create --secret-name cert_demo
54
- Global cert created: google-ssl-cert-global-20211021155725
55
- Secret saved: name: cert_demo value: google-ssl-cert-global-20211021155725
53
+ $ google-ssl-cert create CERT_NAME
54
+
55
+ $ google-ssl-cert create cert-app1
56
+ Global cert created: cert-app1-global-20211021155725
57
+ Secret saved: name: cert-app1 value: cert-app1-global-20211021155725
58
+
59
+ The secret conventionally is the same as the cert name. You can override it with `--secret-name`.
56
60
 
57
61
  Check that cert and secret was created on google cloud:
58
62
 
59
63
  % gcloud compute ssl-certificates list
60
- NAME TYPE CREATION_TIMESTAMP EXPIRE_TIME MANAGED_STATUS
61
- google-ssl-cert-global-20211021155725 SELF_MANAGED 2021-10-21T08:57:26.005-07:00 2022-01-12T15:59:59.000-08:00
64
+ NAME TYPE CREATION_TIMESTAMP EXPIRE_TIME MANAGED_STATUS
65
+ cert-app1-global-20211021155725 SELF_MANAGED 2021-10-21T08:57:26.005-07:00 2022-01-12T15:59:59.000-08:00
62
66
  ~/environment/cert-files git:master aws:tung:us-west-2 gke:default
63
67
  %
64
- $ gcloud secrets versions access latest --secret cert_demo
65
- google-ssl-cert-global-20211021155725
68
+ $ gcloud secrets versions access latest --secret cert-app1
69
+ cert-app1-global-20211021155725
66
70
 
67
71
  ## Usage: Region Cert
68
72
 
69
73
  If you need to create a region cert instead, IE: for internal load balancers, specify the `--no-global` flag. Example:
70
74
 
71
- $ google-ssl-cert create --secret-name cert_demo --no-global
72
- Region cert created: google-ssl-cert-us-central1-20211021155852 in region: us-central1
73
- Secret saved: name: cert_demo value: google-ssl-cert-us-central1-20211021155852
75
+ $ google-ssl-cert create --cert-name cert-app1 --no-global
76
+ Region cert created: cert-app1-us-central1-20211021155852 in region: us-central1
77
+ Secret saved: name: cert-app1 value: cert-app1-us-central1-20211021155852
74
78
 
75
79
  Check that cert and secret was created on google cloud:
76
80
 
77
81
  $ gcloud compute ssl-certificates list
78
- NAME TYPE CREATION_TIMESTAMP EXPIRE_TIME MANAGED_STATUS
79
- google-ssl-cert-us-central1-20211021155852 SELF_MANAGED 2021-10-21T08:58:53.514-07:00 2022-01-12T15:59:59.000-08:00
80
-
81
- ## Usage: Specifying the Cert Name
82
-
83
- You can also specify the cert name:
84
-
85
- $ google-ssl-cert create --cert-name google-ssl-cert-v1 --no-timestamp --secret-name cert_demo
86
- Global cert created: google-ssl-cert-v1
87
- Secret saved: name: cert_demo value: google-ssl-cert-v1
88
-
89
- Check that cert was created on google cloud:
90
-
91
- $ gcloud compute ssl-certificates list
92
- NAME TYPE CREATION_TIMESTAMP EXPIRE_TIME MANAGED_STATUS
93
- google-ssl-cert-v1 SELF_MANAGED 2021-10-21T09:00:43.975-07:00 2022-01-12T15:59:59.000-08:00
82
+ NAME TYPE CREATION_TIMESTAMP EXPIRE_TIME MANAGED_STATUS
83
+ cert-app1-us-central1-20211021155852 SELF_MANAGED 2021-10-21T08:58:53.514-07:00 2022-01-12T15:59:59.000-08:00
94
84
 
95
85
  ## Required Env Vars
96
86
 
@@ -98,7 +88,8 @@ These env vars should be set:
98
88
 
99
89
  Name | Description
100
90
  --- | ---
101
- GOOGLE\_APPLICATION_CREDENTIALS | A service account as must be set up with `GOOGLE_APPLICATION_CREDENTIALS`. IE: `export GOOGLE_APPLICATION_CREDENTIALS=~/.gcp/credentials.json`
91
+ GOOGLE\_APPLICATION_CREDENTIALS or
92
+ GOOGLE_CREDENTIALS | A service account as must be set up. `GOOGLE_APPLICATION_CREDENTIALS` is set to the path of the file. `GOOGLE_CREDENTIALS` is set as the full json data structure. IE: `export GOOGLE_APPLICATION_CREDENTIALS=~/.gcp/credentials.json`
102
93
  GOOGLE_PROJECT | The env var `GOOGLE_PROJECT` and must be set.
103
94
  GOOGLE_REGION | The env var `GOOGLE_REGION` and must be set when creating a region-based google ssl cert. So when using the `--no-global` flag
104
95
 
@@ -138,7 +129,7 @@ You can also specify the path to the certificate and private key explicitly:
138
129
 
139
130
  To prune or delete old google ssl certs after rotating:
140
131
 
141
- google-ssl-cert prune
132
+ google-ssl-cert prune CERT_NAME
142
133
 
143
134
  ## Installation
144
135
 
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
9
9
  spec.authors = ["Tung Nguyen"]
10
10
  spec.email = ["tongueroo@gmail.com"]
11
11
  spec.summary = "Google SSL Cert Tool"
12
- spec.homepage = "https://github.com/boltopspro/google-ssl-cert"
12
+ spec.homepage = "https://github.com/boltops-tools/google-ssl-cert"
13
13
  spec.license = "Apache-2.0"
14
14
 
15
15
  spec.files = File.directory?('.git') ? `git ls-files`.split($/) : Dir.glob("**/*")
@@ -2,7 +2,8 @@ class GoogleSslCert::CLI
2
2
  class Create < Base
3
3
  def initialize(options={})
4
4
  super
5
- @cert_name = GoogleSslCert::Name.new(@options).generate
5
+ @cert_name = GoogleSslCert::Name.new(@options)
6
+ @secret_name = @options[:secret_name] || @cert_name.base_name
6
7
  end
7
8
 
8
9
  def run
@@ -14,7 +15,7 @@ class GoogleSslCert::CLI
14
15
  # Google API Docs:
15
16
  # https://cloud.google.com/compute/docs/reference/rest/v1/sslCertificates/insert
16
17
  def create_cert
17
- GoogleSslCert::Cert.new(@options.merge(cert_name: @cert_name)).create
18
+ GoogleSslCert::Cert.new(@options.merge(cert_name: @cert_name.generated_name)).create
18
19
  end
19
20
 
20
21
  # The secret name is expected to be static/predictable
@@ -32,9 +33,8 @@ class GoogleSslCert::CLI
32
33
  # demo_ssl-cert-name 2021-10-13T23:10:06 automatic
33
34
  #
34
35
  def save_secret
35
- secret_name = @options[:secret_name]
36
- secret_value = @cert_name # @cert_name the value because it will be referenced. the @cert_name or 'key' will be the same
37
- secret.save(secret_name, secret_value)
36
+ secret_value = @cert_name.generated_name # @cert_name the value because it will be referenced. the @cert_name or 'key' will be the same
37
+ secret.save(@secret_name, secret_value)
38
38
  end
39
39
 
40
40
  def secret
@@ -54,14 +54,17 @@ class GoogleSslCert::CLI
54
54
  if !ENV['GOOGLE_REGION'] and !global?
55
55
  errors << "ERROR: The GOOGLE_REGION env var must be when creating a region cert."
56
56
  end
57
+
58
+ # extra validation early to prevent google ssl cert name error
59
+ # An error has occurred when making a REST request: Invalid value for field 'resource.name': 'cert_app1-global-20211031234501'. Must be a match of regex '(?:[a-z](?:[-a-z0-9]{0,61}[a-z0-9])?)' (Google::Cloud::InvalidArgumentError)
60
+ if @secret_name !~ /^[a-zA-Z\-0-9]+$/ # no underscore allowed
61
+ errors << "ERROR: CERT_NAME invalid format. Expected format: [a-zA-Z0-9]+" # Expected format taken from `gcloud secrets create`
62
+ end
63
+
57
64
  unless errors.empty?
58
65
  logger.error errors.join("\n")
59
66
  exit 1
60
67
  end
61
-
62
- # Call here so validation happens at the beginning with the rest of validation
63
- # want command to exit early and not even create a google ssl cert
64
- secret.validate!
65
68
  end
66
69
  end
67
70
  end
@@ -8,7 +8,15 @@ class GoogleSslCert::CLI
8
8
  certs = ssl_certs[0..right] || [] # delete all except the last cert
9
9
 
10
10
  if certs.empty?
11
- logger.info "No timestamped certs to prune with cert name: #{cert_base_name}"
11
+ unless ssl_certs.empty?
12
+ logger.info "Found certs:"
13
+ ssl_certs.each do |cert|
14
+ logger.info " #{cert.name}"
15
+ end
16
+ end
17
+ cert_word = keep > 1 ? "certs" : "cert"
18
+ logger.info "Keeping #{keep} #{cert_word}."
19
+ logger.info "No certs to prune with base cert name: #{cert_base_name}"
12
20
  return
13
21
  end
14
22
 
@@ -9,11 +9,11 @@ module GoogleSslCert
9
9
  global_option = Proc.new do
10
10
  option :global, type: :boolean, default: true, desc: "Flag to create global vs region cert"
11
11
  end
12
- cert_name_option = Proc.new do
13
- option :cert_name, desc: "Google SSL Cert name"
12
+ append_type_option = Proc.new do
13
+ option :append_type, type: :boolean, default: true, desc: "Append the cert type to name. IE: global, us-central1"
14
14
  end
15
15
 
16
- desc "create", "Create Google SSL Certificate and save to Secrets Manager"
16
+ desc "create CERT_NAME", "Create Google SSL Certificate and save to Secrets Manager"
17
17
  long_desc Help.text(:create)
18
18
  option :private_key, desc: "private key path"
19
19
  option :certificate, desc: "certificate path"
@@ -21,21 +21,21 @@ module GoogleSslCert
21
21
  option :extra_certs, desc: "Additional certs to be added to the secret value"
22
22
  option :timestamp, type: :boolean, default: true, desc: "Auto-append timestamp to cert name. Appending a timestamp allows auto-pruning also"
23
23
  option :prune, type: :boolean, default: true, desc: "Auto-prune old certs based on timestamp"
24
- cert_name_option.call
24
+ append_type_option.call
25
25
  secret_name_option.call
26
26
  global_option.call
27
- def create
28
- Create.new(options).run
27
+ def create(cert_name)
28
+ Create.new(options.merge(cert_name: cert_name)).run
29
29
  end
30
30
 
31
- desc "prune", "prune Google SSL Certificate and save to Secrets Manager"
31
+ desc "prune CERT_NAME", "prune Google SSL Certificate and save to Secrets Manager"
32
32
  long_desc Help.text(:prune)
33
- cert_name_option.call
33
+ append_type_option.call
34
34
  global_option.call
35
35
  option :yes, aliases: %w[y], type: :boolean, desc: "Skip 'are you sure' prompt"
36
36
  option :keep, type: :numeric, default: 1, desc: "Number of certs to keep"
37
- def prune
38
- Prune.new(options).run
37
+ def prune(cert_name)
38
+ Prune.new(options.merge(cert_name: cert_name)).run
39
39
  end
40
40
 
41
41
  desc "secret SUBCOMMAND", "secret subcommands"
@@ -1,19 +1,21 @@
1
1
  module GoogleSslCert
2
2
  class Name
3
- attr_reader :base_name
3
+ extend Memoist
4
+
4
5
  def initialize(options={})
5
6
  @options = options
6
- @base_name = @options[:cert_name] || default_cert_name
7
+ @append_type = @options[:append_type].nil? ? true : @options[:append_type]
7
8
  end
8
9
 
9
- def generate
10
+ def generated_name
10
11
  ts = Time.now.strftime("%Y%m%d%H%M%S") unless @options[:timestamp] == false # nil defaults to true
11
- [@base_name, ts].compact.join('-')
12
+ [base_name, ts].compact.join('-')
12
13
  end
14
+ memoize :generated_name
13
15
 
14
- def default_cert_name
15
- type = @options[:global] ? "global" : ENV['GOOGLE_REGION']
16
- ["google-ssl-cert", type].join('-')
16
+ def base_name
17
+ type = @options[:global] ? "global" : ENV['GOOGLE_REGION'] if @append_type
18
+ [@options[:cert_name], type].compact.join('-')
17
19
  end
18
20
  end
19
21
  end
@@ -15,7 +15,6 @@ module GoogleSslCert
15
15
  # https://cloud.google.com/secret-manager/docs/reference/rest/v1/projects.secrets/addVersion
16
16
  # https://cloud.google.com/secret-manager/docs/reference/rest/v1/SecretPayload
17
17
  def save(name, value)
18
- validate!
19
18
  create_secret(name, value)
20
19
  url_path = "#{parent}/secrets/#{name}"
21
20
  secret_manager_service.add_secret_version(parent: url_path, payload: {data: value})
@@ -66,21 +65,5 @@ module GoogleSslCert
66
65
  logger.error e.message
67
66
  "NOT FOUND #{name}" # simple string so Kubernetes YAML is valid
68
67
  end
69
-
70
- def validate!
71
- errors = []
72
- secret_name = @options[:secret_name]
73
- if @options[:save_secret] && !secret_name
74
- errors << "ERROR: --secret-name must be provided or --no-save-secret option must be used"
75
- end
76
- # extra validation early to prevent google ssl cert from being created but the secret not being stored
77
- if secret_name && secret_name !~ /^[a-zA-Z_\-0-9]+$/
78
- errors << "ERROR: --secret-name invalid format. Expected format: [a-zA-Z_0-9]+" # Expected format taken from `gcloud secrets create`
79
- end
80
- unless errors.empty?
81
- logger.error errors.join("\n")
82
- exit 1
83
- end
84
- end
85
68
  end
86
69
  end
@@ -1,3 +1,3 @@
1
1
  module GoogleSslCert
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: google-ssl-cert
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tung Nguyen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-10-23 00:00:00.000000000 Z
11
+ date: 2021-10-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -243,11 +243,11 @@ files:
243
243
  - lib/google_ssl_cert/version.rb
244
244
  - spec/cli_spec.rb
245
245
  - spec/spec_helper.rb
246
- homepage: https://github.com/boltopspro/google-ssl-cert
246
+ homepage: https://github.com/boltops-tools/google-ssl-cert
247
247
  licenses:
248
248
  - Apache-2.0
249
249
  metadata:
250
- homepage_uri: https://github.com/boltopspro/google-ssl-cert
250
+ homepage_uri: https://github.com/boltops-tools/google-ssl-cert
251
251
  post_install_message:
252
252
  rdoc_options: []
253
253
  require_paths: