|
6 | 6 | * file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
7 | 7 | */
|
8 | 8 |
|
9 |
| -import * as execa from "execa" |
10 |
| -import { safeLoad } from "js-yaml" |
11 |
| -import * as Joi from "joi" |
12 |
| -import { join } from "path" |
13 |
| -import { GardenPlugin, PluginFactoryParams } from "../../../types/plugin/plugin" |
14 |
| -import { |
15 |
| - gardenPlugin as k8sPlugin, |
16 |
| - KubernetesBaseConfig, |
17 |
| - kubernetesConfigBase, |
18 |
| -} from "../kubernetes" |
19 |
| -import { readFile } from "fs-extra" |
20 |
| -import { homedir } from "os" |
| 9 | +import { GardenPlugin } from "../../../types/plugin/plugin" |
| 10 | +import { gardenPlugin as k8sPlugin } from "../kubernetes" |
21 | 11 | import { getLocalEnvironmentStatus, prepareLocalEnvironment } from "../init"
|
22 |
| -import { ConfigureProviderParams } from "../../../types/plugin/params" |
23 |
| - |
24 |
| -// TODO: split this into separate plugins to handle Docker for Mac and Minikube |
25 |
| - |
26 |
| -// note: this is in order of preference, in case neither is set as the current kubectl context |
27 |
| -// and none is explicitly configured in the garden.yml |
28 |
| -const supportedContexts = ["docker-for-desktop", "minikube"] |
29 |
| -const kubeConfigPath = join(homedir(), ".kube", "config") |
30 |
| - |
31 |
| -async function getKubeConfig(): Promise<any> { |
32 |
| - try { |
33 |
| - return safeLoad((await readFile(kubeConfigPath)).toString()) |
34 |
| - } catch { |
35 |
| - return {} |
36 |
| - } |
37 |
| -} |
38 |
| - |
39 |
| -/** |
40 |
| - * Automatically set docker environment variables for minikube |
41 |
| - * TODO: it would be better to explicitly provide those to docker instead of using process.env |
42 |
| - */ |
43 |
| -async function setMinikubeDockerEnv() { |
44 |
| - const minikubeEnv = await execa.stdout("minikube", ["docker-env", "--shell=bash"]) |
45 |
| - for (const line of minikubeEnv.split("\n")) { |
46 |
| - const matched = line.match(/^export (\w+)="(.+)"$/) |
47 |
| - if (matched) { |
48 |
| - process.env[matched[1]] = matched[2] |
49 |
| - } |
50 |
| - } |
51 |
| -} |
52 |
| - |
53 |
| -export interface LocalKubernetesConfig extends KubernetesBaseConfig { |
54 |
| - _system?: Symbol |
55 |
| - setupIngressController: string | boolean | null |
56 |
| -} |
57 |
| - |
58 |
| -export const configSchema = kubernetesConfigBase |
59 |
| - .keys({ |
60 |
| - namespace: Joi.string() |
61 |
| - .default(undefined, "<project name>") |
62 |
| - .description( |
63 |
| - "Specify which namespace to deploy services to (defaults to the project name). " + |
64 |
| - "Note that the framework generates other namespaces as well with this name as a prefix.", |
65 |
| - ), |
66 |
| - setupIngressController: Joi.string() |
67 |
| - .allow("nginx", false, null) |
68 |
| - .default("nginx") |
69 |
| - .description("Set this to null or false to skip installing/enabling the `nginx` ingress controller."), |
70 |
| - _system: Joi.any().meta({ internal: true }), |
71 |
| - }) |
72 |
| - .description("The provider configuration for the local-kubernetes plugin.") |
| 12 | +import { configureProvider, configSchema } from "./config" |
73 | 13 |
|
74 | 14 | export const name = "local-kubernetes"
|
75 | 15 |
|
76 |
| -export function gardenPlugin({ projectName, log }: PluginFactoryParams): GardenPlugin { |
| 16 | +export function gardenPlugin(): GardenPlugin { |
77 | 17 | const plugin = k8sPlugin()
|
78 | 18 |
|
79 | 19 | plugin.configSchema = configSchema
|
80 | 20 |
|
81 |
| - plugin.actions!.configureProvider = async ({ config }: ConfigureProviderParams<LocalKubernetesConfig>) => { |
82 |
| - let context = config.context |
83 |
| - let defaultHostname = config.defaultHostname |
84 |
| - let setupIngressController = config.setupIngressController |
85 |
| - |
86 |
| - if (!context) { |
87 |
| - // automatically detect supported kubectl context if not explicitly configured |
88 |
| - const kubeConfig = await getKubeConfig() |
89 |
| - const currentContext = kubeConfig["current-context"] |
90 |
| - |
91 |
| - if (currentContext && supportedContexts.includes(currentContext)) { |
92 |
| - // prefer current context if set and supported |
93 |
| - context = currentContext |
94 |
| - log.debug({ section: name, msg: `Using current context: ${context}` }) |
95 |
| - } else if (kubeConfig.contexts) { |
96 |
| - const availableContexts = kubeConfig.contexts.map(c => c.name) |
97 |
| - |
98 |
| - for (const supportedContext of supportedContexts) { |
99 |
| - if (availableContexts.includes(supportedContext)) { |
100 |
| - context = supportedContext |
101 |
| - log.debug({ section: name, msg: `Using detected context: ${context}` }) |
102 |
| - break |
103 |
| - } |
104 |
| - } |
105 |
| - } |
106 |
| - } |
107 |
| - |
108 |
| - if (!context) { |
109 |
| - context = supportedContexts[0] |
110 |
| - log.debug({ section: name, msg: `No kubectl context auto-detected, using default: ${context}` }) |
111 |
| - } |
112 |
| - |
113 |
| - if (context === "minikube") { |
114 |
| - await execa("minikube", ["config", "set", "WantUpdateNotification", "false"]) |
115 |
| - |
116 |
| - if (!defaultHostname) { |
117 |
| - // use the nip.io service to give a hostname to the instance, if none is explicitly configured |
118 |
| - const minikubeIp = await execa.stdout("minikube", ["ip"]) |
119 |
| - defaultHostname = `${projectName}.${minikubeIp}.nip.io` |
120 |
| - } |
121 |
| - |
122 |
| - if (config.setupIngressController === "nginx") { |
123 |
| - log.silly("Using minikube's ingress addon") |
124 |
| - await execa("minikube", ["addons", "enable", "ingress"]) |
125 |
| - // make sure the prepare handler doesn't also set up the ingress controller |
126 |
| - setupIngressController = false |
127 |
| - } |
128 |
| - |
129 |
| - await setMinikubeDockerEnv() |
130 |
| - |
131 |
| - } else { |
132 |
| - if (!defaultHostname) { |
133 |
| - defaultHostname = `${projectName}.local.app.garden` |
134 |
| - } |
135 |
| - } |
136 |
| - |
137 |
| - config = { |
138 |
| - name: config.name, |
139 |
| - context, |
140 |
| - defaultHostname, |
141 |
| - deploymentRegistry: { |
142 |
| - hostname: "foo.garden", // this is not used by this plugin, but required by the base plugin |
143 |
| - namespace: "_", |
144 |
| - }, |
145 |
| - forceSsl: false, |
146 |
| - imagePullSecrets: config.imagePullSecrets, |
147 |
| - ingressHttpPort: 80, |
148 |
| - ingressHttpsPort: 443, |
149 |
| - ingressClass: "nginx", |
150 |
| - namespace: config.namespace || projectName, |
151 |
| - setupIngressController, |
152 |
| - tlsCertificates: config.tlsCertificates, |
153 |
| - _system: config._system, |
154 |
| - } |
155 |
| - |
156 |
| - return { name: config.name, config } |
157 |
| - } |
| 21 | + plugin.actions!.configureProvider = configureProvider |
158 | 22 |
|
159 | 23 | // override the environment configuration steps
|
160 | 24 | plugin.actions!.getEnvironmentStatus = getLocalEnvironmentStatus
|
|
0 commit comments