kubes 0.2.6 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/docs/_docs/auto-context.md +4 -4
  4. data/docs/_docs/config/env.md +3 -3
  5. data/docs/_docs/dsl/resources/service.md +21 -5
  6. data/docs/_docs/learn/dsl/deploy.md +2 -0
  7. data/docs/_docs/learn/dsl/new-project.md +1 -2
  8. data/docs/_docs/learn/yaml/deploy.md +2 -0
  9. data/docs/_docs/learn/yaml/new-project.md +1 -1
  10. data/docs/_includes/intro/install.md +5 -1
  11. data/docs/_includes/learn/cluster.md +21 -4
  12. data/docs/_includes/learn/repo +0 -0
  13. data/docs/_includes/learn/repos.md +10 -0
  14. data/docs/_includes/learn/review.md +2 -2
  15. data/docs/_reference/kubes-apply.md +2 -2
  16. data/docs/_reference/kubes-delete.md +1 -1
  17. data/docs/_reference/kubes-deploy.md +1 -1
  18. data/docs/_reference/kubes-describe.md +24 -0
  19. data/docs/_reference/kubes-exec.md +42 -0
  20. data/docs/_reference/kubes-get.md +27 -0
  21. data/docs/_reference/kubes-init.md +1 -1
  22. data/docs/_reference/kubes-logs.md +26 -0
  23. data/docs/bin/web +1 -1
  24. data/docs/reference.md +4 -0
  25. data/lib/kubes/cli.rb +21 -0
  26. data/lib/kubes/cli/apply.rb +1 -1
  27. data/lib/kubes/cli/base.rb +4 -0
  28. data/lib/kubes/cli/delete.rb +7 -2
  29. data/lib/kubes/cli/describe.rb +1 -1
  30. data/lib/kubes/cli/exec.rb +33 -0
  31. data/lib/kubes/cli/get.rb +3 -1
  32. data/lib/kubes/cli/help/exec.md +17 -0
  33. data/lib/kubes/cli/logs.rb +13 -0
  34. data/lib/kubes/compiler/dsl/syntax/deployment.rb +72 -2
  35. data/lib/kubes/compiler/dsl/syntax/service.rb +11 -0
  36. data/lib/kubes/hooks/builder.rb +2 -1
  37. data/lib/kubes/kubectl.rb +15 -3
  38. data/lib/kubes/kubectl/batch.rb +8 -1
  39. data/lib/kubes/kubectl/fetch/base.rb +24 -0
  40. data/lib/kubes/kubectl/fetch/deployment.rb +34 -0
  41. data/lib/kubes/kubectl/fetch/pods.rb +21 -0
  42. data/lib/kubes/util/sh.rb +1 -0
  43. data/lib/kubes/version.rb +1 -1
  44. data/lib/templates/dsl/.kubes/resources/web/deployment.rb +2 -1
  45. data/lib/templates/dsl/.kubes/resources/web/service.rb +1 -1
  46. metadata +14 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 38315c41de75e3132ebd72d88227c7b2dfd5051e62beaebba937081bd04bf87a
4
- data.tar.gz: 1e5ad418c423fee55f4b735a446b20835fc2256699d00ed58b162390526e1610
3
+ metadata.gz: f6a93c63c1e8d4aeea46969a491b3065c97e9a1a290bfd871286e794c35cb0d6
4
+ data.tar.gz: d8dbb91a1214bf8c42a5c9dd1e591dfcf6c41ffee6feb36af0af2f7b3a519ebd
5
5
  SHA512:
