kubes_google 0.3.0 → 0.3.5

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: c2b41e672639ece65b0c749581b7321b30a48213744e28aa63e3e71bf6cf3fd3
4
- data.tar.gz: 0b4006a22492fb1424c3d45b880f9a784deee99d824e986fb7a52e835196f955
3
+ metadata.gz: c4940b31e1e64807b1036d0980ab6c1ebe81aa6f05581b1e2d00b3bf915d12c0
4
+ data.tar.gz: 6761294987f6c33fef1d9764712bab015b7b264fa8e5b84c166a633f03bc44aa
5
5
  SHA512:
6
- metadata.gz: 139e70fe3e151df3fcefa12a4a8d7a7a45b08bc62909815b4be865906e7400f1c5141a42e41331b13aa774b6f04caca3d06a7a882c6a486646047d11a0d09a3f
7
- data.tar.gz: 9c6058c9157f05a8be7aa662fedc71ada94171e7c4fe5086552c68743a683467a2247fa549d2217f6017ea3ed84fdc80cf18f85a2a2f934753546d95d93af943
6
+ metadata.gz: 4c09463d4a76e82240502a5779e90a9874b9c91d4f195f91af128fa48a134b44a9485a5c327fad74826834edd57e0137ebd9375558f4253ec0ca5242610061a7
7
+ data.tar.gz: a7ecffa4255c71544b92fd5df88bac16a5a06eb4e2c8e48eed9d9b1f61a12c98f18c3c6edd8f92aef51ffeb595605a9cccb578a42dbc810b89fc9eeb9a97fe02
@@ -3,6 +3,22 @@
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.3.5] - 2020-11-12
7
+ - add KubesGoogle.cloudbuild? check
8
+ - fetcher sdk friendly suggestion to use gcloud when vpn errors
9
+
10
+ ## [0.3.4] - 2020-11-12
11
+ - fix KubesGoogle.config.secrets.fetcher check
12
+
13
+ ## [0.3.3] - 2020-11-12
14
+ - [#6](https://github.com/boltops-tools/kubes_google/pull/6) sdk and gcloud secrets fetcher strategy: secrets.fetcher option
15
+
16
+ ## [0.3.2] - 2020-11-11
17
+ - [#5](https://github.com/boltops-tools/kubes_google/pull/5) config.base64 option
18
+
19
+ ## [0.3.1] - 2020-11-11
20
+ - [#4](https://github.com/boltops-tools/kubes_google/pull/4) get_credentials hook
21
+
6
22
  ## [0.3.0]
7
23
  - #3 gke hook to whitelist ip
8
24
 
@@ -1,14 +1,22 @@
1
1
  gke = KubesGoogle::Gke.new(
2
- name: KubesGoogle.config.gke.cluster_name,
2
+ cluster_name: KubesGoogle.config.gke.cluster_name,
3
+ google_region: KubesGoogle.config.gke.google_region,
4
+ google_project: KubesGoogle.config.gke.google_project,
5
+ enable_get_credentials: KubesGoogle.config.gke.enable_get_credentials,
3
6
  whitelist_ip: KubesGoogle.config.gke.whitelist_ip,
4
7
  )
5
8
 
9
+ before("apply",
10
+ label: "gke get-credentials hook",
11
+ execute: gke.method(:get_credentials).to_proc,
12
+ ) if gke.get_credentials_enabled?
13
+
6
14
  before("apply",
7
15
  label: "gke whitelist hook",
8
16
  execute: gke.method(:allow).to_proc,
9
- )
17
+ ) if gke.enabled?
10
18
 
11
19
  after("apply",
12
20
  label: "gke whitelist hook",
13
21
  execute: gke.method(:deny).to_proc,
14
- )
22
+ ) if gke.enabled?
@@ -35,6 +35,10 @@ module KubesGoogle
35
35
  Config.instance.config
36
36
  end
37
37
 
38
+ def cloudbuild?
39
+ !!ENV['BUILDER_OUTPUT'] # cloudbuild env vars: https://gist.github.com/tongueroo/7ae26abd60d30da3972e86b4e7ca315e
40
+ end
41
+
38
42
  extend self
39
43
  end
40
44
 
@@ -6,8 +6,14 @@ module KubesGoogle
6
6
  c = ActiveSupport::OrderedOptions.new
7
7
  c.gke = ActiveSupport::OrderedOptions.new
8
8
  c.gke.cluster_name = nil
9
+ c.gke.enable_get_credentials = nil
9
10
  c.gke.enable_hooks = nil # nil since need cluster_name also. setting to false will explicitly disable hooks
11
+ c.gke.google_project = nil
12
+ c.gke.google_region = nil
10
13
  c.gke.whitelist_ip = nil # default will auto-detect IP
14
+ c.secrets = ActiveSupport::OrderedOptions.new
15
+ c.secrets.fetcher = "sdk"
16
+ c.secrets.base64 = true
11
17
  c
12
18
  end
13
19
 
@@ -5,35 +5,56 @@ module KubesGoogle
5
5
  extend Memoist
6
6
  include Logging
7
7
  include Services
8
+ include Util::Sh
8
9
 
9
- def initialize(name:, whitelist_ip: nil)
10
- @name, @whitelist_ip = name, whitelist_ip
10
+ def initialize(cluster_name:,
11
+ enable_get_credentials: false,
12
+ google_project: nil,
13
+ google_region: "us-central1",
14
+ whitelist_ip: nil)
15
+ @cluster_name = cluster_name
16
+ @enable_get_credentials = enable_get_credentials
17
+ @google_project = ENV['GOOGLE_PROJECT'] || google_project
18
+ @google_region = ENV['GOOGLE_REGION'] || google_region
19
+ @whitelist_ip = whitelist_ip
11
20
  end
12
21
 
13
22
  def allow
14
- return unless enabled?
15
23
  logger.debug "Updating cluster. Adding IP: #{ip}"
16
24
  update_cluster(cidr_blocks(:with_whitelist))
17
25
  end
18
26
 
19
27
  def deny
20
- return unless enabled?
21
28
  logger.debug "Updating cluster. Removing IP: #{ip}"
22
29
  update_cluster(cidr_blocks(:without_whitelist))
23
30
  end
24
31
 
25
- # Setting the cluster name is enough to enable the hooks
32
+ def get_credentials
33
+ return unless get_credentials_enabled?
34
+ sh "gcloud container clusters get-credentials --project=#{@google_project} --region=#{@google_region} #{@cluster_name}"
35
+ end
36
+
37
+ def full_name
38
+ "projects/#{@google_project}/locations/#{@google_region}/clusters/#{@cluster_name}"
39
+ end
40
+
26
41
  def enabled?
27
42
  enable = KubesGoogle.config.gke.enable_hooks
28
43
  enable = enable.nil? ? true : enable
29
44
  # gke = KubesGoogle::Gke.new(name: KubesGoogle.config.gke.cluster_name)
30
45
  # so @name = KubesGoogle.config.gke.cluster_name
31
- !!(enable && @name)
46
+ !!(enable && @cluster_name)
47
+ end
48
+
49
+ def get_credentials_enabled?
50
+ enable = KubesGoogle.config.gke.enable_get_credentials
51
+ enable = enable.nil? ? false : enable
52
+ !!(enable && full_name)
32
53
  end
33
54
 
34
55
  def update_cluster(cidr_blocks)
35
56
  resp = cluster_manager.update_cluster(
36
- name: @name,
57
+ name: full_name,
37
58
  update: {
38
59
  desired_master_authorized_networks_config: {
39
60
  cidr_blocks: cidr_blocks,
@@ -67,7 +88,7 @@ module KubesGoogle
67
88
  end
68
89
 
69
90
  def old_cidrs
70
- resp = cluster_manager.get_cluster(name: @name)
91
+ resp = cluster_manager.get_cluster(name: full_name)
71
92
  config = resp.master_authorized_networks_config.to_h
72
93
  config[:cidr_blocks]
73
94
  end
@@ -1,41 +1,22 @@
1
1
  class KubesGoogle::Secrets
2
2
  class Fetcher
3
- include KubesGoogle::Logging
4
- include KubesGoogle::Services
3
+ extend Memoist
5
4
 
6
5
  def initialize(options={})
7
6
  @options = options
8
- @base64 = options[:base64].nil? ? true : options[:base64]
9
- @project_id = ENV['GOOGLE_PROJECT'] || raise("GOOGLE_PROJECT env variable is not set. It's required.")
10
7
  end
11
8
 
12
9
  def fetch(short_name)
13
- value = fetch_value(short_name)
14
- value = Base64.strict_encode64(value).strip if @base64
15
- value
10
+ fetcher.fetch(short_name)
16
11
  end
17
12
 
18
- def fetch_value(short_name)
19
- name = "projects/#{project_number}/secrets/#{short_name}/versions/latest"
20
- version = secret_manager_service.access_secret_version(name: name)
21
- version.payload.data
22
- rescue Google::Cloud::NotFoundError => e
23
- logger.info "WARN: secret #{name} not found".color(:yellow)
24
- logger.info e.message
25
- "NOT FOUND #{name}" # simple string so Kubernetes YAML is valid
26
- end
27
-
28
- # TODO: Get the project from the list project api instead. Unsure where the docs are for this.
29
- # If someone knows, let me know.
30
- # Right now grabbing the first secret to then be able to get the google project number
31
- @@project_number = nil
32
- def project_number
33
- return @@project_number if @@project_number
34
-
35
- parent = "projects/#{@project_id}"
36
- resp = secret_manager_service.list_secrets(parent: parent) # note: page_size doesnt seem to get respected
37
- name = resp.first.name # IE: projects/686010496118/secrets/demo-dev-db_host
38
- @@project_number = name.split('/')[1]
13
+ def fetcher
14
+ if KubesGoogle.config.secrets.fetcher == "sdk"
15
+ Sdk.new(@options)
16
+ else
17
+ Gcloud.new(@options)
18
+ end
39
19
  end
20
+ memoize :fetcher
40
21
  end
41
22
  end
@@ -0,0 +1,15 @@
1
+ class KubesGoogle::Secrets::Fetcher
2
+ class Base
3
+ include KubesGoogle::Logging
4
+
5
+ def initialize(options={})
6
+ @options = options
7
+ @base64 = options[:base64]
8
+ @project_id = options[:google_project] || ENV['GOOGLE_PROJECT'] || raise("GOOGLE_PROJECT env variable is not set. It's required.")
9
+ end
10
+
11
+ def base64?
12
+ @base64.nil? ? KubesGoogle.config.secrets.base64 : @base64
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,21 @@
1
+ class KubesGoogle::Secrets::Fetcher
2
+ class Gcloud < Base
3
+ include KubesGoogle::Util::Sh
4
+
5
+ def fetch(short_name, version="latest")
6
+ value = gcloud("secrets versions access #{version} --secret #{short_name}")
7
+ if value.include?("ERROR") && value.include?("NOT_FOUND")
8
+ logger.info "WARN: secret #{short_name} not found".color(:yellow)
9
+ logger.info e.message
10
+ "NOT FOUND #{short_name}" # simple string so Kubernetes YAML is valid
11
+ else
12
+ value = Base64.strict_encode64(value).strip if base64?
13
+ value
14
+ end
15
+ end
16
+
17
+ def gcloud(args)
18
+ capture("gcloud --project #{@project_id} #{args}")
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,47 @@
1
+ class KubesGoogle::Secrets::Fetcher
2
+ class Sdk < Base
3
+ include KubesGoogle::Services
4
+
5
+ def fetch(short_name, version="latest")
6
+ value = fetch_value(short_name, version)
7
+ value = Base64.strict_encode64(value).strip if base64?
8
+ value
9
+ end
10
+
11
+ def fetch_value(short_name, version="latest")
12
+ name = "projects/#{project_number}/secrets/#{short_name}/versions/#{version}"
13
+ version = secret_manager_service.access_secret_version(name: name)
14
+ version.payload.data
15
+ rescue Google::Cloud::NotFoundError => e
16
+ logger.info "WARN: secret #{name} not found".color(:yellow)
17
+ logger.info e.message
18
+ "NOT FOUND #{name}" # simple string so Kubernetes YAML is valid
19
+ end
20
+
21
+ # TODO: Get the project from the list project api instead. Unsure where the docs are for this.
22
+ # If someone knows, let me know.
23
+ # Right now grabbing the first secret to then be able to get the google project number
24
+ @@project_number = nil
25
+ def project_number
26
+ return @@project_number if @@project_number
27
+
28
+ parent = "projects/#{@project_id}"
29
+ resp = secret_manager_service.list_secrets(parent: parent) # note: page_size doesnt seem to get respected
30
+ name = resp.first.name # IE: projects/686010496118/secrets/demo-dev-db_host
31
+ @@project_number = name.split('/')[1]
32
+ rescue Google::Cloud::UnavailableError => e
33
+ logger.error "ERROR: #{e.message}"
34
+ if e.message.include?("failed to connect")
35
+ logger.info <<~EOL
36
+ SSL Handshake failed. This error seems to happen with some VPN setups.
37
+ Please try the gcloud fetcher instead. To set up see:
38
+
39
+ https://kubes.guru/docs/helpers/google/secrets/#fetcher-strategy
40
+ EOL
41
+ exit 1
42
+ else
43
+ raise
44
+ end
45
+ end
46
+ end
47
+ end
@@ -4,6 +4,7 @@ require "json"
4
4
  module KubesGoogle
5
5
  class ServiceAccount
6
6
  include Logging
7
+ include Util::Sh
7
8
 
8
9
  def initialize(app:, namespace:nil, roles: [], gsa: nil, ksa: nil)
9
10
  @app, @roles = app, roles
@@ -71,25 +72,5 @@ module KubesGoogle
71
72
  --member=serviceAccount:#{@service_account} \
72
73
  --role=#{role} > /dev/null".squish
73
74
  end
74
-
75
- private
76
- def sh(command)
77
- logger.debug "=> #{command}"
78
- success = system(command)
79
- unless success
80
- logger.info "WARN: Running #{command}"
81
- end
82
- success
83
- end
84
-
85
- def capture(command)
86
- out = `#{command}`
87
- unless $?.exitstatus == 0
88
- logger.info "ERROR: Running #{command}"
89
- logger.info out
90
- exit 1
91
- end
92
- out
93
- end
94
75
  end
95
76
  end
@@ -0,0 +1,23 @@
1
+ module KubesGoogle::Util
2
+ module Sh
3
+ private
4
+ def sh(command)
5
+ logger.debug "=> #{command}"
6
+ success = system(command)
7
+ unless success
8
+ logger.info "WARN: Running #{command}"
9
+ end
10
+ success
11
+ end
12
+
13
+ def capture(command)
14
+ out = `#{command}`
15
+ unless $?.exitstatus == 0
16
+ logger.info "ERROR: Running #{command}"
17
+ logger.info out
18
+ exit 1
19
+ end
20
+ out
21
+ end
22
+ end
23
+ end
@@ -1,3 +1,3 @@
1
1
  module KubesGoogle
2
- VERSION = "0.3.0"
2
+ VERSION = "0.3.5"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kubes_google
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tung Nguyen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-11-10 00:00:00.000000000 Z
11
+ date: 2020-11-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -119,8 +119,12 @@ files:
119
119
  - lib/kubes_google/logging.rb
120
120
  - lib/kubes_google/secrets.rb
121
121
  - lib/kubes_google/secrets/fetcher.rb
122
+ - lib/kubes_google/secrets/fetcher/base.rb
123
+ - lib/kubes_google/secrets/fetcher/gcloud.rb
124
+ - lib/kubes_google/secrets/fetcher/sdk.rb
122
125
  - lib/kubes_google/service_account.rb
123
126
  - lib/kubes_google/services.rb
127
+ - lib/kubes_google/util/sh.rb
124
128
  - lib/kubes_google/version.rb
125
129
  homepage: https://github.com/boltops-tools/kubes_google
126
130
  licenses: