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
31 changes: 21 additions & 10 deletions libs/i18n/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -928,30 +928,38 @@
"Failed to retrieve repository details": "Failed to retrieve repository details",
"Failed to retrieve the resource syncs": "Failed to retrieve the resource syncs",
"The repository cannot be modified at the moment because some of its details could not be obtained.": "The repository cannot be modified at the moment because some of its details could not be obtained.",
"Basic authentication": "Basic authentication",
"Username": "Username",
"Password": "Password",
"Skip server verification": "Skip server verification",
"CA certificate": "CA certificate",
"HTTP": "HTTP",
"SSH": "SSH",
"Validation suffix": "Validation suffix",
"Suffix to the repository's base URL used to validate if the HTTP service is accessible.": "Suffix to the repository's base URL used to validate if the HTTP service is accessible.",
"Full validation URL: <1>{`${values.url}${values.validationSuffix || ''}`}</1>": "Full validation URL: <1>{`${values.url}${values.validationSuffix || ''}`}</1>",
"Basic authentication": "Basic authentication",
"Username": "Username",
"Password": "Password",
"mTLS authentication": "mTLS authentication",
"Client TLS certificate": "Client TLS certificate",
"Client TLS key": "Client TLS key",
"Skip server verification": "Skip server verification",
"CA certificate": "CA certificate",
"JWT authentication token for the HTTP service": "JWT authentication token for the HTTP service",
"Token": "Token",
"SSH private key": "SSH private key",
"Private key passphrase": "Private key passphrase",
"Use Git repository": "Use Git repository",
"Use HTTP service": "Use HTTP service",
"Use OCI registry": "Use OCI registry",
"Switching the repository type will cause some data to be lost.": "Switching the repository type will cause some data to be lost.",
"Are you sure you want to change the repository type?": "Are you sure you want to change the repository type?",
"Change": "Change",
"Registry hostname": "Registry hostname",
"For example: quay.io, registry.redhat.io, myregistry.com:5000": "For example: quay.io, registry.redhat.io, myregistry.com:5000",
"Repository URL": "Repository URL",
"For example: {{ demoRepositoryUrl }}": "For example: {{ demoRepositoryUrl }}",
"Scheme": "Scheme",
"HTTPS": "HTTPS",
"Access mode": "Access mode",
"Read only": "Read only",
"Read and write": "Read and write",
"Use advanced configurations": "Use advanced configurations",
"Use resource syncs": "Use resource syncs",
"Resource sync name": "Resource sync name",
Expand All @@ -963,16 +971,18 @@
"Add another resource sync": "Add another resource sync",
"Target revision is required.": "Target revision is required.",
"Must be an absolute path.": "Must be an absolute path.",
"Enter a valid repository URL. Example: {{ demoRepositoryUrl }}": "Enter a valid repository URL. Example: {{ demoRepositoryUrl }}",
"Repository URL is required": "Repository URL is required",
"Enter a valid HTTP service URL. Example: https://my-service-url": "Enter a valid HTTP service URL. Example: https://my-service-url",
"HTTP service URL is required": "HTTP service URL is required",
"Repository type is required": "Repository type is required",
"Username is required": "Username is required",
"Password is required": "Password is required",
"Client TLS certificate is required": "Client TLS certificate is required",
"Client TLS key is required": "Client TLS key is required",
"Must be a valid JWT token": "Must be a valid JWT token",
"Enter a valid registry hostname (e.g., quay.io, registry.redhat.io, myregistry.com:5000)": "Enter a valid registry hostname (e.g., quay.io, registry.redhat.io, myregistry.com:5000)",
"Registry hostname is required": "Registry hostname is required",
"Enter a valid repository URL. Example: {{ demoRepositoryUrl }}": "Enter a valid repository URL. Example: {{ demoRepositoryUrl }}",
"Repository URL is required": "Repository URL is required",
"Enter a valid HTTP service URL. Example: https://my-service-url": "Enter a valid HTTP service URL. Example: https://my-service-url",
"HTTP service URL is required": "HTTP service URL is required",
"Deleting {{count}} resource sync_one": "Deleting {{count}} resource sync",
"Deleting {{count}} resource sync_other": "Deleting {{count}} resource syncs",
"{{count}} resource sync could not be deleted. Try deleting it manually._one": "{{count}} resource sync could not be deleted. Try deleting it manually.",
Expand All @@ -988,9 +998,10 @@
"Delete repository": "Delete repository",
"Private repository": "Private repository",
"Public repository": "Public repository",
"Url": "Url",
"OCI registry": "OCI registry",
"HTTP service": "HTTP service",
"Git repository": "Git repository",
"Registry": "Registry",
"Privacy": "Privacy",
"Edge Manager will monitor the specified paths, import the defined fleets and synchronise devices": "Edge Manager will monitor the specified paths, import the defined fleets and synchronise devices",
"Copy Url": "Copy Url",
Expand Down
5 changes: 5 additions & 0 deletions libs/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export { ApplicationsSummaryStatusType } from './models/ApplicationsSummaryStatu
export { ApplicationStatusType } from './models/ApplicationStatusType';
export type { ApplicationVolume } from './models/ApplicationVolume';
export type { ApplicationVolumeProviderSpec } from './models/ApplicationVolumeProviderSpec';
export { ApplicationVolumeReclaimPolicy } from './models/ApplicationVolumeReclaimPolicy';
export type { ApplicationVolumeStatus } from './models/ApplicationVolumeStatus';
export { AppType } from './models/AppType';
export type { AuthConfig } from './models/AuthConfig';
Expand Down Expand Up @@ -77,6 +78,7 @@ export { DeviceUpdatedStatusType } from './models/DeviceUpdatedStatusType';
export type { DeviceUpdatePolicySpec } from './models/DeviceUpdatePolicySpec';
export type { DiskResourceMonitorSpec } from './models/DiskResourceMonitorSpec';
export type { DisruptionBudget } from './models/DisruptionBudget';
export type { DockerAuth } from './models/DockerAuth';
export type { Duration } from './models/Duration';
export { EncodingType } from './models/EncodingType';
export type { EnrollmentConfig } from './models/EnrollmentConfig';
Expand Down Expand Up @@ -142,6 +144,9 @@ export type { OAuth2Introspection } from './models/OAuth2Introspection';
export type { OAuth2ProviderSpec } from './models/OAuth2ProviderSpec';
export type { ObjectMeta } from './models/ObjectMeta';
export type { ObjectReference } from './models/ObjectReference';
export type { OciAuth } from './models/OciAuth';
export { OciAuthType } from './models/OciAuthType';
export { OciRepoSpec } from './models/OciRepoSpec';
export type { OIDCProviderSpec } from './models/OIDCProviderSpec';
export type { OpenShiftProviderSpec } from './models/OpenShiftProviderSpec';
export type { Organization } from './models/Organization';
Expand Down
2 changes: 2 additions & 0 deletions libs/types/models/ApplicationVolume.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { ApplicationVolumeReclaimPolicy } from './ApplicationVolumeReclaimPolicy';
import type { ImageMountVolumeProviderSpec } from './ImageMountVolumeProviderSpec';
import type { ImageVolumeProviderSpec } from './ImageVolumeProviderSpec';
import type { MountVolumeProviderSpec } from './MountVolumeProviderSpec';
Expand All @@ -10,5 +11,6 @@ export type ApplicationVolume = ({
* Unique name of the volume used within the application.
*/
name: string;
reclaimPolicy?: ApplicationVolumeReclaimPolicy;
} & (ImageVolumeProviderSpec | MountVolumeProviderSpec | ImageMountVolumeProviderSpec));