6
- metadata.gz: 74e34ea429c1acfa0b642c99b83ea6f7d5889f0539fb905c329380d9f31f116241401ec5af16445694b6507d205b5c3f17d6e099086b9208a68afc835396c01e
7
- data.tar.gz: 200b3bec023fec1caf42d418449533035b1f05ecf069770800a90538c93ca344e755701ef35883956512383710fcb1668893ecf9ea2f2e5e148ba0c4fd9fff13
6
+ metadata.gz: dfc13591d144fb99837297c4c766354ceed410df631e505e54517e9759b9b44b03ce9adb7738db167b55c877d7f47bbd644f1bb832df38c4213651243fcbe668
7
+ data.tar.gz: 9ed84b118c29ec8531407f4b069840d1c576eb6f120f58ead3a8560242af44b62ca3b6339f4949a5433c64fc966003d65f2871134b0ed17984cc2f461b9537bd
@@ -3,6 +3,11 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  This project *loosely tries* to adhere to [Semantic Versioning](http://semver.org/), even before v1.0.
5
5
 
6
+ ## [0.3.0]
7
+ - #19 new commands: exec, logs
8
+ - delete preview
9
+ - show pods as part of get
10
+
6
11
  ## [0.2.6]
7
12
  - #18 gcloud builder. change to config.builder
8
13
 
@@ -22,7 +22,7 @@ You can override configs on a per-env basis with `config/env` files. Examples:
22
22
  ```ruby
23
23
  Kubes.configure do |config|
24
24
  config.repo = "222222222222.dkr.ecr.us-west-2.amazonaws.com/demo"
25
- config.kubectl.context = "dev-services"
25
+ config.kubectl.context = "dev-cluster"
26
26
  end
27
27
  ```
28
28
 
@@ -31,7 +31,7 @@ end
31
31
  ```ruby
32
32
  Kubes.configure do |config|
33
33
  config.repo = "333333333333.dkr.ecr.us-west-2.amazonaws.com/demo"
34
- config.kubectl.context = "prod-services"
34
+ config.kubectl.context = "prod-cluster"
35
35
  end
36
36
  ```
37
37
 
@@ -39,8 +39,8 @@ end
39
39
 
40
40
  With this setup, when you deploy with kubes, it will automatically switch the kubectl context based on `KUBES_ENV`. Example:
41
41
 
42
- KUBES_ENV=dev kubes deploy # to dev-services context
43
- KUBES_ENV=prod kubes deploy # to prod-services context
42
+ KUBES_ENV=dev kubes deploy # to dev-cluster context
43
+ KUBES_ENV=prod kubes deploy # to prod-cluster context
44
44
 
45
45
  ## context_keep Option
46
46
 
@@ -11,7 +11,7 @@ Kubes.configure do |config|
11
11
  config.repo = "111111111111.dkr.ecr.us-west-2.amazonaws.com/demo"
12
12
  config.logger.level = "info"
13
13
  # auto-switching
14
- # config.kubectl.context = "dev-services"
14
+ # config.kubectl.context = "dev-cluster"
15
15
  # config.kubectl.context_keep = false
16
16
  end
17
17
  ```
@@ -25,7 +25,7 @@ You can override configs on a per-env basis with `config/env` files. Examples:
25
25
  ```ruby
26
26
  Kubes.configure do |config|
27
27
  config.repo = "222222222222.dkr.ecr.us-west-2.amazonaws.com/demo"
28
- config.kubectl.context = "dev-services"
28
+ config.kubectl.context = "dev-cluster"
29
29
  end
30
30
  ```
31
31
 
@@ -34,7 +34,7 @@ end
34
34
  ```ruby
35
35
  Kubes.configure do |config|
36
36
  config.repo = "333333333333.dkr.ecr.us-west-2.amazonaws.com/demo"
37
- config.kubectl.context = "prod-services"
37
+ config.kubectl.context = "prod-cluster"
38
38
  end
39
39
  ```
40
40
 
@@ -46,15 +46,31 @@ spec:
46
46
 
47
47
  ## DSL Methods
48
48
 
49
- Here's a list of more common methods:
49
+ Here's a list of some of the methods:
50
+
51
+ kubectl explain service.spec
52
+
53
+ * clusterIP
54
+ * externalIPs
55
+ * externalName
56
+ * externalTrafficPolicy
57
+ * healthCheckNodePort
58
+ * ipFamily
59
+ * loadBalancerIP
60
+ * loadBalancerSourceRanges
61
+ * ports
62
+ * publishNotReadyAddresses
63
+ * selector
64
+ * sessionAffinity
65
+ * sessionAffinityConfig
66
+ * type
67
+
68
+ kubectl explain service.spec.ports
50
69
 
51
70
  * nodePort
52
71
  * port
53
- * portName: Note this field doesn't match the original field name. It's more qualified.
54
- * ports
72
+ * portName: : Note this field doesn't match the original field name. It's more qualified.
55
73
  * protocol
56
- * selector
57
74
  * targetPort
58
- * type
59
75
 
60
76
  {% include dsl/methods.md name="service" %}
@@ -22,6 +22,8 @@ You'll see output like this:
22
22
  deployment.apps/demo-web created
23
23
  $
24
24
 
25
+ Note: Showing an AWS ECR repo, but it may be different if you're using another repo like Google GCR.
26
+
25
27
  What did Kubes do?
26
28
 
27
29
  {% include kubes-steps.md %}
@@ -7,11 +7,10 @@ If you already a project with an existing Dockerfile, you can use that. If you d
7
7
  mkdir demo
8
8
  cd demo
9
9
 
10
- For this tutorial, we'll use an ECR repo, though any repo will work.
10
+ {% include learn/repos.md %}
11
11
 
12
12
  Let's generate a starter project:
13
13
 
14
- $ REPO=$(aws ecr describe-repositories --repository-name demo | jq -r '.repositories[].repositoryUri')
15
14
  $ kubes init --app demo --repo $REPO --type dsl
16
15
  create .kubes/config.rb
17
16
  create .kubes/config/env/dev.rb
@@ -22,6 +22,8 @@ You'll see output like this:
22
22
  deployment.apps/demo-web created
23
23
  $
24
24
 
25
+ Note: Showing an AWS ECR repo, but it may be different if you're using another repo like Google GCR.
26
+
25
27
  What did Kubes do?
26
28
 
27
29
  {% include kubes-steps.md %}
@@ -7,7 +7,7 @@ If you already a project with an existing Dockerfile, you can use that. If you d
7
7
  mkdir demo
8
8
  cd demo
9
9
 
10
- For this tutorial, we'll use an ECR repo, though any repo will work.
10
+ {% include learn/repos.md %}
11
11
 
12
12
  Let's generate a starter project:
13
13
 
@@ -4,7 +4,7 @@ Install kubes via RubyGems.
4
4
 
5
5
  gem install kubes
6
6
 
7
- Ruby 2.7 and patch variants of it is recommended.
7
+ Ruby 2.7 and above is recommended.
8
8
 
9
9
  ## kubectl
10
10
 
@@ -13,3 +13,7 @@ Kubes calls kubectl. Kubes has been tested with kubectl v1.15+. Generally, it sh
13
13
  ## docker
14
14
 
15
15
  Kubes calls docker. Kubes has been tested with docker 18.x-ce+. Generally, it should work with most versions of docker.
16
+
17
+ ## gcloud
18
+
19
+ If you are using the [gcloud builder](% link _docs/config/builder.md %), set up and configure the [gcloud cli](https://cloud.google.com/sdk/install).
@@ -1,12 +1,12 @@
1
- You'll need a Kubernetes cluster and a Docker repo to be able to push to. Setting up a Kubernetes cluster is a little bit out scope for this tutorial. We'll provide the docs and links though. We'll also use an AWS EKS cluster and ECR.
1
+ You'll need a Kubernetes cluster and a Docker repo to be able to push to. Setting up a Kubernetes cluster is a little bit out scope for this tutorial. We'll provide the docs and links though. We'll provide instructions for AWS and Google.
2
2
 
3
- ## Create an EKS cluster
3
+ ## AWS: Create an EKS cluster
4
4
 
5
5
  Here are the AWS docs to create an EKS cluster:
6
6
 
7
7
  * [Creating an Amazon EKS cluster](https://docs.aws.amazon.com/eks/latest/userguide/create-cluster.html)
8
8
 
9
- ## Create an ECR Repo
9
+ ## AWS: Create an ECR Repo
10
10
 
11
11
  Here are the AWS docs to create a repo:
12
12
 
@@ -19,4 +19,21 @@ Here are also the commands to create an ECR repo:
19
19
 
20
20
  We'll be using the `$REPO` variable for the rest of the tutorial.
21
21
 
22
- Note: Though we're using AWS here, Kubes works with any Cloud Provider. Please adjust your commands and the `$REPO` variable for your cloud provider.
22
+ ## Google: Create GKE Cluster
23
+
24
+ Here are the Google docs to create an GKE cluster:
25
+
26
+ * [Creating an Google GKE cluster](https://cloud.google.com/kubernetes-engine/docs/how-to/creating-a-regional-cluster)
27
+
28
+ ## Google: GCR Repo
29
+
30
+ For google, you do not have to create a repo. You simply push to the right repo url. Example:
31
+
32
+ export GOOGLE_PROJECT=project-123
33
+ REPO=gcr.io/$GOOGLE_PROJECT/demo
34
+
35
+ ## Repo Variable
36
+
37
+ We'll be using the `$REPO` variable for the rest of the tutorial.
38
+
39
+ Note: Though we're using AWS and Google here, Kubes works with any Cloud Provider. Please adjust your commands and the `$REPO` variable for your cloud provider.
File without changes
@@ -0,0 +1,10 @@
1
+ For this tutorial, here are examples of AWS ECR and Google GCR repos, though any repo will work.
2
+
3
+ AWS:
4
+
5
+ REPO=$(aws ecr describe-repositories --repository-name demo | jq -r '.repositories[].repositoryUri')
6
+
7
+ Google:
8
+
9
+ export GOOGLE_PROJECT=project-123
10
+ REPO=gcr.io/$GOOGLE_PROJECT/demo
@@ -4,10 +4,10 @@ The `config.rb` is where you can configure Kubes settings.
4
4
 
5
5
  ```ruby
6
6
  Kubes.configure do |config|
7
- config.repo = "112233445566.dkr.ecr.us-west-2.amazonaws.com/demo"
7
+ config.repo = "112233445566.dkr.ecr.us-west-2.amazonaws.com/demo" # may be gcr.io/project-123/demo
8
8
  config.logger.level = "info"
9
9
  # auto-switching
10
- # config.kubectl.context = "dev-services"
10
+ # config.kubectl.context = "dev-cluster"
11
11
  end
12
12
  ```
13
13
 
@@ -5,11 +5,11 @@ reference: true
5
5
 
6
6
  ## Usage
7
7
 
8
- kubes apply [APP] [RESOURCE]
8
+ kubes apply [ROLE] [RESOURCE]
9
9
 
10
10
  ## Description
11
11
 
12
- Apply the Kubernetes YAML files without changing them
12
+ Apply the Kubernetes YAML files without building docker image
13
13
 
14
14
 
15
15
  ## Options
@@ -5,7 +5,7 @@ reference: true
5
5
 
6
6
  ## Usage
7
7
 
8
- kubes delete [APP] [RESOURCE]
8
+ kubes delete [ROLE] [RESOURCE]
9
9
 
10
10
  ## Description
11
11
 
@@ -5,7 +5,7 @@ reference: true
5
5
 
6
6
  ## Usage
7
7
 
8
- kubes deploy [APP] [RESOURCE]
8
+ kubes deploy [ROLE] [RESOURCE]
9
9
 
10
10
  ## Description
11
11
 
@@ -0,0 +1,24 @@
1
+ ---
2
+ title: kubes describe
3
+ reference: true
4
+ ---
5
+
6
+ ## Usage
7
+
8
+ kubes describe [ROLE] [RESOURCE]
9
+
10
+ ## Description
11
+
12
+ Describe Kubernetes resource using the compiled YAML files
13
+
14
+
15
+ ## Options
16
+
17
+ ```
18
+ [--image=IMAGE] # override image
19
+ [--compile], [--no-compile] # whether or not to compile the .kube/resources
20
+ # Default: true
21
+ [--verbose], [--no-verbose]
22
+ [--noop], [--no-noop]
23
+ ```
24
+
@@ -0,0 +1,42 @@
1
+ ---
2
+ title: kubes exec
3
+ reference: true
4
+ ---
5
+
6
+ ## Usage
7
+
8
+ kubes exec
9
+
10
+ ## Description
11
+
12
+ Exec into the latest container from the deployment
13
+
14
+ The exec command finds the latest pod from the deployment and runs `kubectl exec -ti POD bash` to get you into it. It spares you from having to manually find and type it.
15
+
16
+ ## Examples
17
+
18
+ kubes exec
19
+ kubes exec sh
20
+ kubes exec ls -l
21
+
22
+ ## Multiple Deployments
23
+
24
+ If you have have multiple deployments in your ``.kubes/resources` then the command will use the first deployment by default. You can specify the specfic deployment with the `--name` option. Examples:
25
+
26
+ kubes exec --name demo-web
27
+ kubes exec --name demo-clock
28
+ kubes exec --name demo-worker
29
+ kubes exec --name demo-web sh
30
+ kubes exec --name demo-web ls -l
31
+
32
+
33
+ ## Options
34
+
35
+ ```
36
+ [--compile], [--no-compile] # whether or not to compile the .kube/resources
37
+ # Default: true
38
+ n, [--name=NAME] # deployment name to use. IE: demo-web
39
+ [--verbose], [--no-verbose]
40
+ [--noop], [--no-noop]
41
+ ```
42
+
@@ -0,0 +1,27 @@
1
+ ---
2
+ title: kubes get
3
+ reference: true
4
+ ---
5
+
6
+ ## Usage
7
+
8
+ kubes get [ROLE] [RESOURCE]
9
+
10
+ ## Description
11
+
12
+ Get Kubernetes resource using the compiled YAML files
13
+
14
+
15
+ ## Options
16
+
17
+ ```
18
+ [--image=IMAGE] # override image
19
+ [--compile], [--no-compile] # whether or not to compile the .kube/resources
20
+ # Default: true
21
+ o, [--output=OUTPUT] # Output format: json|yaml|wide|name
22
+ [--show-pods], [--no-show-pods] # Also show pods from deployments
23
+ # Default: true
24
+ [--verbose], [--no-verbose]
25
+ [--noop], [--no-noop]
26
+ ```
27
+
@@ -15,7 +15,7 @@ Init project
15
15
  ## Options
16
16
 
17
17
  ```
18
- a, --app=APP # Docker repo name. Example: demo-web. Generates .kubes/APP/resources folder
18
+ a, --app=APP # Docker repo name. Example: web. Generates .kubes/APP/resources folder
19
19
  [--force] # Bypass overwrite are you sure prompt for existing files
20
20
  t, [--type=TYPE] # Type: dsl or yaml
21
21
  # Default: yaml
@@ -0,0 +1,26 @@
1
+ ---
2
+ title: kubes logs
3
+ reference: true
4
+ ---
5
+
6
+ ## Usage
7
+
8
+ kubes logs
9
+
10
+ ## Description
11
+
12
+ logs from all deployment pods
13
+
14
+
15
+ ## Options
16
+
17
+ ```
18
+ [--compile], [--no-compile] # whether or not to compile the .kube/resources
19
+ # Default: true
20
+ n, [--name=NAME] # deployment name to use. IE: demo-web
21
+ f, [--follow], [--no-follow] # Follow logs
22
+ # Default: true
23
+ [--verbose], [--no-verbose]
24
+ [--noop], [--no-noop]
25
+ ```
26
+
@@ -5,4 +5,4 @@
5
5
  # bin/web -P 8888
6
6
 
7
7
  bundle exec jekyll clean
8
- exec bundle exec jekyll serve --host 0.0.0.0 "$@"
8
+ exec bundle exec jekyll serve "$@"
@@ -10,6 +10,10 @@ title: CLI Reference
10
10
  * [kubes completion_script]({% link _reference/kubes-completion_script.md %})
11
11
  * [kubes delete]({% link _reference/kubes-delete.md %})
12
12
  * [kubes deploy]({% link _reference/kubes-deploy.md %})
13
+ * [kubes describe]({% link _reference/kubes-describe.md %})
13
14
  * [kubes docker]({% link _reference/kubes-docker.md %})
15
+ * [kubes exec]({% link _reference/kubes-exec.md %})
16
+ * [kubes get]({% link _reference/kubes-get.md %})
14
17
  * [kubes init]({% link _reference/kubes-init.md %})
18
+ * [kubes logs]({% link _reference/kubes-logs.md %})
15
19
  * [kubes version]({% link _reference/kubes-version.md %})
@@ -9,6 +9,9 @@ module Kubes
9
9
  compile_option = Proc.new {
10
10
  option :compile, type: :boolean, default: true, desc: "whether or not to compile the .kube/resources"
11
11
  }
12
+ name_option = Proc.new {
13
+ option :name, aliases: %w[n], desc: "deployment name to use. IE: demo-web"
14
+ }
12
15
 
13
16
  desc "docker SUBCOMMAND", "Docker subcommands"
14
17
  long_desc Help.text(:docker)
@@ -60,15 +63,33 @@ module Kubes
60
63
  Describe.new(options.merge(role: role, resource: resource)).run
61
64
  end
62
65
 
66
+ desc "exec", "Exec into the latest container from the deployment"
67
+ long_desc Help.text(:exec)
68
+ compile_option.call
69
+ name_option.call
70
+ def exec(*cmd)
71
+ Exec.new(options.merge(cmd: cmd)).run
72
+ end
73
+
63
74
  desc "get [ROLE] [RESOURCE]", "Get Kubernetes resource using the compiled YAML files"
64
75
  long_desc Help.text(:get)
65
76
  image_option.call
66
77
  compile_option.call
67
78
  option :output, aliases: %w[o], desc: "Output format: json|yaml|wide|name"
79
+ option :show_pods, type: :boolean, default: true, desc: "Also show pods from deployments"
68
80
  def get(role=nil, resource=nil)
69
81
  Get.new(options.merge(role: role, resource: resource)).run
70
82
  end
71
83
 
84
+ desc "logs", "logs from all deployment pods"
85
+ long_desc Help.text(:logs)
86
+ compile_option.call
87
+ name_option.call
88
+ option :follow, aliases: %w[f], type: :boolean, default: true, desc: "Follow logs"
89
+ def logs(*cmd)
90
+ Logs.new(options.merge(cmd: cmd)).run
91
+ end
92
+
72
93
  long_desc Help.text(:init)
73
94
  Init.options.each { |args| option(*args) }
74
95
  register(Init, "init", "init", "Init project")
@@ -1,7 +1,7 @@
1
1
  class Kubes::CLI
2
2
  class Apply < Base
3
3
  def run
4
- Compile.new(@options).run unless @options[:compile] == false
4
+ compile
5
5
  logger.info "Deploying kubes resources"
6
6
  Kubes::Kubectl::Decider.new(:apply, @options).run
7
7
  end
@@ -5,5 +5,9 @@ class Kubes::CLI
5
5
  def initialize(options={})
6
6
  @options = options
7
7
  end
8
+
9
+ def compile
10
+ Compile.new(@options).run unless @options[:compile] == false
11
+ end
8
12
  end
9
13
  end
@@ -3,9 +3,14 @@ class Kubes::CLI
3
3
  include Kubes::Util::Sure
4
4
 
5
5
  def run
6
+ compile
7
+ perform(preview: true) unless @options[:yes]
6
8
  sure?("This will delete resources. Are you sure?")
7
- Compile.new(@options).run
8
- Kubes::Kubectl::Decider.new(:delete, @options).run
9
+ perform(preview: false)
10
+ end
11
+
12
+ def perform(preview: false)
13
+ Kubes::Kubectl::Decider.new(:delete, @options.merge(preview: preview)).run
9
14
  end
10
15
  end
11
16
  end
@@ -1,7 +1,7 @@
1
1
  class Kubes::CLI
2
2
  class Describe < Base
3
3
  def run
4
- Compile.new(@options).run unless @options[:compile] == false
4
+ compile
5
5
  Kubes::Kubectl.run(:describe, @options)
6
6
  end
7
7
  end
@@ -0,0 +1,33 @@
1
+ class Kubes::CLI
2
+ class Exec < Base
3
+ include Kubes::Util::Sh
4
+
5
+ def run
6
+ compile
7
+ metadata = Kubes::Kubectl::Fetch::Deployment.new(@options).metadata
8
+
9
+ labels = metadata['labels'].map { |k,v| "#{k}=#{v}" }.join(',')
10
+ ns = metadata['namespace']
11
+
12
+ resp = capture("kubectl get pod -l #{labels} -n #{ns} -o json")
13
+ data = JSON.load(resp)
14
+ pod = latest_pod(data['items'])
15
+
16
+ unless pod
17
+ logger.error "ERROR: Unable to find a running pod".color(:red)
18
+ exit 1
19
+ end
20
+
21
+ name = pod['metadata']['name']
22
+ cmd = @options[:cmd].empty? ? "bash" : @options[:cmd].join(' ')
23
+ sh("kubectl exec -n #{ns} -ti #{name} -- #{cmd}")
24
+ end
25
+
26
+ # get latest running pod
27
+ def latest_pod(items)
28
+ running = items.select { |i| i['status']['phase'] == 'Running' }
29
+ sorted = running.sort_by { |i| i['metadata']['creationTimestamp'] || 0 }
30
+ sorted.last
31
+ end
32
+ end
33
+ end
@@ -1,8 +1,10 @@
1
1
  class Kubes::CLI
2
2
  class Get < Base
3
3
  def run
4
- Compile.new(@options).run unless @options[:compile] == false
4
+ compile
5
5
  Kubes::Kubectl.run(:get, @options)
6
+ pods = Kubes::Kubectl::Fetch::Pods.new(@options)
7
+ pods.show if @options[:show_pods]
6
8
  end
7
9
  end
8
10
  end
@@ -0,0 +1,17 @@
1
+ The exec command finds the latest pod from the deployment and runs `kubectl exec -ti POD bash` to get you into it. It spares you from having to manually find and type it.
2
+
3
+ ## Examples
4
+
5
+ kubes exec
6
+ kubes exec sh
7
+ kubes exec ls -l
8
+
9
+ ## Multiple Deployments
10
+
11
+ If you have have multiple deployments in your ``.kubes/resources` then the command will use the first deployment by default. You can specify the specfic deployment with the `--name` option. Examples:
12
+
13
+ kubes exec --name demo-web
14
+ kubes exec --name demo-clock
15
+ kubes exec --name demo-worker
16
+ kubes exec --name demo-web sh
17
+ kubes exec --name demo-web ls -l
@@ -0,0 +1,13 @@
1
+ class Kubes::CLI
2
+ class Logs < Base
3
+ include Kubes::Util::Sh
4
+
5
+ def run
6
+ compile
7
+ metadata = Kubes::Kubectl::Fetch::Deployment.new(@options).metadata
8
+ name = metadata['name']
9
+ follow = " -f" if @options[:follow]
10
+ sh("kubectl logs deployment/#{name}#{follow}")
11
+ end
12
+ end
13
+ end
@@ -1,7 +1,6 @@
1
1
  module Kubes::Compiler::Dsl::Syntax
2
2
  class Deployment < Resource
3
3
  fields :container, # <Object>
4
- :containers, # <[]Object>
5
4
  "matchLabels:hash", # <map[string]string>
6
5
  :sidecar, # <Object>
7
6
  :templateMetadata, # <Object>
@@ -21,6 +20,42 @@ module Kubes::Compiler::Dsl::Syntax
21
20
  fields :maxSurge, # <string>
22
21
  :maxUnavailable # <string>
23
22
 
23
+ # kubectl explain deploy.spec.template.spec
24
+ fields :activeDeadlineSeconds, # <integer>
25
+ :affinity, # <Object>
26
+ :automountServiceAccountToken, # <boolean>
27
+ :containers, # <[]Object> -required-
28
+ :dnsConfig, # <Object>
29
+ :dnsPolicy, # <string>
30
+ :enableServiceLinks, # <boolean>
31
+ :ephemeralContainers, # <[]Object>
32
+ :hostAliases, # <[]Object>
33
+ :hostIPC, # <boolean>
34
+ :hostNetwork, # <boolean>
35
+ :hostPID, # <boolean>
36
+ :hostname, # <string>
37
+ :imagePullSecrets, # <[]Object>
38
+ :initContainers, # <[]Object>
39
+ :nodeName, # <string>
40
+ :nodeSelector, # <map[string]string>
41
+ :overhead, # <map[string]string>
42
+ :preemptionPolicy, # <string>
43
+ :priority, # <integer>
44
+ :priorityClassName, # <string>
45
+ :readinessGates, # <[]Object>
46
+ :restartPolicy, # <string>
47
+ :runtimeClassName, # <string>
48
+ :schedulerName, # <string>
49
+ :securityContext, # <Object>
50
+ :serviceAccount, # <string>
51
+ :serviceAccountName, # <string>
52
+ :shareProcessNamespace, # <boolean>
53
+ :subdomain, # <string>
54
+ :terminationGracePeriodSeconds,# <integer>
55
+ :tolerations, # <[]Object>
56
+ :topologySpreadConstraints, # <[]Object>
57
+ :volumes # <[]Object>
58
+
24
59
  # kubectl explain deployment.spec.template.spec.containers
25
60
  fields :args, # <[]string>
26
61
  :command, # <[]string>
@@ -104,7 +139,42 @@ module Kubes::Compiler::Dsl::Syntax
104
139
  end
105
140
 
106
141
  def default_templateSpec
107
- { containers: containers }
142
+ {
143
+ activeDeadlineSeconds: activeDeadlineSeconds,
144
+ affinity: affinity,
145
+ automountServiceAccountToken: automountServiceAccountToken,
146
+ containers: containers,
147
+ dnsConfig: dnsConfig,
148
+ dnsPolicy: dnsPolicy,
149
+ enableServiceLinks: enableServiceLinks,
150
+ ephemeralContainers: ephemeralContainers,
151
+ hostAliases: hostAliases,
152
+ hostIPC: hostIPC,
153
+ hostNetwork: hostNetwork,
154
+ hostPID: hostPID,
155
+ hostname: hostname,
156
+ imagePullSecrets: imagePullSecrets,
157
+ initContainers: initContainers,
158
+ nodeName: nodeName,
159
+ nodeSelector: nodeSelector,
160
+ overhead: overhead,
161
+ preemptionPolicy: preemptionPolicy,
162
+ priority: priority,
163
+ priorityClassName: priorityClassName,
164
+ readinessGates: readinessGates,
165
+ restartPolicy: restartPolicy,
166
+ runtimeClassName: runtimeClassName,
167
+ schedulerName: schedulerName,
168
+ securityContext: securityContext,
169
+ serviceAccount: serviceAccount,
170
+ serviceAccountName: serviceAccountName,
171
+ shareProcessNamespace: shareProcessNamespace,
172
+ subdomain: subdomain,
173
+ terminationGracePeriodSeconds: terminationGracePeriodSeconds,
174
+ tolerations: tolerations,
175
+ topologySpreadConstraints: topologySpreadConstraints,
176
+ volumes: volumes,
177
+ }
108
178
  end
109
179
 
110
180
  def default_templateMetadata
@@ -33,8 +33,19 @@ module Kubes::Compiler::Dsl::Syntax
33
33
 
34
34
  def default_spec
35
35
  {
36
+ clusterIP: clusterIP,
37
+ externalIPs: externalIPs,
38
+ externalName: externalName,
39
+ externalTrafficPolicy: externalTrafficPolicy,
40
+ healthCheckNodePort: healthCheckNodePort,
41
+ ipFamily: ipFamily,
42
+ loadBalancerIP: loadBalancerIP,
43
+ loadBalancerSourceRanges: loadBalancerSourceRanges,
36
44
  ports: ports,
45
+ publishNotReadyAddresses: publishNotReadyAddresses,
37
46
  selector: selector,
47
+ sessionAffinity: sessionAffinity,
48
+ sessionAffinityConfig: sessionAffinityConfig,
38
49
  type: type,
39
50
  }
40
51
  end
@@ -23,8 +23,9 @@ module Kubes::Hooks
23
23
  def run_hooks
24
24
  build
25
25
  run_hook("before")
26
- yield if block_given?
26
+ out = yield if block_given?
27
27
  run_hook("after")
28
+ out
28
29
  end
29
30
 
30
31
  def run_hook(type)
@@ -9,17 +9,29 @@ module Kubes
9
9
 
10
10
  def run
11
11
  validate!
12
+
13
+ options = @options.dup
14
+ options[:exit_on_fail] = exit_on_fail unless exit_on_fail.nil?
15
+
12
16
  params = args.flatten.join(' ')
13
17
  command = "kubectl #{@name} #{params}" # @name: apply or delete
14
- options = {}
15
- options[:exit_on_fail] = exit_on_fail unless exit_on_fail.nil?
18
+
16
19
  switch_context do
17
20
  run_hooks(@name) do
18
- sh(command, options)
21
+ if options[:capture]
22
+ capture(command, options)
23
+ else
24
+ sh(command, options)
25
+ end
19
26
  end
20
27
  end
21
28
  end
22
29
 
30
+ def execute(args, options={})
31
+ command = "kubectl #{args}"
32
+ capture(command)
33
+ end
34
+
23
35
  # Useful for kustomize mode
24
36
  def validate!
25
37
  return true unless Kubes.kustomize?
@@ -1,5 +1,6 @@
1
1
  class Kubes::Kubectl
2
2
  class Batch
3
+ include Kubes::Logging
3
4
  include Kubes::Util::Consider
4
5
  include Ordering
5
6
 
@@ -8,8 +9,14 @@ class Kubes::Kubectl
8
9
  end
9
10
 
10
11
  def run
12
+ # @options[:preview] is really only used for kubectl delete
13
+ logger.info "Will run:" if @options[:preview]
11
14
  sorted_files.each do |file|
12
- Kubes::Kubectl.run(@name, @options.merge(file: file))
15
+ if @options[:preview]
16
+ logger.info " kubectl #{@name} -f #{file}"
17
+ else
18
+ Kubes::Kubectl.run(@name, @options.merge(file: file))
19
+ end
13
20
  end
14
21
  end
15
22
 
@@ -0,0 +1,24 @@
1
+ require "json"
2
+
3
+ module Kubes::Kubectl::Fetch
4
+ class Base
5
+ include Kubes::Logging
6
+ include Kubes::Util::Sh
7
+
8
+ def initialize(options={})
9
+ @options = options
10
+ end
11
+
12
+ def fetch_items
13
+ o = {
14
+ capture: true,
15
+ output: "json",
16
+ show_command: false,
17
+ }
18
+ kubectl = Kubes::Kubectl.new(:get, @options.merge(o)) # kubes get -f .kubes/output
19
+ resp = kubectl.run
20
+ data = JSON.load(resp)
21
+ data['items']
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,34 @@
1
+ module Kubes::Kubectl::Fetch
2
+ class Deployment < Base
3
+ def metadata
4
+ items = fetch_items
5
+ # Not checking if deployment exists because kubes will error on `kubes get` from missing deployments already
6
+ deployments = items.select { |i| i['kind'] == "Deployment" }
7
+
8
+ if deployments.size > 1 && !@options[:name]
9
+ names = deployments.map { |d| d['metadata']['name'] }
10
+ logger.info <<~EOL
11
+ INFO: More than one deployment found.
12
+ Deployment names: #{names.join(', ')}
13
+ Using #{names.first}
14
+ Note: You can specify the deployment to use with --name
15
+ EOL
16
+ end
17
+
18
+ deployment = find_deployment(deployments)
19
+ unless deployment
20
+ logger.error "ERROR: No deployment found".color(:red)
21
+ exit 1
22
+ end
23
+ deployment['metadata']
24
+ end
25
+
26
+ def find_deployment(deployments)
27
+ if @options[:name]
28
+ deployments.find { |d| d['metadata']['name'] == @options[:name] }
29
+ else
30
+ deployments.first
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,21 @@
1
+ module Kubes::Kubectl::Fetch
2
+ class Pods < Base
3
+ def show
4
+ items = fetch_items
5
+ # Not checking if deployment exists because kubes will error on `kubes get` from missing deployments already
6
+ deployments = items.select { |i| i['kind'] == "Deployment" }
7
+
8
+ deployments.each do |deployment|
9
+ logger.info "Pods for deployment #{deployment['metadata']['name']}:".color(:green)
10
+ show_for(deployment)
11
+ end
12
+ end
13
+
14
+ def show_for(deployment)
15
+ metadata = deployment['metadata']
16
+ labels = metadata['labels'].map { |k,v| "#{k}=#{v}" }.join(',')
17
+ ns = metadata['namespace']
18
+ sh("kubectl get pod -l #{labels} -n #{ns}")
19
+ end
20
+ end
21
+ end
@@ -32,6 +32,7 @@ module Kubes::Util
32
32
 
33
33
  def capture(command, options={})
34
34
  exit_on_fail = options[:exit_on_fail].nil? ? true : options[:exit_on_fail]
35
+ logger.info "=> #{command}" if options[:show_command]
35
36
  out = `#{command}`.strip
36
37
  unless $?.success?
37
38
  logger.error "ERROR: running #{command}".color(:red)
@@ -1,3 +1,3 @@
1
1
  module Kubes
2
- VERSION = "0.2.6"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -7,4 +7,5 @@ image built_image # IE: user/<%= app %>:kubes-2020-06-13T19-55-16-43afc6e
7
7
  # revisionHistoryLimit 1 # uncomment to reduce old ReplicaSets, default is 10 https://bit.ly/3hqrzyP
8
8
  # maxUnavailable 25
9
9
 
10
- # More docs: kubes.guru/docs/dsl/deployment/
10
+ # More docs: kubes.guru/docs/dsl/resources/deployment/
11
+
@@ -5,4 +5,4 @@ labels(role: "web")
5
5
  # port 80
6
6
  targetPort dockerfile_port # expose port in Dockerfile
7
7
 
8
- # More docs: kubes.guru/docs/dsl/service/
8
+ # More docs: kubes.guru/docs/dsl/resources/service/
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kubes
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.6
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tung Nguyen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-07-28 00:00:00.000000000 Z
11
+ date: 2020-08-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -317,6 +317,8 @@ files:
317
317
  - docs/_includes/layering/layers.md
318
318
  - docs/_includes/learn/cluster.md
319
319
  - docs/_includes/learn/next-steps.md
320
+ - docs/_includes/learn/repo
321
+ - docs/_includes/learn/repos.md
320
322
  - docs/_includes/learn/review.md
321
323
  - docs/_includes/learn/start.md
322
324
  - docs/_includes/reference.md
@@ -329,11 +331,15 @@ files:
329
331
  - docs/_reference/kubes-completion_script.md
330
332
  - docs/_reference/kubes-delete.md
331
333
  - docs/_reference/kubes-deploy.md
334
+ - docs/_reference/kubes-describe.md
332
335
  - docs/_reference/kubes-docker-build.md
333
336
  - docs/_reference/kubes-docker-help.md
334
337
  - docs/_reference/kubes-docker-push.md
335
338
  - docs/_reference/kubes-docker.md
339
+ - docs/_reference/kubes-exec.md
340
+ - docs/_reference/kubes-get.md
336
341
  - docs/_reference/kubes-init.md
342
+ - docs/_reference/kubes-logs.md
337
343
  - docs/_reference/kubes-version.md
338
344
  - docs/_sass/bootstrap-overrides.scss
339
345
  - docs/_sass/buttons.scss
@@ -457,12 +463,15 @@ files:
457
463
  - lib/kubes/cli/deploy.rb
458
464
  - lib/kubes/cli/describe.rb
459
465
  - lib/kubes/cli/docker.rb
466
+ - lib/kubes/cli/exec.rb
460
467
  - lib/kubes/cli/get.rb
461
468
  - lib/kubes/cli/help.rb
462
469
  - lib/kubes/cli/help/completion.md
463
470
  - lib/kubes/cli/help/completion_script.md
464
471
  - lib/kubes/cli/help/deploy.md
472
+ - lib/kubes/cli/help/exec.md
465
473
  - lib/kubes/cli/init.rb
474
+ - lib/kubes/cli/logs.rb
466
475
  - lib/kubes/cli/sequence.rb
467
476
  - lib/kubes/command.rb
468
477
  - lib/kubes/compiler.rb
@@ -533,6 +542,9 @@ files:
533
542
  - lib/kubes/kubectl/args/standard.rb
534
543
  - lib/kubes/kubectl/batch.rb
535
544
  - lib/kubes/kubectl/decider.rb
545
+ - lib/kubes/kubectl/fetch/base.rb
546
+ - lib/kubes/kubectl/fetch/deployment.rb
547
+ - lib/kubes/kubectl/fetch/pods.rb
536
548
  - lib/kubes/kubectl/kustomize.rb
537
549
  - lib/kubes/kubectl/ordering.rb
538
550
  - lib/kubes/logger.rb