Skip to content
This repository has been archived by the owner on Jul 2, 2024. It is now read-only.

Commit

Permalink
EVG-19946: Add Docker to provider settings page
Browse files Browse the repository at this point in the history
  • Loading branch information
minnakt committed Sep 1, 2023
1 parent fc9c67e commit 46ae0f3
Show file tree
Hide file tree
Showing 12 changed files with 526 additions and 115 deletions.
100 changes: 75 additions & 25 deletions cypress/integration/distroSettings/provider_section.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,88 @@
import { save } from "./utils";

describe("provider section", () => {
beforeEach(() => {
cy.visit("/distro/localhost/settings/provider");
});
describe("static", () => {
beforeEach(() => {
cy.visit("/distro/localhost/settings/provider");
});

it("successfully updates static provider fields", () => {
cy.dataCy("provider-select").contains("Static IP/VM");

// Correct fields are displayed
cy.dataCy("provider-settings").within(() => {
cy.get("button").should("have.length", 1);
cy.get("textarea").should("have.length", 1);
cy.get("input[type=checkbox]").should("have.length", 1);
cy.get("input[type=text]").should("have.length", 0);
});

cy.getInputByLabel("User Data").type("my user data");
cy.getInputByLabel("Merge with existing user data").check({
force: true,
});
cy.contains("button", "Add security group").click();
cy.getInputByLabel("Security Group ID").type("group-1234");

save();
cy.validateToast("success");

it("successfully updates static provider fields", () => {
cy.dataCy("provider-select").contains("Static IP/VM");
cy.getInputByLabel("User Data").clear();
cy.getInputByLabel("Merge with existing user data").uncheck({
force: true,
});
cy.dataCy("delete-item-button").click();

// Correct fields are displayed
cy.dataCy("provider-settings").within(() => {
cy.get("button").should("have.length", 1);
cy.get("textarea").should("have.length", 1);
cy.get("input[type=checkbox]").should("have.length", 1);
cy.get("input[type=text]").should("have.length", 0);
save();
cy.validateToast("success");
});
});

cy.getInputByLabel("User Data").type("my user data");
cy.getInputByLabel("Merge with existing user data").check({
force: true,
describe.only("docker", () => {
beforeEach(() => {
cy.visit("/distro/ubuntu1604-container-test/settings/provider");
});
cy.contains("button", "Add security group").click();
cy.getInputByLabel("Security Group ID").type("group-1234");

save();
cy.validateToast("success");
it("successfully updates docker provider fields", () => {
cy.dataCy("provider-select").contains("Docker");

cy.getInputByLabel("User Data").clear();
cy.getInputByLabel("Merge with existing user data").uncheck({
force: true,
});
cy.dataCy("delete-item-button").click();
// Correct fields are displayed
cy.dataCy("provider-settings").within(() => {
cy.getInputByLabel("Docker Image URL").should("exist");
cy.getInputByLabel("Image Build Method").should("exist");
cy.getInputByLabel("Username for Registries").should("exist");
cy.getInputByLabel("Password for Registries").should("exist");
cy.getInputByLabel("Container Pool ID").should("exist");
cy.getInputByLabel("Pool Mapping Information").should("exist");
cy.getInputByLabel("User Data").should("exist");
cy.getInputByLabel("Merge with existing user data").should("exist");
cy.contains("button", "Add security group").should("exist");
});

// Change field values.
cy.selectLGOption("Image Build Method", "Pull");
cy.selectLGOption("Container Pool ID", /^test-pool$/);
cy.getInputByLabel("Username for Registries").type("username");
cy.getInputByLabel("Password for Registries").type("password");
cy.getInputByLabel("User Data").type("my user data");
cy.getInputByLabel("Merge with existing user data").check({
force: true,
});
save();
cy.validateToast("success");

save();
cy.validateToast("success");
// Revert fields to original values.
cy.selectLGOption("Image Build Method", "Import");
cy.selectLGOption("Container Pool ID", "ubuntu-test-pool");
cy.getInputByLabel("Username for Registries").clear();
cy.getInputByLabel("Password for Registries").clear();
cy.getInputByLabel("User Data").clear();
cy.getInputByLabel("Merge with existing user data").uncheck({
force: true,
});

save();
cy.validateToast("success");
});
});
});
2 changes: 2 additions & 0 deletions src/components/SpruceForm/Widgets/LeafyGreenWidgets.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,7 @@ export const LeafyGreenTextArea: React.FC<SpruceWidgetProps> = ({
label,
onChange,
options,
placeholder,
rawErrors,
readonly,
value,
Expand Down Expand Up @@ -368,6 +369,7 @@ export const LeafyGreenTextArea: React.FC<SpruceWidgetProps> = ({
<ElementWrapper css={elementWrapperCSS}>
<TextArea
ref={el}
placeholder={placeholder || undefined}
data-cy={dataCy}
label={label}
disabled={disabled || readonly}
Expand Down
94 changes: 59 additions & 35 deletions src/gql/generated/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,19 @@ export enum CommunicationMethod {
Ssh = "SSH",
}

export type ContainerPool = {
__typename?: "ContainerPool";
distro: Scalars["String"]["output"];
id: Scalars["String"]["output"];
maxContainers: Scalars["Int"]["output"];
port: Scalars["Int"]["output"];
};

export type ContainerPoolsConfig = {
__typename?: "ContainerPoolsConfig";
pools: Array<ContainerPool>;
};

export type ContainerResources = {
__typename?: "ContainerResources";
cpu: Scalars["Int"]["output"];
Expand Down Expand Up @@ -2324,6 +2337,7 @@ export type SpruceConfig = {
__typename?: "SpruceConfig";
banner?: Maybe<Scalars["String"]["output"]>;
bannerTheme?: Maybe<Scalars["String"]["output"]>;
containerPools?: Maybe<ContainerPoolsConfig>;
githubOrgs: Array<Scalars["String"]["output"]>;
jira?: Maybe<JiraConfig>;
providers?: Maybe<CloudProviderConfig>;
Expand Down Expand Up @@ -7780,41 +7794,6 @@ export type RepoSettingsQuery = {
};
};

export type SpruceConfigQueryVariables = Exact<{ [key: string]: never }>;

export type SpruceConfigQuery = {
__typename?: "Query";
spruceConfig?: {
__typename?: "SpruceConfig";
banner?: string | null;
bannerTheme?: string | null;
jira?: { __typename?: "JiraConfig"; host?: string | null } | null;
providers?: {
__typename?: "CloudProviderConfig";
aws?: {
__typename?: "AWSConfig";
maxVolumeSizePerUser?: number | null;
pod?: {
__typename?: "AWSPodConfig";
ecs?: {
__typename?: "ECSConfig";
maxCPU: number;
maxMemoryMb: number;
} | null;
} | null;
} | null;
} | null;
slack?: { __typename?: "SlackConfig"; name?: string | null } | null;
spawnHost: {
__typename?: "SpawnHostConfig";
spawnHostsPerUser: number;
unexpirableHostsPerUser: number;
unexpirableVolumesPerUser: number;
};
ui?: { __typename?: "UIConfig"; defaultProject: string } | null;
} | null;
};

export type SystemLogsQueryVariables = Exact<{
id: Scalars["String"]["input"];
execution?: InputMaybe<Scalars["Int"]["input"]>;
Expand Down Expand Up @@ -8641,6 +8620,51 @@ export type SpawnTaskQuery = {
} | null;
};

export type SpruceConfigQueryVariables = Exact<{ [key: string]: never }>;

export type SpruceConfigQuery = {
__typename?: "Query";
spruceConfig?: {
__typename?: "SpruceConfig";
banner?: string | null;
bannerTheme?: string | null;
containerPools?: {
__typename?: "ContainerPoolsConfig";
pools: Array<{
__typename?: "ContainerPool";
distro: string;
id: string;
maxContainers: number;
port: number;
}>;
} | null;
jira?: { __typename?: "JiraConfig"; host?: string | null } | null;
providers?: {
__typename?: "CloudProviderConfig";
aws?: {
__typename?: "AWSConfig";
maxVolumeSizePerUser?: number | null;
pod?: {
__typename?: "AWSPodConfig";
ecs?: {
__typename?: "ECSConfig";
maxCPU: number;
maxMemoryMb: number;
} | null;
} | null;
} | null;
} | null;
slack?: { __typename?: "SlackConfig"; name?: string | null } | null;
spawnHost: {
__typename?: "SpawnHostConfig";
spawnHostsPerUser: number;
unexpirableHostsPerUser: number;
unexpirableVolumesPerUser: number;
};
ui?: { __typename?: "UIConfig"; defaultProject: string } | null;
} | null;
};

export type SubnetAvailabilityZonesQueryVariables = Exact<{
[key: string]: never;
}>;
Expand Down
2 changes: 1 addition & 1 deletion src/gql/queries/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ import GET_PROJECTS from "./get-projects.graphql";
import GET_MY_PUBLIC_KEYS from "./get-public-keys.graphql";
import GET_REPO_EVENT_LOGS from "./get-repo-event-logs.graphql";
import GET_REPO_SETTINGS from "./get-repo-settings.graphql";
import GET_SPRUCE_CONFIG from "./get-spruce-config.graphql";
import GET_SYSTEM_LOGS from "./get-system-logs.graphql";
import GET_TASK_ALL_EXECUTIONS from "./get-task-all-executions.graphql";
import GET_TASK_EVENT_LOGS from "./get-task-event-logs.graphql";
Expand All @@ -71,6 +70,7 @@ import PROJECT_HEALTH_VIEW from "./project-health-view.graphql";
import GET_PROJECT_PATCHES from "./project-patches.graphql";
import GET_SPAWN_EXPIRATION_INFO from "./spawn-expiration.graphql";
import GET_SPAWN_TASK from "./spawn-task.graphql";
import GET_SPRUCE_CONFIG from "./spruce-config.graphql";
import GET_SUBNET_AVAILABILITY_ZONES from "./subnet-availability-zones.graphql";
import TASK_QUEUE_DISTROS from "./task-queue-distros.graphql";
import USER_DISTRO_SETTINGS_PERMISSIONS from "./user-distro-settings-permissions.graphql";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,14 @@ query SpruceConfig {
spruceConfig {
banner
bannerTheme
containerPools {
pools {
distro
id
maxContainers
port
}
}
jira {
host
}
Expand Down
21 changes: 20 additions & 1 deletion src/pages/distroSettings/tabs/ProviderTab/ProviderTab.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,31 @@
import { useMemo } from "react";
import { DistroSettingsTabRoutes } from "constants/routes";
import { useSpruceConfig } from "hooks";
import { useDistroSettingsContext } from "pages/distroSettings/Context";
import { omitTypename } from "utils/string";
import { BaseTab } from "../BaseTab";
import { getFormSchema } from "./getFormSchema";
import { TabProps } from "./types";

export const ProviderTab: React.FC<TabProps> = ({ distroData }) => {
const initialFormState = distroData;

const formSchema = useMemo(() => getFormSchema(), []);
const { getTab } = useDistroSettingsContext();
const { formData } = getTab(DistroSettingsTabRoutes.Provider);

const { containerPools } = useSpruceConfig();
const { pools = [] } = containerPools || {};

const selectedPoolId = formData?.providerSettings?.containerPoolId;
const selectedPool = pools.find((p) => p.id === selectedPoolId) ?? null;
const poolMappingInfo = selectedPool
? JSON.stringify(omitTypename(selectedPool), null, 4)
: "";

const formSchema = useMemo(
() => getFormSchema({ pools, poolMappingInfo }),
[pools, poolMappingInfo]
);

return (
<BaseTab formSchema={formSchema} initialFormState={initialFormState} />
Expand Down
Loading

0 comments on commit 46ae0f3

Please sign in to comment.