feat: [AH-844]: Implement Maven Repository List, create, update, update, setupclient setup (#3294)

* feat: [AH-844]: correct spelling mistake
* feat: [AH-844]: fix PR comments
* feat: [AH-844]: add new mavenCentral source in upstream proxy
* feat: [AH-844]: Support Maven Central Source in Upstream registry flow
* feat: [AH-844]: Implement Maven Repository List, create, update, update, setupclient setup
This commit is contained in:
Shivanand Sonnad 2025-01-23 07:44:24 +00:00 committed by Harness
parent 8890cfb783
commit d27437dd2c
16 changed files with 228 additions and 41 deletions

View File

@ -51,7 +51,7 @@
"@codemirror/view": "^6.9.6",
"@harnessio/design-system": "^2.1.1",
"@harnessio/icons": "^2.1.9",
"@harnessio/react-har-service-client": "^0.6.0",
"@harnessio/react-har-service-client": "^0.7.0",
"@harnessio/react-ssca-manager-client": "^0.65.0",
"@harnessio/uicore": "^4.1.2",
"@tanstack/react-query": "4.20.4",

View File

@ -134,5 +134,6 @@ export interface MFEAppProps {
export enum FeatureFlags {
HAR_GENERIC_ARTIFACT_ENABLED = 'HAR_GENERIC_ARTIFACT_ENABLED',
HAR_TRIGGERS = 'HAR_TRIGGERS'
HAR_TRIGGERS = 'HAR_TRIGGERS',
HAR_MAVEN_ARTIFACT_ENABLED = 'HAR_MAVEN_ARTIFACT_ENABLED'
}

View File

@ -25,3 +25,4 @@ export { useGetSpaceRef } from './useGetSpaceRef'
export { useParentContextObj } from './useParentContextObj'
export { useLicenseStore } from './useLicenseStore'
export { useFeatureFlags, useFeatureFlag } from './useFeatureFlag'
export { useGetUpstreamRepositoryPackageTypes } from './useGetUpstreamRepositoryPackageTypes'

View File

@ -67,6 +67,7 @@ const RepositoryTypes: RepositoryTypeListItem[] = [
label: 'repositoryTypes.maven',
value: RepositoryPackageType.MAVEN,
icon: 'maven-repository-type',
featureFlag: FeatureFlags.HAR_MAVEN_ARTIFACT_ENABLED,
tooltip: 'Coming Soon!',
disabled: true
},

View File

@ -0,0 +1,68 @@
/*
* Copyright 2024 Harness, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import type { IconName } from '@harnessio/icons'
import { FeatureFlags } from '@ar/MFEAppTypes'
import type { StringsMap } from '@ar/frameworks/strings'
import { UpstreamProxyPackageType } from '@ar/pages/upstream-proxy-details/types'
import { useFeatureFlags } from './useFeatureFlag'
export interface UpstreamRepositoryPackageTypeListItem {
label: keyof StringsMap
value: UpstreamProxyPackageType
icon: IconName
disabled?: boolean
tooltip?: string
featureFlag?: FeatureFlags
}
export const useGetUpstreamRepositoryPackageTypes = (): UpstreamRepositoryPackageTypeListItem[] => {
const featureFlags = useFeatureFlags()
return UpstreamProxyPackageTypeList.map(repo => {
if (repo.disabled && repo.featureFlag && featureFlags[repo.featureFlag]) {
return {
...repo,
disabled: false,
tooltip: undefined
}
}
return repo
})
}
export const UpstreamProxyPackageTypeList: UpstreamRepositoryPackageTypeListItem[] = [
{
label: 'repositoryTypes.docker',
value: UpstreamProxyPackageType.DOCKER,
icon: 'docker-step'
},
{
label: 'repositoryTypes.helm',
value: UpstreamProxyPackageType.HELM,
icon: 'service-helm'
},
{
label: 'repositoryTypes.maven',
value: UpstreamProxyPackageType.MAVEN,
featureFlag: FeatureFlags.HAR_MAVEN_ARTIFACT_ENABLED,
icon: 'maven-repository-type',
tooltip: 'Coming Soon!',
disabled: true
}
]

View File

@ -0,0 +1,130 @@
/*
* Copyright 2024 Harness, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React from 'react'
import type { IconName } from '@harnessio/icons'
import { RepositoryConfigType, RepositoryPackageType } from '@ar/common/types'
import UpstreamProxyActions from '@ar/pages/upstream-proxy-details/components/UpstreamProxyActions/UpstreamProxyActions'
import UpstreamProxyConfigurationForm from '@ar/pages/upstream-proxy-details/components/Forms/UpstreamProxyConfigurationForm'
import UpstreamProxyCreateFormContent from '@ar/pages/upstream-proxy-details/components/FormContent/UpstreamProxyCreateFormContent'
import UpstreamProxyDetailsHeader from '@ar/pages/upstream-proxy-details/components/UpstreamProxyDetailsHeader/UpstreamProxyDetailsHeader'
import {
type CreateRepositoryFormProps,
type RepositoryActionsProps,
type RepositoryConfigurationFormProps,
type RepositoryDetailsHeaderProps,
RepositoryStep,
type RepositoySetupClientProps
} from '@ar/frameworks/RepositoryStep/Repository'
import {
UpstreamProxyAuthenticationMode,
type UpstreamRegistryRequest,
UpstreamRepositoryURLInputSource
} from '@ar/pages/upstream-proxy-details/types'
import type { Repository, VirtualRegistryRequest } from '../types'
import RepositoryActions from '../components/Actions/RepositoryActions'
import RedirectPageView from '../components/RedirectPageView/RedirectPageView'
import SetupClientContent from '../components/SetupClientContent/SetupClientContent'
import RepositoryConfigurationForm from '../components/Forms/RepositoryConfigurationForm'
import RepositoryCreateFormContent from '../components/FormContent/RepositoryCreateFormContent'
import RepositoryDetailsHeader from '../components/RepositoryDetailsHeader/RepositoryDetailsHeader'
export class MavenRepositoryType extends RepositoryStep<VirtualRegistryRequest> {
protected packageType = RepositoryPackageType.MAVEN
protected repositoryName = 'Maven Repository'
protected repositoryIcon: IconName = 'maven-repository-type'
protected supportedScanners = []
protected supportsUpstreamProxy = true
protected supportedUpstreamURLSources = [
UpstreamRepositoryURLInputSource.MavenCentral,
UpstreamRepositoryURLInputSource.Custom
]
protected defaultValues: VirtualRegistryRequest = {
packageType: RepositoryPackageType.MAVEN,
identifier: '',
config: {
type: RepositoryConfigType.VIRTUAL
},
scanners: []
}
protected defaultUpstreamProxyValues: UpstreamRegistryRequest = {
packageType: RepositoryPackageType.MAVEN,
identifier: '',
config: {
type: RepositoryConfigType.UPSTREAM,
authType: UpstreamProxyAuthenticationMode.ANONYMOUS,
source: UpstreamRepositoryURLInputSource.Custom,
url: ''
},
cleanupPolicy: [],
scanners: []
}
renderCreateForm(props: CreateRepositoryFormProps): JSX.Element {
const { type } = props
if (type === RepositoryConfigType.VIRTUAL) {
return <RepositoryCreateFormContent isEdit={false} />
} else {
return <UpstreamProxyCreateFormContent isEdit={false} readonly={false} />
}
}
renderCofigurationForm(props: RepositoryConfigurationFormProps<Repository>): JSX.Element {
const { type } = props
if (type === RepositoryConfigType.VIRTUAL) {
return <RepositoryConfigurationForm ref={props.formikRef} readonly={props.readonly} />
} else {
return <UpstreamProxyConfigurationForm ref={props.formikRef} readonly={props.readonly} />
}
}
renderActions(props: RepositoryActionsProps<Repository>): JSX.Element {
if (props.type === RepositoryConfigType.VIRTUAL) {
return <RepositoryActions data={props.data} readonly={props.readonly} pageType={props.pageType} />
}
return <UpstreamProxyActions data={props.data} readonly={props.readonly} pageType={props.pageType} />
}
renderSetupClient(props: RepositoySetupClientProps): JSX.Element {
const { repoKey, onClose, artifactKey, versionKey } = props
return (
<SetupClientContent
repoKey={repoKey}
artifactKey={artifactKey}
versionKey={versionKey}
onClose={onClose}
packageType={RepositoryPackageType.GENERIC}
/>
)
}
renderRepositoryDetailsHeader(props: RepositoryDetailsHeaderProps<Repository>): JSX.Element {
const { type } = props
if (type === RepositoryConfigType.VIRTUAL) {
return <RepositoryDetailsHeader data={props.data} />
} else {
return <UpstreamProxyDetailsHeader data={props.data} />
}
}
renderRedirectPage(): JSX.Element {
return <RedirectPageView />
}
}

View File

@ -16,9 +16,11 @@
import repositoryFactory from '@ar/frameworks/RepositoryStep/RepositoryFactory'
import { DockerRepositoryType } from './DockerRepository/DockerRepositoryType'
import { MavenRepositoryType } from './MavenRepository/MavenRepository'
import { HelmRepositoryType } from './HelmRepository/HelmRepositoryType'
import { GenericRepositoryType } from './GenericRepository/GenericRepositoryType'
repositoryFactory.registerStep(new DockerRepositoryType())
repositoryFactory.registerStep(new HelmRepositoryType())
repositoryFactory.registerStep(new GenericRepositoryType())
repositoryFactory.registerStep(new MavenRepositoryType())

View File

@ -54,5 +54,9 @@ export const URLSourceToSupportedAuthTypesMapping: Record<
[UpstreamRepositoryURLInputSource.Custom]: [
UpstreamProxyAuthenticationMode.USER_NAME_AND_PASSWORD,
UpstreamProxyAuthenticationMode.ANONYMOUS
],
[UpstreamRepositoryURLInputSource.MavenCentral]: [
UpstreamProxyAuthenticationMode.USER_NAME_AND_PASSWORD,
UpstreamProxyAuthenticationMode.ANONYMOUS
]
}

View File

@ -29,7 +29,7 @@ import {
} from '@harnessio/uicore'
import { useCreateRegistryMutation } from '@harnessio/react-har-service-client'
import { useAppStore, useGetSpaceRef } from '@ar/hooks'
import { useAppStore, useGetSpaceRef, useGetUpstreamRepositoryPackageTypes } from '@ar/hooks'
import { useStrings } from '@ar/frameworks/strings'
import { decodeRef } from '@ar/hooks/useGetSpaceRef'
import { setFormikRef } from '@ar/common/utils'
@ -41,7 +41,6 @@ import {
UpstreamRegistry,
UpstreamRegistryRequest
} from '@ar/pages/upstream-proxy-details/types'
import { UpstreamProxyPackageTypeList } from '@ar/pages/upstream-proxy-details/constants'
import CreateRepositoryWidget from '@ar/frameworks/RepositoryStep/CreateRepositoryWidget'
import repositoryFactory from '@ar/frameworks/RepositoryStep/RepositoryFactory'
@ -67,6 +66,7 @@ function FormContent(props: FormContentProps): JSX.Element {
const { getString } = useStrings()
const { values } = formikProps
const { packageType } = values
const packageTypeList = useGetUpstreamRepositoryPackageTypes()
return (
<Container>
@ -77,7 +77,7 @@ function FormContent(props: FormContentProps): JSX.Element {
<Container>
<ThumbnailSelect
name="packageType"
items={UpstreamProxyPackageTypeList.map(each => ({
items={packageTypeList.map(each => ({
...each,
label: getString(each.label)
}))}

View File

@ -117,7 +117,11 @@ export function getFormattedFormDataForAuthType(
} else if (draft.config.authType === UpstreamProxyAuthenticationMode.ANONYMOUS) {
set(draft, 'config.auth', null)
}
if (draft.config.source === UpstreamRepositoryURLInputSource.Dockerhub) {
if (
[UpstreamRepositoryURLInputSource.Dockerhub, UpstreamRepositoryURLInputSource.MavenCentral].includes(
draft.config.source as UpstreamRepositoryURLInputSource
)
) {
set(draft, 'config.url', '')
}
})

View File

@ -33,5 +33,9 @@ export const UpstreamURLSourceConfig: Record<UpstreamRepositoryURLInputSource, R
[UpstreamRepositoryURLInputSource.Custom]: {
label: 'upstreamProxyDetails.createForm.source.custom',
value: UpstreamRepositoryURLInputSource.Custom
},
[UpstreamRepositoryURLInputSource.MavenCentral]: {
label: 'upstreamProxyDetails.createForm.source.mavenCentral',
value: UpstreamRepositoryURLInputSource.MavenCentral
}
}

View File

@ -14,37 +14,6 @@
* limitations under the License.
*/
import type { IconName } from '@harnessio/icons'
import type { StringsMap } from '@ar/strings/types'
import { UpstreamProxyPackageType } from './types'
interface UpstreamProxyPackageTypeListType {
label: keyof StringsMap
value: UpstreamProxyPackageType
icon: IconName
disabled?: boolean
tooltip?: string
}
export const UpstreamProxyPackageTypeList: UpstreamProxyPackageTypeListType[] = [
{
label: 'repositoryTypes.docker',
value: UpstreamProxyPackageType.DOCKER,
icon: 'docker-step'
},
{
label: 'repositoryTypes.helm',
value: UpstreamProxyPackageType.HELM,
icon: 'service-helm'
},
{
label: 'repositoryTypes.maven',
value: UpstreamProxyPackageType.MAVEN,
icon: 'maven-repository-type',
tooltip: 'Comming Soon!',
disabled: true
}
]
export enum UpstreamProxyDetailsTab {
PACKAGES = 'packages',
CONFIGURATION = 'configuration'

View File

@ -12,6 +12,7 @@ createForm:
dockerHub: Docker Hub
ecr: AWS ECR
custom: Custom
mavenCentral: Maven Central
authentication:
title: Authentication
userNameAndPassword: Username and Password

View File

@ -26,6 +26,7 @@ export enum UpstreamProxyPackageType {
export enum UpstreamRepositoryURLInputSource {
Dockerhub = 'Dockerhub',
MavenCentral = 'MavenCentral',
AwsEcr = 'AwsEcr',
Custom = 'Custom'
}

View File

@ -141,6 +141,7 @@ export interface StringsMap {
'upstreamProxyDetails.createForm.source.custom': string
'upstreamProxyDetails.createForm.source.dockerHub': string
'upstreamProxyDetails.createForm.source.ecr': string
'upstreamProxyDetails.createForm.source.mavenCentral': string
'upstreamProxyDetails.createForm.source.title': string
'upstreamProxyDetails.createForm.title': string
'upstreamProxyDetails.createForm.url': string

View File

@ -1945,10 +1945,10 @@
yargs "^17.6.2"
zod "^3.19.1"
"@harnessio/react-har-service-client@^0.6.0":
version "0.6.0"
resolved "https://registry.yarnpkg.com/@harnessio/react-har-service-client/-/react-har-service-client-0.6.0.tgz#25253fd935fe6a28a5d26d98148ba0ba51d545ef"
integrity sha512-jCCCInwmVoCWrambIop6dK8SvJXHpsq+8MdZNPbguMPjJgqR0d6i6Ms+4lpfBswJ/5TVVEvo/uFJhlAUVtf2fQ==
"@harnessio/react-har-service-client@^0.7.0":
version "0.7.0"
resolved "https://registry.yarnpkg.com/@harnessio/react-har-service-client/-/react-har-service-client-0.7.0.tgz#e78e1b1e770586ed3f5215b0bc7277b8b12dcd8f"
integrity sha512-810Z3OLEcPxul/PQdb92S8/DKG8tA83hbMgGdA0v+7+e4cCnIigSYP9lvUa2i7I8Bm8LtP4kiipg8aky90m70w==
dependencies:
"@harnessio/oats-cli" "^3.0.0"