From 8ab86e75f2dbe79825c00bb4f32ad8f8e01ca329 Mon Sep 17 00:00:00 2001 From: Bence Date: Mon, 2 Dec 2024 10:35:41 +0100 Subject: [PATCH 01/13] fix: agent update image (#1017) --- web/crux/src/config/app.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web/crux/src/config/app.config.ts b/web/crux/src/config/app.config.ts index 5816e5a36..0a64960bc 100644 --- a/web/crux/src/config/app.config.ts +++ b/web/crux/src/config/app.config.ts @@ -26,7 +26,7 @@ const configSchema = yup.object({ ENCRYPTION_DEPRECATED_KEY: encryptionKeyRule.optional(), CRUX_AGENT_ADDRESS: yup.string().required(), - CRUX_AGENT_IMAGE: yup.string().default('latest').required(), + CRUX_AGENT_IMAGE: yup.string(), AGENT_INSTALL_SCRIPT_DISABLE_PULL: yup.bool().default(false).required(), LOG_LEVEL: yup.string().oneOf(LOG_LEVEL_VALUES).required(), From a2482b8532b0ce549ce5cfba258352694e83c339 Mon Sep 17 00:00:00 2001 From: Mate Vago Date: Tue, 3 Dec 2024 12:15:01 +0100 Subject: [PATCH 02/13] Revert "fix: deploy bug & separate config schema" This reverts commit c5f654f67193f107c61f9a81bff0c2103d6ff739. --- .../edit-container-config-card.tsx | 4 +-- .../container-configurations/[configId].tsx | 14 +++++++-- web/crux-ui/src/validations/container.ts | 29 +++++++------------ web/crux-ui/src/validations/deployment.ts | 4 +-- web/crux-ui/src/validations/image.ts | 4 +-- web/crux-ui/src/validations/index.ts | 1 + web/crux-ui/src/validations/instance.ts | 12 ++++++++ web/crux/src/app/image/image.service.ts | 7 +---- web/crux/src/domain/start-deployment.ts | 4 --- 9 files changed, 42 insertions(+), 37 deletions(-) create mode 100644 web/crux-ui/src/validations/instance.ts diff --git a/web/crux-ui/src/components/container-configs/edit-container-config-card.tsx b/web/crux-ui/src/components/container-configs/edit-container-config-card.tsx index 8771e2563..3564fde5e 100644 --- a/web/crux-ui/src/components/container-configs/edit-container-config-card.tsx +++ b/web/crux-ui/src/components/container-configs/edit-container-config-card.tsx @@ -10,7 +10,7 @@ import DyoMessage from '@app/elements/dyo-message' import { DyoConfirmationModal } from '@app/elements/dyo-modal' import useConfirmation from '@app/hooks/use-confirmation' import { ContainerConfig, ContainerConfigParent, VersionImage } from '@app/models' -import { createConfigSchema, getValidationError } from '@app/validations' +import { createContainerConfigSchema, getValidationError } from '@app/validations' import useTranslation from 'next-translate/useTranslation' import { QA_DIALOG_LABEL_DELETE_IMAGE } from 'quality-assurance' import ContainerConfigJsonEditor from './container-config-json-editor' @@ -74,7 +74,7 @@ const EditContainerConfigCard = (props: Ed const errorMessage = state.parseError ?? - getValidationError(createConfigSchema("image", image?.labels ?? {}), state.config, null, t)?.message + getValidationError(createContainerConfigSchema(image?.labels ?? {}), state.config, null, t)?.message return ( <> diff --git a/web/crux-ui/src/pages/[teamSlug]/container-configurations/[configId].tsx b/web/crux-ui/src/pages/[teamSlug]/container-configurations/[configId].tsx index dae84c7e1..ac1fad5f2 100644 --- a/web/crux-ui/src/pages/[teamSlug]/container-configurations/[configId].tsx +++ b/web/crux-ui/src/pages/[teamSlug]/container-configurations/[configId].tsx @@ -50,8 +50,8 @@ import { TeamRoutes } from '@app/routes' import { withContextAuthorization } from '@app/utils' import { ContainerConfigValidationErrors, - createConfigSchema, - getConfigFieldErrorsForSchema, + getConcreteContainerConfigFieldErrors, + getContainerConfigFieldErrors, jsonErrorOf, } from '@app/validations' import { WsMessage } from '@app/websockets/common' @@ -134,7 +134,15 @@ const getConfigErrors = ( config: ContainerConfigDetails, imageLabels: Record, t: Translate, -): ContainerConfigValidationErrors => getConfigFieldErrorsForSchema(createConfigSchema(config.type, imageLabels), config, t) +): ContainerConfigValidationErrors => { + const type = containerConfigTypeToSectionType(config.type) + + if (type === 'concrete') { + return getConcreteContainerConfigFieldErrors(config as ConcreteContainerConfigData, imageLabels, t) + } + + return getContainerConfigFieldErrors(config, imageLabels, t) +} const getBaseConfig = (config: ContainerConfigDetails, relations: ContainerConfigRelations): ContainerConfigData => { switch (config.type) { diff --git a/web/crux-ui/src/validations/container.ts b/web/crux-ui/src/validations/container.ts index ea89de8cd..4cf4f6f3d 100644 --- a/web/crux-ui/src/validations/container.ts +++ b/web/crux-ui/src/validations/container.ts @@ -18,7 +18,6 @@ import { Metrics, UniqueKeyValue, VolumeType, - ContainerConfigType, } from '@app/models' import * as yup from 'yup' import { matchNoLeadingOrTrailingWhitespaces, matchNoWhitespace } from './common' @@ -500,11 +499,9 @@ const testEnvironment = (imageLabels: Record) => (arr: UniqueKey return true } -const createContainerConfigBaseSchema = (imageLabels: Record, nameRequired: boolean, secretsHaveValue: boolean) => +const createContainerConfigBaseSchema = (imageLabels: Record) => yup.object().shape({ - name: matchContainerName(nameRequired - ? yup.string().required().label('container:common.containerName') - : yup.string().optional().nullable().label('container:common.containerName')), + name: matchContainerName(yup.string().required().label('container:common.containerName')), environment: uniqueKeyValuesSchema .default(null) .nullable() @@ -525,7 +522,6 @@ const createContainerConfigBaseSchema = (imageLabels: Record, na initContainers: initContainerRule, capabilities: uniqueKeyValuesSchema.default(null).nullable().optional().label('container:common.capabilities'), storage: storageRule, - secrets: (secretsHaveValue ? uniqueKeyValuesSchema : uniqueKeySchema).default(null).nullable().optional().label('container:common.secrets'), // dagent: logConfig: logConfigRule, @@ -552,15 +548,12 @@ const createContainerConfigBaseSchema = (imageLabels: Record, na metrics: metricsRule, }) -export const createConfigSchema = (type: ContainerConfigType, imageLabels: Record) => { - /** - * image/instance should require a container name - * bundle/deployment should not - * - * config bundles should also be able to store secret values (no agent key though...) - */ - - const nameRequired = (type === "image" || type === "instance") - const secretsHaveValue = (type === "image" || type === "deployment") - return createContainerConfigBaseSchema(imageLabels, nameRequired, secretsHaveValue) -} +export const createContainerConfigSchema = (imageLabels: Record) => + createContainerConfigBaseSchema(imageLabels).shape({ + secrets: uniqueKeySchema.default(null).nullable().optional().label('container:common.secrets'), + }) + +export const createConcreteContainerConfigSchema = (imageLabels: Record) => + createContainerConfigBaseSchema(imageLabels).shape({ + secrets: uniqueKeyValuesSchema.default(null).nullable().optional().label('container:common.secrets'), + }) diff --git a/web/crux-ui/src/validations/deployment.ts b/web/crux-ui/src/validations/deployment.ts index 99f14cbdd..88f9eeca7 100644 --- a/web/crux-ui/src/validations/deployment.ts +++ b/web/crux-ui/src/validations/deployment.ts @@ -1,6 +1,6 @@ import yup from './yup' import { nameRule } from './common' -import { createConfigSchema, uniqueKeyValuesSchema } from './container' +import { createConcreteContainerConfigSchema, uniqueKeyValuesSchema } from './container' export const prefixRule = yup .string() @@ -41,7 +41,7 @@ export const startDeploymentSchema = yup.object({ instances: yup .array( yup.object().shape({ - config: createConfigSchema("instance", null), + config: createConcreteContainerConfigSchema(null), }), ) .ensure() diff --git a/web/crux-ui/src/validations/image.ts b/web/crux-ui/src/validations/image.ts index f2898368c..1acd108e2 100644 --- a/web/crux-ui/src/validations/image.ts +++ b/web/crux-ui/src/validations/image.ts @@ -1,8 +1,8 @@ import { ContainerConfigData } from '@app/models' import yup from './yup' import { ErrorWithPath, getValidationError } from './common' +import { createContainerConfigSchema } from './container' import { Translate } from 'next-translate' -import { createConfigSchema } from './container' export type ContainerConfigValidationErrors = Record @@ -23,7 +23,7 @@ export const getContainerConfigFieldErrors = ( imageLabels: Record, t: Translate, ): ContainerConfigValidationErrors => - getConfigFieldErrorsForSchema(createConfigSchema("image", imageLabels), newConfig, t) + getConfigFieldErrorsForSchema(createContainerConfigSchema(imageLabels), newConfig, t) export const jsonErrorOf = (fieldErrors: ContainerConfigValidationErrors) => { const entries = Object.entries(fieldErrors) diff --git a/web/crux-ui/src/validations/index.ts b/web/crux-ui/src/validations/index.ts index 0f2a2ccfe..3bc7b0beb 100644 --- a/web/crux-ui/src/validations/index.ts +++ b/web/crux-ui/src/validations/index.ts @@ -4,6 +4,7 @@ export * from './config-bundle' export * from './container' export * from './deployment' export * from './image' +export * from './instance' export * from './node' export * from './notification' export * from './pipeline' diff --git a/web/crux-ui/src/validations/instance.ts b/web/crux-ui/src/validations/instance.ts new file mode 100644 index 000000000..e4f038f64 --- /dev/null +++ b/web/crux-ui/src/validations/instance.ts @@ -0,0 +1,12 @@ +import { ConcreteContainerConfigData } from '@app/models' +import { Translate } from 'next-translate' +import { getConfigFieldErrorsForSchema, ContainerConfigValidationErrors } from './image' +import { createConcreteContainerConfigSchema } from './container' + +// eslint-disable-next-line import/prefer-default-export +export const getConcreteContainerConfigFieldErrors = ( + newConfig: ConcreteContainerConfigData, + validation: Record, + t: Translate, +): ContainerConfigValidationErrors => + getConfigFieldErrorsForSchema(createConcreteContainerConfigSchema(validation), newConfig, t) diff --git a/web/crux/src/app/image/image.service.ts b/web/crux/src/app/image/image.service.ts index 10dbb9399..f658356a7 100644 --- a/web/crux/src/app/image/image.service.ts +++ b/web/crux/src/app/image/image.service.ts @@ -122,12 +122,7 @@ export default class ImageService { data: { registry: { connect: { id: registyImages.registryId } }, version: { connect: { id: versionId } }, - config: { - create: { - type: 'image', - name: imageName, - } - }, + config: { create: { type: 'image' } }, createdBy: identity.id, name: imageName, tag: imageTag, diff --git a/web/crux/src/domain/start-deployment.ts b/web/crux/src/domain/start-deployment.ts index af52b93f3..259df810e 100644 --- a/web/crux/src/domain/start-deployment.ts +++ b/web/crux/src/domain/start-deployment.ts @@ -137,10 +137,6 @@ export const mergePrefixNeighborSecrets = ( deployments .sort((one, other) => other.createdAt.getTime() - one.createdAt.getTime()) .forEach(depl => { - if (!depl.config.secrets) { - return - } - const secrets = depl.config.secrets as UniqueSecretKeyValue[] secrets.forEach(it => { if (it.publicKey !== publicKey) { From a780d10464cd6a6e153392352d2977202c45a8d9 Mon Sep 17 00:00:00 2001 From: Mate Vago Date: Tue, 3 Dec 2024 12:16:44 +0100 Subject: [PATCH 03/13] fix: deployment null secrets --- web/crux/src/domain/start-deployment.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/web/crux/src/domain/start-deployment.ts b/web/crux/src/domain/start-deployment.ts index 259df810e..af52b93f3 100644 --- a/web/crux/src/domain/start-deployment.ts +++ b/web/crux/src/domain/start-deployment.ts @@ -137,6 +137,10 @@ export const mergePrefixNeighborSecrets = ( deployments .sort((one, other) => other.createdAt.getTime() - one.createdAt.getTime()) .forEach(depl => { + if (!depl.config.secrets) { + return + } + const secrets = depl.config.secrets as UniqueSecretKeyValue[] secrets.forEach(it => { if (it.publicKey !== publicKey) { From a942ad017c2d8814dcde6d808a15eeb2f40fdbb8 Mon Sep 17 00:00:00 2001 From: Mate Vago Date: Tue, 3 Dec 2024 14:15:01 +0100 Subject: [PATCH 04/13] fix: config bundle e2e --- web/crux-ui/e2e/utils/config-bundle.ts | 2 +- web/crux-ui/e2e/with-login/config-bundle.spec.ts | 6 ++++-- web/crux-ui/src/routes.ts | 2 -- web/crux-ui/src/validations/container.ts | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/web/crux-ui/e2e/utils/config-bundle.ts b/web/crux-ui/e2e/utils/config-bundle.ts index 571fd2549..99b4f9851 100644 --- a/web/crux-ui/e2e/utils/config-bundle.ts +++ b/web/crux-ui/e2e/utils/config-bundle.ts @@ -31,7 +31,7 @@ export const createConfigBundle = async (page: Page, name: string, data: Record< const configId = page.url().split('/').pop() const ws = await sock - const wsRoute = TEAM_ROUTES.configBundle.detailsSocket(configId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(configId) await page.locator('button:has-text("Environment")').click() diff --git a/web/crux-ui/e2e/with-login/config-bundle.spec.ts b/web/crux-ui/e2e/with-login/config-bundle.spec.ts index 4c89a69c5..62751d66d 100644 --- a/web/crux-ui/e2e/with-login/config-bundle.spec.ts +++ b/web/crux-ui/e2e/with-login/config-bundle.spec.ts @@ -13,12 +13,14 @@ test('Creating a config bundle', async ({ page }) => { }) await page.goto(TEAM_ROUTES.configBundle.details(configBundleId)) + await page.waitForSelector(`h3:text-is("${BUNDLE_NAME}")`) + + await page.locator('button:has-text("Config")').click() + await page.waitForURL(TEAM_ROUTES.containerConfig.details('**')) const keyInput = page.locator('input[placeholder="Key"]').first() - await expect(keyInput).toBeDisabled() await expect(keyInput).toHaveValue(ENV_KEY) const valueInput = page.locator('input[placeholder="Value"]').first() - await expect(valueInput).toBeDisabled() await expect(valueInput).toHaveValue(ENV_VALUE) }) diff --git a/web/crux-ui/src/routes.ts b/web/crux-ui/src/routes.ts index 99b505fc3..61f2e8a0f 100644 --- a/web/crux-ui/src/routes.ts +++ b/web/crux-ui/src/routes.ts @@ -699,8 +699,6 @@ class ConfigBundleRoutes { list = (options?: ListRouteOptions) => appendAnchorWhenDeclared(this.root, ANCHOR_NEW, options?.new) details = (id: string) => `${this.root}/${id}` - - detailsSocket = (id: string) => this.details(id) } export class PackageApi { diff --git a/web/crux-ui/src/validations/container.ts b/web/crux-ui/src/validations/container.ts index 4cf4f6f3d..5abd0e91c 100644 --- a/web/crux-ui/src/validations/container.ts +++ b/web/crux-ui/src/validations/container.ts @@ -501,7 +501,7 @@ const testEnvironment = (imageLabels: Record) => (arr: UniqueKey const createContainerConfigBaseSchema = (imageLabels: Record) => yup.object().shape({ - name: matchContainerName(yup.string().required().label('container:common.containerName')), + name: matchContainerName(yup.string().nullable().optional().label('container:common.containerName')), environment: uniqueKeyValuesSchema .default(null) .nullable() From 0b3741043636ea2494eeda6695a41fca98bd24e5 Mon Sep 17 00:00:00 2001 From: Mate Vago Date: Tue, 3 Dec 2024 14:43:13 +0100 Subject: [PATCH 05/13] fix: golang unit tests --- golang/internal/mapper/grpc_test.go | 37 +-- protobuf/go/agent/agent.pb.go | 270 +++++++++++----------- protobuf/proto/agent.proto | 15 +- web/crux/proto/agent.proto | 15 +- web/crux/src/app/deploy/deploy.service.ts | 1 - web/crux/src/grpc/protobuf/proto/agent.ts | 5 +- 6 files changed, 156 insertions(+), 187 deletions(-) diff --git a/golang/internal/mapper/grpc_test.go b/golang/internal/mapper/grpc_test.go index c6531b5e8..08e8e57ae 100644 --- a/golang/internal/mapper/grpc_test.go +++ b/golang/internal/mapper/grpc_test.go @@ -67,17 +67,13 @@ func testExpectedCommon(req *agent.DeployWorkloadRequest) *v1.DeployImageRequest Password: "test-pass", }, InstanceConfig: v1.InstanceConfig{ - ContainerPreName: "test-prefix", - MountPath: "/path/to/mount", - Name: "test-prefix", - Environment: map[string]string{"Evn1": "Val1", "Env2": "Val2"}, - Registry: "", - RepositoryPreName: "repo-prefix", - SharedEnvironment: map[string]string{}, UseSharedEnvs: false, + Environment: map[string]string{}, + SharedEnvironment: map[string]string{}, + ContainerPreName: "", }, ContainerConfig: v1.ContainerConfig{ - ContainerPreName: "test-prefix", + ContainerPreName: "", Container: "test-common-config", Ports: []builder.PortBinding{{ExposedPort: 0x4d2, PortBinding: pointer.ToUint16(0x1a85)}}, PortRanges: []builder.PortRangeBinding{{Internal: builder.PortRange{From: 0x0, To: 0x18}, External: builder.PortRange{From: 0x40, To: 0x80}}}, @@ -153,7 +149,7 @@ func testExpectedCommon(req *agent.DeployWorkloadRequest) *v1.DeployImageRequest UseLoadBalancer: true, ExtraLBAnnotations: map[string]string{"annotation1": "value1"}, }, - RuntimeConfig: v1.Base64JSONBytes{0x6b, 0x65, 0x79, 0x31, 0x3d, 0x76, 0x61, 0x6c, 0x31, 0x2c, 0x6b, 0x65, 0x79, 0x32, 0x3d, 0x76, 0x61, 0x6c, 0x32}, // encoded string: a2V5MT12YWwxLGtleTI9dmFsMg== + RuntimeConfig: nil, Registry: req.Registry, ImageName: "test-image", Tag: "test-tag", @@ -212,22 +208,17 @@ func TestMapDockerContainerEventToContainerState(t *testing.T) { func testDeployRequest() *agent.DeployWorkloadRequest { registry := "https://my-registry.com" - runtimeCfg := "key1=val1,key2=val2" var uid int64 = 777 upLimit := "5Mi" - mntPath := "/path/to/mount" - repoPrefix := "repo-prefix" strategy := common.ExposeStrategy_EXPOSE_WITH_TLS b := true return &agent.DeployWorkloadRequest{ - Id: "testID", - ContainerName: "test-container", - ImageName: "test-image", - Tag: "test-tag", - Registry: ®istry, - RuntimeConfig: &runtimeCfg, - Dagent: testDagentConfig(), - Crane: testCraneConfig(), + Id: "testID", + ImageName: "test-image", + Tag: "test-tag", + Registry: ®istry, + Dagent: testDagentConfig(), + Crane: testCraneConfig(), Common: &agent.CommonContainerConfig{ Name: "test-common-config", Commands: []string{"make", "test"}, @@ -274,12 +265,6 @@ func testDeployRequest() *agent.DeployWorkloadRequest { Password: "test-pass", Url: "https://test-url.com", }, - InstanceConfig: &agent.InstanceConfig{ - Prefix: "test-prefix", - MountPath: &mntPath, - RepositoryPrefix: &repoPrefix, - Environment: map[string]string{"Evn1": "Val1", "Env2": "Val2"}, - }, } } diff --git a/protobuf/go/agent/agent.pb.go b/protobuf/go/agent/agent.pb.go index 819dd03c0..30837f2db 100644 --- a/protobuf/go/agent/agent.pb.go +++ b/protobuf/go/agent/agent.pb.go @@ -1865,16 +1865,15 @@ type DeployWorkloadRequest struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` - ContainerName string `protobuf:"bytes,2,opt,name=containerName,proto3" json:"containerName,omitempty"` + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // ContainerConfigs - Common *CommonContainerConfig `protobuf:"bytes,3,opt,name=common,proto3,oneof" json:"common,omitempty"` - Dagent *DagentContainerConfig `protobuf:"bytes,4,opt,name=dagent,proto3,oneof" json:"dagent,omitempty"` - Crane *CraneContainerConfig `protobuf:"bytes,5,opt,name=crane,proto3,oneof" json:"crane,omitempty"` - Registry *string `protobuf:"bytes,6,opt,name=registry,proto3,oneof" json:"registry,omitempty"` - ImageName string `protobuf:"bytes,7,opt,name=imageName,proto3" json:"imageName,omitempty"` - Tag string `protobuf:"bytes,8,opt,name=tag,proto3" json:"tag,omitempty"` - RegistryAuth *RegistryAuth `protobuf:"bytes,9,opt,name=registryAuth,proto3,oneof" json:"registryAuth,omitempty"` + Common *CommonContainerConfig `protobuf:"bytes,2,opt,name=common,proto3,oneof" json:"common,omitempty"` + Dagent *DagentContainerConfig `protobuf:"bytes,3,opt,name=dagent,proto3,oneof" json:"dagent,omitempty"` + Crane *CraneContainerConfig `protobuf:"bytes,4,opt,name=crane,proto3,oneof" json:"crane,omitempty"` + Registry *string `protobuf:"bytes,5,opt,name=registry,proto3,oneof" json:"registry,omitempty"` + ImageName string `protobuf:"bytes,6,opt,name=imageName,proto3" json:"imageName,omitempty"` + Tag string `protobuf:"bytes,7,opt,name=tag,proto3" json:"tag,omitempty"` + RegistryAuth *RegistryAuth `protobuf:"bytes,8,opt,name=registryAuth,proto3,oneof" json:"registryAuth,omitempty"` } func (x *DeployWorkloadRequest) Reset() { @@ -1916,13 +1915,6 @@ func (x *DeployWorkloadRequest) GetId() string { return "" } -func (x *DeployWorkloadRequest) GetContainerName() string { - if x != nil { - return x.ContainerName - } - return "" -} - func (x *DeployWorkloadRequest) GetCommon() *CommonContainerConfig { if x != nil { return x.Common @@ -2834,133 +2826,131 @@ var file_protobuf_proto_agent_proto_rawDesc = []byte{ 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x42, 0x07, 0x0a, 0x05, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x42, 0x06, 0x0a, 0x04, 0x5f, 0x54, 0x54, 0x59, 0x42, 0x13, 0x0a, 0x11, 0x5f, 0x77, 0x6f, 0x72, 0x6b, 0x69, 0x6e, 0x67, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, - 0x22, 0xc8, 0x03, 0x0a, 0x15, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x57, 0x6f, 0x72, 0x6b, 0x6c, + 0x22, 0xa2, 0x03, 0x0a, 0x15, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x57, 0x6f, 0x72, 0x6b, 0x6c, 0x6f, 0x61, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x24, 0x0a, 0x0d, 0x63, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0d, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, - 0x12, 0x39, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1c, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x43, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, - 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x39, 0x0a, 0x06, 0x64, - 0x61, 0x67, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x61, 0x67, - 0x65, 0x6e, 0x74, 0x2e, 0x44, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, - 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x01, 0x52, 0x06, 0x64, 0x61, 0x67, - 0x65, 0x6e, 0x74, 0x88, 0x01, 0x01, 0x12, 0x36, 0x0a, 0x05, 0x63, 0x72, 0x61, 0x6e, 0x65, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x43, 0x72, - 0x61, 0x6e, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x48, 0x02, 0x52, 0x05, 0x63, 0x72, 0x61, 0x6e, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1f, - 0x0a, 0x08, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, - 0x48, 0x03, 0x52, 0x08, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x88, 0x01, 0x01, 0x12, - 0x1c, 0x0a, 0x09, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x07, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x09, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, - 0x03, 0x74, 0x61, 0x67, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, - 0x3c, 0x0a, 0x0c, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x41, 0x75, 0x74, 0x68, 0x18, - 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x52, 0x65, - 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x41, 0x75, 0x74, 0x68, 0x48, 0x04, 0x52, 0x0c, 0x72, 0x65, - 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x41, 0x75, 0x74, 0x68, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, - 0x07, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x64, 0x61, 0x67, - 0x65, 0x6e, 0x74, 0x42, 0x08, 0x0a, 0x06, 0x5f, 0x63, 0x72, 0x61, 0x6e, 0x65, 0x42, 0x0b, 0x0a, - 0x09, 0x5f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x72, - 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x41, 0x75, 0x74, 0x68, 0x22, 0x6a, 0x0a, 0x15, 0x43, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, 0x0a, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x88, 0x01, - 0x01, 0x12, 0x1d, 0x0a, 0x07, 0x6f, 0x6e, 0x65, 0x53, 0x68, 0x6f, 0x74, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x08, 0x48, 0x01, 0x52, 0x07, 0x6f, 0x6e, 0x65, 0x53, 0x68, 0x6f, 0x74, 0x88, 0x01, 0x01, - 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x42, 0x0a, 0x0a, 0x08, 0x5f, - 0x6f, 0x6e, 0x65, 0x53, 0x68, 0x6f, 0x74, 0x22, 0x44, 0x0a, 0x16, 0x43, 0x6f, 0x6e, 0x74, 0x61, - 0x69, 0x6e, 0x65, 0x72, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, - 0x74, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x47, 0x0a, - 0x13, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4c, 0x65, - 0x67, 0x61, 0x63, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, - 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x6a, 0x73, 0x6f, 0x6e, 0x22, 0x64, 0x0a, 0x12, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, - 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x26, - 0x0a, 0x0e, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0e, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x53, - 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x2b, 0x0a, 0x13, - 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x28, 0x0a, 0x10, 0x41, 0x67, 0x65, - 0x6e, 0x74, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x14, 0x0a, - 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, - 0x72, 0x6f, 0x72, 0x22, 0x82, 0x01, 0x0a, 0x13, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x4c, 0x6f, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x09, 0x63, - 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x39, 0x0a, 0x06, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x61, 0x67, 0x65, + 0x6e, 0x74, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x00, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x39, 0x0a, 0x06, 0x64, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x44, 0x61, + 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x48, 0x01, 0x52, 0x06, 0x64, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x88, 0x01, 0x01, + 0x12, 0x36, 0x0a, 0x05, 0x63, 0x72, 0x61, 0x6e, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1b, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x43, 0x72, 0x61, 0x6e, 0x65, 0x43, 0x6f, 0x6e, + 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x48, 0x02, 0x52, 0x05, + 0x63, 0x72, 0x61, 0x6e, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1f, 0x0a, 0x08, 0x72, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x72, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x48, 0x03, 0x52, 0x08, 0x72, 0x65, + 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x88, 0x01, 0x01, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x6d, 0x61, + 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x69, 0x6d, + 0x61, 0x67, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x3c, 0x0a, 0x0c, 0x72, 0x65, 0x67, + 0x69, 0x73, 0x74, 0x72, 0x79, 0x41, 0x75, 0x74, 0x68, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x13, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, + 0x41, 0x75, 0x74, 0x68, 0x48, 0x04, 0x52, 0x0c, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, + 0x41, 0x75, 0x74, 0x68, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x64, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x42, 0x08, 0x0a, + 0x06, 0x5f, 0x63, 0x72, 0x61, 0x6e, 0x65, 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x72, 0x65, 0x67, 0x69, + 0x73, 0x74, 0x72, 0x79, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, + 0x79, 0x41, 0x75, 0x74, 0x68, 0x22, 0x6a, 0x0a, 0x15, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x1b, + 0x0a, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, + 0x52, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x88, 0x01, 0x01, 0x12, 0x1d, 0x0a, 0x07, 0x6f, + 0x6e, 0x65, 0x53, 0x68, 0x6f, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x48, 0x01, 0x52, 0x07, + 0x6f, 0x6e, 0x65, 0x53, 0x68, 0x6f, 0x74, 0x88, 0x01, 0x01, 0x42, 0x09, 0x0a, 0x07, 0x5f, 0x70, + 0x72, 0x65, 0x66, 0x69, 0x78, 0x42, 0x0a, 0x0a, 0x08, 0x5f, 0x6f, 0x6e, 0x65, 0x53, 0x68, 0x6f, + 0x74, 0x22, 0x44, 0x0a, 0x16, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x70, + 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x72, 0x65, + 0x66, 0x69, 0x78, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x47, 0x0a, 0x13, 0x44, 0x65, 0x70, 0x6c, 0x6f, + 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x12, 0x1c, + 0x0a, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, + 0x6a, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6a, 0x73, 0x6f, 0x6e, + 0x22, 0x64, 0x0a, 0x12, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x12, 0x26, 0x0a, 0x0e, 0x74, 0x69, 0x6d, 0x65, + 0x6f, 0x75, 0x74, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, + 0x52, 0x0e, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x53, 0x65, 0x63, 0x6f, 0x6e, 0x64, 0x73, + 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x2b, 0x0a, 0x13, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, + 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, + 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x22, 0x28, 0x0a, 0x10, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x41, 0x62, 0x6f, 0x72, + 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x82, 0x01, + 0x0a, 0x13, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4c, 0x6f, 0x67, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, + 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, + 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x09, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x69, 0x6e, 0x67, 0x12, 0x12, + 0x0a, 0x04, 0x74, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x74, 0x61, + 0x69, 0x6c, 0x22, 0x54, 0x0a, 0x17, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, + 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, + 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1b, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x09, 0x63, + 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x22, 0x44, 0x0a, 0x16, 0x43, 0x6c, 0x6f, 0x73, + 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x43, 0x6c, 0x6f, 0x73, 0x65, + 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x2a, 0x69, + 0x0a, 0x0b, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, + 0x18, 0x43, 0x4c, 0x4f, 0x53, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x53, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, + 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x43, + 0x4c, 0x4f, 0x53, 0x45, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x44, + 0x45, 0x53, 0x54, 0x52, 0x55, 0x43, 0x54, 0x10, 0x02, 0x12, 0x0c, 0x0a, 0x08, 0x53, 0x48, 0x55, + 0x54, 0x44, 0x4f, 0x57, 0x4e, 0x10, 0x03, 0x12, 0x10, 0x0a, 0x0c, 0x52, 0x45, 0x56, 0x4f, 0x4b, + 0x45, 0x5f, 0x54, 0x4f, 0x4b, 0x45, 0x4e, 0x10, 0x04, 0x32, 0x9c, 0x05, 0x0a, 0x05, 0x41, 0x67, + 0x65, 0x6e, 0x74, 0x12, 0x32, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x12, 0x10, + 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, + 0x1a, 0x13, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, + 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x30, 0x01, 0x12, 0x37, 0x0a, 0x0c, 0x43, 0x6f, 0x6d, 0x6d, 0x61, + 0x6e, 0x64, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x18, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, + 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x1a, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x12, 0x35, 0x0a, 0x0b, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, + 0x17, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x41, 0x62, 0x6f, + 0x72, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x1a, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x2d, 0x0a, 0x0d, 0x54, 0x6f, 0x6b, 0x65, 0x6e, + 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x64, 0x12, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x44, 0x0a, 0x10, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, + 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1f, 0x2e, 0x63, 0x6f, 0x6d, + 0x6d, 0x6f, 0x6e, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x0d, 0x2e, 0x63, 0x6f, + 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x28, 0x01, 0x12, 0x44, 0x0a, 0x0e, + 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x12, 0x21, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x65, 0x72, 0x52, 0x09, 0x63, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, - 0x69, 0x6e, 0x67, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x73, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x69, 0x6e, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x04, 0x74, 0x61, 0x69, 0x6c, 0x22, 0x54, 0x0a, 0x17, 0x43, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x12, 0x39, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, - 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, - 0x69, 0x65, 0x72, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x22, 0x44, - 0x0a, 0x16, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, - 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x12, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, - 0x2e, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x52, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x52, 0x06, 0x72, 0x65, - 0x61, 0x73, 0x6f, 0x6e, 0x2a, 0x69, 0x0a, 0x0b, 0x43, 0x6c, 0x6f, 0x73, 0x65, 0x52, 0x65, 0x61, - 0x73, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x18, 0x43, 0x4c, 0x4f, 0x53, 0x45, 0x5f, 0x52, 0x45, 0x41, - 0x53, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, - 0x00, 0x12, 0x09, 0x0a, 0x05, 0x43, 0x4c, 0x4f, 0x53, 0x45, 0x10, 0x01, 0x12, 0x11, 0x0a, 0x0d, - 0x53, 0x45, 0x4c, 0x46, 0x5f, 0x44, 0x45, 0x53, 0x54, 0x52, 0x55, 0x43, 0x54, 0x10, 0x02, 0x12, - 0x0c, 0x0a, 0x08, 0x53, 0x48, 0x55, 0x54, 0x44, 0x4f, 0x57, 0x4e, 0x10, 0x03, 0x12, 0x10, 0x0a, - 0x0c, 0x52, 0x45, 0x56, 0x4f, 0x4b, 0x45, 0x5f, 0x54, 0x4f, 0x4b, 0x45, 0x4e, 0x10, 0x04, 0x32, - 0x9c, 0x05, 0x0a, 0x05, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x12, 0x32, 0x0a, 0x07, 0x43, 0x6f, 0x6e, - 0x6e, 0x65, 0x63, 0x74, 0x12, 0x10, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x41, 0x67, 0x65, - 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x1a, 0x13, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x41, - 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x30, 0x01, 0x12, 0x37, 0x0a, - 0x0c, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x18, 0x2e, - 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x41, 0x67, 0x65, 0x6e, 0x74, 0x43, 0x6f, 0x6d, 0x6d, 0x61, - 0x6e, 0x64, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x1a, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, - 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x35, 0x0a, 0x0b, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x17, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x41, 0x67, - 0x65, 0x6e, 0x74, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x1a, 0x0d, - 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x2d, 0x0a, - 0x0d, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x64, 0x12, 0x0d, - 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0d, 0x2e, - 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x44, 0x0a, 0x10, - 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, - 0x12, 0x1f, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, - 0x6d, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, + 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, - 0x28, 0x01, 0x12, 0x44, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x12, 0x21, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x43, 0x6f, - 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x65, 0x4c, 0x69, 0x73, 0x74, - 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, - 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x28, 0x01, 0x12, 0x42, 0x0a, 0x12, 0x43, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4c, 0x6f, 0x67, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1b, - 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, - 0x72, 0x4c, 0x6f, 0x67, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x0d, 0x2e, 0x63, 0x6f, - 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x28, 0x01, 0x12, 0x38, 0x0a, 0x0a, - 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1b, 0x2e, 0x63, 0x6f, 0x6d, - 0x6d, 0x6f, 0x6e, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, - 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x30, 0x0a, 0x10, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, - 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x73, 0x12, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, - 0x6d, 0x6f, 0x6e, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, - 0x6f, 0x6e, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3f, 0x0a, 0x0c, 0x43, 0x6f, 0x6e, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4c, 0x6f, 0x67, 0x12, 0x20, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, - 0x6e, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4c, 0x6f, 0x67, 0x4c, 0x69, - 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, - 0x6d, 0x6f, 0x6e, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x43, 0x0a, 0x10, 0x43, 0x6f, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x12, 0x20, 0x2e, - 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, - 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, - 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42, 0x35, - 0x5a, 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x64, 0x79, 0x72, - 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2d, 0x69, 0x6f, 0x2f, 0x64, 0x79, 0x72, 0x65, 0x63, 0x74, 0x6f, - 0x72, 0x69, 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x67, 0x6f, 0x2f, - 0x61, 0x67, 0x65, 0x6e, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x28, 0x01, 0x12, 0x42, 0x0a, 0x12, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4c, + 0x6f, 0x67, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x1b, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, + 0x6e, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4c, 0x6f, 0x67, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x1a, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x45, + 0x6d, 0x70, 0x74, 0x79, 0x28, 0x01, 0x12, 0x38, 0x0a, 0x0a, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, + 0x4c, 0x69, 0x73, 0x74, 0x12, 0x1b, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x4c, 0x69, + 0x73, 0x74, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x1a, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x12, 0x30, 0x0a, 0x10, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, + 0x6e, 0x65, 0x72, 0x73, 0x12, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x1a, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x45, 0x6d, 0x70, + 0x74, 0x79, 0x12, 0x3f, 0x0a, 0x0c, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4c, + 0x6f, 0x67, 0x12, 0x20, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x43, 0x6f, 0x6e, 0x74, + 0x61, 0x69, 0x6e, 0x65, 0x72, 0x4c, 0x6f, 0x67, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x12, 0x43, 0x0a, 0x10, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, 0x74, 0x12, 0x20, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x6f, 0x6e, + 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x49, 0x6e, 0x73, 0x70, 0x65, 0x63, + 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x0d, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, + 0x6f, 0x6e, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42, 0x35, 0x5a, 0x33, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x64, 0x79, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x2d, + 0x69, 0x6f, 0x2f, 0x64, 0x79, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x69, 0x6f, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x67, 0x6f, 0x2f, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/protobuf/proto/agent.proto b/protobuf/proto/agent.proto index 8b6e43eb4..57d949f53 100644 --- a/protobuf/proto/agent.proto +++ b/protobuf/proto/agent.proto @@ -231,18 +231,17 @@ message CommonContainerConfig { message DeployWorkloadRequest { string id = 1; - string containerName = 2; /* ContainerConfigs */ - optional CommonContainerConfig common = 3; - optional DagentContainerConfig dagent = 4; - optional CraneContainerConfig crane = 5; + optional CommonContainerConfig common = 2; + optional DagentContainerConfig dagent = 3; + optional CraneContainerConfig crane = 4; - optional string registry = 6; - string imageName = 7; - string tag = 8; + optional string registry = 5; + string imageName = 6; + string tag = 7; - optional RegistryAuth registryAuth = 9; + optional RegistryAuth registryAuth = 8; } message ContainerStateRequest { diff --git a/web/crux/proto/agent.proto b/web/crux/proto/agent.proto index 8b6e43eb4..57d949f53 100644 --- a/web/crux/proto/agent.proto +++ b/web/crux/proto/agent.proto @@ -231,18 +231,17 @@ message CommonContainerConfig { message DeployWorkloadRequest { string id = 1; - string containerName = 2; /* ContainerConfigs */ - optional CommonContainerConfig common = 3; - optional DagentContainerConfig dagent = 4; - optional CraneContainerConfig crane = 5; + optional CommonContainerConfig common = 2; + optional DagentContainerConfig dagent = 3; + optional CraneContainerConfig crane = 4; - optional string registry = 6; - string imageName = 7; - string tag = 8; + optional string registry = 5; + string imageName = 6; + string tag = 7; - optional RegistryAuth registryAuth = 9; + optional RegistryAuth registryAuth = 8; } message ContainerStateRequest { diff --git a/web/crux/src/app/deploy/deploy.service.ts b/web/crux/src/app/deploy/deploy.service.ts index 920306862..b62910195 100644 --- a/web/crux/src/app/deploy/deploy.service.ts +++ b/web/crux/src/app/deploy/deploy.service.ts @@ -585,7 +585,6 @@ export default class DeployService { crane: this.mapper.craneConfigToAgentProto(config), dagent: this.mapper.dagentConfigToAgentProto(config), id: it.id, - containerName: it.image.config.name, imageName: it.image.name, tag: it.image.tag, registry: registryUrl, diff --git a/web/crux/src/grpc/protobuf/proto/agent.ts b/web/crux/src/grpc/protobuf/proto/agent.ts index b3ce694c6..30e29af90 100644 --- a/web/crux/src/grpc/protobuf/proto/agent.ts +++ b/web/crux/src/grpc/protobuf/proto/agent.ts @@ -328,7 +328,6 @@ export interface CommonContainerConfig_SecretsEntry { export interface DeployWorkloadRequest { id: string - containerName: string /** ContainerConfigs */ common?: CommonContainerConfig | undefined dagent?: DagentContainerConfig | undefined @@ -1336,14 +1335,13 @@ export const CommonContainerConfig_SecretsEntry = { } function createBaseDeployWorkloadRequest(): DeployWorkloadRequest { - return { id: '', containerName: '', imageName: '', tag: '' } + return { id: '', imageName: '', tag: '' } } export const DeployWorkloadRequest = { fromJSON(object: any): DeployWorkloadRequest { return { id: isSet(object.id) ? String(object.id) : '', - containerName: isSet(object.containerName) ? String(object.containerName) : '', common: isSet(object.common) ? CommonContainerConfig.fromJSON(object.common) : undefined, dagent: isSet(object.dagent) ? DagentContainerConfig.fromJSON(object.dagent) : undefined, crane: isSet(object.crane) ? CraneContainerConfig.fromJSON(object.crane) : undefined, @@ -1357,7 +1355,6 @@ export const DeployWorkloadRequest = { toJSON(message: DeployWorkloadRequest): unknown { const obj: any = {} message.id !== undefined && (obj.id = message.id) - message.containerName !== undefined && (obj.containerName = message.containerName) message.common !== undefined && (obj.common = message.common ? CommonContainerConfig.toJSON(message.common) : undefined) message.dagent !== undefined && From 885cbd1b80e6664dfdec12208f0eb91fe1b669b2 Mon Sep 17 00:00:00 2001 From: Mate Vago Date: Tue, 3 Dec 2024 15:37:37 +0100 Subject: [PATCH 06/13] fix: setting prefix and container name --- golang/pkg/dagent/utils/docker.go | 5 +++++ web/crux/src/domain/start-deployment.ts | 10 +++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/golang/pkg/dagent/utils/docker.go b/golang/pkg/dagent/utils/docker.go index d4c7743fb..a52e1a89d 100644 --- a/golang/pkg/dagent/utils/docker.go +++ b/golang/pkg/dagent/utils/docker.go @@ -561,6 +561,11 @@ func getContainerPrefix(deployImageRequest *v1.DeployImageRequest) string { containerPrefix = deployImageRequest.InstanceConfig.ContainerPreName } } + + if containerPrefix == "" { + containerPrefix = deployImageRequest.ContainerConfig.ContainerPreName + } + return containerPrefix } diff --git a/web/crux/src/domain/start-deployment.ts b/web/crux/src/domain/start-deployment.ts index af52b93f3..3334bc63c 100644 --- a/web/crux/src/domain/start-deployment.ts +++ b/web/crux/src/domain/start-deployment.ts @@ -97,6 +97,7 @@ export const deploymentConfigOf = (deployment: DeployableDeployment): ConcreteCo type DeployableInstance = { image: { config: ContainerConfig + name: string } config: ContainerConfig } @@ -121,7 +122,14 @@ export const instanceConfigOf = ( // then we merge and override the rest with the instance config const instanceConfig = instance.config as any as ConcreteContainerConfigData - return mergeInstanceConfigWithDeploymentConfig(mergedDeploymentConfig, instanceConfig) + const result = mergeInstanceConfigWithDeploymentConfig(mergedDeploymentConfig, instanceConfig) + + // set defaults + if (!result.name) { + result.name = instance.image.name + } + + return result } type SecretCandidate = { From 353b16458345f446dc502dfe714b6a8b65262a70 Mon Sep 17 00:00:00 2001 From: Mate Vago Date: Tue, 3 Dec 2024 16:01:06 +0100 Subject: [PATCH 07/13] fix: duplicated images --- web/crux/src/app/version/version.message.ts | 4 +++ .../src/app/version/version.ws.gateway.ts | 26 +++++++------------ 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/web/crux/src/app/version/version.message.ts b/web/crux/src/app/version/version.message.ts index f66390e72..9dd8d1b0b 100644 --- a/web/crux/src/app/version/version.message.ts +++ b/web/crux/src/app/version/version.message.ts @@ -1,5 +1,6 @@ import { AddImagesDto, ImageDetailsDto } from '../image/image.dto' +export const WS_TYPE_GET_IMAGE = 'get-image' export type GetImageMessage = { id: string } @@ -7,6 +8,7 @@ export type GetImageMessage = { export const WS_TYPE_IMAGE = 'image' export type ImageMessage = ImageDetailsDto +export const WS_TYPE_ADD_IMAGES = 'add-images' export type AddImagesMessage = { registryImages: AddImagesDto[] } @@ -23,6 +25,7 @@ export type ImagesAddedMessage = { images: ImageDetailsDto[] } +export const WS_TYPE_DELETE_IMAGE = 'delete-image' export type DeleteImageMessage = { imageId: string } @@ -33,4 +36,5 @@ export type ImageDeletedMessage = { } export const WS_TYPE_IMAGES_WERE_REORDERED = 'images-were-reordered' +export const WS_TYPE_ORDER_IMAGES = 'order-images' export type OrderImagesMessage = string[] diff --git a/web/crux/src/app/version/version.ws.gateway.ts b/web/crux/src/app/version/version.ws.gateway.ts index 8cd1c3176..9af90dc47 100644 --- a/web/crux/src/app/version/version.ws.gateway.ts +++ b/web/crux/src/app/version/version.ws.gateway.ts @@ -36,13 +36,15 @@ import { ImageDeletedMessage, ImageMessage, ImageTagMessage, - ImagesAddedMessage, OrderImagesMessage, + WS_TYPE_ADD_IMAGES, + WS_TYPE_DELETE_IMAGE, + WS_TYPE_GET_IMAGE, WS_TYPE_IMAGE, - WS_TYPE_IMAGES_ADDED, WS_TYPE_IMAGES_WERE_REORDERED, WS_TYPE_IMAGE_DELETED, WS_TYPE_IMAGE_TAG_UPDATED, + WS_TYPE_ORDER_IMAGES, WS_TYPE_SET_IMAGE_TAG, } from './version.message' import VersionService from './version.service' @@ -114,7 +116,7 @@ export default class VersionWebSocketGateway { } @AuditLogLevel('disabled') - @SubscribeMessage('get-image') + @SubscribeMessage(WS_TYPE_GET_IMAGE) async getImage(@SocketMessage() message: GetImageMessage): Promise> { const data = await this.imageService.getImageDetails(message.id) @@ -124,27 +126,17 @@ export default class VersionWebSocketGateway { } as WsMessage } - @SubscribeMessage('add-images') + @SubscribeMessage(WS_TYPE_ADD_IMAGES) async addImages( @TeamSlug() teamSlug: string, @VersionId() versionId: string, @SocketMessage() message: AddImagesMessage, @IdentityFromSocket() identity: Identity, - @SocketSubscription() subscription: WsSubscription, ): Promise { - const images = await this.imageService.addImagesToVersion(teamSlug, versionId, message.registryImages, identity) - - const res: WsMessage = { - type: WS_TYPE_IMAGES_ADDED, - data: { - images, - }, - } - - subscription.sendToAll(res) + await this.imageService.addImagesToVersion(teamSlug, versionId, message.registryImages, identity) } - @SubscribeMessage('delete-image') + @SubscribeMessage(WS_TYPE_DELETE_IMAGE) async deleteImage( @SocketMessage() message: DeleteImageMessage, @SocketSubscription() subscription: WsSubscription, @@ -189,7 +181,7 @@ export default class VersionWebSocketGateway { } } - @SubscribeMessage('order-images') + @SubscribeMessage(WS_TYPE_ORDER_IMAGES) async orderImages( @SocketClient() client: WsClient, @SocketMessage() message: OrderImagesMessage, From 038495dd95aa3851ae9be0b0ce4ef6cff704f2d4 Mon Sep 17 00:00:00 2001 From: Mate Vago Date: Tue, 3 Dec 2024 16:19:39 +0100 Subject: [PATCH 08/13] fix: container name defaults --- web/crux-ui/src/models/image.ts | 11 ++++++++++- web/crux/src/domain/container.ts | 3 ++- web/crux/src/domain/image.ts | 8 ++++++++ web/crux/src/domain/start-deployment.ts | 6 +++--- 4 files changed, 23 insertions(+), 5 deletions(-) diff --git a/web/crux-ui/src/models/image.ts b/web/crux-ui/src/models/image.ts index 4f366a9fe..52854517f 100644 --- a/web/crux-ui/src/models/image.ts +++ b/web/crux-ui/src/models/image.ts @@ -78,4 +78,13 @@ export type ImageMessage = VersionImage export const imageNameOf = (image: VersionImage): string => imageName(image.name, image.tag) -export const containerNameOfImage = (image: VersionImage) => image.config.name ?? image.name +export const registryImageNameToContainerName = (name: string) => { + if (name.includes('/')) { + return name.split('/').pop() + } + + return name +} + +export const containerNameOfImage = (image: VersionImage) => + image.config.name ?? registryImageNameToContainerName(image.name) diff --git a/web/crux/src/domain/container.ts b/web/crux/src/domain/container.ts index 599cc7f63..bf371f100 100644 --- a/web/crux/src/domain/container.ts +++ b/web/crux/src/domain/container.ts @@ -1,4 +1,5 @@ import { NetworkMode } from '@prisma/client' +import { registryImageNameToContainerName } from './image' export const PORT_MIN = 0 export const PORT_MAX = 65535 @@ -278,4 +279,4 @@ type InstanceWithConfigAndImageConfig = { } export const nameOfInstance = (instance: InstanceWithConfigAndImageConfig) => - instance.config.name ?? instance.image.config.name ?? instance.image.name + instance.config.name ?? instance.image.config.name ?? registryImageNameToContainerName(instance.image.name) diff --git a/web/crux/src/domain/image.ts b/web/crux/src/domain/image.ts index bd0253f61..7ac642a4a 100644 --- a/web/crux/src/domain/image.ts +++ b/web/crux/src/domain/image.ts @@ -76,3 +76,11 @@ export const parseDyrectorioEnvRules = (labels: Record): Record< } }, {}) } + +export const registryImageNameToContainerName = (name: string) => { + if (name.includes('/')) { + return name.split('/').pop() + } + + return name +} diff --git a/web/crux/src/domain/start-deployment.ts b/web/crux/src/domain/start-deployment.ts index 3334bc63c..4114a672b 100644 --- a/web/crux/src/domain/start-deployment.ts +++ b/web/crux/src/domain/start-deployment.ts @@ -1,5 +1,5 @@ import { ContainerConfig, DeploymentStatusEnum, VersionTypeEnum } from '@prisma/client' -import { ConcreteContainerConfigData, ContainerConfigData, UniqueSecretKeyValue } from './container' +import { ConcreteContainerConfigData, ContainerConfigData, UniqueSecretKeyValue, nameOfInstance } from './container' import { mergeConfigsWithConcreteConfig, mergeInstanceConfigWithDeploymentConfig } from './container-merge' import { DeploymentWithConfig } from './deployment' @@ -122,11 +122,11 @@ export const instanceConfigOf = ( // then we merge and override the rest with the instance config const instanceConfig = instance.config as any as ConcreteContainerConfigData - const result = mergeInstanceConfigWithDeploymentConfig(mergedDeploymentConfig, instanceConfig) + const result = mergeInstanceConfigWithDeploymentConfig(mergedDeploymentConfig, instanceConfig) // set defaults if (!result.name) { - result.name = instance.image.name + result.name = nameOfInstance(instance) } return result From 8b21704b35106eb60e3294eb49e3929869a5e7aa Mon Sep 17 00:00:00 2001 From: Mate Vago Date: Wed, 4 Dec 2024 12:11:11 +0100 Subject: [PATCH 09/13] fix: storage saving --- .../container-config/common-editor.spec.ts | 106 +++++------ .../container-config/common-json.spec.ts | 177 +++++++++--------- .../container-config-filters.spec.ts | 20 +- .../container-config/docker-editor.spec.ts | 36 ++-- .../container-config/docker-json.spec.ts | 36 ++-- .../image-config-view-state.spec.ts | 12 +- .../kubernetes-editor.spec.ts | 64 +++---- .../container-config/kubernetes-json.spec.ts | 64 +++---- .../deployment/deployment-copy.spec.ts | 10 +- .../deployment-copyability-versioned.spec.ts | 16 +- .../deployment-deletability.spec.ts | 8 +- .../e2e/with-login/image-config.spec.ts | 48 ++--- .../e2e/with-login/resource-copy.spec.ts | 8 +- .../app/container/container-config.service.ts | 12 +- 14 files changed, 311 insertions(+), 306 deletions(-) diff --git a/web/crux-ui/e2e/with-login/container-config/common-editor.spec.ts b/web/crux-ui/e2e/with-login/container-config/common-editor.spec.ts index 239b71fea..fd56c19a6 100644 --- a/web/crux-ui/e2e/with-login/container-config/common-editor.spec.ts +++ b/web/crux-ui/e2e/with-login/container-config/common-editor.spec.ts @@ -21,7 +21,7 @@ import { } from 'e2e/utils/websocket-match' import { createImage, createProject, createVersion } from '../../utils/projects' import { waitSocketRef, wsPatchSent } from '../../utils/websocket' -import { WS_TYPE_PATCH_IMAGE } from '@app/models' +import { WS_TYPE_PATCH_CONFIG } from '@app/models' const setup = async ( page: Page, @@ -31,26 +31,26 @@ const setup = async ( ): Promise<{ projectId: string; versionId: string; imageId: string }> => { const projectId = await createProject(page, projectName, 'versioned') const versionId = await createVersion(page, projectId, versionName, 'Incremental') - const imageId = await createImage(page, projectId, versionId, imageName) + const imageConfigId = await createImage(page, projectId, versionId, imageName) - return { projectId, versionId, imageId } + return { projectId, versionId, imageConfigId } } test.describe.configure({ mode: 'parallel' }) test.describe('Image common config from editor', () => { test('Container name should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'name-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { projectId, versionId, imageConfigId } = await setup(page, 'name-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) const name = 'new-container-name' - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchContainerName(name)) + const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchContainerName(name)) await page.locator('input[placeholder="Container name"]').fill(name) await wsSent @@ -60,15 +60,15 @@ test.describe('Image common config from editor', () => { }) test('Expose strategy should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'expose-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { projectId, versionId, imageConfigId } = await setup(page, 'expose-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchExpose('exposeWithTls')) + const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchExpose('exposeWithTls')) await page.getByRole('button', { name: 'HTTPS', exact: true }).click() await wsSent @@ -78,17 +78,17 @@ test.describe('Image common config from editor', () => { }) test('User should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'user-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { projectId, versionId, imageConfigId } = await setup(page, 'user-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) const user = 23 - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchUser(user)) + const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchUser(user)) await page.locator('input[placeholder="Container default"]').fill(user.toString()) await wsSent @@ -98,17 +98,17 @@ test.describe('Image common config from editor', () => { }) test('TTY should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'tty-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { projectId, versionId, imageConfigId } = await setup(page, 'tty-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) await page.locator('button:has-text("TTY")').click() - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchTTY(true)) + const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchTTY(true)) await page.locator('button[aria-checked="false"]:right-of(label:has-text("TTY"))').click() await wsSent @@ -118,10 +118,10 @@ test.describe('Image common config from editor', () => { }) test('Port should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'port-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { projectId, versionId, imageConfigId } = await setup(page, 'port-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) @@ -136,7 +136,7 @@ test.describe('Image common config from editor', () => { const internalInput = page.locator('input[placeholder="Internal"]') const externalInput = page.locator('input[placeholder="External"]') - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchPorts(internal, external)) + const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchPorts(internal, external)) await internalInput.fill(internal) await externalInput.fill(external) await wsSent @@ -148,10 +148,10 @@ test.describe('Image common config from editor', () => { }) test('Port ranges should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'port-range-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { projectId, versionId, imageConfigId } = await setup(page, 'port-range-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) @@ -173,7 +173,7 @@ test.describe('Image common config from editor', () => { const wsSent = wsPatchSent( ws, wsRoute, - WS_TYPE_PATCH_IMAGE, + WS_TYPE_PATCH_CONFIG, wsPatchMatchPortRange(internalFrom, externalFrom, internalTo, externalTo), ) await internalInputFrom.fill(internalFrom) @@ -191,10 +191,10 @@ test.describe('Image common config from editor', () => { }) test('Secrets should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'secrets-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { projectId, versionId, imageConfigId } = await setup(page, 'secrets-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) @@ -204,7 +204,7 @@ test.describe('Image common config from editor', () => { const secret = 'secretName' const secretInput = page.locator('input[placeholder="SECRETS"] >> visible=true').nth(0) - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchSecret(secret, true)) + const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchSecret(secret, true)) await secretInput.fill(secret) await page.getByRole('switch', { checked: false }).locator(':right-of(:text("Required"))').click() @@ -217,10 +217,10 @@ test.describe('Image common config from editor', () => { }) test('Commands should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'commands-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { projectId, versionId, imageConfigId } = await setup(page, 'commands-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) @@ -230,7 +230,7 @@ test.describe('Image common config from editor', () => { const command = 'sleep' const commandInput = page.locator('input[placeholder="Commands"] >> visible=true').nth(0) - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchCommand(command)) + const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchCommand(command)) await commandInput.fill(command) await wsSent @@ -240,10 +240,10 @@ test.describe('Image common config from editor', () => { }) test('Arguments should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'arguments-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { projectId, versionId, imageConfigId } = await setup(page, 'arguments-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) @@ -253,7 +253,7 @@ test.describe('Image common config from editor', () => { const argument = '1234' const argumentInput = page.locator('input[placeholder="Arguments"] >> visible=true').nth(0) - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchArgument(argument)) + const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchArgument(argument)) await argumentInput.fill(argument) await wsSent @@ -263,9 +263,9 @@ test.describe('Image common config from editor', () => { }) test('Routing should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'routing-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { projectId, versionId, imageConfigId } = await setup(page, 'routing-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) @@ -278,7 +278,7 @@ test.describe('Image common config from editor', () => { const internalInput = page.locator('input[placeholder="Internal"]') - let wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchPorts(internal)) + let wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchPorts(internal)) await internalInput.fill(internal) await wsSent @@ -293,7 +293,7 @@ test.describe('Image common config from editor', () => { wsSent = wsPatchSent( ws, wsRoute, - WS_TYPE_PATCH_IMAGE, + WS_TYPE_PATCH_CONFIG, wsPatchMatchRouting(domain, path, uploadLimit, stripPath, routedPort), ) await page.locator('input[placeholder="Domain"]').fill(domain) @@ -314,14 +314,14 @@ test.describe('Image common config from editor', () => { }) test('Environment should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup( + const { projectId, versionId, imageConfigId } = await setup( page, 'environment-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG, ) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) @@ -331,7 +331,7 @@ test.describe('Image common config from editor', () => { const key = 'env-key' const value = 'env-value' - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchEnvironment(key, value)) + const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchEnvironment(key, value)) await page.locator('input[placeholder="Key"]').first().fill(key) await page.locator('input[placeholder="Value"]').first().fill(value) await wsSent @@ -343,14 +343,14 @@ test.describe('Image common config from editor', () => { }) test('Config container should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup( + const { projectId, versionId, imageConfigId } = await setup( page, 'config-container-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG, ) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) @@ -362,7 +362,7 @@ test.describe('Image common config from editor', () => { const volume = 'volume' const path = 'test/path/' - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchConfigContainer(img, volume, path, true)) + const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchConfigContainer(img, volume, path, true)) await confDiv.getByLabel('Image').fill(img) await confDiv.getByLabel('Volume').fill(volume) await confDiv.getByLabel('Path').fill(path) @@ -378,14 +378,14 @@ test.describe('Image common config from editor', () => { }) test('Init containers should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup( + const { projectId, versionId, imageConfigId } = await setup( page, 'init-container-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG, ) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) @@ -401,7 +401,7 @@ test.describe('Image common config from editor', () => { await page.locator('button:has-text("Init containers")').click() - let wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE) + let wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG) await page.locator(`[src="/plus.svg"]:right-of(label:has-text("Init containers"))`).first().click() await wsSent @@ -410,7 +410,7 @@ test.describe('Image common config from editor', () => { wsSent = wsPatchSent( ws, wsRoute, - WS_TYPE_PATCH_IMAGE, + WS_TYPE_PATCH_CONFIG, wsPatchMatchInitContainer(name, image, volName, volPath, arg, cmd, envKey, envVal), ) await confDiv.getByLabel('NAME').fill(name) @@ -436,16 +436,16 @@ test.describe('Image common config from editor', () => { }) test('Volume should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'volume-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { projectId, versionId, imageConfigId } = await setup(page, 'volume-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) await page.locator('button:has-text("Volume")').click() - let wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE) + let wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG) await page.locator(`[src="/plus.svg"]:right-of(label:has-text("Volume"))`).first().click() await wsSent @@ -454,7 +454,7 @@ test.describe('Image common config from editor', () => { const path = '/test/volume' const volumeClass = 'class' - wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchVolume(name, size, path, volumeClass)) + wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchVolume(name, size, path, volumeClass)) await page.getByLabel('Name').fill(name) await page.getByLabel('Size').fill(size) await page.getByLabel('Path').fill(path) @@ -470,20 +470,20 @@ test.describe('Image common config from editor', () => { }) test('Storage should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'storage-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { projectId, versionId, imageConfigId } = await setup(page, 'storage-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const storageName = 'image-editor-storage' const storageId = await createStorage(page, storageName, 'storage.com', '1234', '12345') const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) await page.locator('button:has-text("Volume")').click() - let wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE) + let wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG) await page.locator(`[src="/plus.svg"]:right-of(label:has-text("Volume"))`).first().click() await wsSent @@ -492,7 +492,7 @@ test.describe('Image common config from editor', () => { const path = '/storage/volume' const volumeClass = 'class' - wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchVolume(volumeName, size, path, volumeClass)) + wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchVolume(volumeName, size, path, volumeClass)) await page.getByLabel('Name').fill(volumeName) await page.getByLabel('Size').fill(size) await page.getByLabel('Path').fill(path) @@ -503,7 +503,7 @@ test.describe('Image common config from editor', () => { const bucketPath = '/storage/' await page.locator('button:has-text("Storage")').click() - wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchStorage(storageId, bucketPath, volumeName)) + wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchStorage(storageId, bucketPath, volumeName)) await storageDiv.locator(`button:has-text("${storageName}")`).click() await storageDiv.locator('input[placeholder="Bucket path"]').fill(bucketPath) await storageDiv.locator(`button:has-text("${volumeName}")`).click() diff --git a/web/crux-ui/e2e/with-login/container-config/common-json.spec.ts b/web/crux-ui/e2e/with-login/container-config/common-json.spec.ts index a3a91d5f2..5432be017 100644 --- a/web/crux-ui/e2e/with-login/container-config/common-json.spec.ts +++ b/web/crux-ui/e2e/with-login/container-config/common-json.spec.ts @@ -21,32 +21,32 @@ import { } from 'e2e/utils/websocket-match' import { createImage, createProject, createVersion } from '../../utils/projects' import { waitSocketRef, wsPatchSent } from '../../utils/websocket' -import { WS_TYPE_PATCH_IMAGE } from '@app/models' +import { WS_TYPE_PATCH_CONFIG } from '@app/models' const setup = async ( page: Page, projectName: string, versionName: string, imageName: string, -): Promise<{ projectId: string; versionId: string; imageId: string }> => { +): Promise<{ imageConfigId: string }> => { const projectId = await createProject(page, projectName, 'versioned') const versionId = await createVersion(page, projectId, versionName, 'Incremental') - const imageId = await createImage(page, projectId, versionId, imageName) + const imageConfigId = await createImage(page, projectId, versionId, imageName) - return { projectId, versionId, imageId } + return { imageConfigId } } test.describe.configure({ mode: 'parallel' }) test.describe('Image common config from JSON', () => { test('Container name should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'name-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'name-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) - await page.waitForSelector('h2:text-is("Image")') + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) + await page.waitForSelector('h2:text-is("Image config")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) const name = 'new-container-name' @@ -57,7 +57,7 @@ test.describe('Image common config from JSON', () => { const json = JSON.parse(await jsonEditor.inputValue()) json.name = name - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchContainerName(name)) + const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchContainerName(name)) await jsonEditor.fill(JSON.stringify(json)) await wsSent @@ -67,13 +67,13 @@ test.describe('Image common config from JSON', () => { }) test('Expose strategy should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'expose-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'expose-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) - await page.waitForSelector('h2:text-is("Image")') + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) + await page.waitForSelector('h2:text-is("Image config")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) const jsonEditorButton = await page.waitForSelector('button:has-text("JSON")') await jsonEditorButton.click() @@ -82,7 +82,7 @@ test.describe('Image common config from JSON', () => { const json = JSON.parse(await jsonEditor.inputValue()) json.expose = 'exposeWithTls' - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchExpose('exposeWithTls')) + const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchExpose('exposeWithTls')) await jsonEditor.fill(JSON.stringify(json)) await wsSent @@ -92,13 +92,13 @@ test.describe('Image common config from JSON', () => { }) test('User should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'user-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'user-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) - await page.waitForSelector('h2:text-is("Image")') + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) + await page.waitForSelector('h2:text-is("Image config")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) const user = 23 @@ -109,7 +109,7 @@ test.describe('Image common config from JSON', () => { const json = JSON.parse(await jsonEditor.inputValue()) json.user = user - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchUser(user)) + const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchUser(user)) await jsonEditor.fill(JSON.stringify(json)) await wsSent @@ -119,13 +119,13 @@ test.describe('Image common config from JSON', () => { }) test('TTY should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'tty-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'tty-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) - await page.waitForSelector('h2:text-is("Image")') + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) + await page.waitForSelector('h2:text-is("Image config")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) const jsonEditorButton = await page.waitForSelector('button:has-text("JSON")') await jsonEditorButton.click() @@ -134,7 +134,7 @@ test.describe('Image common config from JSON', () => { const json = JSON.parse(await jsonEditor.inputValue()) json.tty = true - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchTTY(true)) + const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchTTY(true)) await jsonEditor.fill(JSON.stringify(json)) await wsSent @@ -144,13 +144,13 @@ test.describe('Image common config from JSON', () => { }) test('Port should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'port-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'port-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) - await page.waitForSelector('h2:text-is("Image")') + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) + await page.waitForSelector('h2:text-is("Image config")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) const jsonEditorButton = await page.waitForSelector('button:has-text("JSON")') await jsonEditorButton.click() @@ -164,7 +164,7 @@ test.describe('Image common config from JSON', () => { const json = JSON.parse(await jsonEditor.inputValue()) json.ports = [{ internal: internalAsNumber, external: externalAsNumber }] - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchPorts(internal, external)) + const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchPorts(internal, external)) await jsonEditor.fill(JSON.stringify(json)) await wsSent @@ -178,13 +178,13 @@ test.describe('Image common config from JSON', () => { }) test('Port ranges should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'port-range-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'port-range-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) - await page.waitForSelector('h2:text-is("Image")') + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) + await page.waitForSelector('h2:text-is("Image config")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) const jsonEditorButton = await page.waitForSelector('button:has-text("JSON")') await jsonEditorButton.click() @@ -210,7 +210,7 @@ test.describe('Image common config from JSON', () => { const wsSent = wsPatchSent( ws, wsRoute, - WS_TYPE_PATCH_IMAGE, + WS_TYPE_PATCH_CONFIG, wsPatchMatchPortRange(internalFrom, externalFrom, internalTo, externalTo), ) await jsonEditor.fill(JSON.stringify(json)) @@ -230,13 +230,13 @@ test.describe('Image common config from JSON', () => { }) test('Secrets should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'secrets-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'secrets-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) - await page.waitForSelector('h2:text-is("Image")') + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) + await page.waitForSelector('h2:text-is("Image config")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) const secret = 'secretName' const secretInput = page.locator('input[placeholder="SECRETS"] >> visible=true').nth(0) @@ -248,7 +248,7 @@ test.describe('Image common config from JSON', () => { const json = JSON.parse(await jsonEditor.inputValue()) json.secrets = [{ key: secret, required: true }] - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchSecret(secret, true)) + const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchSecret(secret, true)) await jsonEditor.fill(JSON.stringify(json)) await wsSent @@ -259,13 +259,13 @@ test.describe('Image common config from JSON', () => { }) test('Commands should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'commands-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'commands-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) - await page.waitForSelector('h2:text-is("Image")') + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) + await page.waitForSelector('h2:text-is("Image config")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) const command = 'sleep' @@ -276,7 +276,7 @@ test.describe('Image common config from JSON', () => { const json = JSON.parse(await jsonEditor.inputValue()) json.commands = [command] - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchCommand(command)) + const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchCommand(command)) await jsonEditor.fill(JSON.stringify(json)) await wsSent @@ -286,13 +286,13 @@ test.describe('Image common config from JSON', () => { }) test('Arguments should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'arguments-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'arguments-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) - await page.waitForSelector('h2:text-is("Image")') + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) + await page.waitForSelector('h2:text-is("Image config")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) const argument = '1234' @@ -303,7 +303,7 @@ test.describe('Image common config from JSON', () => { const json = JSON.parse(await jsonEditor.inputValue()) json.args = [argument] - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchArgument(argument)) + const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchArgument(argument)) await jsonEditor.fill(JSON.stringify(json)) await wsSent @@ -313,12 +313,12 @@ test.describe('Image common config from JSON', () => { }) test('Routing should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'routing-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'routing-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) - await page.waitForSelector('h2:text-is("Image")') + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) + await page.waitForSelector('h2:text-is("Image config")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) const jsonEditorButton = await page.waitForSelector('button:has-text("JSON")') await jsonEditorButton.click() @@ -337,7 +337,7 @@ test.describe('Image common config from JSON', () => { const wsSent = wsPatchSent( ws, wsRoute, - WS_TYPE_PATCH_IMAGE, + WS_TYPE_PATCH_CONFIG, wsPatchMatchRouting(domain, path, uploadLimit, stripPath, port), ) await jsonEditor.fill(JSON.stringify(json)) @@ -352,12 +352,12 @@ test.describe('Image common config from JSON', () => { }) test('Environment should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'environment-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'environment-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) - await page.waitForSelector('h2:text-is("Image")') + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) + await page.waitForSelector('h2:text-is("Image config")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) const key = 'env-key' const value = 'env-value' @@ -369,7 +369,7 @@ test.describe('Image common config from JSON', () => { const json = JSON.parse(await jsonEditor.inputValue()) json.environment = { [key]: value } - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchEnvironment(key, value)) + const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchEnvironment(key, value)) await jsonEditor.fill(JSON.stringify(json)) await wsSent @@ -380,17 +380,12 @@ test.describe('Image common config from JSON', () => { }) test('Config container should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup( - page, - 'config-container-json', - '1.0.0', - NGINX_TEST_IMAGE_WITH_TAG, - ) + const { imageConfigId } = await setup(page, 'config-container-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) - await page.waitForSelector('h2:text-is("Image")') + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) + await page.waitForSelector('h2:text-is("Image config")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) const img = 'image' const volume = 'volume' @@ -403,7 +398,7 @@ test.describe('Image common config from JSON', () => { const json = JSON.parse(await jsonEditor.inputValue()) json.configContainer = { image: img, volume, path, keepFiles: true } - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchConfigContainer(img, volume, path, true)) + const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchConfigContainer(img, volume, path, true)) await jsonEditor.fill(JSON.stringify(json)) await wsSent @@ -417,17 +412,12 @@ test.describe('Image common config from JSON', () => { }) test('Init containers should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup( - page, - 'init-container-json', - '1.0.0', - NGINX_TEST_IMAGE_WITH_TAG, - ) + const { imageConfigId } = await setup(page, 'init-container-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) - await page.waitForSelector('h2:text-is("Image")') + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) + await page.waitForSelector('h2:text-is("Image config")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) const name = 'container-name' const image = 'image' @@ -458,7 +448,7 @@ test.describe('Image common config from JSON', () => { const wsSent = wsPatchSent( ws, wsRoute, - WS_TYPE_PATCH_IMAGE, + WS_TYPE_PATCH_CONFIG, wsPatchMatchInitContainer(name, image, volName, volPath, arg, cmd, envKey, envVal), ) await jsonEditor.fill(JSON.stringify(json)) @@ -478,12 +468,12 @@ test.describe('Image common config from JSON', () => { }) test('Volume should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'volume-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'volume-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) - await page.waitForSelector('h2:text-is("Image")') + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) + await page.waitForSelector('h2:text-is("Image config")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) const jsonEditorButton = await page.waitForSelector('button:has-text("JSON")') await jsonEditorButton.click() @@ -497,7 +487,7 @@ test.describe('Image common config from JSON', () => { const json = JSON.parse(await jsonEditor.inputValue()) json.volumes = [{ name, path, type: 'rwo', class: volumeClass, size }] - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchVolume(name, size, path, volumeClass)) + const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchVolume(name, size, path, volumeClass)) await jsonEditor.fill(JSON.stringify(json)) await wsSent @@ -510,9 +500,9 @@ test.describe('Image common config from JSON', () => { }) test('Storage should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'storage-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) - await page.waitForSelector('h2:text-is("Image")') + const { imageConfigId } = await setup(page, 'storage-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) + await page.waitForSelector('h2:text-is("Image config")') const volumeName = 'volume-name' const size = '1024' @@ -523,10 +513,10 @@ test.describe('Image common config from JSON', () => { const storageId = await createStorage(page, storageName, 'storage.com', '1234', '12345') const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) - await page.waitForSelector('h2:text-is("Image")') + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) + await page.waitForSelector('h2:text-is("Image config")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) const jsonEditorButton = await page.waitForSelector('button:has-text("JSON")') await jsonEditorButton.click() @@ -536,7 +526,12 @@ test.describe('Image common config from JSON', () => { json.volumes = [{ name: volumeName, path, type: 'rwo', class: volumeClass, size }] json.storage = { storageId, bucket: bucketPath, path: volumeName } - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchStorage(storageId, bucketPath, volumeName)) + const wsSent = wsPatchSent( + ws, + wsRoute, + WS_TYPE_PATCH_CONFIG, + wsPatchMatchStorage(storageId, bucketPath, volumeName), + ) await jsonEditor.fill(JSON.stringify(json)) await wsSent diff --git a/web/crux-ui/e2e/with-login/container-config/container-config-filters.spec.ts b/web/crux-ui/e2e/with-login/container-config/container-config-filters.spec.ts index df1cae48d..12d4e5598 100644 --- a/web/crux-ui/e2e/with-login/container-config/container-config-filters.spec.ts +++ b/web/crux-ui/e2e/with-login/container-config/container-config-filters.spec.ts @@ -11,20 +11,20 @@ const setup = async ( ): Promise<{ projectId: string; versionId: string; imageId: string }> => { const projectId = await createProject(page, projectName, 'versioned') const versionId = await createVersion(page, projectId, versionName, 'Incremental') - const imageId = await createImage(page, projectId, versionId, imageName) + const imageConfigId = await createImage(page, projectId, versionId, imageName) return { projectId, versionId, - imageId, + imageConfigId, } } test.describe('Filters', () => { test('None should be selected by default', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'filter-all', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { projectId, versionId, imageConfigId } = await setup(page, 'filter-all', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const allButton = await page.locator('button:has-text("All")') @@ -34,9 +34,9 @@ test.describe('Filters', () => { }) test('All should not be selected if one of the main filters are not selected', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'filter-select', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { projectId, versionId, imageConfigId } = await setup(page, 'filter-select', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') await page.locator(`button:has-text("Common")`).first().click() @@ -47,9 +47,9 @@ test.describe('Filters', () => { }) test('Main filter should not be selected if one of its sub filters are not selected', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'sub-filter', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { projectId, versionId, imageConfigId } = await setup(page, 'sub-filter', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const subFilter = await page.locator(`button:has-text("Network mode")`) @@ -62,9 +62,9 @@ test.describe('Filters', () => { }) test('Config field should be invisible if its sub filter is not selected', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'sub-deselect', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { projectId, versionId, imageConfigId } = await setup(page, 'sub-deselect', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const subFilter = await page.locator(`button:has-text("Deployment strategy")`) diff --git a/web/crux-ui/e2e/with-login/container-config/docker-editor.spec.ts b/web/crux-ui/e2e/with-login/container-config/docker-editor.spec.ts index 810c45490..04b04e169 100644 --- a/web/crux-ui/e2e/with-login/container-config/docker-editor.spec.ts +++ b/web/crux-ui/e2e/with-login/container-config/docker-editor.spec.ts @@ -10,7 +10,7 @@ import { wsPatchMatchRestartPolicy, } from 'e2e/utils/websocket-match' import { createImage, createProject, createVersion } from '../../utils/projects' -import { WS_TYPE_PATCH_IMAGE } from '@app/models' +import { WS_TYPE_PATCH_CONFIG } from '@app/models' const setup = async ( page: Page, @@ -20,28 +20,28 @@ const setup = async ( ): Promise<{ projectId: string; versionId: string; imageId: string }> => { const projectId = await createProject(page, projectName, 'versioned') const versionId = await createVersion(page, projectId, versionName, 'Incremental') - const imageId = await createImage(page, projectId, versionId, imageName) + const imageConfigId = await createImage(page, projectId, versionId, imageName) - return { projectId, versionId, imageId } + return { projectId, versionId, imageConfigId: imageConfigId } } test.describe('Image docker config from editor', () => { test('Network mode should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup( + const { projectId, versionId, imageConfigId } = await setup( page, 'networkmode-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG, ) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) const mode = 'host' - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchNetworkMode(mode)) + const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchNetworkMode(mode)) await page.locator(`div.grid:has(label:has-text("NETWORK MODE")) button:has-text("${mode}")`).click() await wsSent @@ -53,14 +53,14 @@ test.describe('Image docker config from editor', () => { }) test('Docker labels should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup( + const { projectId, versionId, imageConfigId } = await setup( page, 'dockerlabel-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG, ) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) @@ -72,7 +72,7 @@ test.describe('Image docker config from editor', () => { await page.locator('button:has-text("Docker labels")').click() - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchDockerLabel(key, value)) + const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchDockerLabel(key, value)) await keyInput.fill(key) await valueInput.fill(value) await wsSent @@ -84,19 +84,19 @@ test.describe('Image docker config from editor', () => { }) test('Restart policy should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup( + const { projectId, versionId, imageConfigId } = await setup( page, 'restartpolicy-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG, ) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchRestartPolicy('always')) + const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchRestartPolicy('always')) await page.locator('div.grid:has(label:has-text("RESTART POLICY")) button:has-text("Always")').click() await wsSent @@ -108,9 +108,9 @@ test.describe('Image docker config from editor', () => { }) test('Log config should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'logconfig-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { projectId, versionId, imageConfigId } = await setup(page, 'logconfig-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) @@ -123,7 +123,7 @@ test.describe('Image docker config from editor', () => { const loggerConf = page.locator('div.grid:has(label:has-text("LOG CONFIG"))') - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchLogConfig(type, key, value)) + const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchLogConfig(type, key, value)) await loggerConf.locator('input[placeholder="Key"]').first().fill(key) await loggerConf.locator('input[placeholder="Value"]').first().fill(value) await loggerConf.locator(`button:has-text("${type}")`).click() @@ -137,9 +137,9 @@ test.describe('Image docker config from editor', () => { }) test('Networks should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'networks-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { projectId, versionId, imageConfigId } = await setup(page, 'networks-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) @@ -148,7 +148,7 @@ test.describe('Image docker config from editor', () => { const network = '10.16.128.196' - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchNetwork(network)) + const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchNetwork(network)) await page.locator('div.grid:has(label:has-text("NETWORKS")) input[placeholder="Network"]').first().fill(network) await wsSent diff --git a/web/crux-ui/e2e/with-login/container-config/docker-json.spec.ts b/web/crux-ui/e2e/with-login/container-config/docker-json.spec.ts index 9ba93f576..507b3d2bc 100644 --- a/web/crux-ui/e2e/with-login/container-config/docker-json.spec.ts +++ b/web/crux-ui/e2e/with-login/container-config/docker-json.spec.ts @@ -10,7 +10,7 @@ import { wsPatchMatchRestartPolicy, } from 'e2e/utils/websocket-match' import { createImage, createProject, createVersion } from '../../utils/projects' -import { WS_TYPE_PATCH_IMAGE } from '@app/models' +import { WS_TYPE_PATCH_CONFIG } from '@app/models' const setup = async ( page: Page, @@ -20,18 +20,18 @@ const setup = async ( ): Promise<{ projectId: string; versionId: string; imageId: string }> => { const projectId = await createProject(page, projectName, 'versioned') const versionId = await createVersion(page, projectId, versionName, 'Incremental') - const imageId = await createImage(page, projectId, versionId, imageName) + const imageConfigId = await createImage(page, projectId, versionId, imageName) - return { projectId, versionId, imageId } + return { projectId, versionId, imageConfigId: imageConfigId } } test.describe.configure({ mode: 'parallel' }) test.describe('Image docker config from JSON', () => { test('Network mode should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'networkmode-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { projectId, versionId, imageConfigId } = await setup(page, 'networkmode-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) @@ -45,7 +45,7 @@ test.describe('Image docker config from JSON', () => { const json = JSON.parse(await jsonEditor.inputValue()) json.networkMode = mode - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchNetworkMode(mode)) + const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchNetworkMode(mode)) await jsonEditor.fill(JSON.stringify(json)) await wsSent @@ -57,9 +57,9 @@ test.describe('Image docker config from JSON', () => { }) test('Docker labels should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'dockerlabel-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { projectId, versionId, imageConfigId } = await setup(page, 'dockerlabel-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) @@ -74,7 +74,7 @@ test.describe('Image docker config from JSON', () => { const json = JSON.parse(await jsonEditor.inputValue()) json.dockerLabels = { [key]: value } - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchDockerLabel(key, value)) + const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchDockerLabel(key, value)) await jsonEditor.fill(JSON.stringify(json)) await wsSent @@ -89,14 +89,14 @@ test.describe('Image docker config from JSON', () => { }) test('Restart policy should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup( + const { projectId, versionId, imageConfigId } = await setup( page, 'restartpolicy-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG, ) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) @@ -108,7 +108,7 @@ test.describe('Image docker config from JSON', () => { const json = JSON.parse(await jsonEditor.inputValue()) json.restartPolicy = 'always' - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchRestartPolicy('always')) + const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchRestartPolicy('always')) await jsonEditor.fill(JSON.stringify(json)) await wsSent @@ -120,9 +120,9 @@ test.describe('Image docker config from JSON', () => { }) test('Log config should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'logconfig-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { projectId, versionId, imageConfigId } = await setup(page, 'logconfig-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) @@ -138,7 +138,7 @@ test.describe('Image docker config from JSON', () => { const json = JSON.parse(await jsonEditor.inputValue()) json.logConfig = { driver: type, options: { [key]: value } } - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchLogConfig(type, key, value)) + const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchLogConfig(type, key, value)) await jsonEditor.fill(JSON.stringify(json)) await wsSent @@ -151,9 +151,9 @@ test.describe('Image docker config from JSON', () => { }) test('Networks should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'networks-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { projectId, versionId, imageConfigId } = await setup(page, 'networks-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) @@ -169,7 +169,7 @@ test.describe('Image docker config from JSON', () => { const json = JSON.parse(await jsonEditor.inputValue()) json.networks = [network] - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchNetwork(network)) + const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchNetwork(network)) await jsonEditor.fill(JSON.stringify(json)) await wsSent diff --git a/web/crux-ui/e2e/with-login/container-config/image-config-view-state.spec.ts b/web/crux-ui/e2e/with-login/container-config/image-config-view-state.spec.ts index 1a9c3e35d..fde1249dc 100644 --- a/web/crux-ui/e2e/with-login/container-config/image-config-view-state.spec.ts +++ b/web/crux-ui/e2e/with-login/container-config/image-config-view-state.spec.ts @@ -11,20 +11,20 @@ const setup = async ( ): Promise<{ projectId: string; versionId: string; imageId: string }> => { const projectId = await createProject(page, projectName, 'versioned') const versionId = await createVersion(page, projectId, versionName, 'Incremental') - const imageId = await createImage(page, projectId, versionId, imageName) + const imageConfigId = await createImage(page, projectId, versionId, imageName) return { projectId, versionId, - imageId, + imageId: imageConfigId, } } test.describe('View state', () => { test('Editor state should show the configuration fields', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'editor-state-conf', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { projectId, versionId, imageConfigId } = await setup(page, 'editor-state-conf', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const editorButton = await page.waitForSelector('button:has-text("Editor")') @@ -39,9 +39,9 @@ test.describe('View state', () => { }) test('JSON state should show the json editor', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'editor-state-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { projectId, versionId, imageConfigId } = await setup(page, 'editor-state-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const jsonEditorButton = await page.waitForSelector('button:has-text("JSON")') diff --git a/web/crux-ui/e2e/with-login/container-config/kubernetes-editor.spec.ts b/web/crux-ui/e2e/with-login/container-config/kubernetes-editor.spec.ts index 5a6cd1a3f..ef3d1b0e1 100644 --- a/web/crux-ui/e2e/with-login/container-config/kubernetes-editor.spec.ts +++ b/web/crux-ui/e2e/with-login/container-config/kubernetes-editor.spec.ts @@ -18,7 +18,7 @@ import { } from 'e2e/utils/websocket-match' import { createImage, createProject, createVersion } from '../../utils/projects' import { waitSocketRef, wsPatchSent } from '../../utils/websocket' -import { WS_TYPE_PATCH_IMAGE } from '@app/models' +import { WS_TYPE_PATCH_CONFIG } from '@app/models' const setup = async ( page: Page, @@ -28,14 +28,14 @@ const setup = async ( ): Promise<{ projectId: string; versionId: string; imageId: string }> => { const projectId = await createProject(page, projectName, 'versioned') const versionId = await createVersion(page, projectId, versionName, 'Incremental') - const imageId = await createImage(page, projectId, versionId, imageName) + const imageConfigId = await createImage(page, projectId, versionId, imageName) - return { projectId, versionId, imageId } + return { projectId, versionId, imageConfigId: imageConfigId } } test.describe('Image kubernetes config from editor', () => { test('Deployment strategy should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup( + const { projectId, versionId, imageConfigId } = await setup( page, 'deployment-strategy-editor', '1.0.0', @@ -43,14 +43,14 @@ test.describe('Image kubernetes config from editor', () => { ) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) const strategy = 'rolling' - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchDeploymentStrategy(strategy)) + const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchDeploymentStrategy(strategy)) await page.locator(`button:has-text("${strategy}")`).click() await wsSent @@ -60,7 +60,7 @@ test.describe('Image kubernetes config from editor', () => { }) test('Custom headers should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup( + const { projectId, versionId, imageConfigId } = await setup( page, 'custom-headers-editor', '1.0.0', @@ -68,7 +68,7 @@ test.describe('Image kubernetes config from editor', () => { ) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) @@ -80,7 +80,7 @@ test.describe('Image kubernetes config from editor', () => { .locator('div.grid:has(label:has-text("CUSTOM HEADERS")) input[placeholder="Header name"]') .first() - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchCustomHeader(header)) + const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchCustomHeader(header)) await input.fill(header) await wsSent @@ -90,7 +90,7 @@ test.describe('Image kubernetes config from editor', () => { }) test('Proxy headers should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup( + const { projectId, versionId, imageConfigId } = await setup( page, 'proxy-headers-editor', '1.0.0', @@ -98,14 +98,14 @@ test.describe('Image kubernetes config from editor', () => { ) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) await page.locator('button:has-text("Proxy headers")').click() - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchProxyHeader(true)) + const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchProxyHeader(true)) await page.locator('button[aria-checked="false"]:right-of(label:has-text("PROXY HEADERS"))').click() await wsSent @@ -115,7 +115,7 @@ test.describe('Image kubernetes config from editor', () => { }) test('Load balancer should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup( + const { projectId, versionId, imageConfigId } = await setup( page, 'load-balancer-editor', '1.0.0', @@ -123,7 +123,7 @@ test.describe('Image kubernetes config from editor', () => { ) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) @@ -133,11 +133,11 @@ test.describe('Image kubernetes config from editor', () => { const key = 'balancer-key' const value = 'balancer-value' - let wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchLoadBalancer(true)) + let wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchLoadBalancer(true)) await page.locator('button[aria-checked="false"]:right-of(label:has-text("USE LOAD BALANCER"))').click() await wsSent - wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchLBAnnotations(key, value)) + wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchLBAnnotations(key, value)) await page.locator('div.grid:has(label:has-text("USE LOAD BALANCER")) input[placeholder="Key"]').first().fill(key) await page .locator('div.grid:has(label:has-text("USE LOAD BALANCER")) input[placeholder="Value"]') @@ -159,7 +159,7 @@ test.describe('Image kubernetes config from editor', () => { }) test('Health check config should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup( + const { projectId, versionId, imageConfigId } = await setup( page, 'health-check-editor', '1.0.0', @@ -167,7 +167,7 @@ test.describe('Image kubernetes config from editor', () => { ) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) @@ -184,7 +184,7 @@ test.describe('Image kubernetes config from editor', () => { const wsSent = wsPatchSent( ws, wsRoute, - WS_TYPE_PATCH_IMAGE, + WS_TYPE_PATCH_CONFIG, wsPatchMatchHealthCheck(port, liveness, readiness, startup), ) await hcConf.locator('input[placeholder="Port"]').fill(port.toString()) @@ -202,14 +202,14 @@ test.describe('Image kubernetes config from editor', () => { }) test('Resource config should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup( + const { projectId, versionId, imageConfigId } = await setup( page, 'resource-config-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG, ) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) @@ -226,7 +226,7 @@ test.describe('Image kubernetes config from editor', () => { const wsSent = wsPatchSent( ws, wsRoute, - WS_TYPE_PATCH_IMAGE, + WS_TYPE_PATCH_CONFIG, wsPatchMatchResourceConfig(cpuLimits, cpuRequests, memoryLimits, memoryRequests), ) await rsConf.locator('input').nth(0).fill(cpuLimits) @@ -247,10 +247,10 @@ test.describe('Image kubernetes config from editor', () => { page.locator(`div.max-h-128 > div:nth-child(2):near(label:has-text("${category}"))`) test('Labels should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'labels-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { projectId, versionId, imageConfigId } = await setup(page, 'labels-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) @@ -264,15 +264,15 @@ test.describe('Image kubernetes config from editor', () => { const serviceDiv = await getCategoryDiv('Service', page) const ingressDiv = await getCategoryDiv('Ingress', page) - let wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchDeploymentLabel(key, value)) + let wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchDeploymentLabel(key, value)) await deploymentDiv.locator('input[placeholder="Key"]').first().fill(key) await deploymentDiv.locator('input[placeholder="Value"]').first().fill(value) await wsSent - wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchServiceLabel(key, value)) + wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchServiceLabel(key, value)) await serviceDiv.locator('input[placeholder="Key"]').first().fill(key) await serviceDiv.locator('input[placeholder="Value"]').first().fill(value) await wsSent - wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchIngressLabel(key, value)) + wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchIngressLabel(key, value)) await ingressDiv.locator('input[placeholder="Key"]').first().fill(key) await ingressDiv.locator('input[placeholder="Value"]').first().fill(value) await wsSent @@ -288,7 +288,7 @@ test.describe('Image kubernetes config from editor', () => { }) test('Annotations should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup( + const { projectId, versionId, imageConfigId } = await setup( page, 'annotations-editor', '1.0.0', @@ -296,7 +296,7 @@ test.describe('Image kubernetes config from editor', () => { ) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) @@ -310,15 +310,15 @@ test.describe('Image kubernetes config from editor', () => { const serviceDiv = await getCategoryDiv('Service', page) const ingressDiv = await getCategoryDiv('Ingress', page) - let wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchDeploymentAnnotations(key, value)) + let wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchDeploymentAnnotations(key, value)) await deploymentDiv.locator('input[placeholder="Key"]').first().fill(key) await deploymentDiv.locator('input[placeholder="Value"]').first().fill(value) await wsSent - wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchServiceAnnotations(key, value)) + wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchServiceAnnotations(key, value)) await serviceDiv.locator('input[placeholder="Key"]').first().fill(key) await serviceDiv.locator('input[placeholder="Value"]').first().fill(value) await wsSent - wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchIngressAnnotations(key, value)) + wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchIngressAnnotations(key, value)) await ingressDiv.locator('input[placeholder="Key"]').first().fill(key) await ingressDiv.locator('input[placeholder="Value"]').first().fill(value) await wsSent diff --git a/web/crux-ui/e2e/with-login/container-config/kubernetes-json.spec.ts b/web/crux-ui/e2e/with-login/container-config/kubernetes-json.spec.ts index 9fa54071a..166bf48c6 100644 --- a/web/crux-ui/e2e/with-login/container-config/kubernetes-json.spec.ts +++ b/web/crux-ui/e2e/with-login/container-config/kubernetes-json.spec.ts @@ -18,7 +18,7 @@ import { } from 'e2e/utils/websocket-match' import { createImage, createProject, createVersion } from '../../utils/projects' import { waitSocketRef, wsPatchSent } from '../../utils/websocket' -import { WS_TYPE_PATCH_IMAGE } from '@app/models' +import { WS_TYPE_PATCH_CONFIG } from '@app/models' const setup = async ( page: Page, @@ -28,14 +28,14 @@ const setup = async ( ): Promise<{ projectId: string; versionId: string; imageId: string }> => { const projectId = await createProject(page, projectName, 'versioned') const versionId = await createVersion(page, projectId, versionName, 'Incremental') - const imageId = await createImage(page, projectId, versionId, imageName) + const imageConfigId = await createImage(page, projectId, versionId, imageName) - return { projectId, versionId, imageId } + return { projectId, versionId, imageConfigId: imageConfigId } } test.describe('Image kubernetes config from JSON', () => { test('Deployment strategy should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup( + const { projectId, versionId, imageConfigId } = await setup( page, 'deployment-strategy-json', '1.0.0', @@ -43,7 +43,7 @@ test.describe('Image kubernetes config from JSON', () => { ) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) @@ -57,7 +57,7 @@ test.describe('Image kubernetes config from JSON', () => { const json = JSON.parse(await jsonEditor.inputValue()) json.deploymentStrategy = strategy - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchDeploymentStrategy(strategy)) + const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchDeploymentStrategy(strategy)) await jsonEditor.fill(JSON.stringify(json)) await wsSent @@ -67,7 +67,7 @@ test.describe('Image kubernetes config from JSON', () => { }) test('Custom headers should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup( + const { projectId, versionId, imageConfigId } = await setup( page, 'custom-headers-json', '1.0.0', @@ -75,7 +75,7 @@ test.describe('Image kubernetes config from JSON', () => { ) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) @@ -89,7 +89,7 @@ test.describe('Image kubernetes config from JSON', () => { const json = JSON.parse(await jsonEditor.inputValue()) json.customHeaders = [header] - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchCustomHeader(header)) + const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchCustomHeader(header)) await jsonEditor.fill(JSON.stringify(json)) await wsSent @@ -102,7 +102,7 @@ test.describe('Image kubernetes config from JSON', () => { }) test('Proxy headers should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup( + const { projectId, versionId, imageConfigId } = await setup( page, 'proxy-headers-json', '1.0.0', @@ -110,7 +110,7 @@ test.describe('Image kubernetes config from JSON', () => { ) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) @@ -122,7 +122,7 @@ test.describe('Image kubernetes config from JSON', () => { const json = JSON.parse(await jsonEditor.inputValue()) json.proxyHeaders = true - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchProxyHeader(true)) + const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchProxyHeader(true)) await jsonEditor.fill(JSON.stringify(json)) await wsSent @@ -132,7 +132,7 @@ test.describe('Image kubernetes config from JSON', () => { }) test('Load balancer should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup( + const { projectId, versionId, imageConfigId } = await setup( page, 'load-balancer-json', '1.0.0', @@ -140,7 +140,7 @@ test.describe('Image kubernetes config from JSON', () => { ) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) @@ -155,11 +155,11 @@ test.describe('Image kubernetes config from JSON', () => { const json = JSON.parse(await jsonEditor.inputValue()) json.useLoadBalancer = true - let wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchLoadBalancer(true)) + let wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchLoadBalancer(true)) await jsonEditor.fill(JSON.stringify(json)) await wsSent json.extraLBAnnotations = { [key]: value } - wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchLBAnnotations(key, value)) + wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchLBAnnotations(key, value)) await jsonEditor.fill(JSON.stringify(json)) await wsSent @@ -177,10 +177,10 @@ test.describe('Image kubernetes config from JSON', () => { }) test('Health check config should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'health-check-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { projectId, versionId, imageConfigId } = await setup(page, 'health-check-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) @@ -200,7 +200,7 @@ test.describe('Image kubernetes config from JSON', () => { const wsSent = wsPatchSent( ws, wsRoute, - WS_TYPE_PATCH_IMAGE, + WS_TYPE_PATCH_CONFIG, wsPatchMatchHealthCheck(port, liveness, readiness, startup), ) await jsonEditor.fill(JSON.stringify(json)) @@ -216,7 +216,7 @@ test.describe('Image kubernetes config from JSON', () => { }) test('Resource config should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup( + const { projectId, versionId, imageConfigId } = await setup( page, 'resource-config-json', '1.0.0', @@ -224,7 +224,7 @@ test.describe('Image kubernetes config from JSON', () => { ) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) @@ -247,7 +247,7 @@ test.describe('Image kubernetes config from JSON', () => { const wsSent = wsPatchSent( ws, wsRoute, - WS_TYPE_PATCH_IMAGE, + WS_TYPE_PATCH_CONFIG, wsPatchMatchResourceConfig(cpuLimits, cpuRequests, memoryLimits, memoryRequests), ) await jsonEditor.fill(JSON.stringify(json)) @@ -266,10 +266,10 @@ test.describe('Image kubernetes config from JSON', () => { page.locator(`div.max-h-128 > div:nth-child(2):near(label:has-text("${category}"))`) test('Labels should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'labels-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { projectId, versionId, imageConfigId } = await setup(page, 'labels-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) @@ -283,15 +283,15 @@ test.describe('Image kubernetes config from JSON', () => { const jsonEditor = await page.locator('textarea') const json = JSON.parse(await jsonEditor.inputValue()) - let wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchDeploymentLabel(key, value)) + let wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchDeploymentLabel(key, value)) json.labels = { deployment: { [key]: value } } await jsonEditor.fill(JSON.stringify(json)) await wsSent - wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchServiceLabel(key, value)) + wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchServiceLabel(key, value)) json.labels = { deployment: { [key]: value }, service: { [key]: value } } await jsonEditor.fill(JSON.stringify(json)) await wsSent - wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchIngressLabel(key, value)) + wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchIngressLabel(key, value)) json.labels = { deployment: { [key]: value }, service: { [key]: value }, ingress: { [key]: value } } await jsonEditor.fill(JSON.stringify(json)) await wsSent @@ -310,10 +310,10 @@ test.describe('Image kubernetes config from JSON', () => { }) test('Annotations should be saved', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'annotations-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { projectId, versionId, imageConfigId } = await setup(page, 'annotations-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) @@ -327,15 +327,15 @@ test.describe('Image kubernetes config from JSON', () => { const jsonEditor = await page.locator('textarea') const json = JSON.parse(await jsonEditor.inputValue()) - let wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchDeploymentAnnotations(key, value)) + let wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchDeploymentAnnotations(key, value)) json.annotations = { deployment: { [key]: value } } await jsonEditor.fill(JSON.stringify(json)) await wsSent - wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchServiceAnnotations(key, value)) + wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchServiceAnnotations(key, value)) json.annotations = { deployment: { [key]: value }, service: { [key]: value } } await jsonEditor.fill(JSON.stringify(json)) await wsSent - wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchIngressAnnotations(key, value)) + wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchIngressAnnotations(key, value)) json.annotations = { deployment: { [key]: value }, service: { [key]: value }, ingress: { [key]: value } } await jsonEditor.fill(JSON.stringify(json)) await wsSent diff --git a/web/crux-ui/e2e/with-login/deployment/deployment-copy.spec.ts b/web/crux-ui/e2e/with-login/deployment/deployment-copy.spec.ts index 72b356a47..76e850913 100644 --- a/web/crux-ui/e2e/with-login/deployment/deployment-copy.spec.ts +++ b/web/crux-ui/e2e/with-login/deployment/deployment-copy.spec.ts @@ -1,4 +1,4 @@ -import { WS_TYPE_PATCH_IMAGE, WS_TYPE_PATCH_INSTANCE } from '@app/models' +import { WS_TYPE_PATCH_CONFIG, WS_TYPE_PATCH_INSTANCE } from '@app/models' import { Page, expect } from '@playwright/test' import { wsPatchMatchEverySecret, wsPatchMatchNonNullSecretValues } from 'e2e/utils/websocket-match' import { DAGENT_NODE, NGINX_TEST_IMAGE_WITH_TAG, TEAM_ROUTES, waitForURLExcept } from '../../utils/common' @@ -21,7 +21,7 @@ const addSecretToImage = async ( secretKeys: string[], ): Promise => { const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) @@ -33,7 +33,7 @@ const addSecretToImage = async ( const json = JSON.parse(await jsonEditor.inputValue()) json.secrets = secretKeys.map(key => ({ key, required: false })) - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchEverySecret(secretKeys)) + const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchEverySecret(secretKeys)) await jsonEditor.fill(JSON.stringify(json)) await wsSent } @@ -73,9 +73,9 @@ test.describe('Deployment Copy', () => { await createNode(page, newNodeName) const versionId = await createVersion(page, projectId, '0.1.0', 'Incremental') - const imageId = await createImage(page, projectId, versionId, NGINX_TEST_IMAGE_WITH_TAG) + const imageConfigId = await createImage(page, projectId, versionId, NGINX_TEST_IMAGE_WITH_TAG) - await addSecretToImage(page, projectId, versionId, imageId, secretKeys) + await addSecretToImage(page, projectId, versionId, imageConfigId, secretKeys) const { id: deploymentId } = await addDeploymentToVersion(page, projectId, versionId, DAGENT_NODE, { prefix: originalPrefix, diff --git a/web/crux-ui/e2e/with-login/deployment/deployment-copyability-versioned.spec.ts b/web/crux-ui/e2e/with-login/deployment/deployment-copyability-versioned.spec.ts index 39b799f2d..7a78d13bd 100644 --- a/web/crux-ui/e2e/with-login/deployment/deployment-copyability-versioned.spec.ts +++ b/web/crux-ui/e2e/with-login/deployment/deployment-copyability-versioned.spec.ts @@ -1,11 +1,11 @@ -import { ProjectType, WS_TYPE_PATCH_IMAGE } from '@app/models' +import { ProjectType, WS_TYPE_PATCH_CONFIG } from '@app/models' import { Page, expect } from '@playwright/test' import { NGINX_TEST_IMAGE_WITH_TAG, TEAM_ROUTES, waitForURLExcept } from '../../utils/common' import { deployWithDagent } from '../../utils/node-helper' import { createNode } from '../../utils/nodes' import { addDeploymentToVersion, - createImage, + createImage as imageConfigId, createProject, createVersion, fillDeploymentPrefix, @@ -39,7 +39,7 @@ test.describe('Versioned Project', () => { const { projectId } = await setup(page, nodeName, projectName, 'versioned') const versionId = await createVersion(page, projectId, '0.1.0', 'Incremental') - await createImage(page, projectId, versionId, NGINX_TEST_IMAGE_WITH_TAG) + await imageConfigId(page, projectId, versionId, NGINX_TEST_IMAGE_WITH_TAG) const { id: deploymentId } = await addDeploymentToVersion(page, projectId, versionId, nodeName, { prefix }) await page.goto(TEAM_ROUTES.deployment.details(deploymentId)) @@ -66,7 +66,7 @@ test.describe('Versioned Project', () => { const { projectId } = await setup(page, nodeName, projectName, 'versioned') const versionId = await createVersion(page, projectId, '0.1.0', 'Incremental') - await createImage(page, projectId, versionId, NGINX_TEST_IMAGE_WITH_TAG) + await imageConfigId(page, projectId, versionId, NGINX_TEST_IMAGE_WITH_TAG) const { id: deploymentId } = await addDeploymentToVersion(page, projectId, versionId, nodeName, { prefix }) await page.goto(TEAM_ROUTES.deployment.details(deploymentId)) @@ -93,7 +93,7 @@ test.describe('Versioned Project', () => { const { projectId } = await setup(page, nodeName, projectName, 'versioned') const versionId = await createVersion(page, projectId, '1.0.0', 'Incremental') - await createImage(page, projectId, versionId, NGINX_TEST_IMAGE_WITH_TAG) + await imageConfigId(page, projectId, versionId, NGINX_TEST_IMAGE_WITH_TAG) await addDeploymentToVersion(page, projectId, versionId, nodeName, { prefix }) await page.goto(TEAM_ROUTES.deployment.list()) @@ -118,10 +118,10 @@ test.describe('Versioned Project', () => { const projectId = await createProject(page, projectName, 'versioned') const versionId = await createVersion(page, projectId, '0.1.0', 'Incremental') - const imageId = await createImage(page, projectId, versionId, NGINX_TEST_IMAGE_WITH_TAG) + const imageId = await imageConfigId(page, projectId, versionId, NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) @@ -145,7 +145,7 @@ test.describe('Versioned Project', () => { useParentConfig: false, }, ] - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE) + const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG) await jsonContainer.fill(JSON.stringify(configObject)) await wsSent diff --git a/web/crux-ui/e2e/with-login/deployment/deployment-deletability.spec.ts b/web/crux-ui/e2e/with-login/deployment/deployment-deletability.spec.ts index 818ac7305..62ba1da13 100644 --- a/web/crux-ui/e2e/with-login/deployment/deployment-deletability.spec.ts +++ b/web/crux-ui/e2e/with-login/deployment/deployment-deletability.spec.ts @@ -4,17 +4,17 @@ import { NGINX_TEST_IMAGE_WITH_TAG, TEAM_ROUTES } from 'e2e/utils/common' import { deployWithDagent } from '../../utils/node-helper' import { addImageToVersion, createImage, createProject, createVersion } from '../../utils/projects' import { waitSocketRef, wsPatchSent } from '../../utils/websocket' -import { WS_TYPE_PATCH_IMAGE } from '@app/models' +import { WS_TYPE_PATCH_CONFIG } from '@app/models' test('In progress deployment should be not deletable', async ({ page }) => { const projectName = 'project-delete-test-1' const projectId = await createProject(page, projectName, 'versioned') const versionId = await createVersion(page, projectId, '0.1.0', 'Incremental') - const imageId = await createImage(page, projectId, versionId, 'nginx') + const imageConfigId = await createImage(page, projectId, versionId, 'nginx') const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) @@ -38,7 +38,7 @@ test('In progress deployment should be not deletable', async ({ page }) => { useParentConfig: false, }, ] - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE) + const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG) await jsonContainer.fill(JSON.stringify(configObject)) await wsSent diff --git a/web/crux-ui/e2e/with-login/image-config.spec.ts b/web/crux-ui/e2e/with-login/image-config.spec.ts index 88d17dcd2..a03b93299 100644 --- a/web/crux-ui/e2e/with-login/image-config.spec.ts +++ b/web/crux-ui/e2e/with-login/image-config.spec.ts @@ -1,32 +1,32 @@ +import { WS_TYPE_PATCH_CONFIG } from '@app/models' import { expect, Page } from '@playwright/test' -import { test } from '../utils/test.fixture' import { NGINX_TEST_IMAGE_WITH_TAG, screenshotPath, TEAM_ROUTES } from '../utils/common' import { createImage, createProject, createVersion } from '../utils/projects' +import { test } from '../utils/test.fixture' import { waitSocketRef, wsPatchSent } from '../utils/websocket' -import { WS_TYPE_PATCH_IMAGE } from '@app/models' const setup = async ( page: Page, projectName: string, versionName: string, imageName: string, -): Promise<{ projectId: string; versionId: string; imageId: string }> => { +): Promise<{ projectId: string; versionId: string; imageConfigId: string }> => { const projectId = await createProject(page, projectName, 'versioned') const versionId = await createVersion(page, projectId, versionName, 'Incremental') - const imageId = await createImage(page, projectId, versionId, imageName) + const imageConfigId = await createImage(page, projectId, versionId, imageName) return { projectId, versionId, - imageId, + imageConfigId, } } test.describe('View state', () => { test('Editor state should show the configuration fields', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'editor-state-conf', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'editor-state-conf', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const editorButton = await page.waitForSelector('button:has-text("Editor")') @@ -40,9 +40,9 @@ test.describe('View state', () => { }) test('JSON state should show the json editor', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'editor-state-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'editor-state-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const jsonEditorButton = await page.waitForSelector('button:has-text("JSON")') @@ -57,9 +57,9 @@ test.describe('View state', () => { test.describe('Filters', () => { test('None should be selected by default', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'filter-all', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'filter-all', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const allButton = await page.locator('button:has-text("All")') @@ -69,9 +69,9 @@ test.describe('Filters', () => { }) test('All should not be selected if one of the main filters are not selected', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'filter-select', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'filter-select', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') await page.locator(`button:has-text("Common")`).first().click() @@ -82,9 +82,9 @@ test.describe('Filters', () => { }) test('Main filter should not be selected if one of its sub filters are not selected', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'sub-filter', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'sub-filter', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const subFilter = await page.locator(`button:has-text("Network mode")`) @@ -96,9 +96,9 @@ test.describe('Filters', () => { }) test('Config field should be invisible if its sub filter is not selected', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'sub-deselect', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'sub-deselect', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const subFilter = await page.locator(`button:has-text("Deployment strategy")`) @@ -119,17 +119,17 @@ const wsPatchMatchPorts = (internalPort: string, externalPort?: string) => (payl test.describe('Image configurations', () => { test('Port should be saved after adding it from the config field', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'port-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { projectId, versionId, imageConfigId } = await setup(page, 'port-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) await page.locator('button:has-text("Ports")').click() - let wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE) + let wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG) const addPortsButton = await page.locator(`[src="/plus.svg"]:right-of(label:has-text("Ports"))`).first() await addPortsButton.click() await wsSent @@ -140,7 +140,7 @@ test.describe('Image configurations', () => { const internalInput = page.locator('input[placeholder="Internal"]') const externalInput = page.locator('input[placeholder="External"]') - wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchPorts(internal, external)) + wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchPorts(internal, external)) await internalInput.type(internal) await externalInput.type(external) await wsSent @@ -152,10 +152,10 @@ test.describe('Image configurations', () => { }) test('Port should be saved after adding it from the json editor', async ({ page }) => { - const { projectId, versionId, imageId } = await setup(page, 'port-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { projectId, versionId, imageConfigId } = await setup(page, 'port-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) + await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) @@ -172,7 +172,7 @@ test.describe('Image configurations', () => { const json = JSON.parse(await jsonEditor.inputValue()) json.ports = [{ internal: internalAsNumber, external: externalAsNumber }] - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE, wsPatchMatchPorts(internal, external)) + const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchPorts(internal, external)) await jsonEditor.fill(JSON.stringify(json)) await wsSent diff --git a/web/crux-ui/e2e/with-login/resource-copy.spec.ts b/web/crux-ui/e2e/with-login/resource-copy.spec.ts index 86dd95955..947ec6be4 100644 --- a/web/crux-ui/e2e/with-login/resource-copy.spec.ts +++ b/web/crux-ui/e2e/with-login/resource-copy.spec.ts @@ -1,4 +1,4 @@ -import { WS_TYPE_PATCH_IMAGE, WS_TYPE_PATCH_INSTANCE } from '@app/models' +import { WS_TYPE_PATCH_CONFIG, WS_TYPE_PATCH_INSTANCE } from '@app/models' import { expect } from '@playwright/test' import { DAGENT_NODE, NGINX_TEST_IMAGE_WITH_TAG, TEAM_ROUTES, waitForURLExcept } from 'e2e/utils/common' import { addPortsToContainerConfig } from 'e2e/utils/container-config' @@ -51,17 +51,17 @@ test.describe('Deleting default version', () => { const projectId = await createProject(page, projectName, 'versioned') const defaultVersionName = 'default-version' const defaultVersionId = await createVersion(page, projectId, defaultVersionName, 'Rolling') - const defaultVersionImageId = await createImage(page, projectId, defaultVersionId, NGINX_TEST_IMAGE_WITH_TAG) + const imageConfigId = await createImage(page, projectId, defaultVersionId, NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(defaultVersionId, defaultVersionImageId)) + await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(defaultVersionId, imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(defaultVersionId) const internal = '1000' const external = '2000' - await addPortsToContainerConfig(page, ws, wsRoute, WS_TYPE_PATCH_IMAGE, internal, external) + await addPortsToContainerConfig(page, ws, wsRoute, WS_TYPE_PATCH_CONFIG, internal, external) const newVersionId = await createVersion(page, projectId, 'new-version', 'Rolling') diff --git a/web/crux/src/app/container/container-config.service.ts b/web/crux/src/app/container/container-config.service.ts index f0c05a9bd..0c736e400 100644 --- a/web/crux/src/app/container/container-config.service.ts +++ b/web/crux/src/app/container/container-config.service.ts @@ -259,7 +259,17 @@ export default class ContainerConfigService { }) } - const data: ContainerConfigData = req.config ?? {} + const config = await this.prisma.containerConfig.findUnique({ + where: { + id: configId, + }, + }) + + const data: ContainerConfigData = this.mapper.configDtoToConfigData( + config as any as ContainerConfigData, + req.config ?? {}, + ) + if (req.resetSection) { data[req.resetSection] = null } From f42e87fa5a14ccbc5ae3fceb5cb16bd17c443f23 Mon Sep 17 00:00:00 2001 From: Mate Vago Date: Wed, 4 Dec 2024 12:20:03 +0100 Subject: [PATCH 10/13] build: disable e2e --- .github/workflows/deploy_external.yaml | 2 +- .github/workflows/product_builder.yaml | 32 +++++++++++++------------- web/crux-ui/package.json | 2 +- web/crux/package.json | 2 +- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/.github/workflows/deploy_external.yaml b/.github/workflows/deploy_external.yaml index 1702f0c27..cd8bca666 100644 --- a/.github/workflows/deploy_external.yaml +++ b/.github/workflows/deploy_external.yaml @@ -5,7 +5,7 @@ on: workflows: - 'product_builder' branches: - - 'develop' + - 'feat/release-candidate' types: - completed permissions: diff --git a/.github/workflows/product_builder.yaml b/.github/workflows/product_builder.yaml index 004630222..562aa2054 100644 --- a/.github/workflows/product_builder.yaml +++ b/.github/workflows/product_builder.yaml @@ -69,9 +69,9 @@ jobs: crux: ${{ steps.filter.outputs.crux }} cruxui: ${{ steps.filter.outputs.cruxui }} kratos: ${{ steps.filter.outputs.kratos }} - tag: ${{ steps.settag.outputs.tag }} + tag: "0.15.0-rc" # ${{ steps.settag.outputs.tag }} extratag: ${{ steps.settag.outputs.extratag }} - version: ${{ steps.settag.outputs.version }} + version: "0.15.0-rc" # ${{ steps.settag.outputs.version }} minorversion: ${{ steps.settag.outputs.minorversion }} release: ${{ steps.release.outputs.release }} steps: @@ -669,7 +669,7 @@ jobs: defaults: run: working-directory: ${{ env.GOLANG_WORKING_DIRECTORY }} - needs: [gather_changes, e2e] + needs: [gather_changes] if: | always() && (github.ref_name == 'develop' || github.ref_name == 'main' || github.ref_type == 'tag') && @@ -735,16 +735,16 @@ jobs: container: image: ghcr.io/dyrector-io/dyrectorio/builder-images/signer:2 needs: [gather_changes, go_push] - if: | - always() && - (github.ref_name == 'develop' || github.ref_name == 'main' || github.ref_type == 'tag') && - needs.e2e.result == 'success' && - needs.go_build.result == 'success' && - (needs.crux_build.result == 'success' || needs.crux_build.result == 'skipped') && - (needs.crux-ui_build.result == 'success' || needs.crux-ui_build.result == 'skipped') && - (needs.kratos_build.result == 'success' || needs.kratos_build.result == 'skipped') && - needs.conventional_commits.result == 'success' && - needs.gather_changes.result == 'success' && needs.go_push.result == 'success' + # if: | + # always() && + # (github.ref_name == 'develop' || github.ref_name == 'main' || github.ref_type == 'tag') && + # needs.e2e.result == 'success' && + # needs.go_build.result == 'success' && + # (needs.crux_build.result == 'success' || needs.crux_build.result == 'skipped') && + # (needs.crux-ui_build.result == 'success' || needs.crux-ui_build.result == 'skipped') && + # (needs.kratos_build.result == 'success' || needs.kratos_build.result == 'skipped') && + # needs.conventional_commits.result == 'success' && + # needs.gather_changes.result == 'success' && needs.go_push.result == 'success' environment: Workflow - Protected steps: - name: Login to GHCR @@ -800,7 +800,7 @@ jobs: runs-on: ubuntu-22.04 container: image: ghcr.io/dyrector-io/dyrectorio/builder-images/signer:2 - needs: [crux_build, e2e, gather_changes] + needs: [crux_build, gather_changes] if: | always() && (github.ref_name == 'develop' || github.ref_name == 'main' || github.ref_type == 'tag') && @@ -863,7 +863,7 @@ jobs: runs-on: ubuntu-22.04 container: image: ghcr.io/dyrector-io/dyrectorio/builder-images/signer:2 - needs: [crux-ui_build, e2e, gather_changes] + needs: [crux-ui_build, gather_changes] if: | always() && (github.ref_name == 'develop' || github.ref_name == 'main' || github.ref_type == 'tag') && @@ -926,7 +926,7 @@ jobs: runs-on: ubuntu-22.04 container: image: ghcr.io/dyrector-io/dyrectorio/builder-images/signer:2 - needs: [kratos_build, e2e, gather_changes] + needs: [kratos_build, gather_changes] if: | always() && (github.ref_name == 'develop' || github.ref_name == 'main' || github.ref_type == 'tag') && diff --git a/web/crux-ui/package.json b/web/crux-ui/package.json index 2ae23b454..83f8ca63d 100644 --- a/web/crux-ui/package.json +++ b/web/crux-ui/package.json @@ -1,6 +1,6 @@ { "name": "crux-ui", - "version": "0.14.1", + "version": "0.15.0-rc", "description": "Open-source delivery platform that helps developers to deliver applications efficiently by simplifying software releases and operations in any environment.", "author": "dyrector.io", "private": true, diff --git a/web/crux/package.json b/web/crux/package.json index 4c92c568b..936f80181 100644 --- a/web/crux/package.json +++ b/web/crux/package.json @@ -1,6 +1,6 @@ { "name": "crux", - "version": "0.14.1", + "version": "0.15.0-rc", "description": "Open-source delivery platform that helps developers to deliver applications efficiently by simplifying software releases and operations in any environment.", "author": "dyrector.io", "private": true, From 44d73cade90212288fde7984a41ea1e8629cb132 Mon Sep 17 00:00:00 2001 From: Mate Vago Date: Wed, 4 Dec 2024 12:24:51 +0100 Subject: [PATCH 11/13] fix: remove e2e need --- .github/workflows/product_builder.yaml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/product_builder.yaml b/.github/workflows/product_builder.yaml index 562aa2054..9df64e9f4 100644 --- a/.github/workflows/product_builder.yaml +++ b/.github/workflows/product_builder.yaml @@ -673,7 +673,6 @@ jobs: if: | always() && (github.ref_name == 'develop' || github.ref_name == 'main' || github.ref_type == 'tag') && - needs.e2e.result == 'success' && needs.go_build.result == 'success' && (needs.crux_build.result == 'success' || needs.crux_build.result == 'skipped') && (needs.crux-ui_build.result == 'success' || needs.crux-ui_build.result == 'skipped') && @@ -804,7 +803,6 @@ jobs: if: | always() && (github.ref_name == 'develop' || github.ref_name == 'main' || github.ref_type == 'tag') && - needs.e2e.result == 'success' && (needs.go_build.result == 'success' || needs.go_build.result == 'skipped') && needs.crux_build.result == 'success' && (needs.crux-ui_build.result == 'success' || needs.crux-ui_build.result == 'skipped') && @@ -867,7 +865,6 @@ jobs: if: | always() && (github.ref_name == 'develop' || github.ref_name == 'main' || github.ref_type == 'tag') && - needs.e2e.result == 'success' && (needs.go_build.result == 'success' || needs.go_build.result == 'skipped') && (needs.crux_build.result == 'success' || needs.crux_build.result == 'skipped') && needs.crux-ui_build.result == 'success' && @@ -930,7 +927,6 @@ jobs: if: | always() && (github.ref_name == 'develop' || github.ref_name == 'main' || github.ref_type == 'tag') && - needs.e2e.result == 'success' && (needs.go_build.result == 'success' || needs.go_build.result == 'skipped') && (needs.crux_build.result == 'success' || needs.crux_build.result == 'skipped') && (needs.crux-ui_build.result == 'success' || needs.crux-ui_build.result == 'skipped') && From e6b85801d9a807c16c0f484a1fbe756f8e882ec1 Mon Sep 17 00:00:00 2001 From: Mate Vago Date: Wed, 4 Dec 2024 12:34:10 +0100 Subject: [PATCH 12/13] fix: lint --- .../container-config/common-editor.spec.ts | 83 ++++++++----------- .../container-config-filters.spec.ts | 18 ++-- .../container-config/docker-editor.spec.ts | 39 +++------ .../container-config/docker-json.spec.ts | 29 +++---- .../image-config-view-state.spec.ts | 12 +-- .../kubernetes-editor.spec.ts | 71 ++++------------ .../container-config/kubernetes-json.spec.ts | 65 +++++---------- .../deployment/deployment-copy.spec.ts | 2 +- .../deployment-copyability-versioned.spec.ts | 18 ++-- .../deployment-deletability.spec.ts | 2 +- .../e2e/with-login/image-config.spec.ts | 8 +- 11 files changed, 122 insertions(+), 225 deletions(-) diff --git a/web/crux-ui/e2e/with-login/container-config/common-editor.spec.ts b/web/crux-ui/e2e/with-login/container-config/common-editor.spec.ts index fd56c19a6..6fa73895e 100644 --- a/web/crux-ui/e2e/with-login/container-config/common-editor.spec.ts +++ b/web/crux-ui/e2e/with-login/container-config/common-editor.spec.ts @@ -1,5 +1,5 @@ +import { WS_TYPE_PATCH_CONFIG } from '@app/models' import { expect, Page } from '@playwright/test' -import { test } from '../../utils/test.fixture' import { NGINX_TEST_IMAGE_WITH_TAG, TEAM_ROUTES } from 'e2e/utils/common' import { createStorage } from 'e2e/utils/storages' import { @@ -20,33 +20,33 @@ import { wsPatchMatchVolume, } from 'e2e/utils/websocket-match' import { createImage, createProject, createVersion } from '../../utils/projects' +import { test } from '../../utils/test.fixture' import { waitSocketRef, wsPatchSent } from '../../utils/websocket' -import { WS_TYPE_PATCH_CONFIG } from '@app/models' const setup = async ( page: Page, projectName: string, versionName: string, imageName: string, -): Promise<{ projectId: string; versionId: string; imageId: string }> => { +): Promise<{ imageConfigId: string }> => { const projectId = await createProject(page, projectName, 'versioned') const versionId = await createVersion(page, projectId, versionName, 'Incremental') const imageConfigId = await createImage(page, projectId, versionId, imageName) - return { projectId, versionId, imageConfigId } + return { imageConfigId } } test.describe.configure({ mode: 'parallel' }) test.describe('Image common config from editor', () => { test('Container name should be saved', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup(page, 'name-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'name-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) const name = 'new-container-name' @@ -60,13 +60,13 @@ test.describe('Image common config from editor', () => { }) test('Expose strategy should be saved', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup(page, 'expose-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'expose-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchExpose('exposeWithTls')) await page.getByRole('button', { name: 'HTTPS', exact: true }).click() @@ -78,13 +78,13 @@ test.describe('Image common config from editor', () => { }) test('User should be saved', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup(page, 'user-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'user-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) const user = 23 @@ -98,13 +98,13 @@ test.describe('Image common config from editor', () => { }) test('TTY should be saved', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup(page, 'tty-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'tty-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) await page.locator('button:has-text("TTY")').click() @@ -118,13 +118,13 @@ test.describe('Image common config from editor', () => { }) test('Port should be saved', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup(page, 'port-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'port-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) await page.locator('button:has-text("Ports")').click() @@ -148,13 +148,13 @@ test.describe('Image common config from editor', () => { }) test('Port ranges should be saved', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup(page, 'port-range-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'port-range-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) await page.locator('button:has-text("Port ranges")').click() @@ -191,13 +191,13 @@ test.describe('Image common config from editor', () => { }) test('Secrets should be saved', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup(page, 'secrets-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'secrets-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) await page.locator('button:has-text("Secrets")').click() @@ -217,13 +217,13 @@ test.describe('Image common config from editor', () => { }) test('Commands should be saved', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup(page, 'commands-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'commands-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) await page.locator('button:has-text("Commands")').click() @@ -240,13 +240,13 @@ test.describe('Image common config from editor', () => { }) test('Arguments should be saved', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup(page, 'arguments-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'arguments-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) await page.locator('button:has-text("Arguments")').click() @@ -263,12 +263,12 @@ test.describe('Image common config from editor', () => { }) test('Routing should be saved', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup(page, 'routing-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'routing-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) await page.locator('button:has-text("Ports")').click() @@ -314,17 +314,12 @@ test.describe('Image common config from editor', () => { }) test('Environment should be saved', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup( - page, - 'environment-editor', - '1.0.0', - NGINX_TEST_IMAGE_WITH_TAG, - ) + const { imageConfigId } = await setup(page, 'environment-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) await page.locator('button:has-text("Environment")').click() @@ -343,17 +338,12 @@ test.describe('Image common config from editor', () => { }) test('Config container should be saved', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup( - page, - 'config-container-editor', - '1.0.0', - NGINX_TEST_IMAGE_WITH_TAG, - ) + const { imageConfigId } = await setup(page, 'config-container-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) await page.locator('button:has-text("Config container")').click() const confDiv = page.locator('div.grid:has(label:has-text("CONFIG CONTAINER"))') @@ -378,17 +368,12 @@ test.describe('Image common config from editor', () => { }) test('Init containers should be saved', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup( - page, - 'init-container-editor', - '1.0.0', - NGINX_TEST_IMAGE_WITH_TAG, - ) + const { imageConfigId } = await setup(page, 'init-container-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) const name = 'container-name' const image = 'image' @@ -436,12 +421,12 @@ test.describe('Image common config from editor', () => { }) test('Volume should be saved', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup(page, 'volume-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'volume-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) await page.locator('button:has-text("Volume")').click() @@ -470,7 +455,7 @@ test.describe('Image common config from editor', () => { }) test('Storage should be saved', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup(page, 'storage-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'storage-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const storageName = 'image-editor-storage' const storageId = await createStorage(page, storageName, 'storage.com', '1234', '12345') @@ -479,7 +464,7 @@ test.describe('Image common config from editor', () => { await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) await page.locator('button:has-text("Volume")').click() diff --git a/web/crux-ui/e2e/with-login/container-config/container-config-filters.spec.ts b/web/crux-ui/e2e/with-login/container-config/container-config-filters.spec.ts index 12d4e5598..fbf3249a5 100644 --- a/web/crux-ui/e2e/with-login/container-config/container-config-filters.spec.ts +++ b/web/crux-ui/e2e/with-login/container-config/container-config-filters.spec.ts @@ -1,28 +1,24 @@ import { expect, Page } from '@playwright/test' -import { test } from '../../utils/test.fixture' import { NGINX_TEST_IMAGE_WITH_TAG, TEAM_ROUTES } from 'e2e/utils/common' import { createImage, createProject, createVersion } from '../../utils/projects' +import { test } from '../../utils/test.fixture' const setup = async ( page: Page, projectName: string, versionName: string, imageName: string, -): Promise<{ projectId: string; versionId: string; imageId: string }> => { +): Promise<{ imageConfigId: string }> => { const projectId = await createProject(page, projectName, 'versioned') const versionId = await createVersion(page, projectId, versionName, 'Incremental') const imageConfigId = await createImage(page, projectId, versionId, imageName) - return { - projectId, - versionId, - imageConfigId, - } + return { imageConfigId } } test.describe('Filters', () => { test('None should be selected by default', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup(page, 'filter-all', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'filter-all', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') @@ -34,7 +30,7 @@ test.describe('Filters', () => { }) test('All should not be selected if one of the main filters are not selected', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup(page, 'filter-select', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'filter-select', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') @@ -47,7 +43,7 @@ test.describe('Filters', () => { }) test('Main filter should not be selected if one of its sub filters are not selected', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup(page, 'sub-filter', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'sub-filter', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') @@ -62,7 +58,7 @@ test.describe('Filters', () => { }) test('Config field should be invisible if its sub filter is not selected', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup(page, 'sub-deselect', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'sub-deselect', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') diff --git a/web/crux-ui/e2e/with-login/container-config/docker-editor.spec.ts b/web/crux-ui/e2e/with-login/container-config/docker-editor.spec.ts index 04b04e169..7a68cc2e8 100644 --- a/web/crux-ui/e2e/with-login/container-config/docker-editor.spec.ts +++ b/web/crux-ui/e2e/with-login/container-config/docker-editor.spec.ts @@ -17,27 +17,22 @@ const setup = async ( projectName: string, versionName: string, imageName: string, -): Promise<{ projectId: string; versionId: string; imageId: string }> => { +): Promise<{ imageConfigId: string }> => { const projectId = await createProject(page, projectName, 'versioned') const versionId = await createVersion(page, projectId, versionName, 'Incremental') const imageConfigId = await createImage(page, projectId, versionId, imageName) - return { projectId, versionId, imageConfigId: imageConfigId } + return { imageConfigId } } test.describe('Image docker config from editor', () => { test('Network mode should be saved', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup( - page, - 'networkmode-editor', - '1.0.0', - NGINX_TEST_IMAGE_WITH_TAG, - ) + const { imageConfigId } = await setup(page, 'networkmode-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) const mode = 'host' @@ -53,17 +48,12 @@ test.describe('Image docker config from editor', () => { }) test('Docker labels should be saved', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup( - page, - 'dockerlabel-editor', - '1.0.0', - NGINX_TEST_IMAGE_WITH_TAG, - ) + const { imageConfigId } = await setup(page, 'dockerlabel-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) const key = 'docker-key' const value = 'docker-value' @@ -84,17 +74,12 @@ test.describe('Image docker config from editor', () => { }) test('Restart policy should be saved', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup( - page, - 'restartpolicy-editor', - '1.0.0', - NGINX_TEST_IMAGE_WITH_TAG, - ) + const { imageConfigId } = await setup(page, 'restartpolicy-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG, wsPatchMatchRestartPolicy('always')) await page.locator('div.grid:has(label:has-text("RESTART POLICY")) button:has-text("Always")').click() @@ -108,12 +93,12 @@ test.describe('Image docker config from editor', () => { }) test('Log config should be saved', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup(page, 'logconfig-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'logconfig-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) await page.locator('button:has-text("Log config")').click() @@ -137,12 +122,12 @@ test.describe('Image docker config from editor', () => { }) test('Networks should be saved', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup(page, 'networks-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'networks-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) await page.locator('button:has-text("Networks")').click() diff --git a/web/crux-ui/e2e/with-login/container-config/docker-json.spec.ts b/web/crux-ui/e2e/with-login/container-config/docker-json.spec.ts index 507b3d2bc..ab69528e8 100644 --- a/web/crux-ui/e2e/with-login/container-config/docker-json.spec.ts +++ b/web/crux-ui/e2e/with-login/container-config/docker-json.spec.ts @@ -17,24 +17,24 @@ const setup = async ( projectName: string, versionName: string, imageName: string, -): Promise<{ projectId: string; versionId: string; imageId: string }> => { +): Promise<{ imageConfigId: string }> => { const projectId = await createProject(page, projectName, 'versioned') const versionId = await createVersion(page, projectId, versionName, 'Incremental') const imageConfigId = await createImage(page, projectId, versionId, imageName) - return { projectId, versionId, imageConfigId: imageConfigId } + return { imageConfigId } } test.describe.configure({ mode: 'parallel' }) test.describe('Image docker config from JSON', () => { test('Network mode should be saved', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup(page, 'networkmode-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'networkmode-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) const mode = 'host' @@ -57,12 +57,12 @@ test.describe('Image docker config from JSON', () => { }) test('Docker labels should be saved', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup(page, 'dockerlabel-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'dockerlabel-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) const key = 'docker-key' const value = 'docker-value' @@ -89,17 +89,12 @@ test.describe('Image docker config from JSON', () => { }) test('Restart policy should be saved', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup( - page, - 'restartpolicy-json', - '1.0.0', - NGINX_TEST_IMAGE_WITH_TAG, - ) + const { imageConfigId } = await setup(page, 'restartpolicy-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) const jsonEditorButton = await page.waitForSelector('button:has-text("JSON")') await jsonEditorButton.click() @@ -120,12 +115,12 @@ test.describe('Image docker config from JSON', () => { }) test('Log config should be saved', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup(page, 'logconfig-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'logconfig-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) const type = 'json-file' const key = 'logger-key' @@ -151,12 +146,12 @@ test.describe('Image docker config from JSON', () => { }) test('Networks should be saved', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup(page, 'networks-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'networks-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) await page.locator('button:has-text("Networks")').click() diff --git a/web/crux-ui/e2e/with-login/container-config/image-config-view-state.spec.ts b/web/crux-ui/e2e/with-login/container-config/image-config-view-state.spec.ts index fde1249dc..414acbf56 100644 --- a/web/crux-ui/e2e/with-login/container-config/image-config-view-state.spec.ts +++ b/web/crux-ui/e2e/with-login/container-config/image-config-view-state.spec.ts @@ -8,21 +8,17 @@ const setup = async ( projectName: string, versionName: string, imageName: string, -): Promise<{ projectId: string; versionId: string; imageId: string }> => { +): Promise<{ imageConfigId: string }> => { const projectId = await createProject(page, projectName, 'versioned') const versionId = await createVersion(page, projectId, versionName, 'Incremental') const imageConfigId = await createImage(page, projectId, versionId, imageName) - return { - projectId, - versionId, - imageId: imageConfigId, - } + return { imageConfigId } } test.describe('View state', () => { test('Editor state should show the configuration fields', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup(page, 'editor-state-conf', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'editor-state-conf', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') @@ -39,7 +35,7 @@ test.describe('View state', () => { }) test('JSON state should show the json editor', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup(page, 'editor-state-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'editor-state-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') diff --git a/web/crux-ui/e2e/with-login/container-config/kubernetes-editor.spec.ts b/web/crux-ui/e2e/with-login/container-config/kubernetes-editor.spec.ts index ef3d1b0e1..972d7a16f 100644 --- a/web/crux-ui/e2e/with-login/container-config/kubernetes-editor.spec.ts +++ b/web/crux-ui/e2e/with-login/container-config/kubernetes-editor.spec.ts @@ -25,28 +25,23 @@ const setup = async ( projectName: string, versionName: string, imageName: string, -): Promise<{ projectId: string; versionId: string; imageId: string }> => { +): Promise<{ imageConfigId: string }> => { const projectId = await createProject(page, projectName, 'versioned') const versionId = await createVersion(page, projectId, versionName, 'Incremental') const imageConfigId = await createImage(page, projectId, versionId, imageName) - return { projectId, versionId, imageConfigId: imageConfigId } + return { imageConfigId } } test.describe('Image kubernetes config from editor', () => { test('Deployment strategy should be saved', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup( - page, - 'deployment-strategy-editor', - '1.0.0', - NGINX_TEST_IMAGE_WITH_TAG, - ) + const { imageConfigId } = await setup(page, 'deployment-strategy-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) const strategy = 'rolling' @@ -60,18 +55,13 @@ test.describe('Image kubernetes config from editor', () => { }) test('Custom headers should be saved', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup( - page, - 'custom-headers-editor', - '1.0.0', - NGINX_TEST_IMAGE_WITH_TAG, - ) + const { imageConfigId } = await setup(page, 'custom-headers-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) await page.locator('button:has-text("Custom headers")').click() @@ -90,18 +80,13 @@ test.describe('Image kubernetes config from editor', () => { }) test('Proxy headers should be saved', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup( - page, - 'proxy-headers-editor', - '1.0.0', - NGINX_TEST_IMAGE_WITH_TAG, - ) + const { imageConfigId } = await setup(page, 'proxy-headers-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) await page.locator('button:has-text("Proxy headers")').click() @@ -115,18 +100,13 @@ test.describe('Image kubernetes config from editor', () => { }) test('Load balancer should be saved', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup( - page, - 'load-balancer-editor', - '1.0.0', - NGINX_TEST_IMAGE_WITH_TAG, - ) + const { imageConfigId } = await setup(page, 'load-balancer-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) await page.locator('button:has-text("Use load balancer")').click() @@ -159,18 +139,13 @@ test.describe('Image kubernetes config from editor', () => { }) test('Health check config should be saved', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup( - page, - 'health-check-editor', - '1.0.0', - NGINX_TEST_IMAGE_WITH_TAG, - ) + const { imageConfigId } = await setup(page, 'health-check-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) await page.locator('button:has-text("Health check config")').click() @@ -202,17 +177,12 @@ test.describe('Image kubernetes config from editor', () => { }) test('Resource config should be saved', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup( - page, - 'resource-config-editor', - '1.0.0', - NGINX_TEST_IMAGE_WITH_TAG, - ) + const { imageConfigId } = await setup(page, 'resource-config-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) await page.locator('button:has-text("Resource config")').click() @@ -247,13 +217,13 @@ test.describe('Image kubernetes config from editor', () => { page.locator(`div.max-h-128 > div:nth-child(2):near(label:has-text("${category}"))`) test('Labels should be saved', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup(page, 'labels-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'labels-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) await page.getByRole('button', { name: 'Labels', exact: true }).click() @@ -288,18 +258,13 @@ test.describe('Image kubernetes config from editor', () => { }) test('Annotations should be saved', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup( - page, - 'annotations-editor', - '1.0.0', - NGINX_TEST_IMAGE_WITH_TAG, - ) + const { imageConfigId } = await setup(page, 'annotations-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) await page.getByRole('button', { name: 'Annotations', exact: true }).click() diff --git a/web/crux-ui/e2e/with-login/container-config/kubernetes-json.spec.ts b/web/crux-ui/e2e/with-login/container-config/kubernetes-json.spec.ts index 166bf48c6..3e372bf41 100644 --- a/web/crux-ui/e2e/with-login/container-config/kubernetes-json.spec.ts +++ b/web/crux-ui/e2e/with-login/container-config/kubernetes-json.spec.ts @@ -1,5 +1,5 @@ +import { WS_TYPE_PATCH_CONFIG } from '@app/models' import { expect, Page } from '@playwright/test' -import { test } from '../../utils/test.fixture' import { NGINX_TEST_IMAGE_WITH_TAG, TEAM_ROUTES } from 'e2e/utils/common' import { wsPatchMatchCustomHeader, @@ -17,36 +17,31 @@ import { wsPatchMatchServiceLabel, } from 'e2e/utils/websocket-match' import { createImage, createProject, createVersion } from '../../utils/projects' +import { test } from '../../utils/test.fixture' import { waitSocketRef, wsPatchSent } from '../../utils/websocket' -import { WS_TYPE_PATCH_CONFIG } from '@app/models' const setup = async ( page: Page, projectName: string, versionName: string, imageName: string, -): Promise<{ projectId: string; versionId: string; imageId: string }> => { +): Promise<{ imageConfigId: string }> => { const projectId = await createProject(page, projectName, 'versioned') const versionId = await createVersion(page, projectId, versionName, 'Incremental') const imageConfigId = await createImage(page, projectId, versionId, imageName) - return { projectId, versionId, imageConfigId: imageConfigId } + return { imageConfigId } } test.describe('Image kubernetes config from JSON', () => { test('Deployment strategy should be saved', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup( - page, - 'deployment-strategy-json', - '1.0.0', - NGINX_TEST_IMAGE_WITH_TAG, - ) + const { imageConfigId } = await setup(page, 'deployment-strategy-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) const strategy = 'rolling' @@ -67,18 +62,13 @@ test.describe('Image kubernetes config from JSON', () => { }) test('Custom headers should be saved', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup( - page, - 'custom-headers-json', - '1.0.0', - NGINX_TEST_IMAGE_WITH_TAG, - ) + const { imageConfigId } = await setup(page, 'custom-headers-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) const header = 'test-header' @@ -102,18 +92,13 @@ test.describe('Image kubernetes config from JSON', () => { }) test('Proxy headers should be saved', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup( - page, - 'proxy-headers-json', - '1.0.0', - NGINX_TEST_IMAGE_WITH_TAG, - ) + const { imageConfigId } = await setup(page, 'proxy-headers-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) const jsonEditorButton = await page.waitForSelector('button:has-text("JSON")') await jsonEditorButton.click() @@ -132,18 +117,13 @@ test.describe('Image kubernetes config from JSON', () => { }) test('Load balancer should be saved', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup( - page, - 'load-balancer-json', - '1.0.0', - NGINX_TEST_IMAGE_WITH_TAG, - ) + const { imageConfigId } = await setup(page, 'load-balancer-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) const key = 'balancer-key' const value = 'balancer-value' @@ -177,13 +157,13 @@ test.describe('Image kubernetes config from JSON', () => { }) test('Health check config should be saved', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup(page, 'health-check-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'health-check-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) const port = 12560 const liveness = 'test/liveness/' @@ -216,18 +196,13 @@ test.describe('Image kubernetes config from JSON', () => { }) test('Resource config should be saved', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup( - page, - 'resource-config-json', - '1.0.0', - NGINX_TEST_IMAGE_WITH_TAG, - ) + const { imageConfigId } = await setup(page, 'resource-config-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) const cpuLimits = '50' const cpuRequests = '25' @@ -266,13 +241,13 @@ test.describe('Image kubernetes config from JSON', () => { page.locator(`div.max-h-128 > div:nth-child(2):near(label:has-text("${category}"))`) test('Labels should be saved', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup(page, 'labels-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'labels-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) const key = 'label-key' const value = 'label-value' @@ -310,13 +285,13 @@ test.describe('Image kubernetes config from JSON', () => { }) test('Annotations should be saved', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup(page, 'annotations-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'annotations-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) const key = 'annotation-key' const value = 'annotation-value' diff --git a/web/crux-ui/e2e/with-login/deployment/deployment-copy.spec.ts b/web/crux-ui/e2e/with-login/deployment/deployment-copy.spec.ts index 76e850913..99bd90b95 100644 --- a/web/crux-ui/e2e/with-login/deployment/deployment-copy.spec.ts +++ b/web/crux-ui/e2e/with-login/deployment/deployment-copy.spec.ts @@ -24,7 +24,7 @@ const addSecretToImage = async ( await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) const jsonEditorButton = await page.waitForSelector('button:has-text("JSON")') await jsonEditorButton.click() diff --git a/web/crux-ui/e2e/with-login/deployment/deployment-copyability-versioned.spec.ts b/web/crux-ui/e2e/with-login/deployment/deployment-copyability-versioned.spec.ts index 7a78d13bd..5837f5cb0 100644 --- a/web/crux-ui/e2e/with-login/deployment/deployment-copyability-versioned.spec.ts +++ b/web/crux-ui/e2e/with-login/deployment/deployment-copyability-versioned.spec.ts @@ -1,11 +1,11 @@ -import { ProjectType, WS_TYPE_PATCH_CONFIG } from '@app/models' +import { ProjectType, WS_TYPE_PATCH_IMAGE } from '@app/models' import { Page, expect } from '@playwright/test' import { NGINX_TEST_IMAGE_WITH_TAG, TEAM_ROUTES, waitForURLExcept } from '../../utils/common' import { deployWithDagent } from '../../utils/node-helper' import { createNode } from '../../utils/nodes' import { addDeploymentToVersion, - createImage as imageConfigId, + createImage, createProject, createVersion, fillDeploymentPrefix, @@ -39,7 +39,7 @@ test.describe('Versioned Project', () => { const { projectId } = await setup(page, nodeName, projectName, 'versioned') const versionId = await createVersion(page, projectId, '0.1.0', 'Incremental') - await imageConfigId(page, projectId, versionId, NGINX_TEST_IMAGE_WITH_TAG) + await createImage(page, projectId, versionId, NGINX_TEST_IMAGE_WITH_TAG) const { id: deploymentId } = await addDeploymentToVersion(page, projectId, versionId, nodeName, { prefix }) await page.goto(TEAM_ROUTES.deployment.details(deploymentId)) @@ -66,7 +66,7 @@ test.describe('Versioned Project', () => { const { projectId } = await setup(page, nodeName, projectName, 'versioned') const versionId = await createVersion(page, projectId, '0.1.0', 'Incremental') - await imageConfigId(page, projectId, versionId, NGINX_TEST_IMAGE_WITH_TAG) + await createImage(page, projectId, versionId, NGINX_TEST_IMAGE_WITH_TAG) const { id: deploymentId } = await addDeploymentToVersion(page, projectId, versionId, nodeName, { prefix }) await page.goto(TEAM_ROUTES.deployment.details(deploymentId)) @@ -93,7 +93,7 @@ test.describe('Versioned Project', () => { const { projectId } = await setup(page, nodeName, projectName, 'versioned') const versionId = await createVersion(page, projectId, '1.0.0', 'Incremental') - await imageConfigId(page, projectId, versionId, NGINX_TEST_IMAGE_WITH_TAG) + await createImage(page, projectId, versionId, NGINX_TEST_IMAGE_WITH_TAG) await addDeploymentToVersion(page, projectId, versionId, nodeName, { prefix }) await page.goto(TEAM_ROUTES.deployment.list()) @@ -118,13 +118,13 @@ test.describe('Versioned Project', () => { const projectId = await createProject(page, projectName, 'versioned') const versionId = await createVersion(page, projectId, '0.1.0', 'Incremental') - const imageId = await imageConfigId(page, projectId, versionId, NGINX_TEST_IMAGE_WITH_TAG) + const imageId = await createImage(page, projectId, versionId, NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) - await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) + await page.goto(TEAM_ROUTES.project.versions(projectId).imageDetails(versionId, imageId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) const editorButton = await page.waitForSelector('button:has-text("JSON")') await editorButton.click() @@ -145,7 +145,7 @@ test.describe('Versioned Project', () => { useParentConfig: false, }, ] - const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_CONFIG) + const wsSent = wsPatchSent(ws, wsRoute, WS_TYPE_PATCH_IMAGE) await jsonContainer.fill(JSON.stringify(configObject)) await wsSent diff --git a/web/crux-ui/e2e/with-login/deployment/deployment-deletability.spec.ts b/web/crux-ui/e2e/with-login/deployment/deployment-deletability.spec.ts index 62ba1da13..7d605877c 100644 --- a/web/crux-ui/e2e/with-login/deployment/deployment-deletability.spec.ts +++ b/web/crux-ui/e2e/with-login/deployment/deployment-deletability.spec.ts @@ -17,7 +17,7 @@ test('In progress deployment should be not deletable', async ({ page }) => { await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) const editorButton = await page.waitForSelector('button:has-text("JSON")') await editorButton.click() diff --git a/web/crux-ui/e2e/with-login/image-config.spec.ts b/web/crux-ui/e2e/with-login/image-config.spec.ts index a03b93299..eb009625d 100644 --- a/web/crux-ui/e2e/with-login/image-config.spec.ts +++ b/web/crux-ui/e2e/with-login/image-config.spec.ts @@ -119,13 +119,13 @@ const wsPatchMatchPorts = (internalPort: string, externalPort?: string) => (payl test.describe('Image configurations', () => { test('Port should be saved after adding it from the config field', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup(page, 'port-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'port-editor', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) await page.locator('button:has-text("Ports")').click() @@ -152,13 +152,13 @@ test.describe('Image configurations', () => { }) test('Port should be saved after adding it from the json editor', async ({ page }) => { - const { projectId, versionId, imageConfigId } = await setup(page, 'port-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) + const { imageConfigId } = await setup(page, 'port-json', '1.0.0', NGINX_TEST_IMAGE_WITH_TAG) const sock = waitSocketRef(page) await page.goto(TEAM_ROUTES.containerConfig.details(imageConfigId)) await page.waitForSelector('h2:text-is("Image")') const ws = await sock - const wsRoute = TEAM_ROUTES.project.versions(projectId).detailsSocket(versionId) + const wsRoute = TEAM_ROUTES.containerConfig.detailsSocket(imageConfigId) const jsonEditorButton = await page.waitForSelector('button:has-text("JSON")') await jsonEditorButton.click() From 3d3afac4259500062056fc972ad58671b6be6314 Mon Sep 17 00:00:00 2001 From: Mate Vago Date: Wed, 4 Dec 2024 12:36:04 +0100 Subject: [PATCH 13/13] fix: go_push needs --- .github/workflows/product_builder.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/product_builder.yaml b/.github/workflows/product_builder.yaml index 9df64e9f4..32a237369 100644 --- a/.github/workflows/product_builder.yaml +++ b/.github/workflows/product_builder.yaml @@ -669,7 +669,7 @@ jobs: defaults: run: working-directory: ${{ env.GOLANG_WORKING_DIRECTORY }} - needs: [gather_changes] + needs: [gather_changes, go_build] if: | always() && (github.ref_name == 'develop' || github.ref_name == 'main' || github.ref_type == 'tag') &&