dapp 0.10.2 → 0.36.24

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 (287) hide show
  1. checksums.yaml +5 -5
  2. data/bin/dapp +77 -15
  3. data/config/en/common.yml +20 -11
  4. data/config/en/net_status.yml +108 -27
  5. data/lib/dapp/cli/cli.rb +1 -0
  6. data/lib/dapp/cli/command/base.rb +111 -0
  7. data/lib/dapp/cli/command/sample/base.rb +28 -0
  8. data/lib/dapp/cli/command/sample/create.rb +24 -0
  9. data/lib/dapp/cli/command/sample/list.rb +25 -0
  10. data/lib/dapp/cli/command/sample.rb +20 -0
  11. data/lib/dapp/cli/command/slug.rb +26 -0
  12. data/lib/dapp/cli/command/update.rb +65 -0
  13. data/lib/dapp/cli/options/ssh.rb +18 -0
  14. data/lib/dapp/cli/options/tag.rb +51 -0
  15. data/lib/dapp/cli.rb +11 -3
  16. data/lib/dapp/config/config.rb +21 -0
  17. data/lib/dapp/config/directive/base.rb +100 -3
  18. data/lib/dapp/core_ext/hash.rb +14 -0
  19. data/lib/dapp/core_ext/pathname.rb +6 -4
  20. data/lib/dapp/dapp/chef.rb +1 -9
  21. data/lib/dapp/dapp/command/common.rb +24 -0
  22. data/lib/dapp/dapp/command/sample/common.rb +54 -0
  23. data/lib/dapp/dapp/command/sample/create.rb +57 -0
  24. data/lib/dapp/dapp/command/sample/list.rb +13 -0
  25. data/lib/dapp/dapp/command/slug.rb +11 -0
  26. data/lib/dapp/dapp/dapp_config.rb +85 -0
  27. data/lib/dapp/dapp/dappfile.rb +108 -27
  28. data/lib/dapp/dapp/deps/base.rb +9 -32
  29. data/lib/dapp/dapp/deps/common.rb +26 -0
  30. data/lib/dapp/dapp/deps/gitartifact.rb +2 -20
  31. data/lib/dapp/dapp/deps/toolchain.rb +11 -0
  32. data/lib/dapp/dapp/git_artifact.rb +6 -4
  33. data/lib/dapp/dapp/lock.rb +6 -5
  34. data/lib/dapp/dapp/logging/base.rb +32 -20
  35. data/lib/dapp/dapp/logging/i18n.rb +5 -1
  36. data/lib/dapp/dapp/logging/process.rb +6 -6
  37. data/lib/dapp/dapp/option_tags.rb +98 -0
  38. data/lib/dapp/dapp/ruby2go.rb +130 -0
  39. data/lib/dapp/dapp/sentry.rb +97 -0
  40. data/lib/dapp/dapp/shellout/base.rb +26 -18
  41. data/lib/dapp/dapp/shellout/streaming.rb +2 -2
  42. data/lib/dapp/dapp/slug.rb +12 -0
  43. data/lib/dapp/dapp/ssh_agent.rb +25 -7
  44. data/lib/dapp/dapp.rb +192 -41
  45. data/lib/dapp/deployment.rb +1 -0
  46. data/lib/dapp/dimg/artifact.rb +12 -4
  47. data/lib/dapp/dimg/build/stage/artifact_base.rb +26 -30
  48. data/lib/dapp/dimg/build/stage/artifact_default.rb +50 -28
  49. data/lib/dapp/dimg/build/stage/base.rb +187 -52
  50. data/lib/dapp/dimg/build/stage/before_install.rb +4 -15
  51. data/lib/dapp/dimg/build/stage/before_install_artifact.rb +4 -0
  52. data/lib/dapp/dimg/build/stage/before_setup.rb +1 -20
  53. data/lib/dapp/dimg/build/stage/build_artifact.rb +1 -20
  54. data/lib/dapp/dimg/build/stage/docker_instructions.rb +5 -4
  55. data/lib/dapp/dimg/build/stage/from.rb +62 -9
  56. data/lib/dapp/dimg/build/stage/ga_archive.rb +14 -1
  57. data/lib/dapp/dimg/build/stage/ga_artifact_patch.rb +1 -5
  58. data/lib/dapp/dimg/build/stage/ga_base.rb +5 -35
  59. data/lib/dapp/dimg/build/stage/ga_latest_patch.rb +15 -34
  60. data/lib/dapp/dimg/build/stage/ga_related_base.rb +21 -0
  61. data/lib/dapp/dimg/build/stage/import_artifact.rb +22 -11
  62. data/lib/dapp/dimg/build/stage/install/ga_post_install_patch.rb +6 -2
  63. data/lib/dapp/dimg/build/stage/install/ga_pre_install_patch.rb +6 -2
  64. data/lib/dapp/dimg/build/stage/install/install.rb +1 -19
  65. data/lib/dapp/dimg/build/stage/instructions.rb +27 -0
  66. data/lib/dapp/dimg/build/stage/mod/group.rb +19 -7
  67. data/lib/dapp/dimg/build/stage/mod/logging.rb +15 -19
  68. data/lib/dapp/dimg/build/stage/setup/ga_post_setup_patch.rb +24 -1
  69. data/lib/dapp/dimg/build/stage/setup/ga_pre_setup_patch.rb +6 -2
  70. data/lib/dapp/dimg/build/stage/setup/setup.rb +1 -19
  71. data/lib/dapp/dimg/builder/ansible.rb +5 -0
  72. data/lib/dapp/dimg/builder/chef/cookbook.rb +8 -8
  73. data/lib/dapp/dimg/builder/chef.rb +29 -16
  74. data/lib/dapp/dimg/builder/none.rb +1 -34
  75. data/lib/dapp/dimg/builder/ruby2go.rb +57 -0
  76. data/lib/dapp/dimg/builder/shell.rb +1 -20
  77. data/lib/dapp/dimg/cli/cli.rb +2 -1
  78. data/lib/dapp/dimg/cli/command/base.rb +24 -0
  79. data/lib/dapp/dimg/cli/command/dimg/bp.rb +60 -0
  80. data/lib/dapp/dimg/cli/command/dimg/build.rb +43 -0
  81. data/lib/dapp/dimg/cli/{build_context → command/dimg/build_context}/export.rb +9 -4
  82. data/lib/dapp/dimg/cli/{build_context → command/dimg/build_context}/import.rb +4 -4
  83. data/lib/dapp/dimg/cli/{build_context.rb → command/dimg/build_context.rb} +5 -5
  84. data/lib/dapp/dimg/cli/{cleanup.rb → command/dimg/cleanup.rb} +4 -6
  85. data/lib/dapp/dimg/cli/command/dimg/cleanup_repo.rb +47 -0
  86. data/lib/dapp/dimg/cli/command/dimg/flush_local.rb +24 -0
  87. data/lib/dapp/dimg/cli/command/dimg/flush_repo.rb +36 -0
  88. data/lib/dapp/dimg/cli/{list.rb → command/dimg/list.rb} +6 -3
  89. data/lib/dapp/dimg/cli/{mrproper.rb → command/dimg/mrproper.rb} +4 -4
  90. data/lib/dapp/dimg/cli/command/dimg/push.rb +39 -0
  91. data/lib/dapp/dimg/cli/{run.rb → command/dimg/run.rb} +30 -15
  92. data/lib/dapp/dimg/cli/{spush.rb → command/dimg/spush.rb} +4 -4
  93. data/lib/dapp/dimg/cli/{stage_image.rb → command/dimg/stage_image.rb} +12 -3
  94. data/lib/dapp/dimg/cli/command/dimg/stages/base.rb +13 -0
  95. data/lib/dapp/dimg/cli/{stages → command/dimg/stages}/cleanup_local.rb +13 -9
  96. data/lib/dapp/dimg/cli/{stages → command/dimg/stages}/cleanup_repo.rb +6 -8
  97. data/lib/dapp/dimg/cli/command/dimg/stages/flush_local.rb +21 -0
  98. data/lib/dapp/dimg/cli/command/dimg/stages/flush_repo.rb +28 -0
  99. data/lib/dapp/dimg/cli/command/dimg/stages/pull.rb +34 -0
  100. data/lib/dapp/dimg/cli/command/dimg/stages/push.rb +30 -0
  101. data/lib/dapp/dimg/cli/command/dimg/stages.rb +22 -0
  102. data/lib/dapp/dimg/cli/command/dimg/tag.rb +24 -0
  103. data/lib/dapp/dimg/cli/command/dimg.rb +31 -0
  104. data/lib/dapp/dimg/cli/options/introspection.rb +45 -0
  105. data/lib/dapp/dimg/config/config.rb +24 -0
  106. data/lib/dapp/dimg/config/directive/artifact.rb +13 -15
  107. data/lib/dapp/dimg/config/directive/artifact_base.rb +13 -8
  108. data/lib/dapp/dimg/config/directive/artifact_dimg.rb +12 -0
  109. data/lib/dapp/dimg/config/directive/artifact_group.rb +60 -0
  110. data/lib/dapp/dimg/config/directive/dimg/instance_methods.rb +203 -0
  111. data/lib/dapp/dimg/config/directive/dimg/validation.rb +217 -0
  112. data/lib/dapp/dimg/config/directive/dimg.rb +36 -0
  113. data/lib/dapp/dimg/config/directive/dimg_group.rb +73 -0
  114. data/lib/dapp/dimg/config/directive/dimg_group_base.rb +46 -0
  115. data/lib/dapp/dimg/config/directive/docker/artifact.rb +5 -0
  116. data/lib/dapp/dimg/config/directive/docker/base.rb +2 -3
  117. data/lib/dapp/dimg/config/directive/docker/dimg.rb +4 -4
  118. data/lib/dapp/dimg/config/directive/git_artifact_local.rb +24 -5
  119. data/lib/dapp/dimg/config/directive/git_artifact_remote.rb +23 -12
  120. data/lib/dapp/dimg/config/directive/mount.rb +11 -3
  121. data/lib/dapp/dimg/config/directive/shell/dimg.rb +2 -2
  122. data/lib/dapp/dimg/dapp/command/bp.rb +3 -5
  123. data/lib/dapp/dimg/dapp/command/build.rb +4 -6
  124. data/lib/dapp/dimg/dapp/command/build_context/common.rb +2 -2
  125. data/lib/dapp/dimg/dapp/command/build_context/export.rb +14 -14
  126. data/lib/dapp/dimg/dapp/command/build_context/import.rb +28 -23
  127. data/lib/dapp/dimg/dapp/command/cleanup.rb +4 -11
  128. data/lib/dapp/dimg/dapp/command/cleanup_repo.rb +143 -0
  129. data/lib/dapp/dimg/dapp/command/common.rb +148 -38
  130. data/lib/dapp/dimg/dapp/command/flush_local.rb +25 -0
  131. data/lib/dapp/dimg/dapp/command/flush_repo.rb +25 -0
  132. data/lib/dapp/dimg/dapp/command/list.rb +1 -1
  133. data/lib/dapp/dimg/dapp/command/mrproper.rb +16 -63
  134. data/lib/dapp/dimg/dapp/command/push.rb +11 -16
  135. data/lib/dapp/dimg/dapp/command/ruby2go_cleanup.rb +48 -0
  136. data/lib/dapp/dimg/dapp/command/run.rb +4 -4
  137. data/lib/dapp/dimg/dapp/command/spush.rb +4 -5
  138. data/lib/dapp/dimg/dapp/command/stage_image.rb +2 -2
  139. data/lib/dapp/dimg/dapp/command/stages/cleanup_local.rb +13 -115
  140. data/lib/dapp/dimg/dapp/command/stages/cleanup_repo.rb +23 -102
  141. data/lib/dapp/dimg/dapp/command/stages/common.rb +57 -39
  142. data/lib/dapp/dimg/dapp/command/stages/flush_local.rb +13 -7
  143. data/lib/dapp/dimg/dapp/command/stages/flush_repo.rb +14 -8
  144. data/lib/dapp/dimg/dapp/command/stages/pull.rb +4 -13
  145. data/lib/dapp/dimg/dapp/command/stages/push.rb +4 -9
  146. data/lib/dapp/dimg/dapp/command/tag.rb +4 -6
  147. data/lib/dapp/dimg/dapp/config_artifact_group.rb +20 -0
  148. data/lib/dapp/dimg/dapp/dapp.rb +40 -0
  149. data/lib/dapp/dimg/dapp/dappfile.rb +43 -0
  150. data/lib/dapp/dimg/dapp/dimg.rb +41 -0
  151. data/lib/dapp/dimg/dimg/git_artifact.rb +25 -11
  152. data/lib/dapp/dimg/dimg/path.rb +7 -9
  153. data/lib/dapp/dimg/dimg/stages.rb +27 -15
  154. data/lib/dapp/dimg/dimg.rb +172 -69
  155. data/lib/dapp/dimg/docker_registry/base.rb +31 -74
  156. data/lib/dapp/dimg/docker_registry/dimg.rb +55 -0
  157. data/lib/dapp/dimg/docker_registry.rb +5 -23
  158. data/lib/dapp/dimg/error/build.rb +1 -1
  159. data/lib/dapp/dimg/error/chef.rb +1 -5
  160. data/lib/dapp/dimg/error/{command.rb → default.rb} +1 -1
  161. data/lib/dapp/dimg/error/dimg.rb +1 -1
  162. data/lib/dapp/dimg/error/lock.rb +1 -1
  163. data/lib/dapp/dimg/error/registry.rb +1 -1
  164. data/lib/dapp/dimg/error/rugged.rb +1 -1
  165. data/lib/dapp/dimg/error/tar_writer.rb +1 -1
  166. data/lib/dapp/dimg/git_artifact.rb +195 -179
  167. data/lib/dapp/dimg/git_repo/base.rb +49 -45
  168. data/lib/dapp/dimg/git_repo/local.rb +45 -0
  169. data/lib/dapp/dimg/git_repo/own.rb +3 -31
  170. data/lib/dapp/dimg/git_repo/remote.rb +65 -26
  171. data/lib/dapp/dimg/image/argument.rb +15 -50
  172. data/lib/dapp/dimg/image/dimg.rb +15 -0
  173. data/lib/dapp/dimg/image/scratch.rb +35 -9
  174. data/lib/dapp/dimg/image/stage.rb +223 -44
  175. data/lib/dapp/dimg/lock/file.rb +4 -4
  176. data/lib/dapp/downloader.rb +117 -0
  177. data/lib/dapp/error/base.rb +1 -5
  178. data/lib/dapp/error/command.rb +5 -0
  179. data/lib/dapp/error/config.rb +5 -0
  180. data/lib/dapp/error/dapp.rb +1 -1
  181. data/lib/dapp/error/dappfile.rb +1 -1
  182. data/lib/dapp/error/default.rb +11 -0
  183. data/lib/dapp/error/mod/user.rb +11 -0
  184. data/lib/dapp/error/shellout.rb +1 -1
  185. data/lib/dapp/exception/base.rb +1 -1
  186. data/lib/dapp/helper/case_conversion.rb +17 -0
  187. data/lib/dapp/helper/cli.rb +18 -7
  188. data/lib/dapp/helper/net_status.rb +5 -1
  189. data/lib/dapp/helper/sha256.rb +1 -1
  190. data/lib/dapp/helper/tar.rb +31 -0
  191. data/lib/dapp/helper/trivia.rb +40 -1
  192. data/lib/dapp/helper/url.rb +23 -0
  193. data/lib/dapp/helper/yaml.rb +24 -0
  194. data/lib/dapp/kube/cli/cli.rb +1 -0
  195. data/lib/dapp/kube/cli/command/base.rb +14 -0
  196. data/lib/dapp/kube/cli/command/kube/chart_create.rb +19 -0
  197. data/lib/dapp/kube/cli/command/kube/deploy.rb +80 -0
  198. data/lib/dapp/kube/cli/command/kube/dismiss.rb +31 -0
  199. data/lib/dapp/kube/cli/command/kube/lint.rb +53 -0
  200. data/lib/dapp/kube/cli/command/kube/minikube_setup.rb +19 -0
  201. data/lib/dapp/kube/cli/command/kube/render.rb +63 -0
  202. data/lib/dapp/kube/cli/command/kube/secret_edit.rb +30 -0
  203. data/lib/dapp/kube/cli/command/kube/secret_extract.rb +39 -0
  204. data/lib/dapp/kube/cli/command/kube/secret_generate.rb +34 -0
  205. data/lib/dapp/kube/cli/command/kube/secret_key_generate.rb +16 -0
  206. data/lib/dapp/kube/cli/command/kube/secret_regenerate.rb +29 -0
  207. data/lib/dapp/kube/cli/command/kube/value_get.rb +47 -0
  208. data/lib/dapp/kube/cli/command/kube.rb +28 -0
  209. data/lib/dapp/kube/dapp/command/chart_create.rb +103 -0
  210. data/lib/dapp/kube/dapp/command/common.rb +379 -0
  211. data/lib/dapp/kube/dapp/command/deploy.rb +351 -0
  212. data/lib/dapp/kube/dapp/command/dismiss.rb +50 -0
  213. data/lib/dapp/kube/dapp/command/lint.rb +69 -0
  214. data/lib/dapp/kube/dapp/command/minikube_setup.rb +402 -0
  215. data/lib/dapp/kube/dapp/command/render.rb +54 -0
  216. data/lib/dapp/kube/dapp/command/ruby2go.rb +17 -0
  217. data/lib/dapp/kube/dapp/command/secret_edit.rb +21 -0
  218. data/lib/dapp/kube/dapp/command/secret_extract.rb +17 -0
  219. data/lib/dapp/kube/dapp/command/secret_generate.rb +21 -0
  220. data/lib/dapp/kube/dapp/command/secret_key_generate.rb +13 -0
  221. data/lib/dapp/kube/dapp/command/secret_regenerate.rb +13 -0
  222. data/lib/dapp/kube/dapp/command/value_get.rb +32 -0
  223. data/lib/dapp/kube/dapp/dapp.rb +26 -0
  224. data/lib/dapp/kube/error/default.rb +7 -0
  225. data/lib/dapp/kube/helm/release.rb +189 -0
  226. data/lib/dapp/kube/helm/values.rb +148 -0
  227. data/lib/dapp/kube/helm.rb +5 -0
  228. data/lib/dapp/kube/kubernetes/client/error.rb +43 -0
  229. data/lib/dapp/kube/kubernetes/client/resource/base.rb +33 -0
  230. data/lib/dapp/kube/kubernetes/client/resource/deployment.rb +11 -0
  231. data/lib/dapp/kube/kubernetes/client/resource/event.rb +8 -0
  232. data/lib/dapp/kube/kubernetes/client/resource/job.rb +27 -0
  233. data/lib/dapp/kube/kubernetes/client/resource/pod.rb +62 -0
  234. data/lib/dapp/kube/kubernetes/client/resource/replicaset.rb +8 -0
  235. data/lib/dapp/kube/kubernetes/client.rb +314 -0
  236. data/lib/dapp/kube/kubernetes/config.rb +132 -0
  237. data/lib/dapp/kube/kubernetes/error.rb +15 -0
  238. data/lib/dapp/kube/kubernetes/manager/base.rb +15 -0
  239. data/lib/dapp/kube/kubernetes/manager/container.rb +103 -0
  240. data/lib/dapp/kube/kubernetes/manager/deployment.rb +212 -0
  241. data/lib/dapp/kube/kubernetes/manager/job.rb +65 -0
  242. data/lib/dapp/kube/kubernetes/manager/pod.rb +69 -0
  243. data/lib/dapp/kube/kubernetes.rb +6 -0
  244. data/lib/dapp/kube/secret.rb +93 -0
  245. data/lib/dapp/kube.rb +1 -0
  246. data/lib/dapp/version.rb +2 -2
  247. data/lib/dapp.rb +155 -61
  248. metadata +208 -61
  249. data/lib/dapp/cli/base.rb +0 -63
  250. data/lib/dapp/config/base.rb +0 -54
  251. data/lib/dapp/config/error/config.rb +0 -7
  252. data/lib/dapp/dimg/build/stage/ga_archive_dependencies.rb +0 -27
  253. data/lib/dapp/dimg/build/stage/ga_dependencies_base.rb +0 -20
  254. data/lib/dapp/dimg/build/stage/install/ga_post_install_patch_dependencies.rb +0 -22
  255. data/lib/dapp/dimg/build/stage/install/ga_pre_install_patch_dependencies.rb +0 -22
  256. data/lib/dapp/dimg/build/stage/mod/git_artifact_dependencies.rb +0 -23
  257. data/lib/dapp/dimg/build/stage/setup/ga_post_setup_patch_dependencies.rb +0 -32
  258. data/lib/dapp/dimg/build/stage/setup/ga_pre_setup_patch_dependencies.rb +0 -22
  259. data/lib/dapp/dimg/cli/base.rb +0 -16
  260. data/lib/dapp/dimg/cli/bp.rb +0 -37
  261. data/lib/dapp/dimg/cli/build.rb +0 -64
  262. data/lib/dapp/dimg/cli/dimg.rb +0 -30
  263. data/lib/dapp/dimg/cli/push.rb +0 -61
  264. data/lib/dapp/dimg/cli/stages/flush_local.rb +0 -23
  265. data/lib/dapp/dimg/cli/stages/flush_repo.rb +0 -24
  266. data/lib/dapp/dimg/cli/stages/pull.rb +0 -28
  267. data/lib/dapp/dimg/cli/stages/push.rb +0 -24
  268. data/lib/dapp/dimg/cli/stages.rb +0 -22
  269. data/lib/dapp/dimg/cli/tag.rb +0 -24
  270. data/lib/dapp/dimg/config/artifact_dimg.rb +0 -17
  271. data/lib/dapp/dimg/config/artifact_group.rb +0 -43
  272. data/lib/dapp/dimg/config/base.rb +0 -7
  273. data/lib/dapp/dimg/config/dimg/instance_methods.rb +0 -179
  274. data/lib/dapp/dimg/config/dimg/validation.rb +0 -126
  275. data/lib/dapp/dimg/config/dimg.rb +0 -24
  276. data/lib/dapp/dimg/config/dimg_group.rb +0 -61
  277. data/lib/dapp/dimg/config/dimg_group_base.rb +0 -54
  278. data/lib/dapp/dimg/config/dimg_group_main.rb +0 -22
  279. data/lib/dapp/dimg/dapp/command.rb +0 -21
  280. data/lib/dapp/dimg/dimg/tags.rb +0 -65
  281. data/lib/dapp/dimg/docker_registry/base/authorization.rb +0 -63
  282. data/lib/dapp/dimg/docker_registry/base/request.rb +0 -34
  283. data/lib/dapp/dimg/docker_registry/default.rb +0 -18
  284. data/lib/dapp/dimg/error/base.rb +0 -7
  285. data/lib/dapp/dimg/error/config.rb +0 -7
  286. data/lib/dapp/dimg/exception/introspect_image.rb +0 -7
  287. data/lib/dapp/dimg/image/docker.rb +0 -134
@@ -0,0 +1,314 @@
1
+ module Dapp
2
+ module Kube
3
+ module Kubernetes
4
+ # TODO endpoints can be gathered from api-server by api discovery.
5
+ K8S_API_ENDPOINTS = {
6
+ '1.6' => {
7
+ '/api/v1' => [:service, :replicationcontroller, :pod, :podtemplate, ],
8
+ '/apis/apps/v1beta1' => [:deployment, :statefulset, ],
9
+ '/apis/extensions/v1beta1' => [:replicaset, :daemonset, ],
10
+ '/apis/batch/v1' => [:job, ],
11
+ '/apis/batch/v2aplha1' => [:cronjob, ],
12
+ },
13
+ '1.7' => {
14
+ '/api/v1' => [:service, :replicationcontroller, :pod, :podtemplate, ],
15
+ '/apis/apps/v1beta1' => [:deployment, :statefulset, ],
16
+ '/apis/extensions/v1beta1' => [:replicaset, :daemonset, ],
17
+ '/apis/batch/v1' => [:job, ],
18
+ '/apis/batch/v2aplha1' => [:cronjob, ],
19
+ },
20
+ '1.8' => {
21
+ '/api/v1' => [:service, :replicationcontroller, :pod, :podtemplate, ],
22
+ '/apis/apps/v1beta2' => [:daemonset, :deployment, :replicaset, :statefulset, ],
23
+ '/apis/batch/v1' => [:job, ],
24
+ '/apis/batch/v1beta1' => [:cronjob, ],
25
+ },
26
+ '1.9' => {
27
+ '/api/v1' => [:service, :replicationcontroller, :pod, :podtemplate, ],
28
+ '/apis/apps/v1' => [:daemonset, :deployment, :replicaset, :statefulset, ],
29
+ '/apis/batch/v1' => [:job, ],
30
+ '/apis/batch/v1beta1' => [:cronjob, ],
31
+ },
32
+ '1.10' => {
33
+ '/api/v1' => [:service, :replicationcontroller, :pod, :podtemplate, ],
34
+ '/apis/apps/v1' => [:daemonset, :deployment, :replicaset, :statefulset, ],
35
+ '/apis/batch/v1' => [:job, ],
36
+ '/apis/batch/v1beta1' => [:cronjob, ],
37
+ },
38
+ '1.11' => {
39
+ '/api/v1' => [:service, :replicationcontroller, :pod, :podtemplate, ],
40
+ '/apis/apps/v1' => [:daemonset, :deployment, :replicaset, :statefulset, ],
41
+ '/apis/batch/v1' => [:job, ],
42
+ '/apis/batch/v1beta1' => [:cronjob, ],
43
+ },
44
+ 'stable' => {
45
+ '/api/v1' => [:service, :replicationcontroller, :pod, :podtemplate, ],
46
+ '/apis/batch/v1' => [:job, ],
47
+ },
48
+ }
49
+
50
+ class Client
51
+ include Helper::YAML
52
+ extend Helper::YAML
53
+
54
+ ::Dapp::Dapp::Shellout::Base.default_env_keys << 'KUBECONFIG'
55
+
56
+ attr_reader :config
57
+ attr_reader :context
58
+ attr_reader :namespace
59
+ attr_reader :timeout
60
+
61
+ def initialize(config, context, namespace, timeout: nil)
62
+ @config = config
63
+ @context = context
64
+ @namespace = namespace
65
+ @timeout = timeout
66
+ @query_parameters = {}
67
+ @cluster_version
68
+ end
69
+
70
+ # Чтобы не перегружать методы явной передачей namespace.
71
+ # Данный метод может пригодиться только в ситуации, когда надо указать другой namespace,
72
+ # в большинстве случаев используется namespace из конструктора.
73
+ def with_namespace(namespace, &blk)
74
+ old_namespace = @namespace
75
+ begin
76
+ @namespace = namespace
77
+ return yield
78
+ ensure
79
+ @namespace = old_namespace
80
+ end
81
+ end
82
+
83
+ def with_query(query, &blk)
84
+ old_query = @query_parameters
85
+ begin
86
+ @query_parameters = query
87
+ return yield
88
+ ensure
89
+ @query_parameters = old_query
90
+ end
91
+ end
92
+
93
+ # NOTICE: Название метода аналогично kind'у выдаваемого результата.
94
+ # NOTICE: В данном случае в результате kind=DeploymentList.
95
+ # NOTICE: Методы создания/обновления/удаления сущностей kubernetes заканчиваются на '!'. Например, create_deployment!.
96
+ # В каждом методе происходит выбор api на основе версии кластера
97
+
98
+ def resource_endpoint_path(resource)
99
+ K8S_API_ENDPOINTS[cluster_version()].map do |path, resources|
100
+ resources.include?(resource) ? path : nil
101
+ end.compact.first
102
+ end
103
+
104
+ [
105
+ :service, :replicationcontroller, :pod, :podtemplate,
106
+ :daemonset, :deployment, :replicaset, :statefulset,
107
+ :job,
108
+ :cronjob,
109
+ ].each do |resource|
110
+ define_method :"#{resource}_list" do |**query_parameters|
111
+ api_path = resource_endpoint_path(resource)
112
+ request!(:get, "#{api_path}/namespaces/#{namespace}/#{resource}s", **query_parameters)
113
+ end
114
+
115
+ define_method resource do |name, **query_parameters|
116
+ api_path = resource_endpoint_path(resource)
117
+ request!(:get, "#{api_path}/namespaces/#{namespace}/#{resource}s/#{name}", **query_parameters)
118
+ end
119
+
120
+ define_method "#{resource}_status" do |name, **query_parameters|
121
+ api_path = resource_endpoint_path(resource)
122
+ request!(:get, "#{api_path}/namespaces/#{namespace}/#{resource}s/#{name}/status", **query_parameters)
123
+ end
124
+
125
+ define_method :"create_#{resource}!" do |spec, **query_parameters|
126
+ api_path = resource_endpoint_path(resource)
127
+ request!(:post, "#{api_path}/namespaces/#{namespace}/#{resource}s", body: spec, **query_parameters)
128
+ end
129
+
130
+ define_method :"replace_#{resource}!" do |name, spec, **query_parameters|
131
+ api_path = resource_endpoint_path(resource)
132
+ request!(:put, "#{api_path}/namespaces/#{namespace}/#{resource}s/#{name}", body: spec, **query_parameters)
133
+ end
134
+
135
+ define_method :"delete_#{resource}!" do |name, **query_parameters|
136
+ api_path = resource_endpoint_path(resource)
137
+ request!(:delete, "#{api_path}/namespaces/#{namespace}/#{resource}s/#{name}", **query_parameters)
138
+ end
139
+
140
+ define_method :"delete_#{resource}s!" do |**query_parameters|
141
+ api_path = resource_endpoint_path(resource)
142
+ request!(:delete, "#{api_path}/namespaces/#{namespace}/#{resource}s", **query_parameters)
143
+ end
144
+
145
+ define_method :"#{resource}?" do |name, **query_parameters|
146
+ public_send(:"#{resource}_list", **query_parameters)['items'].map { |item| item['metadata']['name'] }.include?(name)
147
+ end
148
+ end
149
+
150
+
151
+ def namespace_list(**query_parameters)
152
+ request!(:get, '/api/v1/namespaces', **query_parameters)
153
+ end
154
+
155
+ def namespace?(name, **query_parameters)
156
+ namespace_list(**query_parameters)['items'].map { |item| item['metadata']['name'] }.include?(name)
157
+ end
158
+
159
+ def create_namespace!(name, **query_parameters)
160
+ request!(:post, '/api/v1/namespaces', body: { metadata: { name: name } }, **query_parameters)
161
+ end
162
+
163
+ def delete_namespace!(name, **query_parameters)
164
+ request!(:delete, "/api/v1/namespaces/#{name}", **query_parameters)
165
+ end
166
+
167
+ # minikube returns empty major and minor. Fallback to stable only apis for minikube setup
168
+ def cluster_version(**query_parameters)
169
+ version_obj = request!(:get, "/version", **query_parameters)
170
+ @cluster_version ||= begin
171
+ major = version_obj['major']
172
+ minor = version_obj['minor'].gsub(/\+$/,'')
173
+ k8s_version = "#{major}.#{minor}"
174
+ if K8S_API_ENDPOINTS.has_key?(k8s_version)
175
+ k8s_version
176
+ else
177
+ "stable"
178
+ end
179
+ end
180
+ end
181
+
182
+ def pod_log(name, follow: false, **query_parameters, &blk)
183
+ excon_parameters = follow ? { response_block: blk } : {}
184
+ request!(:get,
185
+ "/api/v1/namespaces/#{namespace}/pods/#{name}/log",
186
+ excon_parameters: excon_parameters,
187
+ response_body_parameters: {json: false},
188
+ **{ follow: follow }.merge(query_parameters))
189
+ rescue Excon::Error::Timeout
190
+ raise Error::Timeout
191
+ rescue Error::Base => err
192
+ if err.net_status[:code] == :bad_request and err.net_status[:data][:response_body]
193
+ msg = err.net_status[:data][:response_body]['message']
194
+ if msg.end_with? 'ContainerCreating'
195
+ raise Error::Pod::ContainerCreating, data: err.net_status[:data]
196
+ elsif msg.end_with? 'PodInitializing'
197
+ raise Error::Pod::PodInitializing, data: err.net_status[:data]
198
+ end
199
+ end
200
+
201
+ raise
202
+ end
203
+
204
+ def event_list(**query_parameters)
205
+ request!(:get, "/api/v1/namespaces/#{namespace}/events", **query_parameters)
206
+ end
207
+
208
+ protected
209
+
210
+ # query_parameters — соответствует 'Query Parameters' в документации kubernetes
211
+ # excon_parameters — соответствует connection-опциям Excon
212
+ # body — hash для http-body, соответствует 'Body Parameters' в документации kubernetes, опционален
213
+ def request!(method, path, body: nil, excon_parameters: {}, response_body_parameters: {}, **query_parameters)
214
+ if method == :get
215
+ excon_parameters[:idempotent] = true
216
+ excon_parameters[:retry_limit] = 6
217
+ excon_parameters[:retry_interval] = 5
218
+ end
219
+
220
+ excon_parameters[:connect_timeout] ||= timeout
221
+ excon_parameters[:read_timeout] ||= timeout
222
+ excon_parameters[:write_timeout] ||= timeout
223
+
224
+ with_connection(excon_parameters: excon_parameters) do |conn|
225
+ request_parameters = {method: method, path: path, query: @query_parameters.merge(query_parameters)}
226
+ request_parameters[:body] = JSON.dump(body) if body
227
+ load_body! conn.request(request_parameters), request_parameters, **response_body_parameters
228
+ end
229
+ end
230
+
231
+ def load_body!(response, request_parameters, json: true)
232
+ response_ok = response.status.to_s.start_with? '2'
233
+
234
+ if response_ok
235
+ if json
236
+ JSON.parse(response.body)
237
+ else
238
+ response.body
239
+ end
240
+ else
241
+ err_data = {}
242
+ err_data[:response_http_status] = response.status
243
+ err_data[:response_raw_body] = response.body
244
+ if response_body = (JSON.parse(response.body) rescue nil)
245
+ err_data[:response_body] = response_body
246
+ end
247
+ err_data[:request_parameters] = request_parameters
248
+
249
+ if response.status.to_s.start_with? '5'
250
+ raise Error::Default, code: :server_error, data: err_data
251
+ elsif response.status.to_s == '404'
252
+ case err_data.fetch(:response_body, {}).fetch('details', {})['kind']
253
+ when 'pods'
254
+ raise Error::Pod::NotFound, data: err_data
255
+ else
256
+ raise Error::NotFound, data: err_data
257
+ end
258
+ elsif not response.status.to_s.start_with? '2'
259
+ raise Error::Base, code: :bad_request, data: err_data
260
+ end
261
+ end
262
+ end
263
+
264
+ def with_connection(excon_parameters: {}, &blk)
265
+ connection = begin
266
+ context_config = config.context_config(context)
267
+ cluster_config = config.cluster_config(context_config['cluster'])
268
+ Excon.new(cluster_config['server'], **kube_server_options(excon_parameters)).tap(&:get)
269
+ rescue Excon::Error::Socket => err
270
+ raise Error::ConnectionRefused,
271
+ code: :server_connection_refused,
272
+ data: { url: cluster_config['server'], error: err.message }
273
+ end
274
+
275
+ return yield connection
276
+ end
277
+
278
+ def kube_server_options(excon_parameters = {})
279
+ {}.tap do |opts|
280
+ context_config = config.context_config(context)
281
+ user_config = config.user_config(context_config['user'])
282
+ cluster_config = config.cluster_config(context_config['cluster'])
283
+
284
+ client_cert = user_config['client-certificate']
285
+ opts[:client_cert] = client_cert if client_cert
286
+
287
+ client_cert_data= user_config['client-certificate-data']
288
+ opts[:client_cert_data] = Base64.decode64(client_cert_data) if client_cert_data
289
+
290
+ client_key = user_config['client-key']
291
+ opts[:client_key] = client_key if client_key
292
+
293
+ client_key_data = user_config['client-key-data']
294
+ opts[:client_key_data] = Base64.decode64(client_key_data) if client_key_data
295
+
296
+ ssl_cert_store = OpenSSL::X509::Store.new
297
+ if ssl_ca_file = cluster_config['certificate-authority']
298
+ ssl_cert_store.add_file ssl_ca_file
299
+ elsif ssl_ca_data = cluster_config['certificate-authority-data']
300
+ ssl_cert_store.add_cert OpenSSL::X509::Certificate.new(Base64.decode64(ssl_ca_data))
301
+ end
302
+ opts[:ssl_cert_store] = ssl_cert_store
303
+
304
+ opts[:ssl_ca_file] = nil
305
+
306
+ opts[:middlewares] = [*Excon.defaults[:middlewares], Excon::Middleware::RedirectFollower]
307
+
308
+ opts.merge!(excon_parameters)
309
+ end
310
+ end
311
+ end # Client
312
+ end # Kubernetes
313
+ end # Kube
314
+ end # Dapp
@@ -0,0 +1,132 @@
1
+ module Dapp
2
+ module Kube
3
+ module Kubernetes
4
+ class Config
5
+ extend Helper::YAML
6
+ extend Dapp::Shellout::Base
7
+
8
+ class << self
9
+ def new_auto_if_available
10
+ if Kubernetes::Config.kubectl_available?
11
+ Kubernetes::Config.new_from_kubectl
12
+ elsif ENV['KUBECONFIG']
13
+ Kubernetes::Config.new_from_kubeconfig(ENV['KUBECONFIG'])
14
+ else
15
+ default_path = File.join(ENV['HOME'], '.kube/config')
16
+ if File.exists? default_path
17
+ Kubernetes::Config.new_from_kubeconfig(default_path)
18
+ end
19
+ end
20
+ end
21
+
22
+ def new_auto
23
+ new_auto_if_available.tap do |cfg|
24
+ raise(Kubernetes::Error::Default,
25
+ code: :config_not_found,
26
+ data: { },
27
+ ) if cfg.nil?
28
+ end
29
+ end
30
+
31
+ def new_from_kubeconfig(path)
32
+ unless File.exists?(path)
33
+ raise(Kubernetes::Error::Default,
34
+ code: :config_file_not_found,
35
+ data: { config_path: path }
36
+ )
37
+ end
38
+ self.new yaml_load_file(path), path
39
+ end
40
+
41
+ def kubectl_available?
42
+ shellout("kubectl").exitstatus.zero?
43
+ end
44
+
45
+ def new_from_kubectl
46
+ cmd_res = shellout(
47
+ "kubectl config view --raw",
48
+ env: {"KUBECONFIG" => ENV["KUBECONFIG"]}
49
+ )
50
+
51
+ shellout_cmd_should_succeed! cmd_res
52
+
53
+ self.new YAML.load(cmd_res.stdout), "kubectl config view --raw"
54
+ end
55
+ end # << self
56
+
57
+ attr_reader :config_hash, :config_path
58
+
59
+ def initialize(config_hash, config_path)
60
+ @config_hash = config_hash
61
+ @config_path = config_path
62
+ end
63
+
64
+ def context_names
65
+ config_hash.fetch('contexts', []).map {|context| context['name']}
66
+ end
67
+
68
+ def current_context_name
69
+ @current_context_name ||= begin
70
+ config_hash['current-context'] || begin
71
+ if (context = config_hash.fetch('contexts', []).first)
72
+ warn "[WARN] .kube/config current-context is not set, using first context '#{context['name']}'"
73
+ context['name']
74
+ end
75
+ end
76
+ end
77
+ end
78
+
79
+ def context_config(context_name)
80
+ res = config_hash.fetch('contexts', [])
81
+ .find {|context| context['name'] == context_name}
82
+
83
+ raise(Kubernetes::Error::Default,
84
+ code: :context_config_not_found,
85
+ data: {config_path: config_path,
86
+ config: config_hash,
87
+ context_name: context_name}
88
+ ) if res.nil?
89
+
90
+ res['context']
91
+ end
92
+
93
+ def user_config(user_name)
94
+ res = config_hash.fetch('users', [])
95
+ .find {|user| user['name'] == user_name}
96
+
97
+ raise(Kubernetes::Error::Default,
98
+ code: :user_config_not_found,
99
+ data: {config_path: config_path,
100
+ user: user_name}
101
+ ) if res.nil?
102
+
103
+ res['user']
104
+ end
105
+
106
+ def cluster_config(cluster_name)
107
+ res = config_hash.fetch('clusters', [])
108
+ .find {|cluster| cluster['name'] == cluster_name}
109
+
110
+ raise(Kubernetes::Error::Default,
111
+ code: :cluster_config_not_found,
112
+ data: {config_path: config_path,
113
+ cluster: cluster_name}
114
+ ) if res.nil?
115
+
116
+ res['cluster']
117
+ end
118
+
119
+ def cluster_name(context_name)
120
+ cfg = context_config(context_name)
121
+ cfg['cluster'] if cfg
122
+ end
123
+
124
+ def namespace(context_name)
125
+ cfg = context_config(context_name)
126
+ cfg['namespace'] if cfg
127
+ end
128
+
129
+ end # Kubeconfig
130
+ end # Kubernetes
131
+ end # Kube
132
+ end # Dapp
@@ -0,0 +1,15 @@
1
+ module Dapp
2
+ module Kube
3
+ module Kubernetes::Error
4
+ class Base < ::Dapp::Error::Base
5
+ def initialize(**net_status)
6
+ super(**net_status, context: :kubernetes)
7
+ end
8
+ end
9
+
10
+ class Default < Base
11
+ include ::Dapp::Error::Mod::User
12
+ end
13
+ end # Kubernetes::Error
14
+ end # Kube
15
+ end # Dapp
@@ -0,0 +1,15 @@
1
+ module Dapp
2
+ module Kube
3
+ module Kubernetes::Manager
4
+ class Base
5
+ attr_reader :dapp
6
+ attr_reader :name
7
+
8
+ def initialize(dapp, name)
9
+ @dapp = dapp
10
+ @name = name
11
+ end
12
+ end # Base
13
+ end # Kubernetes::Manager
14
+ end # Kube
15
+ end # Dapp
@@ -0,0 +1,103 @@
1
+ module Dapp
2
+ module Kube
3
+ module Kubernetes::Manager
4
+ class Container < Base
5
+ attr_reader :pod_manager
6
+
7
+ def initialize(dapp, name, pod_manager)
8
+ super(dapp, name)
9
+
10
+ @pod_manager = pod_manager
11
+ @processed_containers_ids = []
12
+ @processed_log_till_time = nil
13
+ @processed_log_timestamps = Set.new
14
+ end
15
+
16
+ def watch_till_terminated!
17
+ pod = Kubernetes::Client::Resource::Pod.new(dapp.kubernetes.pod(pod_manager.name))
18
+ _, container_state_data = pod.container_state(name)
19
+ return if @processed_containers_ids.include? container_state_data['containerID']
20
+
21
+ pod_manager.wait_till_launched!
22
+
23
+ pod = Kubernetes::Client::Resource::Pod.new(dapp.kubernetes.pod(pod_manager.name))
24
+ container_state, container_state_data = pod.container_state(name)
25
+
26
+ dapp.log_process("Watch pod's '#{pod_manager.name}' container '#{name}' log") do
27
+ loop do
28
+ pod = Kubernetes::Client::Resource::Pod.new(dapp.kubernetes.pod(pod_manager.name))
29
+ container_state, container_state_data = pod.container_state(name)
30
+
31
+ if container_state == "waiting"
32
+ if container_state_data["reason"] == "RunContainerError"
33
+ raise Kubernetes::Error::Default, code: :container_stuck, data: {
34
+ state_reason: container_state_data["reason"],
35
+ state_message: container_state_data["message"],
36
+ state: container_state,
37
+ pod_name: pod_manager.name,
38
+ container_name: name
39
+ }
40
+ else
41
+ sleep 0.1
42
+ next
43
+ end
44
+ end
45
+
46
+ chunk_lines_by_time = {}
47
+ begin
48
+ chunk_lines_by_time = dapp.kubernetes.pod_log(pod_manager.name, container: name, timestamps: true, sinceTime: @processed_log_till_time)
49
+ .lines
50
+ .map(&:strip)
51
+ .map do |line|
52
+ timestamp, _, data = line.partition(' ')
53
+ [timestamp, data]
54
+ end
55
+ .reject {|timestamp, _| @processed_log_timestamps.include? timestamp}
56
+ rescue Kubernetes::Client::Error::Pod::ContainerCreating, Kubernetes::Client::Error::Pod::PodInitializing
57
+ sleep 0.1
58
+ next
59
+ rescue Kubernetes::Client::Error::Base => err
60
+ dapp.log_warning("#{dapp.log_time}Error while fetching pod's #{pod_manager.name} logs: #{err.message}", stream: dapp.service_stream)
61
+ break
62
+ end
63
+
64
+ chunk_lines_by_time.each do |timestamp, data|
65
+ dapp.log("[#{timestamp}] #{data}")
66
+ @processed_log_timestamps.add timestamp
67
+ end
68
+
69
+ if container_state == 'terminated'
70
+ failed = (container_state_data['exitCode'].to_i != 0)
71
+
72
+ dapp.log_warning("".tap do |msg|
73
+ msg << "Pod's '#{pod_manager.name}' container '#{name}' has been terminated unsuccessfuly: "
74
+ msg << container_state_data.to_s
75
+ end) if failed
76
+
77
+ @processed_containers_ids << container_state_data['containerID']
78
+
79
+ break
80
+ end
81
+
82
+ @processed_log_till_time = chunk_lines_by_time.last.first if chunk_lines_by_time.any?
83
+
84
+ sleep 0.1 if chunk_lines_by_time.empty?
85
+ end
86
+ end # log_process
87
+ end
88
+
89
+ def done?
90
+ pod = Kubernetes::Client::Resource::Pod.new(dapp.kubernetes.pod(pod_manager.name))
91
+ container_state, container_state_data = pod.container_state(name)
92
+ if container_state == 'terminated'
93
+ failed = (container_state_data['exitCode'].to_i != 0)
94
+ return true if pod.restart_policy == 'Never'
95
+ return true if not failed and pod.restart_policy == 'OnFailure'
96
+ end
97
+
98
+ return false
99
+ end
100
+ end # Container
101
+ end # Kubernetes::Manager
102
+ end # Kube
103
+ end # Dapp