Skip to content

Commit

Permalink
Allow specify envId in connect command (#206)
Browse files Browse the repository at this point in the history
* Allow specify envId in connect command

* fix normalization/validation in up command

* CR change

* fix linting issue

* added env id info

* cosmetic
  • Loading branch information
Yshayy authored Aug 28, 2023
1 parent 7b3aedc commit 962db80
Show file tree
Hide file tree
Showing 7 changed files with 39 additions and 17 deletions.
17 changes: 14 additions & 3 deletions packages/cli/src/commands/proxy/connect.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ux, Args, Flags } from '@oclif/core'
import { jwkThumbprint, commands, profileStore, withSpinner, SshConnection, machineId, normalizeEnvId } from '@preevy/core'
import { jwkThumbprint, commands, profileStore, withSpinner, SshConnection, machineId, validateEnvId, normalizeEnvId, EnvId } from '@preevy/core'
import { tunnelServerFlags, urlFlags } from '@preevy/cli-common'
import { inspect } from 'util'
import { formatPublicKey } from '@preevy/common'
Expand All @@ -16,6 +16,11 @@ export default class Connect extends ProfileCommand<typeof Connect> {
...tunnelServerFlags,
...urlFlags,
...ux.table.flags(),
id: Flags.string({
aliases: ['env-id'],
description: 'specify the environment ID for this app',
required: false,
}),
'private-env': Flags.boolean({
description: 'Mark all services as private',
default: false,
Expand Down Expand Up @@ -48,8 +53,14 @@ export default class Connect extends ProfileCommand<typeof Connect> {
insecureSkipVerify: flags['insecure-skip-verify'],
}
const composeProject = args['compose-project']
const deviceId = (await machineId(this.config.dataDir)).substring(0, 2)
const envId = normalizeEnvId(`${composeProject}-dev-${deviceId}`) // local+find_ambient_id_based on compose dir (?)
let envId:EnvId
if (flags.id) {
envId = validateEnvId(flags.id)
} else {
const deviceId = (await machineId(this.config.dataDir)).substring(0, 2)
envId = normalizeEnvId(`${composeProject}-dev-${deviceId}`)
this.logger.info(`Using environment ID ${envId}, based on Docker Compose and local device`)
}
let client: SshConnection['client'] | undefined
let hostKey: Buffer
let preevyAgentUrl: string
Expand Down
12 changes: 7 additions & 5 deletions packages/cli/src/commands/up.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { Args, Flags, ux } from '@oclif/core'
import {
addBaseComposeTunnelAgentService,
commands, findComposeTunnelAgentUrl,
findEnvIdByProjectName, findProjectName, getTunnelNamesToServicePorts, profileStore,
findEnvId,
findProjectName, getTunnelNamesToServicePorts, profileStore,
telemetryEmitter,
withSpinner,
} from '@preevy/core'
Expand Down Expand Up @@ -47,15 +48,16 @@ export default class Up extends MachineCreationDriverCommand<typeof Up> {
const machineCreationDriver = await this.machineCreationDriver()
const userModel = await this.ensureUserModel()

const { projectName, projectNameBasedOn } = await findProjectName({
const { projectName } = await findProjectName({
userSpecifiedProjectName: flags.project,
userModel,
})

const envId = flags.id ?? await findEnvIdByProjectName({
const envId = await findEnvId({
log: this.logger,
projectName,
projectNameBasedOn,
userSpecifiedEnvId: flags.id,
userSpecifiedProjectName: flags.project,
userModel,
})

const pStore = profileStore(this.store)
Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/commands/proxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { execPromiseStdout } from '../child-process'
import { COMPOSE_TUNNEL_AGENT_SERVICE_NAME, COMPOSE_TUNNEL_AGENT_PORT, addComposeTunnelAgentService } from '../compose-tunnel-agent-client'
import { ComposeModel } from '../compose'
import { TunnelOpts } from '../ssh'
import { EnvId } from '../env-id'

export const agentServiceName = COMPOSE_TUNNEL_AGENT_SERVICE_NAME

Expand Down Expand Up @@ -53,7 +54,7 @@ export function inspectRunningComposeApp(projectName: string) {
}

export function initProxyComposeModel(opts: {
envId: string
envId: EnvId
projectName: string
tunnelOpts: TunnelOpts
tunnelingKeyThumbprint: string
Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/commands/up/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { remoteProjectDir } from '../../remote-files'
import { Logger } from '../../log'
import { FileToCopy, uploadWithSpinner } from '../../upload-files'
import { envMetadata } from '../../env-metadata'
import { EnvId } from '../../env-id'

const createCopiedFileInDataDir = (
{ projectLocalDataDir, filesToCopy } : {
Expand Down Expand Up @@ -95,7 +96,7 @@ const up = async ({
cwd: string
skipUnchangedFiles: boolean
version: string
envId: string
envId: EnvId
expectedServiceUrls: { name: string; port: number; url: string }[]
projectName: string
}): Promise<{ machine: MachineBase }> => {
Expand Down
3 changes: 2 additions & 1 deletion packages/core/src/compose-tunnel-agent-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { withBasicAuthCredentials } from './credentials'
import { EnvMetadata, driverMetadataFilename } from './env-metadata'
import { REMOTE_DIR_BASE } from './remote-files'
import { isPacked, pkgSnapshotDir } from './pkg'
import { EnvId } from './env-id'

export const COMPOSE_TUNNEL_AGENT_SERVICE_NAME = 'preevy_proxy'
export const COMPOSE_TUNNEL_AGENT_PORT = 3000
Expand Down Expand Up @@ -65,7 +66,7 @@ export const addComposeTunnelAgentService = (
knownServerPublicKeyPath: string
debug: boolean
user?: string
envId: string
envId: EnvId
machineStatusCommand?: MachineStatusCommand
envMetadata: EnvMetadata
composeModelPath: string
Expand Down
16 changes: 11 additions & 5 deletions packages/core/src/env-id.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,14 @@ import { gitBranchName } from './git'
import { ComposeModel } from './compose'
import { Logger } from './log'

export type EnvId = string & {
__tag: 'EnvId'
}

export const normalize = (s: string) => s
.toLowerCase()
.replace(/[^a-z0-9_-]/g, '-')
.replace(/^[^a-z]/, firstChar => `a${firstChar}`) // prepend alpha char if first char is not alpha
.replace(/^[^a-z]/, firstChar => `a${firstChar}`) as EnvId // prepend alpha char if first char is not alpha

const envIdFromBranch = (branch: string) => normalize(branch)

Expand All @@ -28,9 +32,11 @@ const validateUserSpecifiedValue = (
if (normalize(value) !== value) {
throw new InvalidIdentifierError(value, fieldDescription)
}
return value
return value as EnvId
}

export const validateEnvId = (envId:string) => validateUserSpecifiedValue({ value: envId, fieldDescription: 'environment ID' })

const findAmbientEnvIdSuffix = async () => {
const ciProvider = detectCiProvider()
if (ciProvider) {
Expand Down Expand Up @@ -81,18 +87,18 @@ export const findEnvIdByProjectName = async ({ log, projectName, projectNameBase
].join(' and ')

log.info(`Using environment ID ${envId}, based on ${envIdBaseOn}`)
return envId
return envId as EnvId
}

export async function findEnvId({ log, userSpecifiedEnvId, userSpecifiedProjectName, userModel }: {
log: Logger
userSpecifiedEnvId: string | undefined
userSpecifiedProjectName: string | undefined
userModel: ComposeModel | (() => Promise<ComposeModel>)
}): Promise<string> {
}): Promise<EnvId> {
if (userSpecifiedEnvId) {
log.debug(`Using user specified environment ID ${userSpecifiedEnvId}`)
return validateUserSpecifiedValue({ value: userSpecifiedEnvId, fieldDescription: 'environment ID' })
return validateEnvId(userSpecifiedEnvId)
}

const { projectName, projectNameBasedOn } = userSpecifiedProjectName
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export { telemetryEmitter, registerEmitter, wireProcessExit, createTelemetryEmit
export { fsTypeFromUrl, Store, VirtualFS, localFsFromUrl } from './store'
export { localComposeClient, ComposeModel, resolveComposeFiles, getExposedTcpServicePorts, remoteUserModel, NoComposeFilesError } from './compose'
export { withSpinner } from './spinner'
export { findEnvId, findProjectName, findEnvIdByProjectName, normalize as normalizeEnvId } from './env-id'
export { findEnvId, findProjectName, findEnvIdByProjectName, validateEnvId, normalize as normalizeEnvId, EnvId } from './env-id'
export { sshKeysStore } from './state'
export { truncateWithHash, truncatePrefix, randomString, alphabets } from './strings'
export { connectSshClient, generateSshKeyPair, SshKeyPairType } from './ssh'
Expand Down

0 comments on commit 962db80

Please sign in to comment.