kube_cluster 0.3.2 → 0.3.4

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 (55) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -0
  3. data/Gemfile.lock +20 -12
  4. data/examples/01-basic-redis-pod/Gemfile +5 -0
  5. data/examples/01-basic-redis-pod/README.md +30 -0
  6. data/examples/01-basic-redis-pod/bin/dev +8 -0
  7. data/examples/01-basic-redis-pod/docker-compose.yml +14 -0
  8. data/examples/01-basic-redis-pod/manifest.rb +1 -1
  9. data/examples/01-basic-redis-pod/redis.conf +2 -0
  10. data/examples/02-manifest-with-middleware/Dockerfile +19 -0
  11. data/examples/02-manifest-with-middleware/Gemfile +5 -0
  12. data/examples/02-manifest-with-middleware/README.md +34 -0
  13. data/examples/02-manifest-with-middleware/bin/dev +9 -0
  14. data/examples/02-manifest-with-middleware/config.ru +3 -0
  15. data/examples/02-manifest-with-middleware/docker-compose.yml +25 -0
  16. data/examples/02-manifest-with-middleware/falcon.rb +11 -0
  17. data/examples/02-manifest-with-middleware/manifest.rb +1 -1
  18. data/examples/02-manifest-with-middleware/registries.yaml +4 -0
  19. data/examples/03-app-with-database/Gemfile +5 -0
  20. data/examples/04-pod-with-ingress/Dockerfile +20 -0
  21. data/examples/04-pod-with-ingress/Gemfile +10 -0
  22. data/examples/04-pod-with-ingress/README.md +42 -0
  23. data/examples/04-pod-with-ingress/bin/dev +10 -0
  24. data/examples/04-pod-with-ingress/config.ru +3 -0
  25. data/examples/04-pod-with-ingress/docker-compose.yml +35 -0
  26. data/examples/04-pod-with-ingress/falcon.rb +11 -0
  27. data/examples/04-pod-with-ingress/manifest.rb +15 -0
  28. data/examples/04-pod-with-ingress/pod_with_ingress.rb +60 -0
  29. data/examples/04-pod-with-ingress/registries.yaml +4 -0
  30. data/examples/05-helm-chart-to-manifest/Gemfile +5 -0
  31. data/examples/05-helm-chart-to-manifest/README.md +44 -0
  32. data/examples/05-helm-chart-to-manifest/bin/dev +6 -0
  33. data/examples/05-helm-chart-to-manifest/docker-compose.yml +16 -0
  34. data/examples/05-helm-chart-to-manifest/manifest.rb +18 -0
  35. data/examples/06-nginx-with-cert-manager/Gemfile +5 -0
  36. data/examples/06-nginx-with-cert-manager/README.md +57 -0
  37. data/examples/06-nginx-with-cert-manager/bin/dev +6 -0
  38. data/examples/06-nginx-with-cert-manager/docker-compose.yml +16 -0
  39. data/examples/06-nginx-with-cert-manager/manifest.rb +45 -0
  40. data/examples/06-nginx-with-cert-manager/resources/namespace.rb +7 -0
  41. data/examples/06-nginx-with-cert-manager/resources/nginx.rb +156 -0
  42. data/examples/06-nginx-with-cert-manager/resources/self_signed_issuer.rb +11 -0
  43. data/examples/README.md +3 -0
  44. data/kube_cluster.gemspec +0 -1
  45. data/lib/kube/cluster/connection.rb +2 -1
  46. data/lib/kube/cluster/resource/extensions/README.md +15 -0
  47. data/lib/kube/cluster/resource/extensions/custom_resource_definition.rb +35 -0
  48. data/lib/kube/cluster/resource/persistence.rb +16 -3
  49. data/lib/kube/cluster/resource.rb +9 -0
  50. data/lib/kube/cluster/version.rb +1 -1
  51. data/lib/kube/cluster.rb +7 -4
  52. data/lib/kube/helm/chart.rb +203 -0
  53. data/lib/kube/helm/endpoint.rb +75 -0
  54. data/lib/kube/helm/repo.rb +121 -0
  55. metadata +44 -15
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Kube
4
+ module Helm
5
+ # Abstracts the differences between Helm chart sources.
6
+ #
7
+ # Traditional Helm repos require `helm repo add` before charts can be
8
+ # referenced, and charts are addressed as "repo-name/chart-name".
9
+ #
10
+ # OCI registries need no `repo add` step, and charts are addressed as
11
+ # the full OCI URI: "oci://host/path/chart-name".
12
+ #
13
+ # endpoint = Kube::Helm::Endpoint.new("https://charts.bitnami.com/bitnami")
14
+ # endpoint.oci? #=> false
15
+ # endpoint.requires_add? #=> true
16
+ # endpoint.chart_ref("nginx", repo_name: "bitnami")
17
+ # #=> "bitnami/nginx"
18
+ #
19
+ # endpoint = Kube::Helm::Endpoint.new("oci://ghcr.io/my-org/charts")
20
+ # endpoint.oci? #=> true
21
+ # endpoint.requires_add? #=> false
22
+ # endpoint.chart_ref("nginx")
23
+ # #=> "oci://ghcr.io/my-org/charts/nginx"
24
+ #
25
+ class Endpoint
26
+ attr_reader :url
27
+
28
+ def initialize(url)
29
+ raise ArgumentError, "url must be a String" unless url.is_a?(String)
30
+ raise ArgumentError, "url must not be empty" if url.strip.empty?
31
+
32
+ @url = url.chomp("/")
33
+ end
34
+
35
+ # Is this an OCI registry endpoint?
36
+ def oci?
37
+ @url.start_with?("oci://")
38
+ end
39
+
40
+ # Traditional Helm repos require `helm repo add`; OCI registries do not.
41
+ def requires_add?
42
+ !oci?
43
+ end
44
+
45
+ # Build the chart reference string Helm expects.
46
+ #
47
+ # For OCI: "oci://host/path/chart-name"
48
+ # For traditional: "repo-name/chart-name"
49
+ #
50
+ # @param chart_name [String] the chart name (e.g. "nginx")
51
+ # @param repo_name [String, nil] the local repo alias (required for non-OCI)
52
+ # @return [String]
53
+ def chart_ref(chart_name, repo_name: nil)
54
+ if oci?
55
+ "#{@url}/#{chart_name}"
56
+ else
57
+ if repo_name.nil?
58
+ raise ArgumentError,
59
+ "repo_name is required for non-OCI endpoints"
60
+ end
61
+
62
+ "#{repo_name}/#{chart_name}"
63
+ end
64
+ end
65
+
66
+ def to_s
67
+ @url
68
+ end
69
+
70
+ def ==(other)
71
+ other.is_a?(Endpoint) && other.url == @url
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,121 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "endpoint"
4
+ require_relative "chart"
5
+
6
+ module Kube
7
+ module Helm
8
+ # Models a Helm chart repository (traditional or OCI).
9
+ #
10
+ # Wraps the lifecycle commands (`helm repo add`, `helm repo update`,
11
+ # `helm repo remove`) and fetches charts for rendering.
12
+ #
13
+ # When a +cluster+ is provided, all Helm commands are scoped to that
14
+ # cluster's kubeconfig.
15
+ #
16
+ # repo = Kube::Helm::Repo.new("bitnami", url: "https://charts.bitnami.com/bitnami")
17
+ # chart = repo.fetch("nginx", version: "18.1.0")
18
+ # manifest = chart.apply_values({ "replicaCount" => 3 })
19
+ #
20
+ # # One-liner
21
+ # manifest = Kube::Helm::Repo
22
+ # .new("bitnami", url: "https://charts.bitnami.com/bitnami")
23
+ # .fetch("nginx", version: "18.1.0")
24
+ # .apply_values({ "replicaCount" => 3 })
25
+ #
26
+ class Repo
27
+ attr_reader :name, :endpoint, :cluster
28
+
29
+ # @param name [String] local alias for this repo (e.g. "bitnami")
30
+ # @param url [String] repository URL (http(s) for traditional, oci:// for OCI)
31
+ # @param cluster [Kube::Cluster::Instance, nil] optional cluster connection
32
+ def initialize(name, url:, cluster: nil)
33
+ unless name.is_a?(String) && !name.strip.empty?
34
+ raise ArgumentError, "name must be a non-empty String"
35
+ end
36
+
37
+ @name = name
38
+ @endpoint = Endpoint.new(url)
39
+ @cluster = cluster
40
+ end
41
+
42
+ # Register this repo with the local Helm client.
43
+ # No-op for OCI registries.
44
+ #
45
+ # @return [self]
46
+ def add
47
+ if endpoint.requires_add?
48
+ repo_name = @name
49
+ repo_url = endpoint.url
50
+ cmd = helm.call { repo.add.(repo_name).(repo_url) }
51
+ helm.run(cmd.to_s)
52
+ end
53
+ self
54
+ end
55
+
56
+ # Update the local chart index for this repo.
57
+ # No-op for OCI registries.
58
+ #
59
+ # @return [self]
60
+ def update
61
+ if endpoint.requires_add?
62
+ repo_name = @name
63
+ cmd = helm.call { repo.update.(repo_name) }
64
+ helm.run(cmd.to_s)
65
+ end
66
+ self
67
+ end
68
+
69
+ # Remove this repo from the local Helm client.
70
+ # No-op for OCI registries.
71
+ #
72
+ # @return [self]
73
+ def remove
74
+ if endpoint.requires_add?
75
+ repo_name = @name
76
+ cmd = helm.call { repo.remove.(repo_name) }
77
+ helm.run(cmd.to_s)
78
+ end
79
+ self
80
+ end
81
+
82
+ # Fetch a chart from this repo.
83
+ #
84
+ # Adds and updates the repo, retrieves the Chart.yaml metadata via
85
+ # `helm show chart`, and returns a Chart object with the ref set
86
+ # for subsequent helm commands.
87
+ #
88
+ # @param chart_name [String] the chart name (e.g. "nginx")
89
+ # @param version [String, nil] chart version constraint (e.g. "18.1.0")
90
+ # @return [Chart]
91
+ def fetch(chart_name, version: nil)
92
+ add
93
+ update
94
+
95
+ ref = endpoint.chart_ref(chart_name, repo_name: @name)
96
+
97
+ cmd = helm.call { show.chart.(ref) }
98
+ cmd = cmd.version(version) if version
99
+ yaml_output = helm.run(cmd.to_s)
100
+
101
+ data = YAML.safe_load(yaml_output, permitted_classes: [Symbol]) || {}
102
+ Chart.new(data, ref: ref, cluster: @cluster)
103
+ end
104
+
105
+ # Is this an OCI-backed repo?
106
+ def oci?
107
+ endpoint.oci?
108
+ end
109
+
110
+ def to_s
111
+ "#{@name} (#{endpoint.url})"
112
+ end
113
+
114
+ private
115
+
116
+ def helm
117
+ @cluster&.connection&.helm || Kube::Helm::Instance.new
118
+ end
119
+ end
120
+ end
121
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kube_cluster
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.3.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nathan K
@@ -65,20 +65,6 @@ dependencies:
65
65
  - - "~>"
