Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"private": true,
"homepage": "/dashboard",
"dependencies": {
"@devtron-labs/devtron-fe-common-lib": "4.0.7",
"@devtron-labs/devtron-fe-common-lib": "4.0.7-beta-12",
"@esbuild-plugins/node-globals-polyfill": "0.2.3",
"@sentry/browser": "7.119.1",
"@sentry/integrations": "7.50.0",
Expand Down
23 changes: 23 additions & 0 deletions src/components/gitOps/BitbucketCloudAuthSelector.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { RadioGroup, RadioGroupItem } from '@devtron-labs/devtron-fe-common-lib'

Check failure on line 1 in src/components/gitOps/BitbucketCloudAuthSelector.tsx

View workflow job for this annotation

GitHub Actions / ci

Run autofix to sort these imports!
import type { BitbucketCloudAuthSelectorProps } from './gitops.type'
import { BITBUCKET_CLOUD_AUTH_MODE_OPTIONS } from './constants'

const BitbucketCloudAuthSelector = ({

Check failure on line 5 in src/components/gitOps/BitbucketCloudAuthSelector.tsx

View workflow job for this annotation

GitHub Actions / ci

Replace `⏎····authMode,⏎····handleAuthModeChange,⏎` with `·authMode,·handleAuthModeChange·`
authMode,
handleAuthModeChange,
}: BitbucketCloudAuthSelectorProps) => (
<RadioGroup

Check failure on line 9 in src/components/gitOps/BitbucketCloudAuthSelector.tsx

View workflow job for this annotation

GitHub Actions / ci

Delete `····`
className="radio-group-no-border"

Check failure on line 10 in src/components/gitOps/BitbucketCloudAuthSelector.tsx

View workflow job for this annotation

GitHub Actions / ci

Delete `····`
name="toggle-bitbucket-cloud-auth-mode"

Check failure on line 11 in src/components/gitOps/BitbucketCloudAuthSelector.tsx

View workflow job for this annotation

GitHub Actions / ci

Delete `····`
value={authMode}

Check failure on line 12 in src/components/gitOps/BitbucketCloudAuthSelector.tsx

View workflow job for this annotation

GitHub Actions / ci

Delete `····`
onChange={handleAuthModeChange}

Check failure on line 13 in src/components/gitOps/BitbucketCloudAuthSelector.tsx

View workflow job for this annotation

GitHub Actions / ci

Replace `············` with `········`
>

Check failure on line 14 in src/components/gitOps/BitbucketCloudAuthSelector.tsx

View workflow job for this annotation

GitHub Actions / ci

Delete `····`
{BITBUCKET_CLOUD_AUTH_MODE_OPTIONS.map((option) => (

Check failure on line 15 in src/components/gitOps/BitbucketCloudAuthSelector.tsx

View workflow job for this annotation

GitHub Actions / ci

Replace `············` with `········`
<RadioGroupItem key={option.value} value={option.value}>

Check failure on line 16 in src/components/gitOps/BitbucketCloudAuthSelector.tsx

View workflow job for this annotation

GitHub Actions / ci

Delete `····`
{option.label}
</RadioGroupItem>
))}
</RadioGroup>
)

export default BitbucketCloudAuthSelector
198 changes: 125 additions & 73 deletions src/components/gitOps/GitOpsConfiguration.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
PasswordField,
DocLink,
DocLinkProps,
Textarea,
} from '@devtron-labs/devtron-fe-common-lib'
import {
TLSConnectionFormActionType,
Expand Down Expand Up @@ -68,12 +69,19 @@
LinkAndLabelSpec,
DefaultErrorFields,
PROVIDER_DOC_LINK_MAP,
UNABLE_TO_DELETE_WARNING,
} from './constants'
import { getGitOpsLabelText } from './utils'
import {
getGitAccessPasswordInputLabel,
getGitOpsLabelText,
getGitAccessUsernameInputPlaceholder,
getGitAccessUsernameInputLabel,
} from './utils'
import { GitProvider } from '@Components/common/GitTabs/constants'
import { GitProviderType } from '@Components/common/GitTabs/types'
import { GitProviderTab } from '@Components/common/GitTabs/GitProviderTab'
import UpdateConfirmationDialog from './UpdateConfirmationDialog'
import BitbucketCloudAuthSelector from './BitbucketCloudAuthSelector'

const OtherGitOpsForm = importComponentFromFELibrary('OtherGitOpsForm', null, 'function')
const BitBucketDCCredentials = importComponentFromFELibrary('BitBucketDCCredentials', null, 'function')
Expand Down Expand Up @@ -231,7 +239,7 @@
provider: GitProvider.GITHUB,
}