10 changes: 10 additions & 0 deletions libs/types/models/ApplicationVolumeReclaimPolicy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
/**
* Defines how the agent handles a volume when the owning application is removed.
*/
export enum ApplicationVolumeReclaimPolicy {
RETAIN = 'Retain',
}
19 changes: 19 additions & 0 deletions libs/types/models/DockerAuth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
/**
* Docker-style authentication for OCI registries.
*/
export type DockerAuth = {
authType: 'docker';
/**
* The username for registry authentication.
*/
username: string;
/**
* The password or token for registry authentication.
*/
password: string;
};

4 changes: 4 additions & 0 deletions libs/types/models/K8sProviderSpec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,9 @@ export type K8sProviderSpec = {
enabled?: boolean;
organizationAssignment: AuthOrganizationAssignment;
roleAssignment: AuthRoleAssignment;
/**
* Optional suffix to strip from ClusterRole names when normalizing role names. Used for multi-release deployments where ClusterRoles have namespace-specific names (e.g., flightctl-admin-<namespace>).
*/
roleSuffix?: string;
};

10 changes: 10 additions & 0 deletions libs/types/models/OciAuth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { DockerAuth } from './DockerAuth';
/**
* Authentication for OCI registries.
*/
export type OciAuth = DockerAuth;