66
66
  - !ruby/object:Gem::Version
67
67
  version: 1.3.0
68
- - !ruby/object:Gem::Dependency
69
- name: kube_kit
70
- requirement: !ruby/object:Gem::Requirement
71
- requirements:
72
- - - ">"
73
- - !ruby/object:Gem::Version
74
- version: '0'
75
- type: :runtime
76
- prerelease: false
77
- version_requirements: !ruby/object:Gem::Requirement
78
- requirements:
79
- - - ">"
80
- - !ruby/object:Gem::Version
81
- version: '0'
82
68
  - !ruby/object:Gem::Dependency
83
69
  name: kube_kubectl
84
70
  requirement: !ruby/object:Gem::Requirement
@@ -120,20 +106,58 @@ files:
120
106
  - bin/tag-version
121
107
  - bin/test
122
108
  - docker-compose.yml
109
+ - examples/01-basic-redis-pod/Gemfile
110
+ - examples/01-basic-redis-pod/README.md
111
+ - examples/01-basic-redis-pod/bin/dev
112
+ - examples/01-basic-redis-pod/docker-compose.yml
123
113
  - examples/01-basic-redis-pod/manifest.rb
114
+ - examples/01-basic-redis-pod/redis.conf
115
+ - examples/02-manifest-with-middleware/Dockerfile
116
+ - examples/02-manifest-with-middleware/Gemfile
117
+ - examples/02-manifest-with-middleware/README.md
118
+ - examples/02-manifest-with-middleware/bin/dev
119
+ - examples/02-manifest-with-middleware/config.ru
120
+ - examples/02-manifest-with-middleware/docker-compose.yml
121
+ - examples/02-manifest-with-middleware/falcon.rb
124
122
  - examples/02-manifest-with-middleware/manifest.rb
