Skip to content

Commit

Permalink
improvement(config): add linkUrl field
Browse files Browse the repository at this point in the history
  • Loading branch information
eysi09 committed Oct 2, 2019
1 parent c983fc3 commit b77fe93
Show file tree
Hide file tree
Showing 12 changed files with 232 additions and 77 deletions.
15 changes: 2 additions & 13 deletions dashboard/src/components/ingresses.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ import React from "react"
import styled from "@emotion/styled"
import { ExternalLink } from "./links"
import { ServiceIngress } from "garden-service/build/src/types/service"
import { truncateMiddle } from "../util/helpers"
import normalizeUrl from "normalize-url"
import { format } from "url"
import { truncateMiddle, getLinkUrl } from "../util/helpers"
import { useUiState } from "../contexts/ui"

const Ingresses = styled.div`
Expand Down Expand Up @@ -42,15 +40,6 @@ const LinkContainer = styled.div`
}
`

const getIngressUrl = (ingress: ServiceIngress) => {
return normalizeUrl(format({
protocol: ingress.protocol,
hostname: ingress.hostname,
port: ingress.port,
pathname: ingress.path,
}))
}

interface IngressesProp {
ingresses: ServiceIngress[] | undefined
}
Expand All @@ -70,7 +59,7 @@ export default ({ ingresses }: IngressesProp) => {
return (
<Ingresses>
{(ingresses || []).map((ingress) => {
const url = getIngressUrl(ingress)
const url = getLinkUrl(ingress)
return (
<LinkContainer key={ingress.path}>
<div className="visible-lg-block">
Expand Down
15 changes: 2 additions & 13 deletions dashboard/src/components/view-ingress.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ import React from "react"
import styled from "@emotion/styled"
import { ExternalLink } from "./links"
import { ServiceIngress } from "garden-service/build/src/types/service"
import { truncateMiddle } from "../util/helpers"
import normalizeUrl from "normalize-url"
import { format } from "url"
import { truncateMiddle, getLinkUrl } from "../util/helpers"
import { useUiState } from "../contexts/ui"
import { ActionIcon } from "./action-icon"

Expand Down Expand Up @@ -58,15 +56,6 @@ const Frame = styled.iframe`
width: 100%;
`

const getIngressUrl = (ingress: ServiceIngress) => {
return normalizeUrl(format({
protocol: ingress.protocol,
hostname: ingress.hostname,
port: ingress.port,
pathname: ingress.path,
}))
}

interface ViewIngressProp {
ingress: ServiceIngress,
height?: string,
Expand All @@ -80,7 +69,7 @@ export default ({ ingress, height, width }: ViewIngressProp) => {
selectIngress(null)
}

const url = getIngressUrl(ingress)
const url = getLinkUrl(ingress)

return (
<ViewIngress>
Expand Down
19 changes: 19 additions & 0 deletions dashboard/src/util/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,11 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

import normalizeUrl from "normalize-url"
import { format } from "url"
import { flatten } from "lodash"
import { ModuleConfig } from "garden-service/build/src/config/module"
import { ServiceIngress } from "garden-service/build/src/types/service"

export function getServiceNames(moduleConfigs: ModuleConfig[]) {
return flatten(moduleConfigs.map(m => m.serviceConfigs.map(s => s.name)))
Expand Down Expand Up @@ -49,3 +52,19 @@ export const truncateMiddle = (str: string, resLength: number = 35) => {

return str
}

/**
* Returns the link URL or falls back to constructing the URL from the ingress spec
*/
export function getLinkUrl(ingress: ServiceIngress) {
if (ingress.linkUrl) {
return ingress.linkUrl
}

return normalizeUrl(format({
protocol: ingress.protocol,
hostname: ingress.hostname,
port: ingress.port,
pathname: ingress.path,
}))
}
2 changes: 1 addition & 1 deletion dashboard/src/util/hooks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,4 @@ export const useConfig = (dispatch: ApiDispatch, requestState: RequestState) =>
* See e.g. here: https://github.com/facebook/react/issues/15865.
* Here's the suggested solution: https://github.com/facebook/create-react-app/issues/6880#issuecomment-488158024
*/
export const useMountEffect = (fun: () => void) => useEffect(fun, [])
export const useMountEffect = (fn: () => void) => useEffect(fn, [])
17 changes: 17 additions & 0 deletions docs/reference/module-types/container.md
Original file line number Diff line number Diff line change
Expand Up @@ -481,6 +481,22 @@ Note that if you're developing locally you may need to add this hostname to your
| -------- | -------- |
| `string` | No |

### `services[].ingresses[].linkUrl`

[services](#services) > [ingresses](#services[].ingresses[]) > linkUrl

The link URL for the ingress to show in the console and on the dashboard.
Also used when calling the service with the `call` command.

Use this if the actual URL is different from what's specified in the ingress,
e.g. because there's a load balancer in front of the service that rewrites the paths.

Otherwise Garden will construct the link URL from the ingress spec.

| Type | Required |
| -------- | -------- |
| `string` | No |

### `services[].ingresses[].path`

[services](#services) > [ingresses](#services[].ingresses[]) > path
Expand Down Expand Up @@ -1046,6 +1062,7 @@ services:
ingresses:
- annotations: {}
hostname:
linkUrl:
path: /
port:
env: {}
Expand Down
17 changes: 17 additions & 0 deletions docs/reference/module-types/maven-container.md
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,22 @@ Note that if you're developing locally you may need to add this hostname to your
| -------- | -------- |
| `string` | No |

### `services[].ingresses[].linkUrl`

[services](#services) > [ingresses](#services[].ingresses[]) > linkUrl

The link URL for the ingress to show in the console and on the dashboard.
Also used when calling the service with the `call` command.

Use this if the actual URL is different from what's specified in the ingress,
e.g. because there's a load balancer in front of the service that rewrites the paths.

Otherwise Garden will construct the link URL from the ingress spec.

| Type | Required |
| -------- | -------- |
| `string` | No |

### `services[].ingresses[].path`

[services](#services) > [ingresses](#services[].ingresses[]) > path
Expand Down Expand Up @@ -1081,6 +1097,7 @@ services:
ingresses:
- annotations: {}
hostname:
linkUrl:
path: /
port:
env: {}
Expand Down
28 changes: 22 additions & 6 deletions garden-service/src/commands/call.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

import { resolve } from "url"
import { parse, resolve } from "url"
import Axios from "axios"
import chalk from "chalk"
import { isObject } from "util"
Expand Down Expand Up @@ -123,12 +123,30 @@ export class CallCommand extends Command<Args> {
})
}

const url = resolve(getIngressUrl(matchedIngress), path || matchedPath)
let url: string
let protocol: string
let host: string

// If a link URL is provided, we use that (and destructure the URL parts from it)...
if (matchedIngress.linkUrl) {
url = matchedIngress.linkUrl
const parsed = parse(url)
protocol = parsed.protocol || ""
host = parsed.hostname || ""
// Overwrite the return path value
path = parsed.path || ""
// ...otherwise we use the ingress spec
} else {
url = resolve(getIngressUrl(matchedIngress), path || matchedPath)
protocol = matchedIngress.protocol
host = matchedIngress.hostname
}

// TODO: support POST requests with request body
const method = "get"

const entry = log.info({
msg: chalk.cyan(`Sending ${matchedIngress.protocol.toUpperCase()} GET request to `) + url + "\n",
msg: chalk.cyan(`Sending ${protocol.toUpperCase()} ${method.toUpperCase()} request to `) + url + "\n",
status: "active",
})

Expand All @@ -138,9 +156,7 @@ export class CallCommand extends Command<Args> {
const req = Axios({
method,
url,
headers: {
host: matchedIngress.hostname,
},
headers: { host },
})

// TODO: add verbose and debug logging (request/response headers etc.)
Expand Down
4 changes: 3 additions & 1 deletion garden-service/src/plugins/container/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {
envVarRegex,
Primitive,
} from "../../config/common"
import { Service, ingressHostnameSchema } from "../../types/service"
import { Service, ingressHostnameSchema, linkUrlSchema } from "../../types/service"
import { DEFAULT_PORT_PROTOCOL } from "../../constants"
import { ModuleSpec, ModuleConfig, baseBuildSpecSchema, BaseBuildSpec } from "../../config/module"
import { CommonServiceSpec, ServiceConfig, baseServiceSpecSchema } from "../../config/service"
Expand All @@ -33,6 +33,7 @@ export const defaultContainerLimits: ServiceLimitSpec = {

export interface ContainerIngressSpec {
annotations: Annotations
linkUrl?: string
hostname?: string
path: string
port: string
Expand Down Expand Up @@ -185,6 +186,7 @@ const ingressSchema = joi.object()
annotations: annotationsSchema
.description("Annotations to attach to the ingress (Note: May not be applicable to all providers)"),
hostname: ingressHostnameSchema,
linkUrl: linkUrlSchema,
path: joi.string()
.default("/")
.description("The path which should be routed to the service."),
Expand Down
1 change: 1 addition & 0 deletions garden-service/src/plugins/kubernetes/container/ingress.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ export async function getIngresses(
hostname: ingress.hostname,
path: ingress.path,
port: ingress.port,
linkUrl: ingress.linkUrl,
protocol: ingress.protocol,
}))
}
Expand Down
4 changes: 2 additions & 2 deletions garden-service/src/tasks/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import chalk from "chalk"
import { includes } from "lodash"
import { LogEntry } from "../logger/log-entry"
import { BaseTask, TaskType, getServiceStatuses, getRunTaskResults } from "./base"
import { Service, ServiceStatus, getIngressUrl } from "../types/service"
import { Service, ServiceStatus, getLinkUrl } from "../types/service"
import { Garden } from "../garden"
import { TaskTask, getTaskVersion } from "./task"
import { BuildTask } from "./build"
Expand Down Expand Up @@ -188,7 +188,7 @@ export class DeployTask extends BaseTask {
}

for (const ingress of status.ingresses || []) {
log.info(chalk.gray("→ Ingress: ") + chalk.underline.gray(getIngressUrl(ingress)))
log.info(chalk.gray("→ Ingress: ") + chalk.underline.gray(getLinkUrl(ingress)))
}

if (this.garden.persistent) {
Expand Down
27 changes: 27 additions & 0 deletions garden-service/src/types/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ export type ServiceProtocol = "http" | "https" // | "tcp" | "udp"

export interface ServiceIngressSpec {
hostname?: string
linkUrl?: string
path: string
port: number
protocol: ServiceProtocol
Expand All @@ -98,6 +99,18 @@ export const ingressHostnameSchema = joi.string()
Note that if you're developing locally you may need to add this hostname to your hosts file.
`)

export const linkUrlSchema = joi.string()
.uri()
.description(dedent`
The link URL for the ingress to show in the console and on the dashboard.
Also used when calling the service with the \`call\` command.
Use this if the actual URL is different from what's specified in the ingress,
e.g. because there's a load balancer in front of the service that rewrites the paths.
Otherwise Garden will construct the link URL from the ingress spec.
`)

const portSchema = joi.number()
.description(dedent`
The port number that the service is exposed on internally.
Expand Down Expand Up @@ -213,6 +226,20 @@ export const serviceStatusSchema = joi.object()
.description("The Garden module version of the deployed service."),
})

/**
* Returns the link URL or falls back to constructing the URL from the ingress spec
*/
export function getLinkUrl(ingress: ServiceIngress) {
if (ingress.linkUrl) {
return ingress.linkUrl
}

return getIngressUrl(ingress)
}

/**
* Returns a normalized URL string, constructed from the ingress spec
*/
export function getIngressUrl(ingress: ServiceIngress) {
return normalizeUrl(format({
protocol: ingress.protocol,
Expand Down
Loading

0 comments on commit b77fe93

Please sign in to comment.