diff --git a/web/Taskfile.yaml b/web/Taskfile.yaml index b210e68ff..bdac9c97d 100644 --- a/web/Taskfile.yaml +++ b/web/Taskfile.yaml @@ -8,7 +8,7 @@ tasks: interactive: true cmds: - | - BASE_URL=dev.kloudlite.io + BASE_URL=gcp-production.kloudlite.io COOKIE_DOMAIN=".kloudlite.io" GATEWAY_URL="http://gateway.kloudlite.svc.cluster.local" case {{.app}} in @@ -55,7 +55,7 @@ tasks: esac - REMIX_DEV_ORIGIN="https://{{.app}}$URL_SUFFIX.dev.kloudlite.io" + REMIX_DEV_ORIGIN="https://{{.app}}$URL_SUFFIX.$BASE_URL" cp -r ./static/common/. ./public/ cp -r ./static/{{.app}}/. ./public/ diff --git a/web/gql-queries-generator/doc/queries.graphql b/web/gql-queries-generator/doc/queries.graphql index 7b22173d6..0413536dc 100644 --- a/web/gql-queries-generator/doc/queries.graphql +++ b/web/gql-queries-generator/doc/queries.graphql @@ -77,6 +77,7 @@ query consoleGetAccount($accountName: String!) { name annotations } + targetNamespace updateTime contactEmail displayName @@ -300,10 +301,6 @@ query consoleListClusters($search: SearchCluster, $pagination: CursorPaginationI spec { messageQueueTopicName kloudliteRelease - credentialsRef { - namespace - name - } clusterTokenRef { key name @@ -398,18 +395,6 @@ query consoleGetCluster($name: String!) { name namespace } - credentialKeys { - keyAccessKey - keyAWSAccountId - keyAWSAssumeRoleExternalID - keyAWSAssumeRoleRoleARN - keyIAMInstanceProfileRole - keySecretKey - } - credentialsRef { - name - namespace - } kloudliteRelease messageQueueTopicName output { @@ -480,15 +465,15 @@ query consoleListProviderSecrets($search: SearchProviderSecret, $pagination: Cur edges { cursor node { - aws { - awsAccountId - } cloudProviderName createdBy { userEmail userId userName } + aws { + authMechanism + } creationTime displayName lastUpdatedBy { @@ -528,9 +513,6 @@ mutation consoleDeleteProviderSecret($secretName: String!) { query consoleGetProviderSecret($name: String!) { infra_getProviderSecret(name: $name) { - aws { - awsAccountId - } cloudProviderName createdBy { userEmail diff --git a/web/src/apps/console/components/code-view.tsx b/web/src/apps/console/components/code-view.tsx index 290460987..232b74597 100644 --- a/web/src/apps/console/components/code-view.tsx +++ b/web/src/apps/console/components/code-view.tsx @@ -14,7 +14,7 @@ interface ICodeView { const CodeView = ({ data, copy, - showShellPrompt, + showShellPrompt: _, language = 'shell', title, }: ICodeView) => { @@ -55,7 +55,7 @@ const CodeView = ({ }} className="group/sha cursor-pointer p-lg rounded-md bodyMd flex flex-row gap-xl items-center hljs w-full" > -
+diff --git a/web/src/apps/console/page-components/new-cluster.tsx b/web/src/apps/console/page-components/new-cluster.tsx index 27ed67069..31a2fef63 100644 --- a/web/src/apps/console/page-components/new-cluster.tsx +++ b/web/src/apps/console/page-components/new-cluster.tsx @@ -1,4 +1,4 @@ -import { useNavigate, useParams } from '@remix-run/react'; +import { useNavigate, useOutletContext, useParams } from '@remix-run/react'; import { useMemo, useState } from 'react'; import Select from '~/components/atoms/select'; import { toast } from '~/components/molecule/toast'; @@ -28,6 +28,7 @@ import MultiStepProgressWrapper from '../components/multi-step-progress-wrapper' import { TitleBox } from '../components/raw-wrapper'; import { BottomNavigation, ReviewComponent } from '../components/commons'; import FillerCluster from '../assets/filler-cluster'; +import { IAccountContext } from '../routes/_main+/$account+/_layout'; type props = | { @@ -50,6 +51,8 @@ export const NewCluster = ({ providerSecrets, cloudProvider }: props) => { [providerSecrets] ); + const { account } = useOutletContext{data}
(); + const options = useMapper(cloudProviders, (provider) => ({ value: parseName(provider), label: provider.displayName, @@ -122,15 +125,19 @@ export const NewCluster = ({ providerSecrets, cloudProvider }: props) => { spec: { cloudProvider: validateClusterCloudProvider(val.cloudProvider), aws: { + credentials: { + authMechanism: 'secret_keys', + secretRef: { + name: val.credentialsRef, + namespace: account.targetNamespace, + }, + }, region: selectedRegion.Name, k3sMasters: { nvidiaGpuEnabled: true, instanceType: 'c6a.xlarge', }, }, - credentialsRef: { - name: val.credentialsRef, - }, availabilityMode: validateAvailabilityMode( val.availabilityMode ), diff --git a/web/src/apps/console/routes/_a+/onboarding+/$a+/$cloudprovider+/validate-cp.tsx b/web/src/apps/console/routes/_a+/onboarding+/$a+/$cloudprovider+/validate-cp.tsx index dd9c55132..ba5f98eaa 100644 --- a/web/src/apps/console/routes/_a+/onboarding+/$a+/$cloudprovider+/validate-cp.tsx +++ b/web/src/apps/console/routes/_a+/onboarding+/$a+/$cloudprovider+/validate-cp.tsx @@ -1,5 +1,3 @@ -/* eslint-disable react/no-unescaped-entities */ -/* eslint-disable no-nested-ternary */ import { IRemixCtx } from '~/root/lib/types/common'; import { useLoaderData, useNavigate, useOutletContext } from '@remix-run/react'; import { defer } from '@remix-run/node'; @@ -22,6 +20,10 @@ import MultiStepProgress, { } from '~/console/components/multi-step-progress'; import { Check } from '~/console/components/icons'; import { BottomNavigation } from '~/console/components/commons'; +import useForm from '~/root/lib/client/hooks/use-form'; +import Yup from '~/root/lib/server/helpers/yup'; +import { PasswordInput } from '~/components/atoms/input'; +import FillerCloudProvider from '~/console/assets/filler-cloud-provider'; import { IAccountContext } from '../../../../_main+/$account+/_layout'; export const loader = async (ctx: IRemixCtx) => { @@ -64,25 +66,90 @@ const Validator = ({ cloudProvider }: { cloudProvider: any }) => { const [isLoading, setIsLoading] = useState(false); const { data, isLoading: il } = useCustomSwr( - () => cloudProvider.metadata!.name + isLoading, + () => parseName(cloudProvider) + isLoading, async () => { - if (!cloudProvider.metadata!.name) { + if (!parseName(cloudProvider.metadata!.name)) { throw new Error('Invalid cloud provider name'); } return api.checkAwsAccess({ - cloudproviderName: cloudProvider.metadata.name, + cloudproviderName: parseName(cloudProvider), }); } ); + const { values, handleChange, errors, handleSubmit } = useForm({ + initialValues: { + accessKey: '', + secretKey: '', + }, + validationSchema: Yup.object({ + accessKey: Yup.string().test( + 'provider', + 'access key is required', + // @ts-ignores + // eslint-disable-next-line react/no-this-in-sfc + function (item) { + return data?.result || item; + } + ), + secretKey: Yup.string().test( + 'provider', + 'secret key is required', + // eslint-disable-next-line func-names + // @ts-ignore + function (item) { + return data?.result || item; + } + ), + }), + onSubmit: async (val) => { + if (data?.result) { + navigate( + `/onboarding/${parseName(account)}/${parseName( + cloudProvider + )}/new-cluster` + ); + return; + } + + try { + const { errors } = await api.updateProviderSecret({ + secret: { + metadata: { + name: parseName(cloudProvider), + }, + cloudProviderName: cloudProvider.cloudProviderName, + displayName: cloudProvider.displayName, + aws: { + authMechanism: 'secret_keys', + authSecretKeys: { + accessKey: val.accessKey, + secretKey: val.secretKey, + }, + }, + }, + }); + + if (errors) { + throw errors[0]; + } + + setIsLoading((s) => !s); + } catch (err) { + handleError(err); + } + }, + }); + const { currentStep, jumpStep } = useMultiStepProgress({ defaultStep: 3, totalSteps: 4, }); return ( -