kubernetes-deploy 0.2.2 → 0.2.3
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 +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
|