-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathRakefile
170 lines (135 loc) · 5.09 KB
/
Rakefile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
require 'bundler'
require 'rspec/core/rake_task'
require 'rubygems/package_task'
require 'sorbet-runtime'
require 'kuby/cert-manager'
Bundler::GemHelper.install_tasks
task default: :spec
desc 'Run specs'
RSpec::Core::RakeTask.new do |t|
t.pattern = './spec/**/*_spec.rb'
end
task generate: [:schemagen, :codegen]
task :schemagen do
require 'base64'
require 'json'
require 'kind-rb'
require 'net/http'
require 'uri'
require 'yaml'
# delete first just in case
system("#{KindRb.executable} delete cluster --name kuby-cert-manager")
system("#{KindRb.executable} create cluster --name kuby-cert-manager")
system("kubectl apply -f https://github.com/jetstack/cert-manager/releases/download/v#{Kuby::CertManager::Plugin::CERT_MANAGER_VERSION}/cert-manager.yaml")
cluster_name = 'kind-kuby-cert-manager'
kubeconfig = YAML.load_file(File.join(Dir.home, '.kube', 'config'))
cluster = kubeconfig['clusters'].find { |cluster| cluster['name'] == cluster_name }
ca_cert_data = Base64.decode64(cluster.dig(*%w(cluster certificate-authority-data)))
cert_store = OpenSSL::X509::Store.new
cert_store.add_cert(OpenSSL::X509::Certificate.new(ca_cert_data))
server = URI.parse(cluster.dig(*%w(cluster server)))
http = Net::HTTP.new(server.host, server.port).tap do |http|
http.use_ssl = true
http.cert_store = cert_store
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
end
token = nil
STDOUT.write("Getting API token from cluster...")
loop do
secrets = JSON.parse(`kubectl --context #{cluster_name} get secrets -o json`)
secret = secrets['items'].find do |secret|
secret.dig(*%w(metadata annotations kubernetes.io/service-account.name)) == 'default'
end
if secret
token = Base64.decode64(secret.dig(*%w(data token)))
puts ' done'
break
else
STDOUT.write('.')
sleep 1
end
end
get = Net::HTTP::Get.new('/openapi/v2')
get['Authorization'] = "Bearer #{token}"
crds = []
schema = nil
STDOUT.write("Requesting OpenAPI v2 schema from cluster...")
loop do
response = http.request(get)
schema = JSON.parse(response.body)
crds = schema['definitions'].each_with_object({}) do |(id, data), memo|
memo[id] = data if id.start_with?('io.cert-manager')
end
if crds.empty?
STDOUT.write('.')
sleep 1
else
puts ' done'
break
end
end
FileUtils.rm_rf('vendor')
FileUtils.mkdir('vendor')
schema = schema.merge('definitions' => crds)
File.write(File.join('vendor', 'open_api.json'), schema.to_json)
puts 'Pulling openapi2jsonschema Docker image'
system('docker pull garethr/openapi2jsonschema')
puts 'Converting OpenAPI format to JSON schema format'
system(<<~END)
docker run --rm \
-v #{File.expand_path('vendor')}:/usr/local/scratch \
garethr/openapi2jsonschema \
--kubernetes --output /usr/local/scratch/json_schema /usr/local/scratch/open_api.json
END
puts "Cleaning up"
system("#{KindRb.executable} delete cluster --name kuby-cert-manager")
end
task :codegen do
require 'pry-byebug'
require 'dry/inflector'
require 'fileutils'
# delete anything that should be re-generated
FileUtils.rm_rf('./lib/kuby/cert-manager/dsl.rb')
FileUtils.rm_rf('./lib/kuby/cert-manager/dsl')
FileUtils.rm_rf('./lib/kuby/cert-manager/entrypoint.rb')
FileUtils.rm_rf('./sorbet/rbi/kuby/cert-manager')
FileUtils.mkdir_p('./lib/kuby/cert-manager/dsl')
local_json_schema_path = 'vendor/json_schema'
generator = KubeDSL::Generator.new(
schema_dir: local_json_schema_path,
output_dir: File.join('lib'),
autoload_prefix: File.join('kuby', 'cert-manager', 'dsl'),
dsl_namespace: ['Kuby', 'CertManager', 'DSL'],
entrypoint_namespace: ['Kuby', 'CertManager'],
inflector: Dry::Inflector.new do |inflections|
inflections.acronym('DSL')
end
)
generator.builder.register_resolver('io.k8s') do |ref_str, builder|
external_ref = ::KubeDSL::ExternalRef.new(
ref_str,
['KubeDSL', 'DSL'],
builder.inflector,
builder.schema_dir,
builder.autoload_prefix,
builder.serialize_handlers
)
ns = external_ref.ruby_namespace + [external_ref.kind]
exists = ns.inject(Object) { |mod, n| mod.const_get(n, false) } rescue false
exists ? external_ref : builder.parse_ref(ref_str)
end
generator.builder.register_serialize_handler('cert-manager', 'v1', 'IssuerSpec', 'selfSigned') do |field, inflector|
"#{field.send(:ruby_safe_name)}_present? ? ::KubeDSL::AllowBlank.new(#{field.serialize_call(inflector)}) : nil"
end
generator.builder.register_serialize_handler('cert-manager', 'v1', 'ClusterIssuerSpec', 'selfSigned') do |field, inflector|
"#{field.send(:ruby_safe_name)}_present? ? ::KubeDSL::AllowBlank.new(#{field.serialize_call(inflector)}) : nil"
end
generator.generate_resource_files
generator.generate_autoload_files
generator.generate_entrypoint_file do |resource, ns|
# only generate entrypoint methods for resources defined at the top-level, i.e.
# not resources defined inside other resources
!resource.ref.inline?
end
FileUtils.rm_rf(File.join('lib', 'kuby.rb'))
end