kuby-crdb 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +2 -0
  3. data/Gemfile +18 -0
  4. data/LICENSE +21 -0
  5. data/Rakefile +154 -0
  6. data/kuby-crdb.gemspec +19 -0
  7. data/lib/kuby/crdb/dsl/crdb/v1alpha1/crdb_cluster.rb +27 -0
  8. data/lib/kuby/crdb/dsl/crdb/v1alpha1/crdb_cluster_list.rb +24 -0
  9. data/lib/kuby/crdb/dsl/crdb/v1alpha1/spec.rb +80 -0
  10. data/lib/kuby/crdb/dsl/crdb/v1alpha1/spec_affinity.rb +23 -0
  11. data/lib/kuby/crdb/dsl/crdb/v1alpha1/spec_affinity_node_affinity.rb +20 -0
  12. data/lib/kuby/crdb/dsl/crdb/v1alpha1/spec_affinity_node_affinity_required_during_scheduling_ignored_during_execution.rb +17 -0
  13. data/lib/kuby/crdb/dsl/crdb/v1alpha1/spec_affinity_pod_affinity.rb +20 -0
  14. data/lib/kuby/crdb/dsl/crdb/v1alpha1/spec_affinity_pod_anti_affinity.rb +20 -0
  15. data/lib/kuby/crdb/dsl/crdb/v1alpha1/spec_data_store.rb +23 -0
  16. data/lib/kuby/crdb/dsl/crdb/v1alpha1/spec_data_store_host_path.rb +20 -0
  17. data/lib/kuby/crdb/dsl/crdb/v1alpha1/spec_data_store_pvc.rb +20 -0
  18. data/lib/kuby/crdb/dsl/crdb/v1alpha1/spec_data_store_pvc_source.rb +20 -0
  19. data/lib/kuby/crdb/dsl/crdb/v1alpha1/spec_data_store_pvc_spec.rb +35 -0
  20. data/lib/kuby/crdb/dsl/crdb/v1alpha1/spec_data_store_pvc_spec_data_source.rb +23 -0
  21. data/lib/kuby/crdb/dsl/crdb/v1alpha1/spec_data_store_pvc_spec_resources.rb +20 -0
  22. data/lib/kuby/crdb/dsl/crdb/v1alpha1/spec_data_store_pvc_spec_selector.rb +20 -0
  23. data/lib/kuby/crdb/dsl/crdb/v1alpha1/spec_image.rb +23 -0
  24. data/lib/kuby/crdb/dsl/crdb/v1alpha1/spec_resources.rb +20 -0
  25. data/lib/kuby/crdb/dsl/crdb/v1alpha1/status.rb +29 -0
  26. data/lib/kuby/crdb/dsl/crdb/v1alpha1.rb +21 -0
  27. data/lib/kuby/crdb/dsl/crdb.rb +3 -0
  28. data/lib/kuby/crdb/dsl.rb +3 -0
  29. data/lib/kuby/crdb/entrypoint.rb +15 -0
  30. data/lib/kuby/crdb/plugin.rb +160 -0
  31. data/lib/kuby/crdb/version.rb +6 -0
  32. data/lib/kuby/crdb.rb +13 -0
  33. metadata +87 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 452c64d31fbe3da91cf3b12066156004ff8dcc50dcd62ce448b9e5a5e72dbb0a
