kubernetes-deploy 0.2.2 → 0.2.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/kubernetes-deploy/kubernetes_resource.rb +15 -13
- data/lib/kubernetes-deploy/kubernetes_resource/cloudsql.rb +2 -2
- data/lib/kubernetes-deploy/kubernetes_resource/config_map.rb +2 -2
- data/lib/kubernetes-deploy/kubernetes_resource/deployment.rb +3 -3
- data/lib/kubernetes-deploy/kubernetes_resource/ingress.rb +2 -2
- data/lib/kubernetes-deploy/kubernetes_resource/persistent_volume_claim.rb +2 -2
- data/lib/kubernetes-deploy/kubernetes_resource/pod.rb +3 -3
- data/lib/kubernetes-deploy/kubernetes_resource/service.rb +2 -2
- data/lib/kubernetes-deploy/runner.rb +17 -8
- data/lib/kubernetes-deploy/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c5451809e19cbb8f15e709ff0eab4787bcdc1c36
|
4
|
+
data.tar.gz: 2eaf109d80b3e11175ebd29cab21dd7419551583
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3a7a97fe1b2c991f58ca8da5d77028d6de450517ed02f82f9fd8f5688f36095f85263eb667cb6444542c69d845bb7f20bb651e54da81851bab37f5d0ab1aed69
|
7
|
+
data.tar.gz: 8490ed13cba69329bb9f13acb9a6b3ddfffbba553cdc84c886d075060a49804ac11e3d8173db8d60c0bdf0e39ab2d96a2b066e723e960405369a9227fa2b9152
|
@@ -5,27 +5,27 @@ require 'shellwords'
|
|
5
5
|
module KubernetesDeploy
|
6
6
|
class KubernetesResource
|
7
7
|
|
8
|
-
attr_reader :name, :namespace, :file
|
8
|
+
attr_reader :name, :namespace, :file, :context
|
9
9
|
attr_writer :type, :deploy_started
|
10
10
|
|
11
11
|
TIMEOUT = 5.minutes
|
12
12
|
|
13
|
-
def self.for_type(type, name, namespace, file)
|
13
|
+
def self.for_type(type, name, namespace, context, file)
|
14
14
|
case type
|
15
|
-
when 'cloudsql' then Cloudsql.new(name, namespace, file)
|
16
|
-
when 'configmap' then ConfigMap.new(name, namespace, file)
|
17
|
-
when 'deployment' then Deployment.new(name, namespace, file)
|
18
|
-
when 'pod' then Pod.new(name, namespace, file)
|
19
|
-
when 'ingress' then Ingress.new(name, namespace, file)
|
20
|
-
when 'persistentvolumeclaim' then PersistentVolumeClaim.new(name, namespace, file)
|
21
|
-
when 'service' then Service.new(name, namespace, file)
|
22
|
-
else self.new(name, namespace, file).tap { |r| r.type = type }
|
15
|
+
when 'cloudsql' then Cloudsql.new(name, namespace, context, file)
|
16
|
+
when 'configmap' then ConfigMap.new(name, namespace, context, file)
|
17
|
+
when 'deployment' then Deployment.new(name, namespace, context, file)
|
18
|
+
when 'pod' then Pod.new(name, namespace, context, file)
|
19
|
+
when 'ingress' then Ingress.new(name, namespace, context, file)
|
20
|
+
when 'persistentvolumeclaim' then PersistentVolumeClaim.new(name, namespace, context, file)
|
21
|
+
when 'service' then Service.new(name, namespace, context, file)
|
22
|
+
else self.new(name, namespace, context, file).tap { |r| r.type = type }
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
-
def initialize(name, namespace, file)
|
26
|
+
def initialize(name, namespace, context, file)
|
27
27
|
# subclasses must also set these
|
28
|
-
@name, @namespace, @file = name, namespace, file
|
28
|
+
@name, @namespace, @context, @file = name, namespace, context, file
|
29
29
|
end
|
30
30
|
|
31
31
|
def id
|
@@ -92,7 +92,9 @@ module KubernetesDeploy
|
|
92
92
|
|
93
93
|
def run_kubectl(*args)
|
94
94
|
raise FatalDeploymentError, "Namespace missing for namespaced command" if namespace.blank?
|
95
|
-
|
95
|
+
raise FatalDeploymentError, "Explicit context is required to run this command" if context.blank?
|
96
|
+
args = args.unshift("kubectl").push("--namespace=#{namespace}").push("--context=#{context}")
|
97
|
+
|
96
98
|
KubernetesDeploy.logger.debug Shellwords.join(args)
|
97
99
|
out, err, st = Open3.capture3(*args)
|
98
100
|
KubernetesDeploy.logger.debug(out.shellescape)
|
@@ -2,8 +2,8 @@ module KubernetesDeploy
|
|
2
2
|
class Cloudsql < KubernetesResource
|
3
3
|
TIMEOUT = 5.minutes
|
4
4
|
|
5
|
-
def initialize(name, namespace, file)
|
6
|
-
@name, @namespace, @file = name, namespace, file
|
5
|
+
def initialize(name, namespace, context, file)
|
6
|
+
@name, @namespace, @context, @file = name, namespace, context, file
|
7
7
|
end
|
8
8
|
|
9
9
|
def sync
|
@@ -2,8 +2,8 @@ module KubernetesDeploy
|
|
2
2
|
class ConfigMap < KubernetesResource
|
3
3
|
TIMEOUT = 30.seconds
|
4
4
|
|
5
|
-
def initialize(name, namespace, file)
|
6
|
-
@name, @namespace, @file = name, namespace, file
|
5
|
+
def initialize(name, namespace, context, file)
|
6
|
+
@name, @namespace, @context, @file = name, namespace, context, file
|
7
7
|
end
|
8
8
|
|
9
9
|
def sync
|
@@ -2,8 +2,8 @@ module KubernetesDeploy
|
|
2
2
|
class Deployment < KubernetesResource
|
3
3
|
TIMEOUT = 15.minutes
|
4
4
|
|
5
|
-
def initialize(name, namespace, file)
|
6
|
-
@name, @namespace, @file = name, namespace, file
|
5
|
+
def initialize(name, namespace, context, file)
|
6
|
+
@name, @namespace, @context, @file = name, namespace, context, file
|
7
7
|
end
|
8
8
|
|
9
9
|
def sync
|
@@ -22,7 +22,7 @@ module KubernetesDeploy
|
|
22
22
|
pods_json = JSON.parse(pod_list)["items"]
|
23
23
|
pods_json.each do |pod_json|
|
24
24
|
pod_name = pod_json["metadata"]["name"]
|
25
|
-
pod = Pod.new(pod_name, namespace, nil, parent: "#{@name.capitalize} deployment")
|
25
|
+
pod = Pod.new(pod_name, namespace, context, nil, parent: "#{@name.capitalize} deployment")
|
26
26
|
pod.deploy_started = @deploy_started
|
27
27
|
pod.interpret_json_data(pod_json)
|
28
28
|
pod.log_status
|
@@ -2,8 +2,8 @@ module KubernetesDeploy
|
|
2
2
|
class Ingress < KubernetesResource
|
3
3
|
TIMEOUT = 30.seconds
|
4
4
|
|
5
|
-
def initialize(name, namespace, file)
|
6
|
-
@name, @namespace, @file = name, namespace, file
|
5
|
+
def initialize(name, namespace, context, file)
|
6
|
+
@name, @namespace, @context, @file = name, namespace, context, file
|
7
7
|
end
|
8
8
|
|
9
9
|
def sync
|
@@ -2,8 +2,8 @@ module KubernetesDeploy
|
|
2
2
|
class PersistentVolumeClaim < KubernetesResource
|
3
3
|
TIMEOUT = 5.minutes
|
4
4
|
|
5
|
-
def initialize(name, namespace, file)
|
6
|
-
@name, @namespace, @file = name, namespace, file
|
5
|
+
def initialize(name, namespace, context, file)
|
6
|
+
@name, @namespace, @context, @file = name, namespace, context, file
|
7
7
|
end
|
8
8
|
|
9
9
|
def sync
|
@@ -3,8 +3,8 @@ module KubernetesDeploy
|
|
3
3
|
TIMEOUT = 15.minutes
|
4
4
|
SUSPICIOUS_CONTAINER_STATES = %w(ImagePullBackOff RunContainerError).freeze
|
5
5
|
|
6
|
-
def initialize(name, namespace, file, parent: nil)
|
7
|
-
@name, @namespace, @file, @parent = name, namespace, file, parent
|
6
|
+
def initialize(name, namespace, context, file, parent: nil)
|
7
|
+
@name, @namespace, @context, @file, @parent = name, namespace, context, file, parent
|
8
8
|
@bare = !@parent
|
9
9
|
end
|
10
10
|
|
@@ -40,7 +40,7 @@ module KubernetesDeploy
|
|
40
40
|
elsif @phase == "Terminating"
|
41
41
|
@status = @phase
|
42
42
|
else
|
43
|
-
ready_condition = pod_data["status"]
|
43
|
+
ready_condition = pod_data["status"].fetch("conditions", []).find { |condition| condition["type"] == "Ready" }
|
44
44
|
@ready = ready_condition.present? && (ready_condition["status"] == "True")
|
45
45
|
@status = "#{@phase} (Ready: #{@ready})"
|
46
46
|
end
|
@@ -2,8 +2,8 @@ module KubernetesDeploy
|
|
2
2
|
class Service < KubernetesResource
|
3
3
|
TIMEOUT = 15.minutes
|
4
4
|
|
5
|
-
def initialize(name, namespace, file)
|
6
|
-
@name, @namespace, @file = name, namespace, file
|
5
|
+
def initialize(name, namespace, context, file)
|
6
|
+
@name, @namespace, @context, @file = name, namespace, context, file
|
7
7
|
end
|
8
8
|
|
9
9
|
def sync
|
@@ -26,6 +26,10 @@ module KubernetesDeploy
|
|
26
26
|
PersistentVolumeClaim
|
27
27
|
Pod
|
28
28
|
)
|
29
|
+
PROTECTED_NAMESPACES = %w(
|
30
|
+
default
|
31
|
+
kube-system
|
32
|
+
)
|
29
33
|
|
30
34
|
# Things removed from default prune whitelist:
|
31
35
|
# core/v1/Namespace -- not namespaced
|
@@ -76,9 +80,9 @@ MSG
|
|
76
80
|
phase_heading("Validating configuration")
|
77
81
|
validate_configuration
|
78
82
|
|
79
|
-
phase_heading("
|
80
|
-
|
81
|
-
|
83
|
+
phase_heading("Identifying deployment target")
|
84
|
+
confirm_context_exists
|
85
|
+
confirm_namespace_exists
|
82
86
|
|
83
87
|
phase_heading("Parsing deploy content")
|
84
88
|
resources = discover_resources
|
@@ -127,7 +131,7 @@ MSG
|
|
127
131
|
split_templates(filename) do |tempfile|
|
128
132
|
resource_id = discover_resource_via_dry_run(tempfile)
|
129
133
|
type, name = resource_id.split("/", 2) # e.g. "pod/web-198612918-dzvfb"
|
130
|
-
resources << KubernetesResource.for_type(type, name, @namespace, tempfile)
|
134
|
+
resources << KubernetesResource.for_type(type, name, @namespace, @context, tempfile)
|
131
135
|
KubernetesDeploy.logger.info "Discovered template for #{resource_id}"
|
132
136
|
end
|
133
137
|
end
|
@@ -217,6 +221,8 @@ MSG
|
|
217
221
|
|
218
222
|
if @namespace.blank?
|
219
223
|
errors << "Namespace must be specified"
|
224
|
+
elsif PROTECTED_NAMESPACES.include?(@namespace)
|
225
|
+
errors << "Refusing to deploy to protected namespace #{@namespace}"
|
220
226
|
end
|
221
227
|
|
222
228
|
if @context.blank?
|
@@ -263,7 +269,7 @@ MSG
|
|
263
269
|
run_kubectl(*command)
|
264
270
|
end
|
265
271
|
|
266
|
-
def
|
272
|
+
def confirm_context_exists
|
267
273
|
out, err, st = run_kubectl("config", "get-contexts", "-o", "name", namespaced: false, with_context: false)
|
268
274
|
available_contexts = out.split("\n")
|
269
275
|
if !st.success?
|
@@ -271,21 +277,24 @@ MSG
|
|
271
277
|
elsif !available_contexts.include?(@context)
|
272
278
|
raise FatalDeploymentError, "Context #{@context} is not available. Valid contexts: #{available_contexts}"
|
273
279
|
end
|
280
|
+
KubernetesDeploy.logger.info("Context #{@context} found")
|
274
281
|
end
|
275
282
|
|
276
|
-
def
|
283
|
+
def confirm_namespace_exists
|
277
284
|
_, _, st = run_kubectl("get", "namespace", @namespace, namespaced: false)
|
278
|
-
raise FatalDeploymentError, "
|
279
|
-
KubernetesDeploy.logger.info("Namespace #{@namespace}
|
285
|
+
raise FatalDeploymentError, "Namespace #{@namespace} not found" unless st.success?
|
286
|
+
KubernetesDeploy.logger.info("Namespace #{@namespace} found")
|
280
287
|
end
|
281
288
|
|
282
289
|
def run_kubectl(*args, namespaced: true, with_context: true)
|
283
290
|
args = args.unshift("kubectl")
|
284
291
|
if namespaced
|
292
|
+
raise FatalDeploymentError, "Namespace missing for namespaced command" if @namespace.blank?
|
285
293
|
args.push("--namespace=#{@namespace}")
|
286
294
|
end
|
287
295
|
|
288
296
|
if with_context
|
297
|
+
raise FatalDeploymentError, "Explicit context is required to run this command" if @context.blank?
|
289
298
|
args.push("--context=#{@context}")
|
290
299
|
end
|
291
300
|
KubernetesDeploy.logger.debug Shellwords.join(args)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: kubernetes-deploy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kir Shatrov
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date: 2017-02-
|
13
|
+
date: 2017-02-06 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activesupport
|
@@ -116,7 +116,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
116
116
|
version: '0'
|
117
117
|
requirements: []
|
118
118
|
rubyforge_project:
|
119
|
-
rubygems_version: 2.5.
|
119
|
+
rubygems_version: 2.5.1
|
120
120
|
signing_key:
|
121
121
|
specification_version: 4
|
122
122
|
summary: Kubernetes deploy scripts
|