const bitbucketCloudConfig = parsedGitList.find((item) => item.provider === GitProvider.BITBUCKET_CLOUD)

Check warning on line 242 in src/components/gitOps/GitOpsConfiguration.tsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Prefer `.some(…)` over `.find(…)`.

See more on https://sonarcloud.io/project/issues?id=devtron-labs_dashboard&issues=AZ9fryFKWwVIITc1hzgl&open=AZ9fryFKWwVIITc1hzgl&pullRequest=3120
const bitbucketDCConfig = parsedGitList.find((item) => item.provider === 'BITBUCKET_DC')
// If bit bucket dc is configured and active or only dc is configured, then default to bitbucket dc else bitbucket cloud
const isBitbucketCloud =
Expand Down Expand Up @@ -342,7 +350,12 @@
// We do not need any https url in aws code commit tab
const isURLValidationOptional =
key === 'host' || this.isAWSCodeCommitTabSelected() || this.getIsOtherGitOpsTabSelected()
const validateUserName = key === 'username' && !this.getIsOtherGitOpsTabSelected()
// Empty username is allowed in case of bitbucket cloud with access token (only send token i.e. Bearer token)
const validateUserName =
key === 'username' &&
(!this.getIsOtherGitOpsTabSelected() ||
(this.state.form.provider === GitProvider.BITBUCKET_CLOUD &&
this.state.form.authMode === GitOpsAuthModeType.ACCESS_TOKEN))
const shouldValidateSSHUrl = key === 'sshHost' && this.isAWSCodeCommitTabSelected()

const isCredentialKey = key === 'token' || key === 'sshKey'
Expand Down Expand Up @@ -428,9 +441,12 @@
}

const isBitBucketDC = this.state.form.provider === 'BITBUCKET_DC'
const isBitBucketCloud = this.state.form.provider === GitProvider.BITBUCKET_CLOUD
const isBitBucketDCCreateView =
!this.state.form.id || this.state.form.authMode !== this.state.initialBitBucketDCAuthMode
const isTokenRequired = isBitBucketDC && isBitBucketDCCreateView

const isTokenRequired = (isBitBucketDC && isBitBucketDCCreateView) || isBitBucketCloud
const isUsernameRequired = !(isBitBucketCloud && this.state.form.authMode === GitOpsAuthModeType.ACCESS_TOKEN)

const isSSHKeyRequired =
isBitBucketDC &&
Expand All @@ -442,7 +458,7 @@

return {
host: this.requiredFieldCheck(form.host),
username: this.requiredFieldCheck(form.username),
username: isUsernameRequired ? this.requiredFieldCheck(form.username) : '',
token: this.state.form.id && !isTokenRequired ? '' : this.requiredFieldCheck(form.token),
gitHubOrgId: this.requiredFieldCheck(form.gitHubOrgId),
gitLabGroupId: this.requiredFieldCheck(form.gitLabGroupId),
Expand Down Expand Up @@ -597,6 +613,11 @@
bitBucketWorkspaceId: this.state.form.bitBucketWorkspaceId.replace(/\s/g, ''),
}
: {}),
...(this.state.form.provider === GitProvider.BITBUCKET_CLOUD
? {
authMode: this.state.form.authMode,
}
: {}),
...(this.state.form.provider === 'BITBUCKET_DC' && {
authMode: this.state.form.authMode,
sshKey: this.state.form.authMode === GitOpsAuthModeType.SSH_AND_PASSWORD ? this.state.form.sshKey : '',
Expand Down Expand Up @@ -823,7 +844,10 @@
username: '',
sshKey: '',
}
const formState = this.getFormStateOnCredentialTypeChange(selectedAuthMode)
const formState =
this.state.form.provider === 'BITBUCKET_DC'

Check warning on line 848 in src/components/gitOps/GitOpsConfiguration.tsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use callback in setState when referencing the previous state.

See more on https://sonarcloud.io/project/issues?id=devtron-labs_dashboard&issues=AZ9fryFKWwVIITc1hzgm&open=AZ9fryFKWwVIITc1hzgm&pullRequest=3120
? this.getFormStateOnCredentialTypeChange(selectedAuthMode)
: { ...this.state.form, authMode: selectedAuthMode, username: '', token: '' }

Check warning on line 850 in src/components/gitOps/GitOpsConfiguration.tsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Use callback in setState when referencing the previous state.

See more on https://sonarcloud.io/project/issues?id=devtron-labs_dashboard&issues=AZ9fryFKWwVIITc1hzgn&open=AZ9fryFKWwVIITc1hzgn&pullRequest=3120

this.setState({
form: formState,
Expand Down Expand Up @@ -1013,12 +1037,10 @@
render() {
const suggestedURL = this.suggestedValidGitOpsUrl()
const key: GitOpsOrganisationIdType = this.getGitOpsOrgId()
const warning =
'Devtron was unable to delete the test repository “devtron-sample-repo-dryrun-…”. Please delete it manually.'
const isAuthModeSSH = this.getIsAuthModeSSH(this.state.form.authMode, this.state.form.provider)
// Would be showing TLS Config Form if auth mode is Password
// Would be showing TLS Config Form if auth mode is Password and provider is not Bitbucket Cloud
const formAuthMode = this.getFormAuthMode(this.state.form.authMode, this.state.form.provider)
const isTLSConfigFormVisible = formAuthMode === GitOpsAuthModeType.PASSWORD
const isTLSConfigFormVisible = formAuthMode === GitOpsAuthModeType.PASSWORD && !this.state.isBitbucketCloud

if (this.state.view === ViewType.LOADING) {
return (
Expand Down Expand Up @@ -1077,7 +1099,7 @@
return null
}
// Keeping dataTestId backward compatible so that automation tests are not broken
const dataTestId = `gitops-${provider.split('_').join('-').toLowerCase()}-button`

Check warning on line 1102 in src/components/gitOps/GitOpsConfiguration.tsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Prefer `String#replaceAll()` over `String#split().join()`.

See more on https://sonarcloud.io/project/issues?id=devtron-labs_dashboard&issues=AZ9fryFKWwVIITc1hzgo&open=AZ9fryFKWwVIITc1hzgo&pullRequest=3120

return (
<GitProviderTab
Expand All @@ -1094,6 +1116,97 @@
</div>
)

const renderGitAccessCredentials = () => {
if (BitBucketDCCredentials && this.state.form.provider === 'BITBUCKET_DC') {
return (
<div className={`flexbox-col ${isTLSConfigFormVisible ? 'mb-16' : ''}`}>
<BitBucketDCCredentials
authMode={this.state.form.authMode}
initialAuthMode={this.state.initialBitBucketDCAuthMode}
handleAuthModeChange={this.handleAuthModeChange}
handleChange={this.handleChange}
username={{
value: this.state.form.username,
error: this.state.isError.username,
}}
sshKey={{
value: this.state.form.sshKey,
error: this.state.isError.sshKey,
}}
token={{
value: this.state.form.token,
error: this.state.isError.token,
}}
id={this.state.form.id}
/>
</div>
)
}

return (
<div className="flexbox-col dc__gap-12 w-100">
{this.state.form.provider === GitProvider.BITBUCKET_CLOUD && (
<BitbucketCloudAuthSelector
authMode={this.state.form.authMode}
handleAuthModeChange={this.handleAuthModeChange}
/>
)}
{this.state.form.provider === GitProvider.BITBUCKET_CLOUD &&
this.state.form.authMode === GitOpsAuthModeType.ACCESS_TOKEN ? (
<Textarea
name="bitbucket-cloud-access-token"
value={this.state.form.token}
onChange={(event) => this.handleChange(event, 'token')}
error={this.state.isError.token}
label={getGitAccessPasswordInputLabel(this.state.form.provider, this.state.form.authMode)}
placeholder="Enter bearer token"
required
/>
) : (
<div className="form__row--two-third w-100">
<div>
<CustomInput
value={this.state.form.username}
onChange={(event) => this.handleChange(event, 'username')}
name="Enter username"
placeholder={getGitAccessUsernameInputPlaceholder(
this.state.form.provider,
this.state.form.authMode,
)}
error={this.state.isError.username}
label={getGitAccessUsernameInputLabel(
this.state.form.provider,
this.state.form.authMode,
)}
required
/>
</div>
<div>
<PasswordField
shouldShowDefaultPlaceholderOnBlur={
this.state.form.token === DEFAULT_SECRET_PLACEHOLDER
}
name="token"
placeholder="Enter access token"
value={this.state.form.token}
onChange={(event) => this.handleChange(event, 'token')}
error={this.state.isError.token}
{...getInputLabelProps(
getGitAccessPasswordInputLabel(
this.state.form.provider,
this.state.form.authMode,
),
PROVIDER_DOC_LINK_MAP[this.state.form.provider],
'Check permissions required for PAT',
)}
/>
</div>
</div>
)}
</div>
)
}

const renderGitOpsFormInputs = () => {
/* Not adding check for isAuthModeSSH since that no relation with form itself */
return (this.isAWSCodeCommitTabSelected() || this.getIsOtherGitOpsTabSelected()) && OtherGitOpsForm ? (
Expand Down Expand Up @@ -1156,7 +1269,7 @@
validationError={this.state.validationError}
validationStatus={this.state.validationStatus}
configName="gitops"
warning={this.state.deleteRepoError ? warning : ''}
warning={this.state.deleteRepoError ? UNABLE_TO_DELETE_WARNING : ''}
/>
)}
<div className="flex-grow-1 w-100">
Expand Down Expand Up @@ -1210,7 +1323,7 @@
'Bitbucket Workspace ID',
GitLink.BITBUCKET_WORKSPACE,
'How to create workspace in bitbucket?',
true
true,
)}
/>
</div>
Expand Down Expand Up @@ -1239,68 +1352,7 @@
Git access credentials
</div>

{BitBucketDCCredentials && this.state.form.provider === 'BITBUCKET_DC' ? (
<div className={`flexbox-col ${isTLSConfigFormVisible ? 'mb-16' : ''}`}>
<BitBucketDCCredentials
authMode={this.state.form.authMode}
initialAuthMode={this.state.initialBitBucketDCAuthMode}
handleAuthModeChange={this.handleAuthModeChange}
handleChange={this.handleChange}
username={{
value: this.state.form.username,
error: this.state.isError.username,
}}
sshKey={{
value: this.state.form.sshKey,
error: this.state.isError.sshKey,
}}
token={{
value: this.state.form.token,
error: this.state.isError.token,
}}
id={this.state.form.id}
/>
</div>
) : (
<div className="form__row--two-third w-100">
<div>
<CustomInput
value={this.state.form.username}
onChange={(event) => this.handleChange(event, 'username')}
name="Enter username"
placeholder="Enter username"
error={this.state.isError.username}
label={
this.state.providerTab === GitProvider.GITLAB
? 'GitLab Username'
: this.state.providerTab === GitProvider.AZURE_DEVOPS
? 'Azure DevOps Username'
: this.state.providerTab === GitProvider.BITBUCKET_CLOUD
? 'Bitbucket Username'
: 'GitHub Username'
}
required
/>
</div>
<div>
<PasswordField
shouldShowDefaultPlaceholderOnBlur={!!this.state.form.id}
name="token"
placeholder="Enter access token"
value={this.state.form.token}
onChange={(event) => this.handleChange(event, 'token')}
error={this.state.isError.token}
{...getInputLabelProps(
this.state.providerTab === GitProvider.AZURE_DEVOPS
? 'Azure DevOps Access Token '
: 'Personal Access Token ',
PROVIDER_DOC_LINK_MAP[this.state.providerTab],
'Check permissions required for PAT',
)}
/>
</div>
</div>
)}
{renderGitAccessCredentials()}
</Fragment>
)
}
Expand Down
10 changes: 9 additions & 1 deletion src/components/gitOps/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

import { DocLinkProps } from '@devtron-labs/devtron-fe-common-lib'
import { DocLinkProps, GitOpsAuthModeType } from '@devtron-labs/devtron-fe-common-lib'

import { GitProvider } from '@Components/common/GitTabs/constants'

Expand Down Expand Up @@ -116,3 +116,11 @@ export const PROVIDER_DOC_LINK_MAP: Record<
[GitProvider.AZURE_DEVOPS]: 'GLOBAL_CONFIG_GITOPS_AZURE',
[GitProvider.BITBUCKET_CLOUD]: 'GLOBAL_CONFIG_GITOPS_BITBUCKET',
}

export const UNABLE_TO_DELETE_WARNING = 'Devtron was unable to delete the test repository “devtron-sample-repo-dryrun-…”. Please delete it manually.'

export const BITBUCKET_CLOUD_AUTH_MODE_OPTIONS = [
{ label: 'App Password', value: GitOpsAuthModeType.PASSWORD },
{ label: 'Access Token', value: GitOpsAuthModeType.ACCESS_TOKEN },
{ label: 'API Token', value: GitOpsAuthModeType.API_TOKEN },
]
5 changes: 5 additions & 0 deletions src/components/gitOps/gitops.type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,3 +171,8 @@ export interface UpdateConfirmationDialogProps
*/
enableBitBucketSource: boolean
}

export interface BitbucketCloudAuthSelectorProps {
authMode: GitOpsAuthModeType
handleAuthModeChange: (event: React.SyntheticEvent) => void
}
Loading
Loading