diff --git a/docs/reference/config.md b/docs/reference/config.md index 3b5542580a..defbe4ce81 100644 --- a/docs/reference/config.md +++ b/docs/reference/config.md @@ -643,16 +643,28 @@ module: # Required. name: - # The protocol of the service container port. + # The protocol of the port. # # Optional. protocol: TCP - # The port number on the service container. + # The port exposed on the container by the running procces. This will also be the + # default value for `servicePort`. + # `servicePort:80 -> containerPort:8080 -> process:8080` + # + # Example: "8080" # # Required. containerPort: + # The port exposed on the service. Defaults to `containerPort` if not specified. + # `servicePort:80 -> containerPort:8080 -> process:8080` + # + # Example: "80" + # + # Optional. + servicePort: + hostPort: # Set this to expose the service on the specified port on the host node (may not be diff --git a/examples/simple-project/services/go-service/garden.yml b/examples/simple-project/services/go-service/garden.yml index 85ac99018b..5ae0d4ae4d 100644 --- a/examples/simple-project/services/go-service/garden.yml +++ b/examples/simple-project/services/go-service/garden.yml @@ -6,7 +6,9 @@ module: - name: go-service ports: - name: http - containerPort: 80 + containerPort: 8080 + # Maps service:80 -> container:8080 + servicePort: 80 ingresses: - path: /hello-go - port: http \ No newline at end of file + port: http diff --git a/examples/simple-project/services/go-service/webserver/main.go b/examples/simple-project/services/go-service/webserver/main.go index 3115511eff..3bdee587e9 100644 --- a/examples/simple-project/services/go-service/webserver/main.go +++ b/examples/simple-project/services/go-service/webserver/main.go @@ -13,5 +13,5 @@ func main() { http.HandleFunc("/hello-go", handler) fmt.Println("Server running...") - http.ListenAndServe(":80", nil) + http.ListenAndServe(":8080", nil) } diff --git a/garden-service/src/docs/config.ts b/garden-service/src/docs/config.ts index 82e5fdc315..e289342a37 100644 --- a/garden-service/src/docs/config.ts +++ b/garden-service/src/docs/config.ts @@ -87,10 +87,10 @@ export function getDefaultValue(description: Joi.Description) { if (defaultSpec === undefined) { return } else if (defaultSpec && defaultSpec.function) { - const value = defaultSpec.function({}) - if (value === undefined){ + const value = defaultSpec.function({}) + if (value === undefined) { return defaultSpec.description - }else { + } else { return value } } else { diff --git a/garden-service/src/plugins/container.ts b/garden-service/src/plugins/container.ts index 8f97a9add9..43518f55d9 100644 --- a/garden-service/src/plugins/container.ts +++ b/garden-service/src/plugins/container.ts @@ -60,6 +60,8 @@ export interface ServicePortSpec { name: string protocol: ServicePortProtocol containerPort: number + // Defaults to containerPort + servicePort: number hostPort?: number nodePort?: number | null } @@ -164,7 +166,7 @@ const healthCheckSchema = Joi.object() .description("Set this to check the service's health by checking if this TCP port is accepting connections."), }).xor("httpGet", "command", "tcpPort") -const portSchema = Joi.object() +export const portSchema = Joi.object() .keys({ name: joiIdentifier() .required() @@ -172,10 +174,21 @@ const portSchema = Joi.object() protocol: Joi.string() .allow("TCP", "UDP") .default(DEFAULT_PORT_PROTOCOL) - .description("The protocol of the service container port."), + .description("The protocol of the port."), containerPort: Joi.number() .required() - .description("The port number on the service container."), + .example("8080") + .description(deline` + The port exposed on the container by the running procces. This will also be the default value + for \`servicePort\`. + + \`servicePort:80 -> containerPort:8080 -> process:8080\``), + servicePort: Joi.number().default((context) => context.containerPort, "") + .example("80") + .description(deline`The port exposed on the service. + Defaults to \`containerPort\` if not specified. + + \`servicePort:80 -> containerPort:8080 -> process:8080\``), hostPort: Joi.number() .meta({ deprecated: true }), nodePort: Joi.number() diff --git a/garden-service/src/plugins/kubernetes/deployment.ts b/garden-service/src/plugins/kubernetes/deployment.ts index 11e87b4b1b..8118ca3a77 100644 --- a/garden-service/src/plugins/kubernetes/deployment.ts +++ b/garden-service/src/plugins/kubernetes/deployment.ts @@ -204,6 +204,7 @@ export async function createDeployment( for (const port of ports) { container.ports.push({ + name: port.name, protocol: port.protocol, containerPort: port.containerPort, }) diff --git a/garden-service/src/plugins/kubernetes/ingress.ts b/garden-service/src/plugins/kubernetes/ingress.ts index 7e9b67514b..927a0bbcb8 100644 --- a/garden-service/src/plugins/kubernetes/ingress.ts +++ b/garden-service/src/plugins/kubernetes/ingress.ts @@ -45,7 +45,7 @@ export async function createIngresses(api: KubeApi, namespace: string, service: path: ingress.path, backend: { serviceName: service.name, - servicePort: findByName(service.spec.ports, ingress.spec.port)!.containerPort, + servicePort: findByName(service.spec.ports, ingress.spec.port)!.servicePort, }, })), }, diff --git a/garden-service/src/plugins/kubernetes/service.ts b/garden-service/src/plugins/kubernetes/service.ts index 83f3656a62..45b65d1533 100644 --- a/garden-service/src/plugins/kubernetes/service.ts +++ b/garden-service/src/plugins/kubernetes/service.ts @@ -42,7 +42,7 @@ export async function createServices(service: ContainerService, namespace: strin name: portSpec.name, protocol: portSpec.protocol, targetPort: portSpec.containerPort, - port: portSpec.containerPort, + port: portSpec.servicePort, }) } diff --git a/garden-service/src/plugins/local/local-docker-swarm.ts b/garden-service/src/plugins/local/local-docker-swarm.ts index 6307921457..4f0461aacf 100644 --- a/garden-service/src/plugins/local/local-docker-swarm.ts +++ b/garden-service/src/plugins/local/local-docker-swarm.ts @@ -60,7 +60,7 @@ export const gardenPlugin = (): GardenPlugin => ({ } if (p.hostPort) { - port.PublishedPort = p.hostPort + port.PublishedPort = p.servicePort } }) diff --git a/garden-service/src/plugins/local/local-google-cloud-functions.ts b/garden-service/src/plugins/local/local-google-cloud-functions.ts index 3323cd8854..94ea353168 100644 --- a/garden-service/src/plugins/local/local-google-cloud-functions.ts +++ b/garden-service/src/plugins/local/local-google-cloud-functions.ts @@ -61,6 +61,7 @@ export const gardenPlugin = (): GardenPlugin => ({ name: "http", protocol: "TCP", containerPort: emulatorPort, + servicePort: emulatorPort, }, ], volumes: [], diff --git a/garden-service/test/src/docs/config.ts b/garden-service/test/src/docs/config.ts index e300ceeb75..fb935c905b 100644 --- a/garden-service/test/src/docs/config.ts +++ b/garden-service/test/src/docs/config.ts @@ -5,11 +5,11 @@ import dedent = require("dedent") describe("config", () => { const serivcePortSchema = Joi.number().default((context) => context.containerPort, "default value") - .example("8080") - .description("description") + .example("8080") + .description("description") const testDefaultSchema = Joi.number().default(() => "result", "default value") - .description("description") + .description("description") const portSchema = Joi.object() .keys({ @@ -22,8 +22,8 @@ describe("config", () => { describe("renderSchemaDescription", () => { it("should render correct markdown", () => { - const yaml = renderSchemaDescription(portSchema.describe(), { required: true }) - expect(yaml).to.equal(dedent`\n# description + const yaml = renderSchemaDescription(portSchema.describe(), { required: true }) + expect(yaml).to.equal(dedent`\n# description # # Required. containerPort: diff --git a/garden-service/test/src/plugins/container.ts b/garden-service/test/src/plugins/container.ts index baca9ed215..99dbf02cfa 100644 --- a/garden-service/test/src/plugins/container.ts +++ b/garden-service/test/src/plugins/container.ts @@ -224,6 +224,7 @@ describe("plugins.container", () => { name: "http", protocol: "TCP", containerPort: 8080, + servicePort: 8080, }], outputs: {}, volumes: [], @@ -275,7 +276,7 @@ describe("plugins.container", () => { }, healthCheck: { httpGet: { path: "/health", port: "http", scheme: "HTTP" } }, - ports: [{ name: "http", protocol: "TCP", containerPort: 8080 }], + ports: [{ name: "http", protocol: "TCP", containerPort: 8080, servicePort: 8080 }], outputs: {}, volumes: [], }], @@ -315,7 +316,7 @@ describe("plugins.container", () => { }, healthCheck: { httpGet: { path: "/health", port: "http", scheme: "HTTP" } }, - ports: [{ name: "http", protocol: "TCP", containerPort: 8080 }], + ports: [{ name: "http", protocol: "TCP", containerPort: 8080, servicePort: 8080 }], outputs: {}, volumes: [], }, diff --git a/garden-service/test/src/plugins/kubernetes/ingress.ts b/garden-service/test/src/plugins/kubernetes/ingress.ts index 3c0e6cba25..8727afb429 100644 --- a/garden-service/test/src/plugins/kubernetes/ingress.ts +++ b/garden-service/test/src/plugins/kubernetes/ingress.ts @@ -21,6 +21,7 @@ const ports = [{ name: "http", protocol: "http", containerPort: 123, + servicePort: 123, }] const basicConfig: KubernetesConfig = { diff --git a/garden-service/test/src/types/container.ts b/garden-service/test/src/types/container.ts new file mode 100644 index 0000000000..abb769f25e --- /dev/null +++ b/garden-service/test/src/types/container.ts @@ -0,0 +1,22 @@ +import { expect } from "chai" +import { validate } from "../../../src/config/common" +import { portSchema } from "../../../src/plugins/container" + +describe("portSchema", () => { + it("should default servicePort to containerPorts value", async () => { + const containerPort = 8080 + const obj = { name: "a", containerPort } + + const value = validate(obj, portSchema) + expect(value["servicePort"]).to.equal(containerPort) + }) + + it("should not default servicePort to containerPorts when configured", async () => { + const containerPort = 8080 + const servicePort = 9090 + const obj = { name: "a", containerPort, servicePort } + + const value = validate(obj, portSchema) + expect(value["servicePort"]).to.equal(servicePort) + }) +})