dapp 0.29.2 → 0.30.0
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 +5 -5
- data/bin/dapp +1 -23
- data/config/en/net_status.yml +5 -4
- data/lib/dapp.rb +1 -1
- data/lib/dapp/dapp/sentry.rb +11 -8
- data/lib/dapp/dimg/dapp/command/cleanup_repo.rb +33 -21
- data/lib/dapp/dimg/dimg/git_artifact.rb +2 -5
- data/lib/dapp/dimg/git_artifact.rb +41 -23
- data/lib/dapp/dimg/git_repo/base.rb +19 -39
- data/lib/dapp/dimg/git_repo/local.rb +15 -14
- data/lib/dapp/dimg/git_repo/remote.rb +32 -19
- data/lib/dapp/kube/cli/command/kube/deploy.rb +4 -0
- data/lib/dapp/kube/cli/command/kube/dismiss.rb +4 -0
- data/lib/dapp/kube/cli/command/kube/lint.rb +4 -0
- data/lib/dapp/kube/cli/command/kube/render.rb +4 -0
- data/lib/dapp/kube/cli/command/kube/value_get.rb +4 -0
- data/lib/dapp/kube/dapp/command/common.rb +21 -18
- data/lib/dapp/kube/dapp/command/minikube_setup.rb +6 -2
- data/lib/dapp/kube/helm/release.rb +1 -1
- data/lib/dapp/kube/helm/values.rb +3 -3
- data/lib/dapp/kube/kubernetes/client.rb +21 -90
- data/lib/dapp/kube/kubernetes/config.rb +129 -0
- data/lib/dapp/version.rb +1 -1
- metadata +6 -44
- data/lib/dapp/deployment/app.rb +0 -120
- data/lib/dapp/deployment/cli/cli.rb +0 -1
- data/lib/dapp/deployment/cli/command/base.rb +0 -14
- data/lib/dapp/deployment/cli/command/deployment.rb +0 -18
- data/lib/dapp/deployment/cli/command/deployment/apply.rb +0 -26
- data/lib/dapp/deployment/cli/command/deployment/mrproper.rb +0 -13
- data/lib/dapp/deployment/config/config.rb +0 -46
- data/lib/dapp/deployment/config/directive/app.rb +0 -28
- data/lib/dapp/deployment/config/directive/app/instance_methods.rb +0 -51
- data/lib/dapp/deployment/config/directive/base.rb +0 -13
- data/lib/dapp/deployment/config/directive/deployment.rb +0 -11
- data/lib/dapp/deployment/config/directive/expose.rb +0 -68
- data/lib/dapp/deployment/config/directive/group.rb +0 -27
- data/lib/dapp/deployment/config/directive/job.rb +0 -28
- data/lib/dapp/deployment/config/directive/mod/group.rb +0 -22
- data/lib/dapp/deployment/config/directive/mod/jobs.rb +0 -26
- data/lib/dapp/deployment/config/directive/namespace.rb +0 -26
- data/lib/dapp/deployment/config/directive/namespace/instance_methods.rb +0 -37
- data/lib/dapp/deployment/core_ext/hash.rb +0 -19
- data/lib/dapp/deployment/dapp/command/apply.rb +0 -71
- data/lib/dapp/deployment/dapp/command/common.rb +0 -17
- data/lib/dapp/deployment/dapp/command/mrproper.rb +0 -12
- data/lib/dapp/deployment/dapp/dapp.rb +0 -15
- data/lib/dapp/deployment/dapp/dappfile.rb +0 -23
- data/lib/dapp/deployment/deployment.rb +0 -46
- data/lib/dapp/deployment/error/app.rb +0 -7
- data/lib/dapp/deployment/error/default.rb +0 -7
- data/lib/dapp/deployment/error/deployment.rb +0 -7
- data/lib/dapp/deployment/error/kubernetes.rb +0 -7
- data/lib/dapp/deployment/kube_app.rb +0 -146
- data/lib/dapp/deployment/kube_base.rb +0 -97
- data/lib/dapp/deployment/kube_deployment.rb +0 -51
- data/lib/dapp/deployment/kubernetes.rb +0 -174
- data/lib/dapp/deployment/kubernetes/error.rb +0 -20
- data/lib/dapp/deployment/mod/jobs.rb +0 -37
- data/lib/dapp/deployment/mod/namespace.rb +0 -58
- data/lib/dapp/deployment/mod/system_environments.rb +0 -30
- data/lib/dapp/deployment/secret.rb +0 -93
- data/lib/dapp/kube/error/kubernetes.rb +0 -7
@@ -1,146 +0,0 @@
|
|
1
|
-
module Dapp
|
2
|
-
module Deployment
|
3
|
-
class KubeApp < KubeBase
|
4
|
-
module Error
|
5
|
-
class Base < ::Dapp::Deployment::Error::Deployment
|
6
|
-
def initialize(**net_status)
|
7
|
-
super(**net_status, context: :kube_app)
|
8
|
-
end
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
attr_reader :app
|
13
|
-
|
14
|
-
def initialize(app)
|
15
|
-
@app = app
|
16
|
-
end
|
17
|
-
|
18
|
-
def deployment
|
19
|
-
app.deployment
|
20
|
-
end
|
21
|
-
|
22
|
-
def labels
|
23
|
-
deployment.kube.labels.merge('dapp-app' => app.name)
|
24
|
-
end
|
25
|
-
|
26
|
-
[[:deployment, 'Deployment'], [:service, 'Service']].each do |(type, resource_name)|
|
27
|
-
define_method "#{type}_exist?" do |name|
|
28
|
-
public_send("existing_#{type}s_names").include?(name)
|
29
|
-
end
|
30
|
-
|
31
|
-
define_method "existing_#{type}s_names" do
|
32
|
-
deployment.kubernetes.public_send(:"#{type}_list", labelSelector: labelSelector)['items'].map do |item|
|
33
|
-
item['metadata']['name']
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
define_method "#{type}_spec_changed?" do |name, spec|
|
38
|
-
current_spec = deployment.kubernetes.public_send(type, name)
|
39
|
-
current_spec != send(:"merge_kube_#{type}_spec", current_spec, spec)
|
40
|
-
end
|
41
|
-
|
42
|
-
define_method "delete_#{type}!" do |*args|
|
43
|
-
deployment.kubernetes.public_send(:"delete_#{type}!", *args)
|
44
|
-
end
|
45
|
-
|
46
|
-
define_method "apply_#{type}!" do |name, spec|
|
47
|
-
if app.kube.send(:"#{type}_exist?", name)
|
48
|
-
if app.kube.send(:"#{type}_spec_changed?", name, spec)
|
49
|
-
app.kube.send(:"replace_#{type}!", name, spec)
|
50
|
-
else
|
51
|
-
app.deployment.dapp.log_step("Kubernetes #{resource_name} #{name} is up to date")
|
52
|
-
end
|
53
|
-
else
|
54
|
-
app.kube.send(:"create_#{type}!", spec)
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
def create_service!(conf_spec)
|
60
|
-
srv = nil
|
61
|
-
app.deployment.dapp.log_process("Creating kubernetes Service #{conf_spec['metadata']['name']}") do
|
62
|
-
srv = app.deployment.kubernetes.create_service!(conf_spec)
|
63
|
-
end
|
64
|
-
_dump_service_info srv
|
65
|
-
end
|
66
|
-
|
67
|
-
def replace_service!(name, conf_spec)
|
68
|
-
srv = nil
|
69
|
-
app.deployment.dapp.log_process("Replacing kubernetes Service #{name}") do
|
70
|
-
old_spec = deployment.kubernetes.service(name)
|
71
|
-
new_spec = merge_kube_service_spec(old_spec, conf_spec)
|
72
|
-
srv = app.deployment.kubernetes.replace_service!(name, new_spec)
|
73
|
-
end
|
74
|
-
_dump_service_info srv
|
75
|
-
end
|
76
|
-
|
77
|
-
def _dump_service_info(srv)
|
78
|
-
app.deployment.dapp.log_info("type: #{srv['spec']['type']}")
|
79
|
-
app.deployment.dapp.log_info("clusterIP: #{srv['spec']['clusterIP']}")
|
80
|
-
|
81
|
-
srv['spec'].fetch('ports', []).each do |port|
|
82
|
-
app.deployment.dapp.log_info("Port #{port['port']}:")
|
83
|
-
app.deployment.dapp.with_log_indent do
|
84
|
-
%w(protocol targetPort nodePort).each do |field_name|
|
85
|
-
app.deployment.dapp.log_info("#{field_name}: #{_field_value_for_log(port[field_name])}")
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
|
91
|
-
def create_deployment!(conf_spec)
|
92
|
-
d = nil
|
93
|
-
app.deployment.dapp.log_process("Creating kubernetes Deployment #{conf_spec['metadata']['name']}") do
|
94
|
-
d = app.deployment.kubernetes.create_deployment!(conf_spec)
|
95
|
-
end
|
96
|
-
_wait_for_deployment(d)
|
97
|
-
end
|
98
|
-
|
99
|
-
def replace_deployment!(name, conf_spec)
|
100
|
-
d = nil
|
101
|
-
old_d_revision = nil
|
102
|
-
app.deployment.dapp.log_process("Replacing kubernetes Deployment #{name}") do
|
103
|
-
old_spec = deployment.kubernetes.deployment(name)
|
104
|
-
old_d_revision = old_spec.fetch('metadata', {}).fetch('annotations', {}).fetch('deployment.kubernetes.io/revision', nil)
|
105
|
-
new_spec = merge_kube_deployment_spec(old_spec, conf_spec)
|
106
|
-
new_spec.fetch('metadata', {}).fetch('annotations', {}).delete('deployment.kubernetes.io/revision')
|
107
|
-
d = app.deployment.kubernetes.replace_deployment!(name, new_spec)
|
108
|
-
end
|
109
|
-
_wait_for_deployment(d, old_d_revision: old_d_revision)
|
110
|
-
end
|
111
|
-
|
112
|
-
def _field_value_for_log(value)
|
113
|
-
value ? value : '-'
|
114
|
-
end
|
115
|
-
|
116
|
-
def merge_kube_deployment_spec(spec1, spec2)
|
117
|
-
merge_kube_controller_spec(spec1, spec2)
|
118
|
-
end
|
119
|
-
|
120
|
-
def merge_kube_service_spec(spec1, spec2)
|
121
|
-
spec1.kube_in_depth_merge(spec2).tap do |spec|
|
122
|
-
spec['metadata'] ||= {}
|
123
|
-
metadata_labels = spec2.fetch('metadata', {}).fetch('labels', nil)
|
124
|
-
spec['metadata']['labels'] = metadata_labels if metadata_labels
|
125
|
-
|
126
|
-
spec['spec'] ||= {}
|
127
|
-
spec_selector = spec2.fetch('spec', {}).fetch('selector', nil)
|
128
|
-
spec['spec']['selector'] = spec_selector if spec_selector
|
129
|
-
spec['spec']['ports'] = begin
|
130
|
-
ports1 = spec1.fetch('spec', {}).fetch('ports', [])
|
131
|
-
ports2 = spec2.fetch('spec', {}).fetch('ports', [])
|
132
|
-
ports2.map do |port2|
|
133
|
-
if (port1 = ports1.find { |p| p['name'] == port2['name'] }).nil?
|
134
|
-
port2
|
135
|
-
else
|
136
|
-
port = port1.merge(port2)
|
137
|
-
port.delete('nodePort') if spec['spec']['type'] == 'ClusterIP'
|
138
|
-
port
|
139
|
-
end
|
140
|
-
end
|
141
|
-
end
|
142
|
-
end
|
143
|
-
end
|
144
|
-
end
|
145
|
-
end
|
146
|
-
end
|
@@ -1,97 +0,0 @@
|
|
1
|
-
module Dapp
|
2
|
-
module Deployment
|
3
|
-
class KubeBase
|
4
|
-
def pod_exist?(name)
|
5
|
-
deployment.kubernetes.pod?(name, labelSelector: labelSelector)
|
6
|
-
end
|
7
|
-
|
8
|
-
def pod_succeeded?(name)
|
9
|
-
return false unless pod_exist?(name)
|
10
|
-
deployment.kubernetes.pod_status(name)['status']['phase'] == 'Succeeded'
|
11
|
-
end
|
12
|
-
|
13
|
-
def delete_pod!(name)
|
14
|
-
deployment.kubernetes.delete_pod!(name)
|
15
|
-
loop do
|
16
|
-
break unless deployment.kubernetes.pod?(name)
|
17
|
-
sleep 1
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def run_job!(spec, name)
|
22
|
-
current_spec = deployment.kubernetes.create_pod!(spec)
|
23
|
-
|
24
|
-
deployment.dapp.log_process(:pending) do
|
25
|
-
loop do
|
26
|
-
current_spec = deployment.kubernetes.pod_status(name)
|
27
|
-
break if current_spec['status']['phase'] != 'Pending'
|
28
|
-
unless current_spec['status']['containerStatuses'].nil?
|
29
|
-
current_spec['status']['containerStatuses'].first['state'].each do |_, desc|
|
30
|
-
if ['ErrImagePull', 'ImagePullBackOff'].include? desc['reason']
|
31
|
-
raise Error::Deployment,
|
32
|
-
code: :bootstrap_image_not_found,
|
33
|
-
data: { reason: desc['reason'], message: desc['message'] }
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
sleep 1
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
deployment.dapp.log_process(:running) do
|
42
|
-
log_thread = Thread.new do
|
43
|
-
begin
|
44
|
-
deployment.kubernetes.pod_log(name, follow: true) { |chunk| puts chunk }
|
45
|
-
rescue Kubernetes::Error::Timeout
|
46
|
-
deployment.dapp.log_warning('Pod log: read timeout reached!')
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
loop do
|
51
|
-
current_spec = deployment.kubernetes.pod_status(name)
|
52
|
-
break if current_spec['status']['phase'] != 'Running'
|
53
|
-
sleep 1
|
54
|
-
end
|
55
|
-
|
56
|
-
sleep 1 # last chance to get a message
|
57
|
-
log_thread.kill if log_thread.alive?
|
58
|
-
|
59
|
-
phase = current_spec['status']['phase']
|
60
|
-
if phase == 'Failed'
|
61
|
-
current_spec['status']['containerStatuses'].first['state'].each do |status, desc|
|
62
|
-
next if status == 'running'
|
63
|
-
raise Error::Deployment,
|
64
|
-
code: :bootstrap_command_failed,
|
65
|
-
data: { reason: desc['reason'], message: desc['message'], exit_code: desc['exitCode'] }
|
66
|
-
end
|
67
|
-
end
|
68
|
-
raise Error::Deployment,
|
69
|
-
code: :bootstrap_failed,
|
70
|
-
data: { phase: phase, message: current_spec['status']['message'] } unless phase == 'Succeeded'
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
def merge_kube_controller_spec(spec1, spec2)
|
75
|
-
spec1.kube_in_depth_merge(spec2).tap do |spec|
|
76
|
-
spec['spec']['template']['spec']['containers'] = begin
|
77
|
-
containers1 = spec1['spec']['template']['spec']['containers']
|
78
|
-
containers2 = spec2['spec']['template']['spec']['containers']
|
79
|
-
containers2.map do |container2|
|
80
|
-
if (container1 = containers1.find { |c| c['name'] == container2['name'] }).nil?
|
81
|
-
container2
|
82
|
-
else
|
83
|
-
container1.kube_in_depth_merge(container2)
|
84
|
-
end
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
|
90
|
-
protected
|
91
|
-
|
92
|
-
def labelSelector
|
93
|
-
labels.map {|key, value| "#{key}=#{value}"}.join(',')
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
@@ -1,51 +0,0 @@
|
|
1
|
-
module Dapp
|
2
|
-
module Deployment
|
3
|
-
class KubeDeployment < KubeBase
|
4
|
-
attr_reader :deployment
|
5
|
-
|
6
|
-
def initialize(deployment)
|
7
|
-
@deployment = deployment
|
8
|
-
end
|
9
|
-
|
10
|
-
def labels
|
11
|
-
{'dapp' => deployment.dapp.name, 'dapp-deployment-version' => 1.to_s}
|
12
|
-
end
|
13
|
-
|
14
|
-
def delete_unknown_resources!
|
15
|
-
# Удаление объектов, связанных с несуществующими более app'ами
|
16
|
-
known_apps_names = deployment.apps.map(&:name)
|
17
|
-
deployment.kubernetes.deployment_list(labelSelector: labelSelector)['items']
|
18
|
-
.reject do |item|
|
19
|
-
known_apps_names.include? item['metadata']['labels']['dapp-app']
|
20
|
-
end
|
21
|
-
.each do |item|
|
22
|
-
deployment.dapp.log "Deleting Deployment '#{item['metadata']['name']}': unknown app '#{item['metadata']['labels']['dapp-app']}'"
|
23
|
-
deployment.kubernetes.delete_deployment!(item['metadata']['name'])
|
24
|
-
end
|
25
|
-
deployment.kubernetes.service_list(labelSelector: labelSelector)['items']
|
26
|
-
.reject do |item|
|
27
|
-
known_apps_names.include? item['metadata']['labels']['dapp-app']
|
28
|
-
end
|
29
|
-
.each do |item|
|
30
|
-
deployment.dapp.log "Deleting Service '#{item['metadata']['name']}': unknown app '#{item['metadata']['labels']['dapp-app']}'"
|
31
|
-
deployment.kubernetes.delete_service!(item['metadata']['name'])
|
32
|
-
end
|
33
|
-
|
34
|
-
# Версионирование объектов из кода dapp, чтобы
|
35
|
-
# иметь возможность автоматом удалить объекты,
|
36
|
-
# созданные по старой логике
|
37
|
-
old_versions_selector = "dapp=#{labels['dapp']},dapp-deployment-version notin (#{labels['dapp-deployment-version']})"
|
38
|
-
deployment.kubernetes.deployment_list(labelSelector: old_versions_selector)['items']
|
39
|
-
.each do |item|
|
40
|
-
deployment.dapp.log "Deleting Deployment '#{item['metadata']['name']}': dapp-deployment-version changed from #{item['metadata']['labels']['dapp-deployment-version']} to #{labels['dapp-deployment-version']}"
|
41
|
-
deployment.kubernetes.delete_deployment!(item['metadata']['name'])
|
42
|
-
end
|
43
|
-
deployment.kubernetes.service_list(labelSelector: old_versions_selector)['items']
|
44
|
-
.each do |item|
|
45
|
-
deployment.dapp.log "Deleting Service '#{item['metadata']['name']}': dapp-deployment-version changed from #{item['metadata']['labels']['dapp-deployment-version']} to #{labels['dapp-deployment-version']}"
|
46
|
-
deployment.kubernetes.delete_service!(item['metadata']['name'])
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
@@ -1,174 +0,0 @@
|
|
1
|
-
module Dapp
|
2
|
-
module Deployment
|
3
|
-
class Kubernetes
|
4
|
-
def initialize(namespace: nil)
|
5
|
-
@namespace = namespace
|
6
|
-
@query_parameters = {}
|
7
|
-
end
|
8
|
-
|
9
|
-
def namespace
|
10
|
-
@namespace || 'default'
|
11
|
-
end
|
12
|
-
|
13
|
-
# Чтобы не перегружать методы явной передачей namespace.
|
14
|
-
# Данный метод может пригодиться только в ситуации, когда надо указать другой namespace,
|
15
|
-
# в большинстве случаев используется namespace из конструктора.
|
16
|
-
def with_namespace(namespace, &blk)
|
17
|
-
old_namespace = @namespace
|
18
|
-
begin
|
19
|
-
@namespace = namespace
|
20
|
-
return yield
|
21
|
-
ensure
|
22
|
-
@namespace = old_namespace
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
def with_query(query, &blk)
|
27
|
-
old_query = @query_parameters
|
28
|
-
begin
|
29
|
-
@query_parameters = query
|
30
|
-
return yield
|
31
|
-
ensure
|
32
|
-
@query_parameters = old_query
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
# NOTICE: Название метода аналогично kind'у выдаваемого результата.
|
37
|
-
# NOTICE: В данном случае в результате kind=DeploymentList.
|
38
|
-
# NOTICE: Методы создания/обновления/удаления сущностей kubernetes заканчиваются на '!'. Например, create_deployment!.
|
39
|
-
|
40
|
-
{
|
41
|
-
'/api/v1' => [:service, :replicationcontroller, :pod],
|
42
|
-
'/apis/extensions/v1beta1' => [:deployment, :replicaset]
|
43
|
-
}.each do |api, objects|
|
44
|
-
objects.each do |object|
|
45
|
-
define_method :"#{object}_list" do |**query_parameters|
|
46
|
-
request!(:get, "#{api}/namespaces/#{namespace}/#{object}s", **query_parameters)
|
47
|
-
end
|
48
|
-
|
49
|
-
define_method object do |name, **query_parameters|
|
50
|
-
request!(:get, "#{api}/namespaces/#{namespace}/#{object}s/#{name}", **query_parameters)
|
51
|
-
end
|
52
|
-
|
53
|
-
define_method "#{object}_status" do |name, **query_parameters|
|
54
|
-
request!(:get, "#{api}/namespaces/#{namespace}/#{object}s/#{name}/status", **query_parameters)
|
55
|
-
end
|
56
|
-
|
57
|
-
define_method :"create_#{object}!" do |spec, **query_parameters|
|
58
|
-
request!(:post, "#{api}/namespaces/#{namespace}/#{object}s", body: spec, **query_parameters)
|
59
|
-
end
|
60
|
-
|
61
|
-
define_method :"replace_#{object}!" do |name, spec, **query_parameters|
|
62
|
-
request!(:put, "#{api}/namespaces/#{namespace}/#{object}s/#{name}", body: spec, **query_parameters)
|
63
|
-
end
|
64
|
-
|
65
|
-
define_method :"delete_#{object}!" do |name, **query_parameters|
|
66
|
-
request!(:delete, "#{api}/namespaces/#{namespace}/#{object}s/#{name}", **query_parameters)
|
67
|
-
end
|
68
|
-
|
69
|
-
define_method :"delete_#{object}s!" do |**query_parameters|
|
70
|
-
request!(:delete, "#{api}/namespaces/#{namespace}/#{object}s", **query_parameters)
|
71
|
-
end
|
72
|
-
|
73
|
-
define_method :"#{object}?" do |name, **query_parameters|
|
74
|
-
public_send(:"#{object}_list", **query_parameters)['items'].map { |item| item['metadata']['name'] }.include?(name)
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
78
|
-
|
79
|
-
def pod_log(name, follow: false, **query_parameters, &blk)
|
80
|
-
excon_parameters = follow ? { response_block: blk } : {}
|
81
|
-
request!(:get,
|
82
|
-
"/api/v1/namespaces/#{namespace}/pods/#{name}/log",
|
83
|
-
excon_parameters: excon_parameters,
|
84
|
-
**{ follow: follow }.merge(query_parameters))
|
85
|
-
rescue Excon::Error::Timeout
|
86
|
-
raise Error::Timeout
|
87
|
-
end
|
88
|
-
|
89
|
-
def event_list(**query_parameters)
|
90
|
-
request!(:get, "/api/v1/namespaces/#{namespace}/events", **query_parameters)
|
91
|
-
end
|
92
|
-
|
93
|
-
protected
|
94
|
-
|
95
|
-
# query_parameters — соответствует 'Query Parameters' в документации kubernetes
|
96
|
-
# excon_parameters — соответствует опциям Excon
|
97
|
-
# body — hash для http-body, соответствует 'Body Parameters' в документации kubernetes, опционален
|
98
|
-
def request!(method, path, body: nil, excon_parameters: {}, **query_parameters)
|
99
|
-
with_connection(excon_parameters: excon_parameters) do |conn|
|
100
|
-
request_parameters = {method: method, path: path, query: @query_parameters.merge(query_parameters)}
|
101
|
-
request_parameters[:body] = JSON.dump(body) if body
|
102
|
-
load_body! conn.request(request_parameters), request_parameters
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
def load_body!(response, request_parameters)
|
107
|
-
response_ok = response.status.to_s.start_with? '2'
|
108
|
-
|
109
|
-
if response_ok
|
110
|
-
JSON.parse(response.body)
|
111
|
-
else
|
112
|
-
err_data = {}
|
113
|
-
err_data[:response_http_status] = response.status
|
114
|
-
if response_body = (JSON.parse(response.body) rescue nil)
|
115
|
-
err_data[:response_body] = response_body
|
116
|
-
else
|
117
|
-
err_data[:response_raw_body] = response.body
|
118
|
-
end
|
119
|
-
err_data[:request_parameters] = request_parameters
|
120
|
-
|
121
|
-
if response.status.to_s.start_with? '5'
|
122
|
-
raise Error::Default, code: :server_error, data: err_data
|
123
|
-
elsif response.status.to_s == '404'
|
124
|
-
raise Error::NotFound, data: err_data
|
125
|
-
else not response.status.to_s.start_with? '2'
|
126
|
-
raise Error::Default, code: :bad_request, data: err_data
|
127
|
-
end
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
def with_connection(excon_parameters: {}, &blk)
|
132
|
-
old_ssl_ca_file = Excon.defaults[:ssl_ca_file]
|
133
|
-
old_middlewares = Excon.defaults[:middlewares].dup
|
134
|
-
|
135
|
-
begin
|
136
|
-
Excon.defaults[:ssl_ca_file] = kube_config.fetch('clusters', [{}]).first.fetch('cluster', {}).fetch('certificate-authority', nil)
|
137
|
-
Excon.defaults[:middlewares] << Excon::Middleware::RedirectFollower
|
138
|
-
|
139
|
-
return yield Excon.new(kube_server_url, **kube_server_options(excon_parameters))
|
140
|
-
ensure
|
141
|
-
Excon.defaults[:ssl_ca_file] = old_ssl_ca_file
|
142
|
-
Excon.defaults[:middlewares] = old_middlewares
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
def kube_server_url
|
147
|
-
@kube_server_url ||= begin
|
148
|
-
kube_config.fetch('clusters', [{}]).first.fetch('cluster', {}).fetch('server', nil).tap do |url|
|
149
|
-
begin
|
150
|
-
Excon.new(url, **kube_server_options).get
|
151
|
-
rescue Excon::Error::Socket
|
152
|
-
raise Error::ConnectionRefused, code: :kube_server_connection_refused, data: { url: url }
|
153
|
-
end
|
154
|
-
end
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
|
-
def kube_server_options(excon_parameters = {})
|
159
|
-
{ client_cert: kube_config.fetch('users', [{}]).first.fetch('user', {}).fetch('client-certificate', nil),
|
160
|
-
client_key: kube_config.fetch('users', [{}]).first.fetch('user', {}).fetch('client-key', nil) }.merge(excon_parameters)
|
161
|
-
end
|
162
|
-
|
163
|
-
def kube_config
|
164
|
-
@kube_config ||= begin
|
165
|
-
if File.exist?((kube_config_path = File.join(ENV['HOME'], '.kube/config')))
|
166
|
-
yaml_load_file(kube_config_path)
|
167
|
-
else
|
168
|
-
raise Error::Default, code: :kube_config_not_found, data: { path: kube_config_path }
|
169
|
-
end
|
170
|
-
end
|
171
|
-
end
|
172
|
-
end
|
173
|
-
end
|
174
|
-
end
|