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.
Files changed (63) hide show
  1. checksums.yaml +5 -5
  2. data/bin/dapp +1 -23
  3. data/config/en/net_status.yml +5 -4
  4. data/lib/dapp.rb +1 -1
  5. data/lib/dapp/dapp/sentry.rb +11 -8
  6. data/lib/dapp/dimg/dapp/command/cleanup_repo.rb +33 -21
  7. data/lib/dapp/dimg/dimg/git_artifact.rb +2 -5
  8. data/lib/dapp/dimg/git_artifact.rb +41 -23
  9. data/lib/dapp/dimg/git_repo/base.rb +19 -39
  10. data/lib/dapp/dimg/git_repo/local.rb +15 -14
  11. data/lib/dapp/dimg/git_repo/remote.rb +32 -19
  12. data/lib/dapp/kube/cli/command/kube/deploy.rb +4 -0
  13. data/lib/dapp/kube/cli/command/kube/dismiss.rb +4 -0
  14. data/lib/dapp/kube/cli/command/kube/lint.rb +4 -0
  15. data/lib/dapp/kube/cli/command/kube/render.rb +4 -0
  16. data/lib/dapp/kube/cli/command/kube/value_get.rb +4 -0
  17. data/lib/dapp/kube/dapp/command/common.rb +21 -18
  18. data/lib/dapp/kube/dapp/command/minikube_setup.rb +6 -2
  19. data/lib/dapp/kube/helm/release.rb +1 -1
  20. data/lib/dapp/kube/helm/values.rb +3 -3
  21. data/lib/dapp/kube/kubernetes/client.rb +21 -90
  22. data/lib/dapp/kube/kubernetes/config.rb +129 -0
  23. data/lib/dapp/version.rb +1 -1
  24. metadata +6 -44
  25. data/lib/dapp/deployment/app.rb +0 -120
  26. data/lib/dapp/deployment/cli/cli.rb +0 -1
  27. data/lib/dapp/deployment/cli/command/base.rb +0 -14
  28. data/lib/dapp/deployment/cli/command/deployment.rb +0 -18
  29. data/lib/dapp/deployment/cli/command/deployment/apply.rb +0 -26
  30. data/lib/dapp/deployment/cli/command/deployment/mrproper.rb +0 -13
  31. data/lib/dapp/deployment/config/config.rb +0 -46
  32. data/lib/dapp/deployment/config/directive/app.rb +0 -28
  33. data/lib/dapp/deployment/config/directive/app/instance_methods.rb +0 -51
  34. data/lib/dapp/deployment/config/directive/base.rb +0 -13
  35. data/lib/dapp/deployment/config/directive/deployment.rb +0 -11
  36. data/lib/dapp/deployment/config/directive/expose.rb +0 -68
  37. data/lib/dapp/deployment/config/directive/group.rb +0 -27
  38. data/lib/dapp/deployment/config/directive/job.rb +0 -28
  39. data/lib/dapp/deployment/config/directive/mod/group.rb +0 -22
  40. data/lib/dapp/deployment/config/directive/mod/jobs.rb +0 -26
  41. data/lib/dapp/deployment/config/directive/namespace.rb +0 -26
  42. data/lib/dapp/deployment/config/directive/namespace/instance_methods.rb +0 -37
  43. data/lib/dapp/deployment/core_ext/hash.rb +0 -19
  44. data/lib/dapp/deployment/dapp/command/apply.rb +0 -71
  45. data/lib/dapp/deployment/dapp/command/common.rb +0 -17
  46. data/lib/dapp/deployment/dapp/command/mrproper.rb +0 -12
  47. data/lib/dapp/deployment/dapp/dapp.rb +0 -15
  48. data/lib/dapp/deployment/dapp/dappfile.rb +0 -23
  49. data/lib/dapp/deployment/deployment.rb +0 -46
  50. data/lib/dapp/deployment/error/app.rb +0 -7
  51. data/lib/dapp/deployment/error/default.rb +0 -7
  52. data/lib/dapp/deployment/error/deployment.rb +0 -7
  53. data/lib/dapp/deployment/error/kubernetes.rb +0 -7
  54. data/lib/dapp/deployment/kube_app.rb +0 -146
  55. data/lib/dapp/deployment/kube_base.rb +0 -97
  56. data/lib/dapp/deployment/kube_deployment.rb +0 -51
  57. data/lib/dapp/deployment/kubernetes.rb +0 -174
  58. data/lib/dapp/deployment/kubernetes/error.rb +0 -20
  59. data/lib/dapp/deployment/mod/jobs.rb +0 -37
  60. data/lib/dapp/deployment/mod/namespace.rb +0 -58
  61. data/lib/dapp/deployment/mod/system_environments.rb +0 -30
  62. data/lib/dapp/deployment/secret.rb +0 -93
  63. data/lib/dapp/kube/error/kubernetes.rb +0 -7
@@ -1,7 +0,0 @@
1
- module Dapp
2
- module Deployment
3
- module Error
4
- class App < Default; end
5
- end
6
- end
7
- end
@@ -1,7 +0,0 @@
1
- module Dapp
2
- module Deployment
3
- module Error
4
- class Default < ::Dapp::Error::Default; end
5
- end
6
- end
7
- end
@@ -1,7 +0,0 @@
1
- module Dapp
2
- module Deployment
3
- module Error
4
- class Deployment < Default; end
5
- end
6
- end
7
- end
@@ -1,7 +0,0 @@
1
- module Dapp
2
- module Deployment
3
- module Error
4
- class Kubernetes < Default; end
5
- end
6
- end
7
- end
@@ -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