4
+ data.tar.gz: 55aca34f100f7cdd53869fb4ce6e675db63a65b9794e9dd001ae35aee82e7aab
5
+ SHA512:
6
+ metadata.gz: 51883863a1bb078941f88c904d162a00e461d1d7d7d192909c625940cf8f9fe4b8f4dca0294ef5b70e956c8b66df539ed709bb5bfa0dec82005db9f867d33d56
7
+ data.tar.gz: d2032dd54d710f1bb4ba7db4330b4c187d59c0f4504b65dfbd8337cf023ea3202fc986c0f85f37ba098c616c24b6ffa0fdc8ef6e6613604e4746ea72d84edfb3
data/CHANGELOG.md ADDED
@@ -0,0 +1,2 @@
1
+ ## 0.1.0
2
+ * Birthday!
data/Gemfile ADDED
@@ -0,0 +1,18 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ group :development do
6
+ gem 'dry-inflector'
7
+ end
8
+
9
+ group :development, :test do
10
+ gem 'kuby-core'
11
+ gem 'kuby-kind'
12
+ gem 'pry-byebug'
13
+ gem 'rake'
14
+ end
15
+
16
+ group :test do
17
+ gem 'rspec', '~> 3.0'
18
+ end
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2021 Cameron Dutro
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,154 @@
1
+ require 'bundler'
2
+ require 'rspec/core/rake_task'
3
+ require 'rubygems/package_task'
4
+
5
+ require 'kuby/crdb'
6
+ require 'pry-byebug'
7
+
8
+ Bundler::GemHelper.install_tasks
9
+
10
+ task default: :spec
11
+
12
+ desc 'Run specs'
13
+ RSpec::Core::RakeTask.new do |t|
14
+ t.pattern = './spec/**/*_spec.rb'
15
+ end
16
+
17
+ task generate: [:schemagen, :codegen]
18
+
19
+ task :schemagen do
20
+ require 'base64'
21
+ require 'json'
22
+ require 'kind-rb'
23
+ require 'net/http'
24
+ require 'uri'
25
+ require 'yaml'
26
+
27
+ # delete first just in case
28
+ system("#{KindRb.executable} delete cluster --name kuby-crdb")
29
+ system("#{KindRb.executable} create cluster --name kuby-crdb")
30
+
31
+ system("kubectl apply -f https://raw.githubusercontent.com/cockroachdb/cockroach-operator/v#{Kuby::CRDB::CRDB_OPERATOR_VERSION}/install/crds.yaml")
32
+
33
+ cluster_name = 'kind-kuby-crdb'
34
+ kubeconfig = YAML.load_file(File.join(Dir.home, '.kube', 'config'))
35
+ cluster = kubeconfig['clusters'].find { |cluster| cluster['name'] == cluster_name }
36
+ ca_cert_data = Base64.decode64(cluster.dig(*%w(cluster certificate-authority-data)))
37
+
38
+ cert_store = OpenSSL::X509::Store.new
39
+ cert_store.add_cert(OpenSSL::X509::Certificate.new(ca_cert_data))
40
+ server = URI.parse(cluster.dig(*%w(cluster server)))
41
+
42
+ http = Net::HTTP.new(server.host, server.port).tap do |http|
43
+ http.use_ssl = true
44
+ http.cert_store = cert_store
45
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
46
+ end
47
+
48
+ token = nil
49
+ STDOUT.write("Getting API token from cluster...")
50
+
51
+ loop do
52
+ secrets = JSON.parse(`kubectl --context #{cluster_name} get secrets -o json`)
53
+ secret = secrets['items'].find do |secret|
54
+ secret.dig(*%w(metadata annotations kubernetes.io/service-account.name)) == 'default'
55
+ end
56
+
57
+ if secret
58
+ token = Base64.decode64(secret.dig(*%w(data token)))
59
+ puts ' done'
60
+ break
61
+ else
62
+ STDOUT.write('.')
63
+ sleep 1
64
+ end
65
+ end
66
+
67
+ get = Net::HTTP::Get.new('/openapi/v2')
68
+ get['Authorization'] = "Bearer #{token}"
69
+
70
+ crds = []
71
+ schema = nil
72
+ STDOUT.write("Requesting OpenAPI v2 schema from cluster...")
73
+
74
+ loop do
75
+ response = http.request(get)
76
+ schema = JSON.parse(response.body)
77
+
78
+ crds = schema['definitions'].each_with_object({}) do |(id, data), memo|
79
+ memo[id] = data if id.start_with?('com.cockroachlabs')
80
+ end
81
+
82
+ if crds.empty?
83
+ STDOUT.write('.')
84
+ sleep 1
85
+ else
86
+ puts ' done'
87
+ break
88
+ end
89
+ end
90
+
91
+ FileUtils.rm_rf('vendor')
92
+ FileUtils.mkdir('vendor')
93
+
94
+ schema = schema.merge('definitions' => crds)
95
+ File.write(File.join('vendor', 'open_api.json'), schema.to_json)
96
+
97
+ puts 'Pulling openapi2jsonschema Docker image'
98
+ system('docker pull garethr/openapi2jsonschema')
99
+
100
+ puts 'Converting OpenAPI format to JSON schema format'
101
+ system(<<~END)
102
+ docker run --rm \
103
+ -v #{File.expand_path('vendor')}:/usr/local/scratch \
104
+ garethr/openapi2jsonschema \
105
+ --kubernetes --output /usr/local/scratch/json_schema /usr/local/scratch/open_api.json
106
+ END
107
+
108
+ puts "Cleaning up"
109
+ system("#{KindRb.executable} delete cluster --name kuby-crdb")
110
+ end
111
+
112
+ task :codegen do
113
+ require 'dry/inflector'
114
+ require 'fileutils'
115
+
116
+ # delete anything that should be re-generated
117
+ FileUtils.rm_rf('./lib/kuby/crdb/dsl.rb')
118
+ FileUtils.rm_rf('./lib/kuby/crdb/dsl')
119
+ FileUtils.mkdir_p('./lib/kuby/crdb/dsl')
120
+
121
+ local_json_schema_path = 'vendor/json_schema'
122
+
123
+ generator = KubeDSL::Generator.new(
124
+ schema_dir: local_json_schema_path,
125
+ output_dir: File.join('lib'),
126
+ autoload_prefix: File.join('kuby', 'crdb', 'dsl'),
127
+ dsl_namespace: ['Kuby', 'CRDB', 'DSL'],
128
+ entrypoint_namespace: ['Kuby', 'CRDB'],
129
+ inflector: Dry::Inflector.new do |inflections|
130
+ inflections.acronym('DSL')
131
+ inflections.acronym('CRDB')
132
+ end
133
+ )
134
+
135
+ generator.builder.register_resolver('io.k8s') do |ref_str, builder|
136
+ external_ref = ::KubeDSL::ExternalRef.new(
137
+ ref_str,
138
+ ['KubeDSL', 'DSL'],
139
+ builder.inflector,
140
+ builder.schema_dir,
141
+ builder.autoload_prefix,
142
+ builder.serialize_handlers
143
+ )
144
+
145
+ ns = external_ref.ruby_namespace + [external_ref.kind]
146
+ exists = ns.inject(Object) { |mod, n| mod.const_get(n, false) } rescue false
147
+ exists ? external_ref : builder.parse_ref(ref_str)
148
+ end
149
+
150
+ generator.generate_resource_files
151
+ generator.generate_autoload_files
152
+
153
+ FileUtils.rm_rf(File.join('lib', 'kuby.rb'))
154
+ end
data/kuby-crdb.gemspec ADDED
@@ -0,0 +1,19 @@
1
+ $:.unshift File.join(File.dirname(__FILE__), 'lib')
2
+ require 'kuby/crdb/version'
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = 'kuby-crdb'
6
+ s.version = ::Kuby::CRDB::VERSION
7
+ s.authors = ['Cameron Dutro']
8
+ s.email = ['camertron@gmail.com']
9
+ s.homepage = 'http://github.com/getkuby/kuby-crdb'
10
+
11
+ s.description = s.summary = 'CockroachDB plugin for Kuby.'
12
+
13
+ s.platform = Gem::Platform::RUBY
14
+
15
+ s.add_dependency 'kube-dsl', '~> 0.7'
16
+
17
+ s.require_path = 'lib'
18
+ s.files = Dir['{lib,spec}/**/*', 'Gemfile', 'LICENSE', 'CHANGELOG.md', 'README.md', 'Rakefile', 'kuby-crdb.gemspec']
19
+ end
@@ -0,0 +1,27 @@
1
+ module Kuby::CRDB::DSL::CRDB::V1alpha1
2
+ class CrdbCluster < ::KubeDSL::DSLObject
3
+ object_field(:status) { Kuby::CRDB::DSL::CRDB::V1alpha1::Status.new }
4
+ object_field(:spec) { Kuby::CRDB::DSL::CRDB::V1alpha1::Spec.new }
5
+ value_field :api_version
6
+ object_field(:metadata) { KubeDSL::DSL::Meta::V1::ObjectMeta.new }
7
+
8
+ validates :status, object: { kind_of: Kuby::CRDB::DSL::CRDB::V1alpha1::Status }
9
+ validates :spec, object: { kind_of: Kuby::CRDB::DSL::CRDB::V1alpha1::Spec }
10
+ validates :api_version, field: { format: :string }, presence: false
11
+ validates :metadata, object: { kind_of: KubeDSL::DSL::Meta::V1::ObjectMeta }
12
+
13
+ def serialize
14
+ {}.tap do |result|
15
+ result[:status] = status.serialize
16
+ result[:kind] = "CrdbCluster"
17
+ result[:spec] = spec.serialize
18
+ result[:apiVersion] = api_version
19
+ result[:metadata] = metadata.serialize
20
+ end
21
+ end
22
+
23
+ def kind_sym
24
+ :crdb_cluster
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,24 @@
1
+ module Kuby::CRDB::DSL::CRDB::V1alpha1
2
+ class CrdbClusterList < ::KubeDSL::DSLObject
3
+ array_field(:item) { Kuby::CRDB::DSL::CRDB::V1alpha1::CrdbCluster.new }
4
+ value_field :api_version
5
+ object_field(:metadata) { KubeDSL::DSL::Meta::V1::ListMeta.new }
6
+
7
+ validates :items, array: { kind_of: Kuby::CRDB::DSL::CRDB::V1alpha1::CrdbCluster }, presence: false
8
+ validates :api_version, field: { format: :string }, presence: false
9
+ validates :metadata, object: { kind_of: KubeDSL::DSL::Meta::V1::ListMeta }
10
+
11
+ def serialize
12
+ {}.tap do |result|
13
+ result[:items] = items.map(&:serialize)
14
+ result[:kind] = "CrdbClusterList"
15
+ result[:apiVersion] = api_version
16
+ result[:metadata] = metadata.serialize
17
+ end
18
+ end
19
+
20
+ def kind_sym
21
+ :crdb_cluster_list
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,80 @@
1
+ module Kuby::CRDB::DSL::CRDB::V1alpha1
2
+ class Spec < ::KubeDSL::DSLObject
3
+ object_field(:image) { Kuby::CRDB::DSL::CRDB::V1alpha1::SpecImage.new }
4
+ value_field :additional_args
5
+ value_field :min_available
6
+ value_field :max_sql_memory
7
+ value_field :cache
8
+ value_field :tls_enabled
9
+ key_value_field(:node_selector, format: :string)
10
+ value_field :http_port
11
+ object_field(:affinity) { Kuby::CRDB::DSL::CRDB::V1alpha1::SpecAffinity.new }
12
+ value_field :tolerations
13
+ value_field :nodes
14
+ value_field :cockroach_db_version
15
+ object_field(:resources) { Kuby::CRDB::DSL::CRDB::V1alpha1::SpecResources.new }
16
+ key_value_field(:additional_annotations, format: :string)
17
+ value_field :client_tls_secret
18
+ key_value_field(:additional_labels, format: :string)
19
+ value_field :sql_port
20
+ value_field :max_unavailable
21
+ value_field :node_tls_secret
22
+ value_field :pod_env_variables
23
+ object_field(:data_store) { Kuby::CRDB::DSL::CRDB::V1alpha1::SpecDataStore.new }
24
+ value_field :grpc_port
25
+
26
+ validates :image, object: { kind_of: Kuby::CRDB::DSL::CRDB::V1alpha1::SpecImage }
27
+ validates :additional_args, field: { format: :string }, presence: false
28
+ validates :min_available, field: { format: :integer }, presence: true
29
+ validates :max_sql_memory, field: { format: :string }, presence: false
30
+ validates :cache, field: { format: :string }, presence: false
31
+ validates :tls_enabled, field: { format: :boolean }, presence: true
32
+ validates :node_selector, kv: { value_format: :string }, presence: true
33
+ validates :http_port, field: { format: :integer }, presence: true
34
+ validates :affinity, object: { kind_of: Kuby::CRDB::DSL::CRDB::V1alpha1::SpecAffinity }
35
+ validates :tolerations, field: { format: :string }, presence: false
36
+ validates :nodes, field: { format: :integer }, presence: true
37
+ validates :cockroach_db_version, field: { format: :string }, presence: false
38
+ validates :resources, object: { kind_of: Kuby::CRDB::DSL::CRDB::V1alpha1::SpecResources }
39
+ validates :additional_annotations, kv: { value_format: :string }, presence: true
40
+ validates :client_tls_secret, field: { format: :string }, presence: false
41
+ validates :additional_labels, kv: { value_format: :string }, presence: true
42
+ validates :sql_port, field: { format: :integer }, presence: true
43
+ validates :max_unavailable, field: { format: :integer }, presence: true
44
+ validates :node_tls_secret, field: { format: :string }, presence: false
45
+ validates :pod_env_variables, field: { format: :string }, presence: false
46
+ validates :data_store, object: { kind_of: Kuby::CRDB::DSL::CRDB::V1alpha1::SpecDataStore }
47
+ validates :grpc_port, field: { format: :integer }, presence: true
48
+
49
+ def serialize
50
+ {}.tap do |result|
51
+ result[:image] = image.serialize
52
+ result[:additionalArgs] = additional_args
53
+ result[:minAvailable] = min_available
54
+ result[:maxSQLMemory] = max_sql_memory
55
+ result[:cache] = cache
56
+ result[:tlsEnabled] = tls_enabled
57
+ result[:nodeSelector] = node_selector.serialize
58
+ result[:httpPort] = http_port
59
+ result[:affinity] = affinity.serialize
60
+ result[:tolerations] = tolerations
61
+ result[:nodes] = nodes
62
+ result[:cockroachDBVersion] = cockroach_db_version
63
+ result[:resources] = resources.serialize
64
+ result[:additionalAnnotations] = additional_annotations.serialize
65
+ result[:clientTLSSecret] = client_tls_secret
66
+ result[:additionalLabels] = additional_labels.serialize
67
+ result[:sqlPort] = sql_port
68
+ result[:maxUnavailable] = max_unavailable
69
+ result[:nodeTLSSecret] = node_tls_secret
70
+ result[:podEnvVariables] = pod_env_variables
71
+ result[:dataStore] = data_store.serialize
72
+ result[:grpcPort] = grpc_port
73
+ end
74
+ end
75
+
76
+ def kind_sym
77
+ :spec
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,23 @@
1
+ module Kuby::CRDB::DSL::CRDB::V1alpha1
2
+ class SpecAffinity < ::KubeDSL::DSLObject
3
+ object_field(:pod_affinity) { Kuby::CRDB::DSL::CRDB::V1alpha1::SpecAffinityPodAffinity.new }
4
+ object_field(:node_affinity) { Kuby::CRDB::DSL::CRDB::V1alpha1::SpecAffinityNodeAffinity.new }
5
+ object_field(:pod_anti_affinity) { Kuby::CRDB::DSL::CRDB::V1alpha1::SpecAffinityPodAntiAffinity.new }
6
+
7
+ validates :pod_affinity, object: { kind_of: Kuby::CRDB::DSL::CRDB::V1alpha1::SpecAffinityPodAffinity }
8
+ validates :node_affinity, object: { kind_of: Kuby::CRDB::DSL::CRDB::V1alpha1::SpecAffinityNodeAffinity }
9
+ validates :pod_anti_affinity, object: { kind_of: Kuby::CRDB::DSL::CRDB::V1alpha1::SpecAffinityPodAntiAffinity }
10
+
11
+ def serialize
12
+ {}.tap do |result|
13
+ result[:podAffinity] = pod_affinity.serialize
14
+ result[:nodeAffinity] = node_affinity.serialize
15
+ result[:podAntiAffinity] = pod_anti_affinity.serialize
16
+ end
17
+ end
18
+
19
+ def kind_sym
20
+ :spec_affinity
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,20 @@
1
+ module Kuby::CRDB::DSL::CRDB::V1alpha1
2
+ class SpecAffinityNodeAffinity < ::KubeDSL::DSLObject
3
+ object_field(:required_during_scheduling_ignored_during_execution) { Kuby::CRDB::DSL::CRDB::V1alpha1::SpecAffinityNodeAffinityRequiredDuringSchedulingIgnoredDuringExecution.new }
4
+ value_field :preferred_during_scheduling_ignored_during_execution
5
+
6
+ validates :required_during_scheduling_ignored_during_execution, object: { kind_of: Kuby::CRDB::DSL::CRDB::V1alpha1::SpecAffinityNodeAffinityRequiredDuringSchedulingIgnoredDuringExecution }
7
+ validates :preferred_during_scheduling_ignored_during_execution, field: { format: :string }, presence: false
8
+
9
+ def serialize
10
+ {}.tap do |result|
11
+ result[:requiredDuringSchedulingIgnoredDuringExecution] = required_during_scheduling_ignored_during_execution.serialize
12
+ result[:preferredDuringSchedulingIgnoredDuringExecution] = preferred_during_scheduling_ignored_during_execution
13
+ end
14
+ end
15
+
16
+ def kind_sym
17
+ :spec_affinity_node_affinity
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,17 @@
1
+ module Kuby::CRDB::DSL::CRDB::V1alpha1
2
+ class SpecAffinityNodeAffinityRequiredDuringSchedulingIgnoredDuringExecution < ::KubeDSL::DSLObject
3
+ value_field :node_selector_terms
4
+
5
+ validates :node_selector_terms, field: { format: :string }, presence: true
6
+
7
+ def serialize
8
+ {}.tap do |result|
9
+ result[:nodeSelectorTerms] = node_selector_terms
10
+ end
11
+ end
12
+
13
+ def kind_sym
14
+ :spec_affinity_node_affinity_required_during_scheduling_ignored_during_execution
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,20 @@
1
+ module Kuby::CRDB::DSL::CRDB::V1alpha1
2
+ class SpecAffinityPodAffinity < ::KubeDSL::DSLObject
3
+ value_field :required_during_scheduling_ignored_during_execution
4
+ value_field :preferred_during_scheduling_ignored_during_execution
5
+
6
+ validates :required_during_scheduling_ignored_during_execution, field: { format: :string }, presence: false
7
+ validates :preferred_during_scheduling_ignored_during_execution, field: { format: :string }, presence: false
8
+
9
+ def serialize
10
+ {}.tap do |result|
11
+ result[:requiredDuringSchedulingIgnoredDuringExecution] = required_during_scheduling_ignored_during_execution
12
+ result[:preferredDuringSchedulingIgnoredDuringExecution] = preferred_during_scheduling_ignored_during_execution
13
+ end
14
+ end
15
+
16
+ def kind_sym
17
+ :spec_affinity_pod_affinity
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ module Kuby::CRDB::DSL::CRDB::V1alpha1
2
+ class SpecAffinityPodAntiAffinity < ::KubeDSL::DSLObject
3
+ value_field :required_during_scheduling_ignored_during_execution
4
+ value_field :preferred_during_scheduling_ignored_during_execution
5
+
6
+ validates :required_during_scheduling_ignored_during_execution, field: { format: :string }, presence: false
7
+ validates :preferred_during_scheduling_ignored_during_execution, field: { format: :string }, presence: false
8
+
9
+ def serialize
10
+ {}.tap do |result|
11
+ result[:requiredDuringSchedulingIgnoredDuringExecution] = required_during_scheduling_ignored_during_execution
12
+ result[:preferredDuringSchedulingIgnoredDuringExecution] = preferred_during_scheduling_ignored_during_execution
13
+ end
14
+ end
15
+
16
+ def kind_sym
17
+ :spec_affinity_pod_anti_affinity
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,23 @@
1
+ module Kuby::CRDB::DSL::CRDB::V1alpha1
2
+ class SpecDataStore < ::KubeDSL::DSLObject
3
+ object_field(:pvc) { Kuby::CRDB::DSL::CRDB::V1alpha1::SpecDataStorePvc.new }
4
+ value_field :supports_auto_resize
5
+ object_field(:host_path) { Kuby::CRDB::DSL::CRDB::V1alpha1::SpecDataStoreHostPath.new }
6
+
7
+ validates :pvc, object: { kind_of: Kuby::CRDB::DSL::CRDB::V1alpha1::SpecDataStorePvc }
8
+ validates :supports_auto_resize, field: { format: :boolean }, presence: true
9
+ validates :host_path, object: { kind_of: Kuby::CRDB::DSL::CRDB::V1alpha1::SpecDataStoreHostPath }
10
+
11
+ def serialize
12
+ {}.tap do |result|
13
+ result[:pvc] = pvc.serialize
14
+ result[:supportsAutoResize] = supports_auto_resize
15
+ result[:hostPath] = host_path.serialize
16
+ end
17
+ end
18
+
19
+ def kind_sym
20
+ :spec_data_store
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,20 @@
1
+ module Kuby::CRDB::DSL::CRDB::V1alpha1
2
+ class SpecDataStoreHostPath < ::KubeDSL::DSLObject
3
+ value_field :path
4
+ value_field :type
5
+
6
+ validates :path, field: { format: :string }, presence: true
7
+ validates :type, field: { format: :string }, presence: false
8
+
9
+ def serialize
10
+ {}.tap do |result|
11
+ result[:path] = path
12
+ result[:type] = type
13
+ end
14
+ end
15
+
16
+ def kind_sym
17
+ :spec_data_store_host_path
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ module Kuby::CRDB::DSL::CRDB::V1alpha1
2
+ class SpecDataStorePvc < ::KubeDSL::DSLObject
3
+ object_field(:source) { Kuby::CRDB::DSL::CRDB::V1alpha1::SpecDataStorePvcSource.new }
4
+ object_field(:spec) { Kuby::CRDB::DSL::CRDB::V1alpha1::SpecDataStorePvcSpec.new }
5
+
6
+ validates :source, object: { kind_of: Kuby::CRDB::DSL::CRDB::V1alpha1::SpecDataStorePvcSource }
7
+ validates :spec, object: { kind_of: Kuby::CRDB::DSL::CRDB::V1alpha1::SpecDataStorePvcSpec }
8
+
9
+ def serialize
10
+ {}.tap do |result|
11
+ result[:source] = source.serialize
12
+ result[:spec] = spec.serialize
13
+ end
14
+ end
15
+
16
+ def kind_sym
17
+ :spec_data_store_pvc
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ module Kuby::CRDB::DSL::CRDB::V1alpha1
2
+ class SpecDataStorePvcSource < ::KubeDSL::DSLObject
3
+ value_field :read_only
4
+ value_field :claim_name
5
+
6
+ validates :read_only, field: { format: :boolean }, presence: true
7
+ validates :claim_name, field: { format: :string }, presence: true
8
+
9
+ def serialize
10
+ {}.tap do |result|
11
+ result[:readOnly] = read_only
12
+ result[:claimName] = claim_name
13
+ end
14
+ end
15
+
16
+ def kind_sym
17
+ :spec_data_store_pvc_source
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,35 @@
1
+ module Kuby::CRDB::DSL::CRDB::V1alpha1
2
+ class SpecDataStorePvcSpec < ::KubeDSL::DSLObject
3
+ value_field :storage_class_name
4
+ value_field :volume_mode
5
+ object_field(:selector) { Kuby::CRDB::DSL::CRDB::V1alpha1::SpecDataStorePvcSpecSelector.new }
6
+ value_field :access_modes
7
+ object_field(:data_source) { Kuby::CRDB::DSL::CRDB::V1alpha1::SpecDataStorePvcSpecDataSource.new }
8
+ value_field :volume_name
9
+ object_field(:resources) { Kuby::CRDB::DSL::CRDB::V1alpha1::SpecDataStorePvcSpecResources.new }
10
+
11
+ validates :storage_class_name, field: { format: :string }, presence: false
12
+ validates :volume_mode, field: { format: :string }, presence: false
13
+ validates :selector, object: { kind_of: Kuby::CRDB::DSL::CRDB::V1alpha1::SpecDataStorePvcSpecSelector }
14
+ validates :access_modes, field: { format: :string }, presence: false
15
+ validates :data_source, object: { kind_of: Kuby::CRDB::DSL::CRDB::V1alpha1::SpecDataStorePvcSpecDataSource }
16
+ validates :volume_name, field: { format: :string }, presence: false
17
+ validates :resources, object: { kind_of: Kuby::CRDB::DSL::CRDB::V1alpha1::SpecDataStorePvcSpecResources }
18
+
19
+ def serialize
20
+ {}.tap do |result|
21
+ result[:storageClassName] = storage_class_name
22
+ result[:volumeMode] = volume_mode
23
+ result[:selector] = selector.serialize
24
+ result[:accessModes] = access_modes
25
+ result[:dataSource] = data_source.serialize
26
+ result[:volumeName] = volume_name
27
+ result[:resources] = resources.serialize
28
+ end
29
+ end
30
+
31
+ def kind_sym
32
+ :spec_data_store_pvc_spec
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,23 @@
1
+ module Kuby::CRDB::DSL::CRDB::V1alpha1
2
+ class SpecDataStorePvcSpecDataSource < ::KubeDSL::DSLObject
3
+ value_field :api_group
4
+ value_field :kind
5
+ value_field :name
6
+
7
+ validates :api_group, field: { format: :string }, presence: false
8
+ validates :kind, field: { format: :string }, presence: true
9
+ validates :name, field: { format: :string }, presence: true
10
+
11
+ def serialize
12
+ {}.tap do |result|
13
+ result[:apiGroup] = api_group
14
+ result[:kind] = kind
15
+ result[:name] = name
16
+ end
17
+ end
18
+
19
+ def kind_sym
20
+ :spec_data_store_pvc_spec_data_source
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,20 @@
1
+ module Kuby::CRDB::DSL::CRDB::V1alpha1
2
+ class SpecDataStorePvcSpecResources < ::KubeDSL::DSLObject
3
+ key_value_field(:requests, format: :string)
4
+ key_value_field(:limits, format: :string)
5
+
6
+ validates :requests, kv: { value_format: :string }, presence: true
7
+ validates :limits, kv: { value_format: :string }, presence: true
8
+
9
+ def serialize
10
+ {}.tap do |result|
11
+ result[:requests] = requests.serialize
12
+ result[:limits] = limits.serialize
13
+ end
14
+ end
15
+
16
+ def kind_sym
17
+ :spec_data_store_pvc_spec_resources
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ module Kuby::CRDB::DSL::CRDB::V1alpha1
2
+ class SpecDataStorePvcSpecSelector < ::KubeDSL::DSLObject
3
+ key_value_field(:match_labels, format: :string)
4
+ value_field :match_expressions
5
+
6
+ validates :match_labels, kv: { value_format: :string }, presence: true
7
+ validates :match_expressions, field: { format: :string }, presence: false
8
+
9
+ def serialize
10
+ {}.tap do |result|
11
+ result[:matchLabels] = match_labels.serialize
12
+ result[:matchExpressions] = match_expressions
13
+ end
14
+ end
15
+
16
+ def kind_sym
17
+ :spec_data_store_pvc_spec_selector
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,23 @@
1
+ module Kuby::CRDB::DSL::CRDB::V1alpha1
2
+ class SpecImage < ::KubeDSL::DSLObject
3
+ value_field :pull_policy
4
+ value_field :name
5
+ value_field :pull_secret
6
+
7
+ validates :pull_policy, field: { format: :string }, presence: false
8
+ validates :name, field: { format: :string }, presence: true
9
+ validates :pull_secret, field: { format: :string }, presence: false
10
+
11
+ def serialize
12
+ {}.tap do |result|
13
+ result[:pullPolicy] = pull_policy
14
+ result[:name] = name
15
+ result[:pullSecret] = pull_secret
16
+ end
17
+ end
18
+
19
+ def kind_sym
20
+ :spec_image
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,20 @@
1
+ module Kuby::CRDB::DSL::CRDB::V1alpha1
2
+ class SpecResources < ::KubeDSL::DSLObject
3
+ key_value_field(:requests, format: :string)
4
+ key_value_field(:limits, format: :string)
5
+
6
+ validates :requests, kv: { value_format: :string }, presence: true
7
+ validates :limits, kv: { value_format: :string }, presence: true
8
+
9
+ def serialize
10
+ {}.tap do |result|
11
+ result[:requests] = requests.serialize
12
+ result[:limits] = limits.serialize
13
+ end
14
+ end
15
+
16
+ def kind_sym
17
+ :spec_resources
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,29 @@
1
+ module Kuby::CRDB::DSL::CRDB::V1alpha1
2
+ class Status < ::KubeDSL::DSLObject
3
+ value_field :cluster_status
4
+ value_field :version
5
+ value_field :conditions
6
+ value_field :operator_actions
7
+ value_field :crdbcontainerimage
8
+
9
+ validates :cluster_status, field: { format: :string }, presence: false
10
+ validates :version, field: { format: :string }, presence: false
11
+ validates :conditions, field: { format: :string }, presence: false
12
+ validates :operator_actions, field: { format: :string }, presence: false
13
+ validates :crdbcontainerimage, field: { format: :string }, presence: false
14
+
15
+ def serialize
16
+ {}.tap do |result|
17
+ result[:clusterStatus] = cluster_status
18
+ result[:version] = version
19
+ result[:conditions] = conditions
20
+ result[:operatorActions] = operator_actions
21
+ result[:crdbcontainerimage] = crdbcontainerimage
22
+ end
23
+ end
24
+
25
+ def kind_sym
26
+ :status
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,21 @@
1
+ module Kuby::CRDB::DSL::CRDB::V1alpha1
2
+ autoload :Status, 'kuby/crdb/dsl/crdb/v1alpha1/status'
3
+ autoload :SpecImage, 'kuby/crdb/dsl/crdb/v1alpha1/spec_image'
4
+ autoload :SpecAffinityPodAffinity, 'kuby/crdb/dsl/crdb/v1alpha1/spec_affinity_pod_affinity'
5
+ autoload :SpecAffinityNodeAffinityRequiredDuringSchedulingIgnoredDuringExecution, 'kuby/crdb/dsl/crdb/v1alpha1/spec_affinity_node_affinity_required_during_scheduling_ignored_during_execution'
6
+ autoload :SpecAffinityNodeAffinity, 'kuby/crdb/dsl/crdb/v1alpha1/spec_affinity_node_affinity'
7
+ autoload :SpecAffinityPodAntiAffinity, 'kuby/crdb/dsl/crdb/v1alpha1/spec_affinity_pod_anti_affinity'
8
+ autoload :SpecAffinity, 'kuby/crdb/dsl/crdb/v1alpha1/spec_affinity'
9
+ autoload :SpecResources, 'kuby/crdb/dsl/crdb/v1alpha1/spec_resources'
10
+ autoload :SpecDataStorePvcSource, 'kuby/crdb/dsl/crdb/v1alpha1/spec_data_store_pvc_source'
11
+ autoload :SpecDataStorePvcSpecSelector, 'kuby/crdb/dsl/crdb/v1alpha1/spec_data_store_pvc_spec_selector'
12
+ autoload :SpecDataStorePvcSpecDataSource, 'kuby/crdb/dsl/crdb/v1alpha1/spec_data_store_pvc_spec_data_source'
13
+ autoload :SpecDataStorePvcSpecResources, 'kuby/crdb/dsl/crdb/v1alpha1/spec_data_store_pvc_spec_resources'
14
+ autoload :SpecDataStorePvcSpec, 'kuby/crdb/dsl/crdb/v1alpha1/spec_data_store_pvc_spec'
15
+ autoload :SpecDataStorePvc, 'kuby/crdb/dsl/crdb/v1alpha1/spec_data_store_pvc'
16
+ autoload :SpecDataStoreHostPath, 'kuby/crdb/dsl/crdb/v1alpha1/spec_data_store_host_path'
17
+ autoload :SpecDataStore, 'kuby/crdb/dsl/crdb/v1alpha1/spec_data_store'
18
+ autoload :Spec, 'kuby/crdb/dsl/crdb/v1alpha1/spec'
19
+ autoload :CrdbClusterList, 'kuby/crdb/dsl/crdb/v1alpha1/crdb_cluster_list'
20
+ autoload :CrdbCluster, 'kuby/crdb/dsl/crdb/v1alpha1/crdb_cluster'
21
+ end
@@ -0,0 +1,3 @@
1
+ module Kuby::CRDB::DSL::CRDB
2
+ autoload :V1alpha1, 'kuby/crdb/dsl/crdb/v1alpha1'
3
+ end
@@ -0,0 +1,3 @@
1
+ module Kuby::CRDB::DSL
2
+ autoload :CRDB, 'kuby/crdb/dsl/crdb'
3
+ end
@@ -0,0 +1,15 @@
1
+ module Kuby::CRDB::Entrypoint
2
+ def crdb_cluster_list(&block)
3
+ ::Kuby::CRDB::DSL::CRDB::V1alpha1::CrdbClusterList.new do
4
+ api_version 'crdb.cockroachlabs.com/v1alpha1'
5
+ instance_eval(&block)
6
+ end
7
+ end
8
+
9
+ def crdb_cluster(&block)
10
+ ::Kuby::CRDB::DSL::CRDB::V1alpha1::CrdbCluster.new do
11
+ api_version 'crdb.cockroachlabs.com/v1alpha1'
12
+ instance_eval(&block)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,160 @@
1
+ require 'kuby'
2
+ require 'kuby/crdb/version'
3
+
4
+ module Kuby
5
+ module CRDB
6
+ class CRDBError < StandardError; end
7
+ class OperatorDeployError < CRDBError; end
8
+ class APIResourcesError < CRDBError; end
9
+
10
+ class Plugin < ::Kuby::Plugin
11
+ CRD_URL = "https://raw.githubusercontent.com/cockroachdb/cockroach-operator/v#{Kuby::CRDB::CRDB_OPERATOR_VERSION}/install/crds.yaml".freeze
12
+ OPERATOR_URL = "https://raw.githubusercontent.com/cockroachdb/cockroach-operator/v#{Kuby::CRDB::CRDB_OPERATOR_VERSION}/install/operator.yaml".freeze
13
+ NAMESPACE = 'cockroach-operator-system'.freeze
14
+ OPERATOR_DEPLOYMENT_NAME = 'cockroach-operator-manager'.freeze
15
+ WAIT_INTERVAL = 5 # seconds
16
+ WAIT_MAX = 120 # seconds
17
+
18
+ REPLICA_SET_MATCH_LABELS = {
19
+ 'app' => 'cockroach-operator'
20
+ }
21
+
22
+ REPLICA_SET_MATCH_LABELS.freeze
23
+
24
+ def setup
25
+ Kuby.logger.info('Deploying CockroachDB operator')
26
+ operator_deployed? ? upgrade_operator : install_operator
27
+
28
+ wait_for_operator do
29
+ Kuby.logger.info('Waiting for CockroachDB operator deployment')
30
+ end
31
+
32
+ wait_for_api_resources do
33
+ Kuby.logger.info('Waiting for API resources to become available')
34
+ end
35
+
36
+ Kuby.logger.info('CockroachDB setup finished')
37
+ end
38
+
39
+ private
40
+
41
+ def install_operator
42
+ kubernetes_cli.apply_uri(CRD_URL)
43
+ kubernetes_cli.apply_uri(OPERATOR_URL)
44
+ end
45
+
46
+ def upgrade_operator
47
+ # TODO: add upgrade logic
48
+ end
49
+
50
+ def wait_for_operator
51
+ time_elapsed = 0
52
+
53
+ loop do
54
+ break if operator_ready?
55
+
56
+ if time_elapsed >= WAIT_MAX
57
+ raise OperatorDeployError, 'timeout waiting for operator to start. '\
58
+ "Waited #{time_elapsed}s."
59
+ end
60
+
61
+ yield
62
+
63
+ sleep WAIT_INTERVAL
64
+ time_elapsed += WAIT_INTERVAL
65
+ end
66
+ end
67
+
68
+ def wait_for_api_resources
69
+ time_elapsed = 0
70
+
71
+ loop do
72
+ begin
73
+ if time_elapsed >= WAIT_MAX
74
+ raise APIResourcesError, 'timeout waiting for API resources to '\
75
+ "become available. Waited #{time_elapsed}s."
76
+ end
77
+
78
+ kubernetes_cli.api_resources
79
+ break
80
+ rescue KubernetesCLI::KubernetesError
81
+ yield
82
+ sleep WAIT_INTERVAL
83
+ time_elapsed += WAIT_INTERVAL
84
+ end
85
+ end
86
+ end
87
+
88
+ def operator_ready?
89
+ depl = operator_deployment
90
+ rs = find_operator_rs(depl)
91
+ return false unless depl && rs
92
+
93
+ observed_generation = depl.dig('status', 'observedGeneration')
94
+ current_generation = depl.dig('metadata', 'generation')
95
+ return false unless observed_generation == current_generation
96
+
97
+ rollout_data = { 'replicas' => 0 }.merge(
98
+ depl['status'].slice(
99
+ *%w(replicas updatedReplicas availableReplicas unavailableReplicas)
100
+ )
101
+ )
102
+
103
+ desired_replicas = depl['spec']['replicas'].to_i
104
+ rs_desired_replicas = rs['spec']['replicas'].to_i
105
+
106
+ rs_ready?(rs) &&
107
+ rs_desired_replicas == desired_replicas &&
108
+ rollout_data['updatedReplicas'].to_i == desired_replicas &&
109
+ rollout_data['updatedReplicas'].to_i == rollout_data['availableReplicas'].to_i
110
+ end
111
+
112
+ def rs_ready?(rs)
113
+ observed_generation = rs.dig('status', 'observedGeneration')
114
+ current_generation = rs.dig('metadata', 'generation')
115
+ return false if observed_generation != current_generation
116
+
117
+ rollout_data = { "replicas" => 0 }.merge(
118
+ rs['status'].slice('replicas', 'availableReplicas', 'readyReplicas')
119
+ )
120
+
121
+ desired_replicas = rs['spec']['replicas'].to_i
122
+ desired_replicas == rollout_data['availableReplicas'].to_i &&
123
+ desired_replicas == rollout_data['readyReplicas'].to_i
124
+ end
125
+
126
+ def operator_deployment
127
+ kubernetes_cli.get_object(
128
+ 'Deployment', NAMESPACE, OPERATOR_DEPLOYMENT_NAME
129
+ )
130
+ rescue ::KubernetesCLI::GetResourceError
131
+ nil
132
+ end
133
+
134
+ def find_operator_rs(depl)
135
+ all_rs_data = kubernetes_cli.get_objects('ReplicaSet', NAMESPACE, REPLICA_SET_MATCH_LABELS)
136
+ current_revision = depl.dig('metadata', 'annotations', 'deployment.kubernetes.io/revision')
137
+
138
+ all_rs_data.find do |rs|
139
+ rs.dig('metadata', 'ownerReferences').any? { |ref| ref['uid'] == depl.dig('metadata', 'uid') } &&
140
+ rs.dig('metadata', 'annotations', 'deployment.kubernetes.io/revision') == current_revision
141
+ end
142
+ rescue ::KubernetesCLI::GetResourceError
143
+ nil
144
+ end
145
+
146
+ def operator_deployed?
147
+ # TODO
148
+ false
149
+ end
150
+
151
+ def kubernetes_cli
152
+ provider.kubernetes_cli
153
+ end
154
+
155
+ def provider
156
+ environment.kubernetes.provider
157
+ end
158
+ end
159
+ end
160
+ end
@@ -0,0 +1,6 @@
1
+ module Kuby
2
+ module CRDB
3
+ VERSION = '0.1.0'.freeze
4
+ CRDB_OPERATOR_VERSION = '2.4.0'
5
+ end
6
+ end
data/lib/kuby/crdb.rb ADDED
@@ -0,0 +1,13 @@
1
+ require 'kube-dsl'
2
+
3
+ module Kuby
4
+ module CRDB
5
+ autoload :DSL, 'kuby/crdb/dsl'
6
+ autoload :Entrypoint, 'kuby/crdb/entrypoint'
7
+ autoload :Plugin, 'kuby/crdb/plugin'
8
+
9
+ extend Entrypoint
10
+ end
11
+ end
12
+
13
+ Kuby.register_plugin(:crdb, ::Kuby::CRDB::Plugin)
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kuby-crdb
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Cameron Dutro
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-05-05 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: kube-dsl
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '0.7'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '0.7'
27
+ description: CockroachDB plugin for Kuby.
28
+ email:
29
+ - camertron@gmail.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - CHANGELOG.md
35
+ - Gemfile
36
+ - LICENSE
37
+ - Rakefile
38
+ - kuby-crdb.gemspec
39
+ - lib/kuby/crdb.rb
40
+ - lib/kuby/crdb/dsl.rb
41
+ - lib/kuby/crdb/dsl/crdb.rb
42
+ - lib/kuby/crdb/dsl/crdb/v1alpha1.rb
43
+ - lib/kuby/crdb/dsl/crdb/v1alpha1/crdb_cluster.rb
44
+ - lib/kuby/crdb/dsl/crdb/v1alpha1/crdb_cluster_list.rb
45
+ - lib/kuby/crdb/dsl/crdb/v1alpha1/spec.rb
46
+ - lib/kuby/crdb/dsl/crdb/v1alpha1/spec_affinity.rb
47
+ - lib/kuby/crdb/dsl/crdb/v1alpha1/spec_affinity_node_affinity.rb
48
+ - lib/kuby/crdb/dsl/crdb/v1alpha1/spec_affinity_node_affinity_required_during_scheduling_ignored_during_execution.rb
49
+ - lib/kuby/crdb/dsl/crdb/v1alpha1/spec_affinity_pod_affinity.rb
50
+ - lib/kuby/crdb/dsl/crdb/v1alpha1/spec_affinity_pod_anti_affinity.rb
51
+ - lib/kuby/crdb/dsl/crdb/v1alpha1/spec_data_store.rb
52
+ - lib/kuby/crdb/dsl/crdb/v1alpha1/spec_data_store_host_path.rb
53
+ - lib/kuby/crdb/dsl/crdb/v1alpha1/spec_data_store_pvc.rb
54
+ - lib/kuby/crdb/dsl/crdb/v1alpha1/spec_data_store_pvc_source.rb
55
+ - lib/kuby/crdb/dsl/crdb/v1alpha1/spec_data_store_pvc_spec.rb
56
+ - lib/kuby/crdb/dsl/crdb/v1alpha1/spec_data_store_pvc_spec_data_source.rb
57
+ - lib/kuby/crdb/dsl/crdb/v1alpha1/spec_data_store_pvc_spec_resources.rb
58
+ - lib/kuby/crdb/dsl/crdb/v1alpha1/spec_data_store_pvc_spec_selector.rb
59
+ - lib/kuby/crdb/dsl/crdb/v1alpha1/spec_image.rb
60
+ - lib/kuby/crdb/dsl/crdb/v1alpha1/spec_resources.rb
61
+ - lib/kuby/crdb/dsl/crdb/v1alpha1/status.rb
62
+ - lib/kuby/crdb/entrypoint.rb
63
+ - lib/kuby/crdb/plugin.rb
64
+ - lib/kuby/crdb/version.rb
65
+ homepage: http://github.com/getkuby/kuby-crdb
66
+ licenses: []
67
+ metadata: {}
68
+ post_install_message:
69
+ rdoc_options: []
70
+ require_paths:
71
+ - lib
72
+ required_ruby_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ requirements: []
83
+ rubygems_version: 3.2.22
84
+ signing_key:
85
+ specification_version: 4
86
+ summary: CockroachDB plugin for Kuby.
87
+ test_files: []