10 changes: 10 additions & 0 deletions libs/types/models/OciAuthType.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
/**
* The type of authentication for OCI registries.
*/
export enum OciAuthType {
DOCKER = 'docker',
}
50 changes: 50 additions & 0 deletions libs/types/models/OciRepoSpec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/* generated using openapi-typescript-codegen -- do no edit */
/* istanbul ignore file */
/* tslint:disable */
/* eslint-disable */
import type { OciAuth } from './OciAuth';
import type { RepoSpecType } from './RepoSpecType';
/**
* OCI container registry specification.
*/
export type OciRepoSpec = {
/**
* The OCI registry hostname, FQDN, or IP address with optional port (e.g., quay.io, registry.redhat.io, myregistry.com:5000, 192.168.1.1:5000, [::1]:5000).
*/
registry: string;
/**
* URL scheme for connecting to the registry.
*/
scheme?: OciRepoSpec.scheme;
type: RepoSpecType;
/**
* Access mode for the registry: "Read" for read-only (pull), "ReadWrite" for read-write (pull and push).
*/
accessMode?: OciRepoSpec.accessMode;
ociAuth?: OciAuth;
/**
* Base64 encoded root CA.
*/
'ca.crt'?: string;
/**
* Skip remote server verification.
*/
skipServerVerification?: boolean;
};
export namespace OciRepoSpec {
/**
* URL scheme for connecting to the registry.
*/
export enum scheme {
HTTP = 'http',
HTTPS = 'https',
}
/**
* Access mode for the registry: "Read" for read-only (pull), "ReadWrite" for read-write (pull and push).
*/
export enum accessMode {
READ = 'Read',
READ_WRITE = 'ReadWrite',
}
}

8 changes: 8 additions & 0 deletions libs/types/models/OpenShiftProviderSpec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,13 @@ export type OpenShiftProviderSpec = {
* The OpenShift cluster control plane URL.
*/
clusterControlPlaneUrl?: string;
/**
* If specified, only projects with this label will be considered. The label selector should be in the format 'key' or 'key=value'. If only the key is provided, any project with that label (regardless of value) will be included. This enables server-side filtering for better performance.
*/
projectLabelFilter?: string;
/**
* Optional suffix to strip from ClusterRole names when normalizing role names. Used for multi-release deployments where ClusterRoles have namespace-specific names (e.g., flightctl-admin-<namespace>).
*/
roleSuffix?: string;
};

1 change: 1 addition & 0 deletions libs/types/models/RepoSpecType.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@
export enum RepoSpecType {
GIT = 'git',
HTTP = 'http',
OCI = 'oci',
}
3 changes: 2 additions & 1 deletion libs/types/models/RepositorySpec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@
/* eslint-disable */
import type { GenericRepoSpec } from './GenericRepoSpec';
import type { HttpRepoSpec } from './HttpRepoSpec';
import type { OciRepoSpec } from './OciRepoSpec';
import type { SshRepoSpec } from './SshRepoSpec';
/**
* RepositorySpec describes a configuration repository.
*/
export type RepositorySpec = (GenericRepoSpec | HttpRepoSpec | SshRepoSpec);
export type RepositorySpec = (GenericRepoSpec | HttpRepoSpec | SshRepoSpec | OciRepoSpec);

Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ import { PlusCircleIcon } from '@patternfly/react-icons/dist/js/icons/plus-circl
import { ExclamationCircleIcon } from '@patternfly/react-icons/dist/js/icons/exclamation-circle-icon';
import { TFunction, Trans } from 'react-i18next';

import { RepoSpecType, Repository } from '@flightctl/types';
import { GenericRepoSpec, HttpRepoSpec, RepoSpecType, Repository } from '@flightctl/types';
import { DeviceSpecConfigFormValues, GitConfigTemplate, HttpConfigTemplate } from '../../../../types/deviceSpec';
import { useTranslation } from '../../../../hooks/useTranslation';
import TextField from '../../../form/TextField';
import FormSelect from '../../../form/FormSelect';
import CreateRepositoryModal from '../../../modals/CreateRepositoryModal/CreateRepositoryModal';
import { FormGroupWithHelperText } from '../../../common/WithHelperText';
import { getRepoUrlOrRegistry } from '../../../Repository/CreateRepository/utils';

type ConfigWithRepositoryTemplateFormProps = {
repoType: RepoSpecType;
Expand All @@ -30,9 +31,11 @@ const getRepositoryItems = (
) => {
const repositoryItems = repositories.reduce((acc, curr) => {
if (curr.spec.type === repoType) {
acc[curr.metadata.name || ''] = {
label: curr.metadata.name,
description: curr.spec.url,
const description = getRepoUrlOrRegistry(curr.spec);
const repoName = curr.metadata.name || '';
acc[repoName] = {
label: repoName,
description,
};
}
return acc;
Expand Down Expand Up @@ -175,6 +178,7 @@ const ConfigWithRepositoryTemplateForm = ({
: getRepositoryItems(t, repositories, repoType, selectedRepoName);

const selectedRepo = repositories.find((repo) => repo.metadata.name === selectedRepoName);
const repoSpec = selectedRepo?.spec as GenericRepoSpec | HttpRepoSpec | undefined;
return (
<>
<FormGroup label={t('Repository')} isRequired>
Expand Down Expand Up @@ -209,7 +213,7 @@ const ConfigWithRepositoryTemplateForm = ({
<HttpConfigForm
template={ct as HttpConfigTemplate}
index={index}
baseURL={selectedRepo?.spec.url}
baseURL={repoSpec?.url || ''}
isReadOnly={isReadOnly}
/>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { FormGroup, FormSection, Grid, Radio } from '@patternfly/react-core';
import { FormikErrors, useFormikContext } from 'formik';
import { Table, Tbody, Td, Th, Thead, Tr } from '@patternfly/react-table';

import { Repository } from '@flightctl/types';
import { GenericRepoSpec, Repository } from '@flightctl/types';
import { ImportFleetFormValues } from '../types';

import { RepositoryForm } from '../../../Repository/CreateRepository/CreateRepositoryForm';
Expand Down Expand Up @@ -36,7 +36,7 @@ const ExistingRepoForm = ({ repositories }: { repositories: Repository[] }) => {
const { values } = useFormikContext<ImportFleetFormValues>();

const currentRepo = repositories.find((r) => r.metadata.name === values.existingRepo);

const repoSpec = currentRepo?.spec as GenericRepoSpec | undefined; // Only git repositories can be used for importing fleets;
return (
<>
<FormGroup label={t('Repository')} fieldId="repository">
Expand All @@ -60,7 +60,7 @@ const ExistingRepoForm = ({ repositories }: { repositories: Repository[] }) => {
</Thead>
<Tbody>
<Tr>
<Td dataLabel={t('URL')}>{currentRepo.spec.url}</Td>
<Td dataLabel={t('URL')}>{repoSpec?.url || '-'}</Td>
<Td dataLabel={t('Sync status')}>
<RepositoryStatus statusInfo={getRepositorySyncStatus(currentRepo)} />
</Td>
Expand Down
Loading