google-ssl-cert 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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: