Skip to content

Commit

Permalink
refactor(cloud): re-structure internals of cloud module (#6709)
Browse files Browse the repository at this point in the history
* refactor: move cloud utilities to cloud dir

* refactor: move `AuthTokenResponse` to `auth.ts`

* refactor: rename `AuthTokenResponse` to `AuthToken`

* refactor: move function `getGardenCloudDomain` to cloud util package
  • Loading branch information
vvagaytsev authored Dec 11, 2024
1 parent 700b9c9 commit 62ddc3c
Show file tree
Hide file tree
Showing 16 changed files with 51 additions and 51 deletions.
5 changes: 3 additions & 2 deletions core/src/cli/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { intersection, mapValues, sortBy } from "lodash-es"
import { resolve, join } from "path"
import fsExtra from "fs-extra"
import { getBuiltinCommands } from "../commands/commands.js"
import { getCloudDistributionName } from "../util/cloud.js"
import { getPackageVersion } from "../util/util.js"
import type { Command, CommandResult, BuiltinArgs } from "../commands/base.js"
import { CommandGroup } from "../commands/base.js"
Expand Down Expand Up @@ -49,7 +48,8 @@ import { generateBasicDebugInfoReport } from "../commands/get/get-debug-info.js"
import type { AnalyticsHandler } from "../analytics/analytics.js"
import type { GardenPluginReference } from "../plugin/plugin.js"
import type { CloudApiFactory } from "../cloud/api.js"
import { GardenCloudApi, CloudApiTokenRefreshError, getGardenCloudDomain } from "../cloud/api.js"
import { CloudApiTokenRefreshError } from "../cloud/api.js"
import { GardenCloudApi } from "../cloud/api.js"
import { findProjectConfig } from "../config/base.js"
import { pMemoizeDecorator } from "../lib/p-memoize.js"
import { getCustomCommands } from "../commands/custom.js"
Expand All @@ -66,6 +66,7 @@ import { wrapActiveSpan } from "../util/open-telemetry/spans.js"
import { JsonFileWriter } from "../logger/writers/json-file-writer.js"
import type minimist from "minimist"
import { styles } from "../logger/styles.js"
import { getCloudDistributionName, getGardenCloudDomain } from "../cloud/util.js"

const { pathExists } = fsExtra

Expand Down
26 changes: 2 additions & 24 deletions core/src/cloud/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import ci from "ci-info"
import { GotHttpError } from "../util/http.js"
import { CloudApiError, GardenError } from "../exceptions.js"
import type { Log } from "../logger/log-entry.js"
import { DEFAULT_GARDEN_CLOUD_DOMAIN, gardenEnv } from "../constants.js"
import { gardenEnv } from "../constants.js"
import { Cookie } from "tough-cookie"
import { omit } from "lodash-es"
import { dedent, deline } from "../util/string.js"
Expand All @@ -31,7 +31,6 @@ import type {
UpdateSecretRequest,
UpdateSecretResponse,
} from "@garden-io/platform-api-types"
import { getCloudDistributionName, getCloudLogSectionName } from "../util/cloud.js"
import type { CommandInfo } from "../plugin-context.js"
import type { ClientAuthToken, GlobalConfigStore } from "../config-store/global.js"
import { LogLevel } from "../logger/logger.js"
Expand All @@ -45,6 +44,7 @@ import { enumerate } from "../util/enumerate.js"
import queryString from "query-string"
import type { ApiFetchOptions } from "./http-client.js"
import { GardenCloudHttpClient } from "./http-client.js"
import { getCloudDistributionName, getCloudLogSectionName } from "./util.js"

export class CloudApiDuplicateProjectsError extends CloudApiError {}

Expand Down Expand Up @@ -80,12 +80,6 @@ export interface BulkUpdateSecretRequest {
secrets: SingleUpdateSecretRequest[]
}

export interface AuthTokenResponse {
token: string
refreshToken: string
tokenValidity: number
}

// TODO: Read this from the `api-types` package once the session registration logic has been released in Cloud.
export interface CloudSessionResponse {
environmentId: string
Expand Down Expand Up @@ -141,22 +135,6 @@ function toCloudProject(project: GetProjectResponse["data"] | CreateProjectsForR
}
}

/**
* A helper function to get the cloud domain from a project config. Uses the env var
* GARDEN_CLOUD_DOMAIN to override a configured domain.
*/
export function getGardenCloudDomain(configuredDomain: string | undefined): string {
let cloudDomain: string | undefined

if (gardenEnv.GARDEN_CLOUD_DOMAIN) {
cloudDomain = new URL(gardenEnv.GARDEN_CLOUD_DOMAIN).origin
} else if (configuredDomain) {
cloudDomain = new URL(configuredDomain).origin
}

return cloudDomain || DEFAULT_GARDEN_CLOUD_DOMAIN
}

export interface CloudApiFactoryParams {
log: Log
cloudDomain: string
Expand Down
13 changes: 9 additions & 4 deletions core/src/cloud/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,24 @@ import bodyParser from "koa-bodyparser"
import Router from "koa-router"
import getPort from "get-port"
import type { Log } from "../logger/log-entry.js"
import type { AuthTokenResponse } from "./api.js"
import { cloneDeep, isArray } from "lodash-es"
import { gardenEnv } from "../constants.js"
import type { GlobalConfigStore } from "../config-store/global.js"
import { getCloudDistributionName } from "../util/cloud.js"
import { dedent, deline } from "../util/string.js"
import { CloudApiError, InternalError } from "../exceptions.js"
import { add } from "date-fns"
import { getCloudDistributionName } from "./util.js"

export interface AuthToken {
token: string
refreshToken: string
tokenValidity: number
}

export async function saveAuthToken(
log: Log,
globalConfigStore: GlobalConfigStore,
tokenResponse: AuthTokenResponse,
tokenResponse: AuthToken,
domain: string
) {
const distroName = getCloudDistributionName(domain)
Expand Down Expand Up @@ -162,7 +167,7 @@ export class AuthRedirectServer {
http.get("/", async (ctx) => {
const { jwt, rt, jwtval } = ctx.request.query
// TODO: validate properly
const tokenResponse: AuthTokenResponse = {
const tokenResponse: AuthToken = {
token: getFirstValue(jwt!),
refreshToken: getFirstValue(rt!),
tokenValidity: parseInt(getFirstValue(jwtval!), 10),
Expand Down
2 changes: 1 addition & 1 deletion core/src/cloud/http-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ import { CloudApiError } from "../exceptions.js"
import type { Log } from "../logger/log-entry.js"
import { isObject } from "lodash-es"
import { dedent, deline } from "../util/string.js"
import { getCloudDistributionName } from "../util/cloud.js"
import { getPackageVersion } from "../util/util.js"
import type { GlobalConfigStore } from "../config-store/global.js"
import { LogLevel } from "../logger/logger.js"
import { getAuthToken, makeAuthHeader } from "./auth.js"
import { RequestError } from "got"
import { getCloudDistributionName } from "./util.js"

const gardenClientName = "garden-core"
const gardenClientVersion = getPackageVersion()
Expand Down
18 changes: 17 additions & 1 deletion core/src/util/cloud.ts → core/src/cloud/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
import { DEFAULT_GARDEN_CLOUD_DOMAIN } from "../constants.js"
import { DEFAULT_GARDEN_CLOUD_DOMAIN, gardenEnv } from "../constants.js"

export type CloudDistroName = "the Garden dashboard" | "Garden Enterprise" | "Garden Cloud"

Expand Down Expand Up @@ -41,3 +41,19 @@ export function getCloudLogSectionName(distroName: CloudDistroName): CloudLogSec
return distroName satisfies never
}
}

/**
* A helper function to get the cloud domain from a project config.
* Uses the env var `GARDEN_CLOUD_DOMAIN` to override a configured domain.
*/
export function getGardenCloudDomain(configuredDomain: string | undefined): string {
let cloudDomain: string | undefined

if (gardenEnv.GARDEN_CLOUD_DOMAIN) {
cloudDomain = new URL(gardenEnv.GARDEN_CLOUD_DOMAIN).origin
} else if (configuredDomain) {
cloudDomain = new URL(configuredDomain).origin
}

return cloudDomain || DEFAULT_GARDEN_CLOUD_DOMAIN
}
2 changes: 1 addition & 1 deletion core/src/commands/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import type { Log } from "../logger/log-entry.js"
import type { LoggerBase, LoggerConfigBase, LogLevel } from "../logger/logger.js"
import { eventLogLevel } from "../logger/logger.js"
import { printEmoji, printFooter } from "../logger/util.js"
import { getCloudDistributionName, getCloudLogSectionName } from "../util/cloud.js"
import { getDurationMsec, getPackageVersion, userPrompt } from "../util/util.js"
import { renderOptions, renderCommands, renderArguments, cliStyles, optionsWithAliasValues } from "../cli/helpers.js"
import type { GlobalOptions, ParameterValues, ParameterObject } from "../cli/params.js"
Expand All @@ -42,6 +41,7 @@ import { withSessionContext } from "../util/open-telemetry/context.js"
import { wrapActiveSpan } from "../util/open-telemetry/spans.js"
import { styles } from "../logger/styles.js"
import { clearVarfileCache } from "../config/base.js"
import { getCloudDistributionName, getCloudLogSectionName } from "../cloud/util.js"

export interface CommandConstructor {
new (parent?: CommandGroup): Command
Expand Down
10 changes: 5 additions & 5 deletions core/src/commands/login.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,18 @@ import type { CommandParams, CommandResult } from "./base.js"
import { Command } from "./base.js"
import { printHeader } from "../logger/util.js"
import dedent from "dedent"
import type { AuthTokenResponse } from "../cloud/api.js"
import { GardenCloudApi, getGardenCloudDomain } from "../cloud/api.js"
import { GardenCloudApi } from "../cloud/api.js"
import type { Log } from "../logger/log-entry.js"
import { ConfigurationError, TimeoutError, InternalError, CloudApiError } from "../exceptions.js"
import type { AuthToken } from "../cloud/auth.js"
import { AuthRedirectServer, saveAuthToken } from "../cloud/auth.js"
import type { EventBus } from "../events/events.js"
import type { ProjectConfig } from "../config/project.js"
import { findProjectConfig } from "../config/base.js"
import { BooleanParameter } from "../cli/params.js"
import { getCloudDistributionName } from "../util/cloud.js"
import { deline } from "../util/string.js"
import { gardenEnv } from "../constants.js"
import { getCloudDistributionName, getGardenCloudDomain } from "../cloud/util.js"

const loginTimeoutSec = 60

Expand Down Expand Up @@ -115,7 +115,7 @@ export async function login(log: Log, cloudDomain: string, events: EventBus) {
const server = new AuthRedirectServer(cloudDomain, events, log)
const distroName = getCloudDistributionName(cloudDomain)
log.debug(`Redirecting to ${distroName} login page...`)
const response: AuthTokenResponse = await new Promise(async (resolve, reject) => {
const response: AuthToken = await new Promise(async (resolve, reject) => {
// The server resolves the promise with the new auth token once it's received the redirect.
await server.start()

Expand All @@ -130,7 +130,7 @@ export async function login(log: Log, cloudDomain: string, events: EventBus) {
)
}, loginTimeoutSec * 1000)

events.once("receivedToken", (tokenResponse: AuthTokenResponse) => {
events.once("receivedToken", (tokenResponse: AuthToken) => {
if (timedOut) {
return
}
Expand Down
4 changes: 2 additions & 2 deletions core/src/commands/logout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@
import type { CommandParams, CommandResult } from "./base.js"
import { Command } from "./base.js"
import { printHeader } from "../logger/util.js"
import { GardenCloudApi, getGardenCloudDomain } from "../cloud/api.js"
import { getCloudDistributionName } from "../util/cloud.js"
import { GardenCloudApi } from "../cloud/api.js"
import { dedent, deline } from "../util/string.js"
import { ConfigurationError } from "../exceptions.js"
import type { ProjectConfig } from "../config/project.js"
import { findProjectConfig } from "../config/base.js"
import { BooleanParameter } from "../cli/params.js"
import { clearAuthToken } from "../cloud/auth.js"
import { getCloudDistributionName, getGardenCloudDomain } from "../cloud/util.js"

export const logoutOpts = {
"disable-project-check": new BooleanParameter({
Expand Down
4 changes: 2 additions & 2 deletions core/src/commands/serve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,18 @@ import { printEmoji, printHeader } from "../logger/util.js"
import { dedent } from "../util/string.js"
import type { CommandLine } from "../cli/command-line.js"
import { GardenInstanceManager } from "../server/instance-manager.js"
import { getCloudDistributionName } from "../util/cloud.js"
import { sleep } from "../util/util.js"
import type { Log } from "../logger/log-entry.js"
import { findProjectConfig } from "../config/base.js"
import { CloudApiTokenRefreshError, getGardenCloudDomain } from "../cloud/api.js"
import { CloudApiTokenRefreshError } from "../cloud/api.js"
import { uuidv4 } from "../util/random.js"
import type { Garden } from "../garden.js"
import type { GardenPluginReference } from "../plugin/plugin.js"
import { CommandError, ParameterError, isEAddrInUseException, isErrnoException } from "../exceptions.js"
import { styles } from "../logger/styles.js"
import { emitLoginWarning } from "../cli/helpers.js"
import { DEFAULT_GARDEN_CLOUD_DOMAIN } from "../constants.js"
import { getCloudDistributionName, getGardenCloudDomain } from "../cloud/util.js"

export const defaultServerPort = 9777

Expand Down
4 changes: 2 additions & 2 deletions core/src/events/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ import type { LogEntryEventPayload } from "../cloud/buffered-event-stream.js"
import type { DeployStatusForEventPayload } from "../types/service.js"
import type { RunStatusForEventPayload } from "../plugin/base.js"
import type { Omit, PickFromUnion } from "../util/util.js"
import type { AuthTokenResponse } from "../cloud/api.js"
import type { ConfigGraph, RenderedActionGraph } from "../graph/config-graph.js"
import type { CommandInfo } from "../plugin-context.js"
import type { GraphResult } from "../graph/results.js"
import type { NamespaceStatus } from "../types/namespace.js"
import type { BuildStatusForEventPayload } from "../plugin/handlers/Build/get-status.js"
import type { ActionStatusPayload } from "./action-status-events.js"
import type { AuthToken } from "../cloud/auth.js"

interface EventContext {
gardenKey?: string
Expand Down Expand Up @@ -193,7 +193,7 @@ export interface Events {
servers: { host: string; command: string; serverAuthKey: string }[]
}
connectionReady: {}
receivedToken: AuthTokenResponse
receivedToken: AuthToken

// Session events - one of these is emitted when the command process ends
sessionCompleted: {} // Command exited with a 0 status
Expand Down
3 changes: 1 addition & 2 deletions core/src/garden.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@ import {
TemplatableConfigContext,
} from "./config/template-contexts/project.js"
import type { GardenCloudApi, CloudProject } from "./cloud/api.js"
import { getGardenCloudDomain } from "./cloud/api.js"
import { OutputConfigContext } from "./config/template-contexts/module.js"
import { ProviderConfigContext } from "./config/template-contexts/provider.js"
import type { ConfigContext } from "./config/template-contexts/base.js"
Expand Down Expand Up @@ -165,9 +164,9 @@ import { detectModuleOverlap, makeOverlapErrors } from "./util/module-overlap.js
import { GotHttpError } from "./util/http.js"
import { styles } from "./logger/styles.js"
import { renderDuration } from "./logger/util.js"
import { getCloudDistributionName, getCloudLogSectionName } from "./util/cloud.js"
import { makeDocsLinkStyled } from "./docs/common.js"
import { getPathInfo } from "./vcs/git.js"
import { getCloudDistributionName, getCloudLogSectionName, getGardenCloudDomain } from "./cloud/util.js"

const defaultLocalAddress = "localhost"

Expand Down
2 changes: 1 addition & 1 deletion core/src/plugins/container/cloudbuilder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,14 @@ import { emitNonRepeatableWarning } from "../../warnings.js"
import { LRUCache } from "lru-cache"
import { DEFAULT_GARDEN_CLOUD_DOMAIN, gardenEnv } from "../../constants.js"
import type { ActionRuntime, ActionRuntimeKind } from "../../plugin/base.js"
import { getCloudDistributionName } from "../../util/cloud.js"
import crypto from "crypto"
import { promisify } from "util"
import AsyncLock from "async-lock"
import { containerHelpers } from "./helpers.js"
import { hashString } from "../../util/util.js"
import { stableStringify } from "../../util/string.js"
import { homedir } from "os"
import { getCloudDistributionName } from "../../cloud/util.js"

const { mkdirp, rm, writeFile, stat } = fsExtra

Expand Down
3 changes: 2 additions & 1 deletion core/src/server/instance-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import { Autocompleter } from "../cli/autocomplete.js"
import { parseCliVarFlags } from "../cli/helpers.js"
import type { ParameterObject, ParameterValues } from "../cli/params.js"
import type { CloudApiFactory, CloudApiFactoryParams } from "../cloud/api.js"
import { GardenCloudApi, getGardenCloudDomain } from "../cloud/api.js"
import { GardenCloudApi } from "../cloud/api.js"
import type { Command } from "../commands/base.js"
import { getBuiltinCommands, flattenCommands } from "../commands/commands.js"
import { getCustomCommands } from "../commands/custom.js"
Expand All @@ -39,6 +39,7 @@ import {
import type { GardenInstanceKeyParams } from "./helpers.js"
import { getGardenInstanceKey } from "./helpers.js"
import { styles } from "../logger/styles.js"
import { getGardenCloudDomain } from "../cloud/util.js"

interface InstanceContext {
garden: Garden
Expand Down
2 changes: 1 addition & 1 deletion core/src/server/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ import { join } from "path"
import { GlobalConfigStore } from "../config-store/global.js"
import { validateSchema } from "../config/validation.js"
import type { ConfigGraph } from "../graph/config-graph.js"
import { getGardenCloudDomain } from "../cloud/api.js"
import type { ServeCommand } from "../commands/serve.js"
import type { AutocompleteSuggestion } from "../cli/autocomplete.js"
import { createServer } from "http"
import { defaultServerPort } from "../commands/serve.js"

import { styles } from "../logger/styles.js"
import { getGardenCloudDomain } from "../cloud/util.js"

const skipLogsForCommands = ["autocomplete"]
const serverLogName = "garden-server"
Expand Down
2 changes: 1 addition & 1 deletion core/test/unit/src/garden.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,11 @@ import { LogLevel, getRootLogger } from "../../../src/logger/logger.js"
import { uuidv4 } from "../../../src/util/random.js"
import { fileURLToPath } from "node:url"
import { resolveMsg } from "../../../src/logger/log-entry.js"
import { getCloudDistributionName } from "../../../src/util/cloud.js"
import { styles } from "../../../src/logger/styles.js"
import type { RunActionConfig } from "../../../src/actions/run.js"
import type { ProjectResult } from "@garden-io/platform-api-types"
import { ProjectStatus } from "@garden-io/platform-api-types"
import { getCloudDistributionName } from "../../../src/cloud/util.js"

const moduleDirName = dirname(fileURLToPath(import.meta.url))

Expand Down
2 changes: 1 addition & 1 deletion core/test/unit/src/util/cloud.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
*/

import { describe } from "mocha"
import { getCloudDistributionName, getCloudLogSectionName } from "../../../../src/util/cloud.js"
import { DEFAULT_GARDEN_CLOUD_DOMAIN } from "../../../../src/constants.js"
import { expect } from "chai"
import { getCloudDistributionName, getCloudLogSectionName } from "../../../../src/cloud/util.js"

describe("garden-cloud", () => {
describe("getCloudDistributionName", () => {
Expand Down

0 comments on commit 62ddc3c

Please sign in to comment.