Skip to content

Commit

Permalink
fix(jobs): environments variables (#422)
Browse files Browse the repository at this point in the history
  • Loading branch information
RemiBonnet committed Dec 14, 2022
1 parent 046d9b2 commit dc3ecd4
Show file tree
Hide file tree
Showing 11 changed files with 112 additions and 33 deletions.
Expand Up @@ -97,6 +97,8 @@ export const createEnvironmentVariablePayloadCreator = async (payload: {

break
case APIVariableScopeEnum.APPLICATION:
case APIVariableScopeEnum.CONTAINER:
case APIVariableScopeEnum.JOB:
default:
if (isContainer(payload.serviceType)) {
response = await containerEnvironmentVariableApi.createContainerEnvironmentVariable(
Expand Down Expand Up @@ -151,6 +153,8 @@ export const createOverrideEnvironmentVariablesPayloadCreator = async (payload:
)
break
case APIVariableScopeEnum.APPLICATION:
case APIVariableScopeEnum.CONTAINER:
case APIVariableScopeEnum.JOB:
default:
if (isContainer(payload.serviceType)) {
response = await containerEnvironmentVariableApi.createContainerEnvironmentVariableOverride(
Expand Down Expand Up @@ -205,13 +209,21 @@ export const createAliasEnvironmentVariables = createAsyncThunk(
)
break
case APIVariableScopeEnum.APPLICATION:
case APIVariableScopeEnum.CONTAINER:
case APIVariableScopeEnum.JOB:
default:
if (isContainer(payload.serviceType)) {
response = await containerEnvironmentVariableApi.createContainerEnvironmentVariableAlias(
entityId,
environmentVariableId,
environmentVariableRequest
)
} else if (isJob(payload.serviceType)) {
response = await jobEnvironmentVariableApi.createJobEnvironmentVariableAlias(
entityId,
environmentVariableId,
environmentVariableRequest
)
} else {
response = await applicationEnvironmentVariableApi.createApplicationEnvironmentVariableAlias(
entityId,
Expand Down Expand Up @@ -254,13 +266,21 @@ export const editEnvironmentVariables = createAsyncThunk(

break
case APIVariableScopeEnum.APPLICATION:
case APIVariableScopeEnum.CONTAINER:
case APIVariableScopeEnum.JOB:
default:
if (isContainer(payload.serviceType)) {
response = await containerEnvironmentVariableApi.editContainerEnvironmentVariable(
payload.entityId,
payload.environmentVariableId,
payload.environmentVariableRequest
)
} else if (isJob(payload.serviceType)) {
response = await jobEnvironmentVariableApi.editJobEnvironmentVariable(
payload.entityId,
payload.environmentVariableId,
payload.environmentVariableRequest
)
} else {
response = await applicationEnvironmentVariableApi.editApplicationEnvironmentVariable(
payload.entityId,
Expand Down Expand Up @@ -299,12 +319,19 @@ export const deleteEnvironmentVariable = createAsyncThunk(

break
case APIVariableScopeEnum.APPLICATION:
case APIVariableScopeEnum.CONTAINER:
case APIVariableScopeEnum.JOB:
default:
if (isContainer(payload.serviceType)) {
response = await containerEnvironmentVariableApi.deleteContainerEnvironmentVariable(
payload.entityId,
payload.environmentVariableId
)
} else if (isJob(payload.serviceType)) {
response = await jobEnvironmentVariableApi.deleteJobEnvironmentVariable(
payload.entityId,
payload.environmentVariableId
)
} else {
response = await applicationEnvironmentVariableApi.deleteApplicationEnvironmentVariable(
payload.entityId,
Expand Down
Expand Up @@ -5,11 +5,12 @@ import {
ContainerSecretApi,
EnvironmentSecretApi,
EnvironmentVariableRequest,
JobSecretApi,
ProjectSecretApi,
Value,
} from 'qovery-typescript-axios'
import { Key } from 'qovery-typescript-axios/api'
import { ServiceTypeEnum, isContainer } from '@qovery/shared/enums'
import { ServiceTypeEnum, isContainer, isJob } from '@qovery/shared/enums'
import { SecretEnvironmentVariableEntity, SecretEnvironmentVariablesState } from '@qovery/shared/interfaces'
import { ToastEnum, toast, toastError } from '@qovery/shared/toast'
import { addOneToManyRelation, getEntitiesByIds } from '@qovery/shared/utils'
Expand All @@ -21,6 +22,7 @@ export const secretEnvironmentVariablesAdapter = createEntityAdapter<SecretEnvir

const applicationSecretApi = new ApplicationSecretApi()
const containerSecretApi = new ContainerSecretApi()
const jobSecretApi = new JobSecretApi()
const environmentSecretApi = new EnvironmentSecretApi()
const projectSecretApi = new ProjectSecretApi()

Expand Down Expand Up @@ -61,12 +63,16 @@ export const createSecret = createAsyncThunk(

break
case APIVariableScopeEnum.APPLICATION:
case APIVariableScopeEnum.CONTAINER:
case APIVariableScopeEnum.JOB:
default:
if (isContainer(payload.serviceType)) {
response = await containerSecretApi.createContainerSecret(
payload.entityId,
payload.environmentVariableRequest
)
} else if (isJob(payload.serviceType)) {
response = await jobSecretApi.createJobSecret(payload.entityId, payload.environmentVariableRequest)
} else {
response = await applicationSecretApi.createApplicationSecret(
payload.entityId,
Expand Down Expand Up @@ -108,13 +114,21 @@ export const createOverrideSecret = createAsyncThunk(
)
break
case APIVariableScopeEnum.APPLICATION:
case APIVariableScopeEnum.CONTAINER:
case APIVariableScopeEnum.JOB:
default:
if (isContainer(payload.serviceType)) {
response = await containerSecretApi.createContainerSecretOverride(
entityId,
environmentVariableId,
environmentVariableRequest
)
} else if (isJob(payload.serviceType)) {
response = await jobSecretApi.createJobSecretOverride(
entityId,
environmentVariableId,
environmentVariableRequest
)
} else {
response = await applicationSecretApi.createApplicationSecretOverride(
entityId,
Expand Down Expand Up @@ -158,13 +172,21 @@ export const createAliasSecret = createAsyncThunk(
)
break
case APIVariableScopeEnum.APPLICATION:
case APIVariableScopeEnum.CONTAINER:
case APIVariableScopeEnum.JOB:
default:
if (isContainer(payload.serviceType)) {
response = await containerSecretApi.createContainerSecretAlias(
entityId,
environmentVariableId,
environmentVariableRequest
)
} else if (isJob(payload.serviceType)) {
response = await jobSecretApi.createJobSecretAlias(
entityId,
environmentVariableId,
environmentVariableRequest
)
} else {
response = await applicationSecretApi.createApplicationSecretAlias(
entityId,
Expand Down Expand Up @@ -207,13 +229,21 @@ export const editSecret = createAsyncThunk(

break
case APIVariableScopeEnum.APPLICATION:
case APIVariableScopeEnum.CONTAINER:
case APIVariableScopeEnum.JOB:
default:
if (isContainer(payload.serviceType)) {
response = await containerSecretApi.editContainerSecret(
payload.entityId,
payload.environmentVariableId,
payload.environmentVariableRequest
)
} else if (isJob(payload.serviceType)) {
response = await jobSecretApi.editJobSecret(
payload.entityId,
payload.environmentVariableId,
payload.environmentVariableRequest
)
} else {
response = await applicationSecretApi.editApplicationSecret(
payload.entityId,
Expand Down Expand Up @@ -246,9 +276,13 @@ export const deleteSecret = createAsyncThunk(

break
case APIVariableScopeEnum.APPLICATION:
case APIVariableScopeEnum.CONTAINER:
case APIVariableScopeEnum.JOB:
default:
if (isContainer(payload.serviceType)) {
response = await containerSecretApi.deleteContainerSecret(payload.entityId, payload.environmentVariableId)
} else if (isJob(payload.serviceType)) {
response = await jobSecretApi.deleteJobSecret(payload.entityId, payload.environmentVariableId)
} else {
response = await applicationSecretApi.deleteApplicationSecret(payload.entityId, payload.environmentVariableId)
}
Expand Down
Expand Up @@ -121,7 +121,7 @@ export function CrudEnvironmentVariableModalFeature(props: CrudEnvironmentVariab
onSubmit={onSubmit}
closeModal={props.closeModal}
type={props.type}
availableScopes={computeAvailableScope(variable?.scope)}
availableScopes={computeAvailableScope(variable?.scope, false, props.serviceType)}
loading={loading}
/>
</FormProvider>
Expand Down
Expand Up @@ -116,6 +116,7 @@ export function ImportEnvironmentVariableModalFeature(props: ImportEnvironmentVa
}}
overwriteEnabled={overwriteEnabled}
setOverwriteEnabled={setOverwriteEnabled}
serviceType={props.serviceType}
/>
</FormProvider>
)
Expand Down
@@ -1,18 +1,20 @@
import { APIVariableScopeEnum } from 'qovery-typescript-axios'
import { ServiceTypeEnum } from '@qovery/shared/enums'
import { EnvironmentVariableSecretOrPublic } from '@qovery/shared/interfaces'
import { getScopeHierarchy } from '../../../utils/compute-available-environment-variable-scope'

export const validateKey = (
value: string,
existingVars: EnvironmentVariableSecretOrPublic[],
currentScope: APIVariableScopeEnum
currentScope: APIVariableScopeEnum,
serviceType?: ServiceTypeEnum
): string | boolean => {
if (value.toLowerCase().startsWith('qovery')) {
return 'Variable name cannot begin with "QOVERY"'
}

const existingVar = existingVars.find((envVar) => envVar.key === value)
if (existingVar && getScopeHierarchy(existingVar.scope) > getScopeHierarchy(currentScope)) {
if (existingVar && getScopeHierarchy(existingVar.scope, serviceType) > getScopeHierarchy(currentScope, serviceType)) {
return 'This variable name already exists on a lower scope'
}

Expand All @@ -23,11 +25,12 @@ export const warningMessage = (
value: string,
existingVars: EnvironmentVariableSecretOrPublic[],
currentScope: APIVariableScopeEnum,
overwriteEnabled = false
overwriteEnabled = false,
serviceType?: ServiceTypeEnum
): string | undefined => {
const existingVar = existingVars.find((envVar) => envVar.key === value)

if (existingVar && getScopeHierarchy(currentScope) > getScopeHierarchy(existingVar.scope)) {
if (existingVar && getScopeHierarchy(currentScope, serviceType) > getScopeHierarchy(existingVar.scope, serviceType)) {
return 'This variable name already exists on a higher scope. An override will be created.'
}

Expand Down
Expand Up @@ -72,7 +72,7 @@ export function CrudEnvironmentVariableModal(props: CrudEnvironmentVariableModal
rules={{
required: 'Please select a value.',
}}
render={({ field, fieldState: { error } }) => (
render={({ field }) => (
<InputSelect
className="mb-6"
portal
Expand Down
@@ -1,6 +1,7 @@
import { APIVariableScopeEnum } from 'qovery-typescript-axios'
import { DropzoneRootProps } from 'react-dropzone'
import { Controller, useFormContext } from 'react-hook-form'
import { ServiceTypeEnum } from '@qovery/shared/enums'
import { EnvironmentVariableSecretOrPublic } from '@qovery/shared/interfaces'
import {
Button,
Expand Down Expand Up @@ -34,6 +35,7 @@ export interface ImportEnvironmentVariableModalProps {
deleteKey: (key: string) => void
overwriteEnabled: boolean
setOverwriteEnabled: (b: boolean) => void
serviceType?: ServiceTypeEnum
}

export function ImportEnvironmentVariableModal(props: ImportEnvironmentVariableModalProps) {
Expand Down Expand Up @@ -158,7 +160,7 @@ export function ImportEnvironmentVariableModal(props: ImportEnvironmentVariableM
<Controller
name={key + '_scope'}
control={control}
render={({ field, fieldState: { error } }) => (
render={({ field }) => (
<InputSelectSmall
data-testid="scope"
className="w-[188px]"
Expand Down
@@ -1,9 +1,7 @@
import { APIVariableScopeEnum } from 'qovery-typescript-axios'
import { ServiceTypeEnum, isContainer, isJob } from '@qovery/shared/enums'

const environmentScopes: {
name: APIVariableScopeEnum
hierarchy: number
}[] = [
const environmentScopes = (serviceType?: ServiceTypeEnum) => [
{
name: APIVariableScopeEnum.BUILT_IN,
hierarchy: -1,
Expand All @@ -17,14 +15,19 @@ const environmentScopes: {
hierarchy: 2,
},
{
name: APIVariableScopeEnum.APPLICATION,
name: isJob(serviceType)
? APIVariableScopeEnum.JOB
: isContainer(serviceType)
? APIVariableScopeEnum.CONTAINER
: APIVariableScopeEnum.APPLICATION,
hierarchy: 3,
},
]

export const computeAvailableScope = (
scope?: APIVariableScopeEnum,
includeBuiltIn?: boolean
includeBuiltIn?: boolean,
serviceType?: ServiceTypeEnum
): APIVariableScopeEnum[] => {
if (!scope) {
const scopeToReturn = []
Expand All @@ -37,23 +40,27 @@ export const computeAvailableScope = (
...scopeToReturn,
APIVariableScopeEnum.PROJECT,
APIVariableScopeEnum.ENVIRONMENT,
APIVariableScopeEnum.APPLICATION,
isJob(serviceType)
? APIVariableScopeEnum.JOB
: isContainer(serviceType)
? APIVariableScopeEnum.CONTAINER
: APIVariableScopeEnum.APPLICATION,
]
}

const theScope = environmentScopes.find((s) => s.name === scope)
const theScope = environmentScopes(serviceType).find((s) => s.name === scope)

return environmentScopes
return environmentScopes(serviceType)
.filter((scope) => {
return scope.hierarchy >= (theScope?.hierarchy || -1) && scope.hierarchy >= 0
})
.map((scope) => scope.name)
}

export function getScopeHierarchy(scope?: APIVariableScopeEnum): number {
export function getScopeHierarchy(scope?: APIVariableScopeEnum, serviceType?: ServiceTypeEnum): number {
if (!scope) return -1

const hierarchy = environmentScopes.find((s) => s.name === scope)?.hierarchy
const hierarchy = environmentScopes(serviceType).find((s) => s.name === scope)?.hierarchy

return hierarchy || -1
}
Expand Up @@ -4,7 +4,13 @@ import { useNavigate, useParams } from 'react-router-dom'
import { Link } from 'react-router-dom'
import { ServiceTypeEnum } from '@qovery/shared/enums'
import { ContainerApplicationEntity, DeploymentService } from '@qovery/shared/interfaces'
import { APPLICATION_GENERAL_URL, APPLICATION_URL, DEPLOYMENT_LOGS_URL } from '@qovery/shared/router'
import {
APPLICATION_GENERAL_URL,
APPLICATION_URL,
DATABASE_GENERAL_URL,
DATABASE_URL,
DEPLOYMENT_LOGS_URL,
} from '@qovery/shared/router'
import {
ButtonIconAction,
IconAwesomeEnum,
Expand Down Expand Up @@ -122,7 +128,13 @@ export function TableRowDeployment(props: TableRowDeploymentProps) {
{(data as DeploymentService).type && (
<div className="px-3">
<Skeleton show={isLoading} width={120} height={20}>
<Link to={APPLICATION_URL(organizationId, projectId, environmentId, data?.id) + APPLICATION_GENERAL_URL}>
<Link
to={
(data as DeploymentService)?.type === ServiceTypeEnum.DATABASE
? `${DATABASE_URL(organizationId, projectId, environmentId, data?.id) + DATABASE_GENERAL_URL}`
: `${APPLICATION_URL(organizationId, projectId, environmentId, data?.id) + APPLICATION_GENERAL_URL}`
}
>
<div className="flex items-center">
<div className="w-8 text-center">
<Icon name={(data as DeploymentService)?.type || ServiceTypeEnum.APPLICATION} className="w-5 h-5" />
Expand Down
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -53,7 +53,7 @@
"msw": "^0.42.1",
"postcss": "8.4.16",
"posthog-js": "^1.24.0",
"qovery-typescript-axios": "^1.1.53",
"qovery-typescript-axios": "^1.1.54",
"react": "18.2.0",
"react-beautiful-dnd": "^13.1.0",
"react-dom": "18.2.0",
Expand Down

0 comments on commit dc3ecd4

Please sign in to comment.