matsuri 0.1.0 → 0.3.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 (157) hide show
  1. checksums.yaml +5 -5
  2. data/.envrc +1 -0
  3. data/.gitignore +2 -0
  4. data/.rubocop.yml +9 -0
  5. data/AGENTS.md +18 -0
  6. data/CHANGELOG.md +642 -0
  7. data/Gemfile +2 -0
  8. data/README.md +86 -8
  9. data/Rakefile +20 -0
  10. data/bin/console +1 -0
  11. data/bin/matsuri +6 -0
  12. data/bin/setup +2 -0
  13. data/docs/acceptors.md +181 -0
  14. data/docs/boot.md +101 -0
  15. data/docs/design/acceptors.md +157 -0
  16. data/docs/design/boot.md +131 -0
  17. data/docs/design/ssa.md +142 -0
  18. data/docs/design/stacks.md +153 -0
  19. data/docs/diff.md +85 -0
  20. data/docs/known-issues.md +19 -0
  21. data/docs/local-dev.md +173 -0
  22. data/docs/presenters.md +317 -0
  23. data/docs/resources.md +121 -0
  24. data/docs/setup.md +97 -0
  25. data/docs/ssa.md +149 -0
  26. data/docs/stacks.md +146 -0
  27. data/flake.lock +61 -0
  28. data/flake.nix +35 -0
  29. data/lib/matsuri/acceptor.rb +33 -0
  30. data/lib/matsuri/acceptors/image_tag.rb +15 -0
  31. data/lib/matsuri/cmd.rb +46 -0
  32. data/lib/matsuri/cmds/apply.rb +78 -0
  33. data/lib/matsuri/cmds/cli.rb +147 -0
  34. data/lib/matsuri/cmds/create.rb +87 -0
  35. data/lib/matsuri/cmds/delete.rb +86 -0
  36. data/lib/matsuri/cmds/diff.rb +105 -0
  37. data/lib/matsuri/cmds/generate.rb +24 -0
  38. data/lib/matsuri/cmds/kubectl.rb +16 -0
  39. data/lib/matsuri/cmds/recreate.rb +65 -0
  40. data/lib/matsuri/cmds/scale.rb +37 -0
  41. data/lib/matsuri/cmds/show.rb +123 -0
  42. data/lib/matsuri/cmds/status.rb +67 -0
  43. data/lib/matsuri/concerns/awaiting.rb +24 -0
  44. data/lib/matsuri/concerns/diffable.rb +135 -0
  45. data/lib/matsuri/concerns/export_manifest.rb +56 -0
  46. data/lib/matsuri/concerns/import_manifest.rb +64 -0
  47. data/lib/matsuri/concerns/pod_template.rb +37 -0
  48. data/lib/matsuri/concerns/pods/spread_pods.rb +47 -0
  49. data/lib/matsuri/concerns/pods/spread_topology.rb +63 -0
  50. data/lib/matsuri/concerns/registry_helpers.rb +59 -0
  51. data/lib/matsuri/config.rb +101 -0
  52. data/lib/matsuri/core_ext.rb +107 -0
  53. data/lib/matsuri/dsl/cluster/aggregated_cluster_role.rb +75 -0
  54. data/lib/matsuri/dsl/cluster/binding.rb +118 -0
  55. data/lib/matsuri/dsl/cluster/cluster_role.rb +41 -0
  56. data/lib/matsuri/dsl/cluster/role.rb +49 -0
  57. data/lib/matsuri/dsl/cluster/scope.rb +245 -0
  58. data/lib/matsuri/dsl/cluster/service_account.rb +76 -0
  59. data/lib/matsuri/dsl/concerns/default_binding.rb +34 -0
  60. data/lib/matsuri/dsl/concerns/manifest_set.rb +21 -0
  61. data/lib/matsuri/dsl/concerns/metadata.rb +56 -0
  62. data/lib/matsuri/dsl/concerns/rbac_rules.rb +39 -0
  63. data/lib/matsuri/initializer.rb +41 -0
  64. data/lib/matsuri/kubernetes/base.rb +107 -0
  65. data/lib/matsuri/kubernetes/config_map.rb +100 -0
  66. data/lib/matsuri/kubernetes/cron_job.rb +115 -0
  67. data/lib/matsuri/kubernetes/daemon_set.rb +62 -0
  68. data/lib/matsuri/kubernetes/deployment.rb +65 -0
  69. data/lib/matsuri/kubernetes/endpoints.rb +57 -0
  70. data/lib/matsuri/kubernetes/horizontal_pod_autoscaler.rb +116 -0
  71. data/lib/matsuri/kubernetes/imported_manifest.rb +61 -0
  72. data/lib/matsuri/kubernetes/ingress.rb +66 -0
  73. data/lib/matsuri/kubernetes/persistent_volume.rb +56 -0
  74. data/lib/matsuri/kubernetes/persistent_volume_claim.rb +41 -0
  75. data/lib/matsuri/kubernetes/pod.rb +355 -0
  76. data/lib/matsuri/kubernetes/replica_set.rb +46 -0
  77. data/lib/matsuri/kubernetes/secret.rb +86 -0
  78. data/lib/matsuri/kubernetes/service.rb +49 -0
  79. data/lib/matsuri/kubernetes/stateful_set.rb +75 -0
  80. data/lib/matsuri/kubernetes/storage_class.rb +45 -0
  81. data/lib/matsuri/platform.rb +38 -0
  82. data/lib/matsuri/presenter.rb +47 -0
  83. data/lib/matsuri/presenters/helpers.rb +39 -0
  84. data/lib/matsuri/presenters/prune_empty.rb +59 -0
  85. data/lib/matsuri/presenters/seed_image.rb +28 -0
  86. data/lib/matsuri/presenters/seed_replicas.rb +25 -0
  87. data/lib/matsuri/presenters/seed_resources.rb +29 -0
  88. data/lib/matsuri/registry.rb +267 -0
  89. data/lib/matsuri/shell_out.rb +119 -0
  90. data/lib/matsuri/stack.rb +276 -0
  91. data/lib/matsuri/task.rb +20 -0
  92. data/lib/matsuri/tasks/cluster.rb +79 -0
  93. data/lib/matsuri/tasks/docker.rb +25 -0
  94. data/lib/matsuri/tasks/hash_diff.rb +61 -0
  95. data/lib/matsuri/tasks/kubectl.rb +21 -0
  96. data/lib/matsuri/tasks/kubectl_ops/apply.rb +24 -0
  97. data/lib/matsuri/tasks/kubectl_ops/create.rb +27 -0
  98. data/lib/matsuri/tasks/kubectl_ops/delete.rb +21 -0
  99. data/lib/matsuri/tasks/kubectl_ops/diff.rb +47 -0
  100. data/lib/matsuri/tasks/kubectl_ops/get.rb +36 -0
  101. data/lib/matsuri/tasks/kubectl_ops/recreate.rb +35 -0
  102. data/lib/matsuri/tasks/kubectl_ops/replace.rb +29 -0
  103. data/lib/matsuri/tasks/kubectl_ops/rollout_status.rb +22 -0
  104. data/lib/matsuri/tasks/kubectl_ops/scale.rb +22 -0
  105. data/lib/matsuri/tasks/kubectl_ops/server_side_apply.rb +32 -0
  106. data/lib/matsuri/tasks/kubectl_ops/status.rb +20 -0
  107. data/lib/matsuri/tasks/kubectl_ops.rb +218 -0
  108. data/lib/matsuri/tasks/pod.rb +56 -0
  109. data/lib/matsuri/tasks/stacks/seed.rb +93 -0
  110. data/lib/matsuri/tasks/stacks.rb +31 -0
  111. data/lib/matsuri/transform/algebra.rb +52 -0
  112. data/lib/matsuri/transform/callable.rb +54 -0
  113. data/lib/matsuri/transform/combinators.rb +61 -0
  114. data/lib/matsuri/transform/env.rb +43 -0
  115. data/lib/matsuri/transform/kubernetes.rb +89 -0
  116. data/lib/matsuri/transform.rb +20 -0
  117. data/lib/matsuri/version.rb +3 -1
  118. data/lib/matsuri.rb +158 -2
  119. data/matsuri.gemspec +20 -7
  120. data/tests/bin/minikube-start.sh +27 -0
  121. data/tests/bin/probe-save-config.sh +46 -0
  122. data/tests/bin/probe-ssa.sh +206 -0
  123. data/tests/example/.gitignore +1 -0
  124. data/tests/example/Gemfile +7 -0
  125. data/tests/example/README.md +91 -0
  126. data/tests/example/bin/matsuri +14 -0
  127. data/tests/example/config/initializer.rb +12 -0
  128. data/tests/example/config/matsuri.rb +9 -0
  129. data/tests/example/config/platform.rb +39 -0
  130. data/tests/example/lib/acme/nodes/dedicated.rb +26 -0
  131. data/tests/example/lib/acme/nodes/preemptible.rb +17 -0
  132. data/tests/example/lib/acme/nodes/required_cores.rb +26 -0
  133. data/tests/example/lib/acme/nodes/resource_class.rb +26 -0
  134. data/tests/example/lib/acme/pods/cacerts.rb +15 -0
  135. data/tests/example/lib/acme/pods/healthcheck.rb +36 -0
  136. data/tests/example/lib/acme.rb +26 -0
  137. data/tests/example/platform/config_maps/billing-settings.rb +8 -0
  138. data/tests/example/platform/config_maps/cacerts.rb +9 -0
  139. data/tests/example/platform/deployments/billing-web.rb +5 -0
  140. data/tests/example/platform/deployments/checkout-web.rb +6 -0
  141. data/tests/example/platform/namespaces/billing-dev.yaml +7 -0
  142. data/tests/example/platform/namespaces/checkout-dev.yaml +7 -0
  143. data/tests/example/platform/pods/billing.rb +31 -0
  144. data/tests/example/platform/pods/checkout.rb +27 -0
  145. data/tests/example/platform/services/billing-web.rb +6 -0
  146. data/tests/example/platform/services/checkout-web.rb +4 -0
  147. data/tests/example/platform/stacks/billing.rb +8 -0
  148. data/tests/example/platform/stacks/checkout.rb +19 -0
  149. data/tests/k8s/save-config/deployment-declared.yaml +19 -0
  150. data/tests/k8s/save-config/deployment-seeded.yaml +20 -0
  151. data/tests/k8s/save-config/namespace.yaml +4 -0
  152. data/tests/k8s/ssa/declared-bumped.yaml +22 -0
  153. data/tests/k8s/ssa/declared.yaml +22 -0
  154. data/tests/k8s/ssa/namespace.yaml +4 -0
  155. data/tests/k8s/ssa/seed-via-create.yaml +24 -0
  156. metadata +288 -20
  157. data/.travis.yml +0 -4
@@ -0,0 +1,147 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'thor'
4
+
5
+ module Matsuri
6
+ module Cmds
7
+ class Cli < Thor
8
+ include Matsuri::Cmd
9
+
10
+ # Don't want to write code to _not_ load in the config, so not going to do it here
11
+ #class_option :config, aliases: :c, type: :string, default: File.join(Matsuri::Config.base_path, 'config', 'matsuri.rb')
12
+ class_option :verbose, aliases: :v, type: :boolean
13
+ class_option :debug, aliases: :D, type: :boolean
14
+
15
+ desc 'generate SUBCOMMAND ...ARGS', 'generate Matsuri scaffolding'
16
+ subcommand 'generate', Matsuri::Cmds::Generate
17
+
18
+ desc 'kubectl SUBCOMMAND ...ARGS', 'manage kubectl configs'
19
+ subcommand 'kubectl', Matsuri::Cmds::Kubectl
20
+
21
+ desc 'show SUBCOMMAND ...ARGS', 'show resource'
22
+ subcommand 'show', Matsuri::Cmds::Show
23
+ map describe: :show
24
+
25
+ desc 'diff SUBCOMMAND ...ARGS', 'diff resource (show what would be applied) '
26
+ subcommand 'diff', Matsuri::Cmds::Diff
27
+
28
+ desc 'status SUBCOMMAND ...ARGS', 'resource status'
29
+ subcommand 'status', Matsuri::Cmds::Status
30
+ map top: :status
31
+
32
+ desc 'create SUBCOMMAND ...ARGS', 'create resource (kubectl create)'
33
+ subcommand 'create', Matsuri::Cmds::Create
34
+ map start: :create
35
+
36
+ desc 'apply SUBCOMMAND ...ARGS', 'create or update resource (kubectl apply)'
37
+ subcommand 'apply', Matsuri::Cmds::Apply
38
+
39
+ desc 'rebuild', 'Not Implementd'
40
+ def rebuild
41
+ puts "Rebuild not implemented yet"
42
+ exit (1)
43
+ end
44
+
45
+ desc 'recreate SUBCOMMAND ...ARGS', 'recreate resource'
46
+ subcommand 'recreate', Matsuri::Cmds::Recreate
47
+ map restart: :recreate
48
+
49
+ desc 'delete SUBCOMMAND ...ARGS', 'delete resource'
50
+ subcommand 'delete', Matsuri::Cmds::Delete
51
+ map stop: :delete
52
+
53
+ desc 'converge STACK_NAME [IMAGE_TAG]', 'Idempotently converges a stack and all dependencies'
54
+ option :restart, type: :boolean, default: false
55
+ option :stack_config, type: :string, banner: 'PATH'
56
+ def converge(name, image_tag = nil)
57
+ with_config do |opt|
58
+ Matsuri::Registry.stack(name)
59
+ .new(image_tag: image_tag, config: stack_config_data(opt))
60
+ .converge!(opt)
61
+ end
62
+ end
63
+
64
+ desc 'reconcile', 'Reconcile and converge cluster-wide resources, such as RBAC and NetworkPolicy'
65
+ def reconcile
66
+ with_config do |opt|
67
+ Matsuri::Tasks::Cluster.new.reconcile!(opt)
68
+ end
69
+ end
70
+
71
+ desc 'reload STACK_NAME', 'Reloads a stack without recreating underlying pods'
72
+ def reload(name, image_tag = nil)
73
+ with_config do |opt|
74
+ Matsuri::Registry.stack(name).new(image_tag: image_tag).reload!(opt)
75
+ end
76
+ end
77
+
78
+ desc 'scale SUBCOMMAND ...ARGS', 'scale resource'
79
+ subcommand 'scale', Matsuri::Cmds::Scale
80
+
81
+ desc 'migrate STACK_NAME VERSION', 'Migrates a stack to VERSION'
82
+ def migrate(name, version)
83
+ with_config do |opt|
84
+ Matsuri::Registry.stack(name).new.migrate!(version, opt)
85
+ end
86
+ end
87
+
88
+ desc 'update STACK_NAME [VERSION]', 'Updates a stack to VERSION'
89
+ option :skip_migrations
90
+ def update(name, version = nil)
91
+ with_config do |opt|
92
+ Matsuri::Registry.stack(name).new.update!(version, opt)
93
+ end
94
+ end
95
+
96
+ desc 'sh STACK_NAME', 'Shells into a stack container'
97
+ option :root, aliases: :r, type: :boolean, default: false
98
+ option :user, aliases: :u, type: :string
99
+ option :pod, aliases: :p, type: :string
100
+ def sh(name, *args)
101
+ with_config do |opt|
102
+ Matsuri::Registry.stack(name).new.sh!(opt, args)
103
+ end
104
+ end
105
+
106
+ desc 'sh! STACK_NAME', 'Shells into a stack container as root'
107
+ option :pod, aliases: :p, type: :string
108
+ def sh!(name, *args)
109
+ with_config do |opt|
110
+ opt[:root] = true
111
+ Matsuri::Registry.stack(name).new.sh!(opt, args)
112
+ end
113
+ end
114
+
115
+ desc 'console STACK_NAME', 'Gets to the console of a stack'
116
+ option :root, type: :boolean, default: false
117
+ option :user, type: :string
118
+ option :pod, aliases: :p, type: :string
119
+ def console(name, *args)
120
+ with_config do |opt|
121
+ Matsuri::Registry.stack(name).new.console!(opt, args)
122
+ end
123
+ end
124
+
125
+ desc 'build STACK_NAME', 'Builds docker image for stack'
126
+ option :dev, type: :boolean, default: false
127
+ option :version, type: :string
128
+ option :branch, type: :string
129
+ option :github_user, type: :string
130
+ option :repo, type: :string
131
+ def build(name)
132
+ with_config do |opt|
133
+ Matsuri::Registry.stack(name).new.build!(opt)
134
+ end
135
+ end
136
+
137
+ desc 'push STACK_NAME', 'Pushes docker image for stack'
138
+ option :dev, type: :boolean, default: false
139
+ option :version, type: :string, default: 'latest'
140
+ def push(name)
141
+ with_config do |opt|
142
+ Matsuri::Registry.stack(name).new.push!(opt)
143
+ end
144
+ end
145
+ end
146
+ end
147
+ end
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Matsuri
4
+ module Cmds
5
+ class Create < Thor
6
+ include Matsuri::Cmd
7
+
8
+ class_option :'no-deps', type: :boolean, default: false
9
+
10
+ def self.create_cmd_for(resource_name, image_tag: false)
11
+ unless image_tag
12
+ define_method(resource_name) do |name = :not_specified|
13
+ create_resource { Matsuri::Registry.fetch_or_load(resource_name, name).new }
14
+ end
15
+ else
16
+ define_method(resource_name) do |name = :not_specified, image_tag = nil|
17
+ create_resource { Matsuri::Registry.fetch_or_load(resource_name, name).new(image_tag: image_tag_for(image_tag)) }
18
+ end
19
+ end
20
+ end
21
+
22
+ desc 'pod POD_NAME [IMAGE_TAG]', 'create a pod'
23
+ create_cmd_for :pod, image_tag: true
24
+
25
+ desc 'replica-set RS_NAME [IMAGE_TAG]', 'create a replica set'
26
+ create_cmd_for :replica_set, image_tag: true
27
+ map replicaset: :replica_set
28
+ map rs: :replica_set
29
+
30
+ desc 'stateful_set STATEFUL_SET_NAME', 'create a stateful_set'
31
+ create_cmd_for :stateful_set, image_tag: true
32
+ map sts: :stateful_set
33
+
34
+ desc 'daemon_set DAEMON_SET_NAME', 'create a daemon_set'
35
+ create_cmd_for :daemon_set, image_tag: true
36
+ map ds: :daemon_set
37
+
38
+ desc 'deployment DEPLOYMENT_NAME [IMAGE_TAG]', 'create a deployment'
39
+ create_cmd_for :deployment, image_tag: true
40
+ map deploy: :deployment
41
+
42
+ desc 'cron-job CRONJOB_NAME', 'apply changes to a cronjob'
43
+ create_cmd_for :cron_job, image_tag: true
44
+ map cj: :cron_job
45
+ map cronjob: :cron_job
46
+
47
+ desc 'service SERVICE_NAME', 'create a service'
48
+ create_cmd_for :service
49
+
50
+ desc 'ingress INGRESS_NAME', 'create a ingress'
51
+ create_cmd_for :ingress
52
+
53
+ desc 'endpoints ENDPOINTS_NAME', 'create an endpoint set'
54
+ create_cmd_for :endpoints
55
+
56
+ desc 'secret SECRET_NAME', 'upload a secret'
57
+ create_cmd_for :secret
58
+
59
+ desc 'config-map CONFIG_MAP_NAME', 'upload a config map'
60
+ create_cmd_for :config_map
61
+ map configmap: :config_map
62
+ map cm: :config_map
63
+
64
+ desc 'pv PV_NAME', 'create a persistent volume'
65
+ create_cmd_for :pv
66
+
67
+ desc 'pvc PVC_NAME', 'create a persistent volume claim'
68
+ create_cmd_for :pvc
69
+
70
+ desc 'storage_class STORAGE_CLASS_NAME', 'upload a storage class'
71
+ create_cmd_for :storage_class
72
+
73
+ desc 'horizontal_pod_autoscaler HPA_NAME', 'create a horizontal pod autoscaler'
74
+ create_cmd_for :horizontal_pod_autoscaler
75
+ map hpa: :horizontal_pod_autoscaler
76
+
77
+ private
78
+
79
+ def create_resource
80
+ with_config do |opt|
81
+ resource = yield
82
+ Matsuri::Tasks::KubectlOps.create(resource)
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,86 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Matsuri
4
+ module Cmds
5
+ class Delete < Thor
6
+ include Matsuri::Cmd
7
+
8
+ def self.delete_cmd_for(resource_name)
9
+ define_method(resource_name) do |name = :not_specified|
10
+ delete_resource { Matsuri::Registry.fetch_or_load(resource_name, name).new }
11
+ end
12
+ end
13
+
14
+ desc 'pod POD_NAME', 'delete a pod'
15
+ delete_cmd_for :pod
16
+
17
+ desc 'replica_set REPLICA_SET_NAME', 'delete a replica_set'
18
+ delete_cmd_for :replica_set
19
+ map replicaset: :replica_set
20
+ map rs: :replica_set
21
+
22
+ desc 'stateful_set STATEFUL_SET_NAME', 'delete stateful_set'
23
+ delete_cmd_for :stateful_set
24
+ map sts: :stateful_set
25
+
26
+ desc 'daemon_set DAEMON_SET_NAME', 'delete daemon_set'
27
+ delete_cmd_for :daemon_set
28
+ map ds: :daemon_set
29
+
30
+ desc 'deployment DEPLOYMENT_NAME', 'delete a deployment'
31
+ delete_cmd_for :deployment
32
+ map deploy: :deployment
33
+
34
+ desc 'cron-job CRONJOB_NAME', 'apply changes to a cronjob'
35
+ delete_cmd_for :cron_job
36
+ map cj: :cron_job
37
+ map cronjob: :cron_job
38
+
39
+ desc 'service SERVICE_NAME', 'delete a service'
40
+ delete_cmd_for :service
41
+
42
+ desc 'ingress INGRESS_NAME', 'delete a ingress'
43
+ delete_cmd_for :ingress
44
+
45
+ desc 'endpoints ENDPOINTS_NAME', 'delete an endpoint set'
46
+ delete_cmd_for :endpoints
47
+
48
+ desc 'stack STACK_NAME', 'deletes all resources in a stack'
49
+ def stack(name = :not_specified)
50
+ with_config do |opt|
51
+ Matsuri::Registry.fetch_or_load(:stack, name).new.delete!
52
+ end
53
+ end
54
+
55
+ desc 'secret SECRET_NAME', 'delete a secret'
56
+ delete_cmd_for :secret
57
+
58
+ desc 'config-map CONFIG_MAP_NAME', 'delete a config map'
59
+ delete_cmd_for :config_map
60
+ map configmap: :config_map
61
+ map cm: :config_map
62
+
63
+ desc 'horizontal_pod_autoscaler HPA_NAME', 'delete a horizontal pod autoscaler'
64
+ delete_cmd_for :horizontal_pod_autoscaler
65
+ map hpa: :horizontal_pod_autoscaler
66
+
67
+ desc 'pv PV_NAME', 'delete a persistent volume'
68
+ delete_cmd_for :pv
69
+
70
+ desc 'pvc PVC_NAME', 'delete a persistent volume claim'
71
+ delete_cmd_for :pvc
72
+
73
+ desc 'storage_class STORAGE_CLASS_NAME', 'delete a storage class'
74
+ delete_cmd_for :storage_class
75
+
76
+ private
77
+
78
+ def delete_resource
79
+ with_config do |opt|
80
+ resource = yield
81
+ Matsuri::Tasks::KubectlOps.delete(resource)
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,105 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+ require 'matsuri/core_ext'
5
+
6
+ module Matsuri
7
+ module Cmds
8
+ class Diff < Thor
9
+ include Matsuri::Cmd
10
+
11
+ class_option :primary_container, aliases: :p, type: :boolean, default: false
12
+ class_option :hash_diff, type: :boolean, default: false
13
+
14
+ def self.diff_cmd_for(resource_name, image_tag: false)
15
+ unless image_tag
16
+ define_method(resource_name) do |name = :not_specified|
17
+ diff_resource { Matsuri::Registry.fetch_or_load(resource_name, name).new }
18
+ end
19
+ else
20
+ define_method(resource_name) do |name = :not_specified, image_tag = nil|
21
+ diff_resource { Matsuri::Registry.fetch_or_load(resource_name, name).new(image_tag: image_tag_for(image_tag)) }
22
+ end
23
+ end
24
+ end
25
+
26
+ desc 'stack STACK_NAME', 'diff manifests for all stack members'
27
+ option :stack_config, type: :string, banner: 'PATH'
28
+ def stack(name = :not_specified)
29
+ with_config do |opt|
30
+ Matsuri::Registry.stack(name).new(config: stack_config_data(opt)).diff!(opt)
31
+ end
32
+ end
33
+
34
+ desc 'pod POD_NAME', 'diff manifest for pod'
35
+ diff_cmd_for :pod, image_tag: true
36
+
37
+ desc 'replica_set REPLICA_SET_NAME', 'diff manifest for replica_set'
38
+ diff_cmd_for :replica_set, image_tag: true
39
+ map replicaset: :replica_set
40
+ map rs: :replica_set
41
+
42
+ desc 'stateful_set STATEFUL_SET_NAME', 'diff manifest for stateful_set'
43
+ diff_cmd_for :stateful_set, image_tag: true
44
+ map sts: :stateful_set
45
+
46
+ desc 'daemon_set DAEMON_SET_NAME', 'diff manifest for daemon_set'
47
+ diff_cmd_for :daemon_set, image_tag: true
48
+ map ds: :daemon_set
49
+
50
+ desc 'deployment DEPLOYMENT_NAME', 'diff manifest for deployment'
51
+ diff_cmd_for :deployment, image_tag: true
52
+ map deploy: :deployment
53
+
54
+ desc 'cron-job CRONJOB_NAME', 'apply changes to a cronjob'
55
+ diff_cmd_for :cron_job, image_tag: true
56
+ map cj: :cron_job
57
+ map cronjob: :cron_job
58
+
59
+ desc 'service SERVICE_NAME', 'diff manifest for service'
60
+ diff_cmd_for :service
61
+
62
+ desc 'ingress INGRESS_NAME', 'diff manifest for ingress'
63
+ diff_cmd_for :ingress
64
+
65
+ desc 'endpoints ENDPOINT_NAME', 'diff manifest for endpoints'
66
+ diff_cmd_for :endpoints
67
+
68
+ desc 'secret SECRET_NAME', 'diff a secret'
69
+ diff_cmd_for :secret
70
+
71
+ desc 'config_map CONFIG_MAP_NAME', 'diff a config map'
72
+ diff_cmd_for :config_map
73
+ map configmap: :config_map
74
+ map cm: :config_map
75
+
76
+ desc 'horizontal_pod_autoscaler HPA_NAME', 'diff a horizontal pod autoscaler'
77
+ diff_cmd_for :horizontal_pod_autoscaler
78
+ map hpa: :horizontal_pod_autoscaler
79
+
80
+ desc 'pv PV_NAME', 'diff manifest for persistent volume'
81
+ diff_cmd_for :pv
82
+
83
+ desc 'pvc PVC_NAME', 'diff manifest for persistent volume claim'
84
+ diff_cmd_for :pvc
85
+
86
+ desc 'storage_class STORAGE_CLASS_NAME', 'diff manifest for storage class'
87
+ diff_cmd_for :storage_class
88
+
89
+ private
90
+
91
+ def diff_resource
92
+ with_config do |opt|
93
+ resource = yield opt
94
+ # --primary-container is a HashDiff-only projection, so it
95
+ # implies --hash-diff
96
+ if opt[:hash_diff] || opt[:primary_container]
97
+ Matsuri::Tasks::HashDiff.new(resource: resource, primary_container: opt[:primary_container]).run!
98
+ else
99
+ Matsuri::Tasks::KubectlOps.diff(resource)
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Matsuri
4
+ module Cmds
5
+ class Generate < Thor
6
+ include Matsuri::Cmd
7
+
8
+ def self.generate_cmd_for(resource_name)
9
+ define_method(resource_name) do |name = :not_specified|
10
+ generate_resource { Matsuri::Registry.fetch_or_load(resource_name, name).new }
11
+ end
12
+ end
13
+
14
+ private
15
+
16
+ def generate_resource
17
+ with_config do |opt|
18
+ resource = yield
19
+ resource.generate_template!
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Matsuri
4
+ module Cmds
5
+ class Kubectl < Thor
6
+ include Matsuri::Cmd
7
+
8
+ desc 'setup', 'generate aliases for kubectl context'
9
+ def setup
10
+ with_config do |opt|
11
+ Matsuri::Tasks::Kubectl.new(opt).setup!
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Matsuri
4
+ module Cmds
5
+ class Recreate < Thor
6
+ include Matsuri::Cmd
7
+
8
+ class_option :r, desc: 'recreate dependencies', type: :boolean, default: false
9
+
10
+ def self.recreate_cmd_for(resource_name, image_tag: false)
11
+ unless image_tag
12
+ define_method(resource_name) do |name = :not_specified|
13
+ recreate_resource { Matsuri::Registry.fetch_or_load(resource_name, name).new }
14
+ end
15
+ else
16
+ define_method(resource_name) do |name = :not_specified, image_tag = nil|
17
+ recreate_resource { Matsuri::Registry.fetch_or_load(resource_name, name).new(image_tag: image_tag_for(image_tag)) }
18
+ end
19
+ end
20
+ end
21
+
22
+ desc 'pod POD_NAME [IMAGE TAG]', 'recreate a pod'
23
+ recreate_cmd_for :pod, image_tag: true
24
+
25
+ desc 'replica-set REPLICA_SET_NAME [IMAGE TAG]', 'recreate a replica set'
26
+ recreate_cmd_for :replica_set, image_tag: true
27
+ map replicaset: :replica_set
28
+ map rs: :replica_set
29
+
30
+ desc 'stateful_set STATEFUL_SET_NAME', 'recreate a stateful_set'
31
+ recreate_cmd_for :stateful_set, image_tag: true
32
+ map sts: :stateful_set
33
+
34
+ desc 'daemon_set DAEMON_SET_NAME', 'recreate a daemon_set'
35
+ recreate_cmd_for :daemon_set, image_tag: true
36
+ map ds: :daemon_set
37
+
38
+ desc 'deployment DEPLOYMENT_NAME [IMAGE TAG]', 'recreate a deployment'
39
+ recreate_cmd_for :deployment, image_tag: true
40
+ map deploy: :deployment
41
+
42
+ desc 'horizontal_pod_autoscaler HPA_NAME', 'recreate a horizontal pod autoscaler'
43
+ recreate_cmd_for :horizontal_pod_autoscaler
44
+ map hpa: :horizontal_pod_autoscaler
45
+
46
+ desc 'service SERVICE_NAME', 'recreate a service'
47
+ recreate_cmd_for :service
48
+
49
+ desc 'ingress INGRESS_NAME', 'recreate a ingress'
50
+ recreate_cmd_for :ingress
51
+
52
+ desc 'endpoints ENDPOINTS_NAME', 'recreate an endpoint set'
53
+ recreate_cmd_for :endpoints
54
+
55
+ private
56
+
57
+ def recreate_resource
58
+ with_config do |opt|
59
+ resource = yield
60
+ Matsuri::Tasks::KubectlOps.recreate(resource)
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Matsuri
4
+ module Cmds
5
+ class Scale < Thor
6
+ include Matsuri::Cmd
7
+
8
+ def self.scale_cmd_for(resource_name)
9
+ define_method(resource_name) do |name = :not_specified, replicas|
10
+ scale_resource(replicas) { Matsuri::Registry.fetch_or_load(resource_name, name).new }
11
+ end
12
+ end
13
+
14
+ desc 'replica-set RS_NAME REPLICAS', 'scale a replica set'
15
+ scale_cmd_for :replica_set
16
+ map replicaset: :replica_set
17
+ map rs: :replica_set
18
+
19
+ desc 'stateful_set STATEFUL_SET_NAME', 'scale a stateful_set'
20
+ scale_cmd_for :stateful_set
21
+ map sts: :stateful_set
22
+
23
+ desc 'deployment DEPLOYMENT_NAME REPLICAS', 'scale a deployment'
24
+ scale_cmd_for :deployment
25
+ map deploy: :deployment
26
+
27
+ private
28
+
29
+ def scale_resource(replicas)
30
+ with_config do |opt|
31
+ resource = yield
32
+ Matsuri::Tasks::KubectlOps.scale(resource, replicas)
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,123 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'yaml'
4
+ require 'matsuri/core_ext'
5
+
6
+ module Matsuri
7
+ module Cmds
8
+ class Show < Thor
9
+ include Matsuri::Cmd
10
+
11
+ class_option :json, aliases: :j, type: :boolean, default: false
12
+
13
+ def self.show_cmd_for(resource_name, image_tag: false)
14
+ unless image_tag
15
+ define_method(resource_name) do |name = :not_specified|
16
+ show_resource { Matsuri::Registry.fetch_or_load(resource_name, name).new }
17
+ end
18
+ else
19
+ define_method(resource_name) do |name = :not_specified, image_tag = nil|
20
+ show_resource { Matsuri::Registry.fetch_or_load(resource_name, name).new(image_tag: image_tag_for(image_tag)) }
21
+ end
22
+ end
23
+ end
24
+
25
+ desc 'config', 'displays config'
26
+ def config
27
+ with_config do |opt|
28
+ puts opt.inspect if opt[:debug]
29
+ conf = Matsuri::Config.save(true)
30
+ platform = Matsuri::Platform.save(true)
31
+ if options[:json]
32
+ puts JSON.pretty_generate(conf), JSON.pretty_generate(platform)
33
+ else
34
+ puts conf.deep_stringify_keys.to_yaml, platform.deep_stringify_keys.to_yaml
35
+ end
36
+ end
37
+ end
38
+
39
+ desc 'stack STACK_NAME', 'show manifests for all stack members'
40
+ option :stack_config, type: :string, banner: 'PATH'
41
+ def stack(name = :not_specified)
42
+ with_config do |opt|
43
+ Matsuri::Registry.stack(name).new(config: stack_config_data(opt)).show!(opt)
44
+ end
45
+ end
46
+
47
+ desc 'imported_manifest NAME', 'show imported manifest'
48
+ show_cmd_for :imported_manifest
49
+
50
+ desc 'pod POD_NAME', 'show manifest for pod'
51
+ show_cmd_for :pod, image_tag: true
52
+
53
+ desc 'replica_set REPLICA_SET_NAME', 'show manifest for replica_set'
54
+ show_cmd_for :replica_set, image_tag: true
55
+ map replicaset: :replica_set
56
+ map rs: :replica_set
57
+
58
+ desc 'stateful_set STATEFUL_SET_NAME', 'show manifest for stateful_set'
59
+ show_cmd_for :stateful_set, image_tag: true
60
+ map sts: :stateful_set
61
+
62
+ desc 'daemon_set DAEMON_SET_NAME', 'show manifest for daemon_set'
63
+ show_cmd_for :daemon_set, image_tag: true
64
+ map ds: :daemon_set
65
+
66
+ desc 'deployment DEPLOYMENT_NAME', 'show manifest for deployment'
67
+ show_cmd_for :deployment, image_tag: true
68
+ map deploy: :deployment
69
+
70
+ desc 'cron-job CRONJOB_NAME', 'apply changes to a cronjob'
71
+ show_cmd_for :cron_job, image_tag: true
72
+ map cj: :cron_job
73
+ map cronjob: :cron_job
74
+
75
+ desc 'service SERVICE_NAME', 'show manifest for service'
76
+ show_cmd_for :service
77
+
78
+ desc 'ingress INGRESS_NAME', 'show manifest for ingress'
79
+ show_cmd_for :ingress
80
+
81
+ desc 'endpoints ENDPOINT_NAME', 'show manifest for endpoints'
82
+ show_cmd_for :endpoints
83
+
84
+ desc 'secret SECRET_NAME', 'show a secret'
85
+ show_cmd_for :secret
86
+
87
+ desc 'config-map CONFIG_MAP_NAME', 'show a config map'
88
+ map configmap: :config_map
89
+ show_cmd_for :config_map
90
+
91
+ desc 'horizontal_pod_autoscaler HPA_NAME', 'show a horizontal pod autoscaler'
92
+ show_cmd_for :horizontal_pod_autoscaler
93
+ map hpa: :horizontal_pod_autoscaler
94
+
95
+ desc 'pv PV_NAME', 'show manifest for persistent volume'
96
+ show_cmd_for :pv
97
+
98
+ desc 'pvc PVC_NAME', 'show manifest for persistent volume claim'
99
+ show_cmd_for :pvc
100
+
101
+ desc 'storage_class STORAGE_CLASS_NAME', 'show manifest for storage class'
102
+ show_cmd_for :storage_class
103
+
104
+ desc 'cluster', 'show manifest set for cluster-wide manifests (RBAC, ResourceQuota, NetworkPolicy, etc.)'
105
+ def cluster
106
+ with_config { |opt| Matsuri::Tasks::Cluster.new.show!(opt) }
107
+ end
108
+
109
+ private
110
+
111
+ def show_resource
112
+ with_config do |opt|
113
+ resource = yield opt
114
+ if options[:json]
115
+ puts resource.pretty_print
116
+ else
117
+ puts resource.to_yaml
118
+ end
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end