125
123
  - examples/02-manifest-with-middleware/middleware/labels.rb
126
124
  - examples/02-manifest-with-middleware/middleware/namespace.rb
125
+ - examples/02-manifest-with-middleware/registries.yaml
127
126
  - examples/02-manifest-with-middleware/templates/config_map.rb
128
127
  - examples/02-manifest-with-middleware/templates/deployment.rb
129
128
  - examples/02-manifest-with-middleware/templates/horizontal_pod_autoscaler.rb
130
129
  - examples/02-manifest-with-middleware/templates/ingress.rb
131
130
  - examples/02-manifest-with-middleware/templates/service.rb
131
+ - examples/03-app-with-database/Gemfile
132
132
  - examples/03-app-with-database/demo.rb
133
133
  - examples/03-app-with-database/helpers.rb
134
134
  - examples/03-app-with-database/my_app.rb
135
135
  - examples/03-app-with-database/postgresql.rb
136
136
  - examples/03-app-with-database/ruby_on_rails.rb
137
+ - examples/04-pod-with-ingress/Dockerfile
138
+ - examples/04-pod-with-ingress/Gemfile
139
+ - examples/04-pod-with-ingress/README.md
140
+ - examples/04-pod-with-ingress/bin/dev
141
+ - examples/04-pod-with-ingress/config.ru
142
+ - examples/04-pod-with-ingress/docker-compose.yml
143
+ - examples/04-pod-with-ingress/falcon.rb
144
+ - examples/04-pod-with-ingress/manifest.rb
145
+ - examples/04-pod-with-ingress/pod_with_ingress.rb
146
+ - examples/04-pod-with-ingress/registries.yaml
147
+ - examples/05-helm-chart-to-manifest/Gemfile
148
+ - examples/05-helm-chart-to-manifest/README.md
149
+ - examples/05-helm-chart-to-manifest/bin/dev
150
+ - examples/05-helm-chart-to-manifest/docker-compose.yml
151
+ - examples/05-helm-chart-to-manifest/manifest.rb
152
+ - examples/06-nginx-with-cert-manager/Gemfile
153
+ - examples/06-nginx-with-cert-manager/README.md
154
+ - examples/06-nginx-with-cert-manager/bin/dev
155
+ - examples/06-nginx-with-cert-manager/docker-compose.yml
156
+ - examples/06-nginx-with-cert-manager/manifest.rb
157
+ - examples/06-nginx-with-cert-manager/resources/namespace.rb
158
+ - examples/06-nginx-with-cert-manager/resources/nginx.rb
159
+ - examples/06-nginx-with-cert-manager/resources/self_signed_issuer.rb
160
+ - examples/README.md
137
161
  - flake.lock
138
162
  - flake.nix
139
163
  - kube_cluster.gemspec
@@ -155,10 +179,15 @@ files:
155
179
  - lib/kube/cluster/middleware/stack.rb
156
180
  - lib/kube/cluster/resource.rb
157
181
  - lib/kube/cluster/resource/dirty_tracking.rb
182
+ - lib/kube/cluster/resource/extensions/README.md
183
+ - lib/kube/cluster/resource/extensions/custom_resource_definition.rb
158
184
  - lib/kube/cluster/resource/persistence.rb
159
185
  - lib/kube/cluster/version.rb
160
186
  - lib/kube/cluster/version.rb.erb
161
187
  - lib/kube/errors.rb
188
+ - lib/kube/helm/chart.rb
189
+ - lib/kube/helm/endpoint.rb
190
+ - lib/kube/helm/repo.rb
162
191
  homepage: https://github.com/general-intelligence-systems/kube_cluster
163
192
  licenses:
164
193
  - Apache-2.0