Skip to content

Commit

Permalink
Add CAPV support (#4630)
Browse files Browse the repository at this point in the history
  • Loading branch information
gusevda authored Oct 15, 2024
1 parent 4e8db9c commit 336a567
Show file tree
Hide file tree
Showing 27 changed files with 2,304 additions and 152 deletions.
20 changes: 20 additions & 0 deletions scripts/generate/mapi-resources.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,23 @@
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
crdURL: https://raw.githubusercontent.com/kubernetes-sigs/cluster-api-provider-azure/main/config/crd/bases/infrastructure.cluster.x-k8s.io_azuremachinepools.yaml

- apiVersionAlias: capvv1beta1
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
resources:
- name: VSphereCluster
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
crdURL: https://raw.githubusercontent.com/kubernetes-sigs/cluster-api-provider-vsphere/refs/heads/main/config/default/crd/bases/infrastructure.cluster.x-k8s.io_vsphereclusters.yaml
verbs:
- get
- name: VSphereMachine
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
crdURL: https://raw.githubusercontent.com/kubernetes-sigs/cluster-api-provider-vsphere/refs/heads/main/config/default/crd/bases/infrastructure.cluster.x-k8s.io_vspheremachines.yaml
verbs:
- get
- list
- name: VSphereMachineTemplate
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
crdURL: https://raw.githubusercontent.com/kubernetes-sigs/cluster-api-provider-vsphere/refs/heads/main/config/default/crd/bases/infrastructure.cluster.x-k8s.io_vspheremachinetemplates.yaml
verbs:
- get
- list
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
fetchControlPlaneForClusterKey,
fetchControlPlaneNodesForCluster,
fetchControlPlaneNodesForClusterKey,
supportsAvailabilityZones,
} from 'MAPI/utils';
import { GenericResponseError } from 'model/clients/GenericResponseError';
import { Providers } from 'model/constants';
Expand Down Expand Up @@ -166,6 +167,9 @@ const ClusterDetailWidgetControlPlaneNodes: React.FC<
controlPlaneNodes
);

const displayAvailabilityZones =
cluster && supportsAvailabilityZones(cluster);

const [isSwitchingToHA, setIsSwitchingToHA] = useState(false);

const onSwitchToHAExit = () => {
Expand Down Expand Up @@ -205,19 +209,24 @@ const ClusterDetailWidgetControlPlaneNodes: React.FC<
)
}
</OptionalValue>
<StyledDot />
<Text margin={{ right: 'xsmall' }}>
{formatAvailabilityZonesLabel(provider, stats.availabilityZones)}
</Text>
<OptionalValue
value={stats.availabilityZones?.sort()}
loaderWidth={100}
loaderHeight={26}
>
{(value) => (
<AvailabilityZonesLabels zones={value} labelsChecked={[]} />
)}
</OptionalValue>

{displayAvailabilityZones && (
<>
<StyledDot />
<Text margin={{ right: 'xsmall' }}>
{formatAvailabilityZonesLabel(provider, stats.availabilityZones)}
</Text>
<OptionalValue
value={stats.availabilityZones?.sort()}
loaderWidth={100}
loaderHeight={26}
>
{(value) => (
<AvailabilityZonesLabels zones={value} labelsChecked={[]} />
)}
</OptionalValue>
</>
)}

{canSwitchToHA && (
<Box basis='100%' margin={{ top: 'small' }}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { extractErrorMessage } from 'MAPI/utils';
import { GenericResponseError } from 'model/clients/GenericResponseError';
import * as capav1beta2 from 'model/services/mapi/capav1beta2';
import * as capgv1beta1 from 'model/services/mapi/capgv1beta1';
import * as capvv1beta1 from 'model/services/mapi/capvv1beta1';
import * as capzv1beta1 from 'model/services/mapi/capzv1beta1';
import * as legacyCredentials from 'model/services/mapi/legacy/credentials';
import { selectOrganizations } from 'model/stores/organization/selectors';
Expand All @@ -28,6 +29,7 @@ import ClusterDetailWidgetProviderAWSManaged from './ClusterDetailWidgetProvider
import ClusterDetailWidgetProviderAzure from './ClusterDetailWidgetProviderAzure';
import ClusterDetailWidgetProviderCAPG from './ClusterDetailWidgetProviderCAPG';
import ClusterDetailWidgetProviderLoader from './ClusterDetailWidgetProviderLoader';
import ClusterDetailWidgetProviderVSphere from './ClusterDetailWidgetProviderVSphere';
import { fetchProviderCredential, fetchProviderCredentialKey } from './utils';

interface IClusterDetailWidgetProviderProps
Expand Down Expand Up @@ -145,6 +147,10 @@ const ClusterDetailWidgetProvider: React.FC<
| legacyCredentials.ICredential
}
/>
) : kind === capvv1beta1.VSphereCluster ? (
<ClusterDetailWidgetProviderVSphere
providerCluster={providerCluster as capvv1beta1.IVSphereCluster}
/>
) : null}
</Grid>
</ClusterDetailWidget>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { Text } from 'grommet';
import { normalizeColor } from 'grommet/utils';
import * as capvv1beta1 from 'model/services/mapi/capvv1beta1';
import React, { useMemo } from 'react';
import styled from 'styled-components';
import OptionalValue from 'UI/Display/OptionalValue/OptionalValue';

const StyledLink = styled.a`
color: ${({ theme }) => normalizeColor('text-weak', theme)};
`;

interface IClusterDetailWidgetProviderAWSProps {
providerCluster: capvv1beta1.IVSphereCluster;
}

const ClusterDetailWidgetProviderAWS: React.FC<
React.PropsWithChildren<IClusterDetailWidgetProviderAWSProps>
> = ({ providerCluster }) => {
const vCenter = useMemo(() => {
if (!providerCluster) return undefined;

return providerCluster.spec?.server ?? '';
}, [providerCluster]);

return (
<>
<Text>vCenter</Text>
<OptionalValue value={vCenter}>
{(value) => (
<StyledLink
href={`https://${value}/ui`}
rel='noopener noreferrer'
target='_blank'
>
<code>{value}</code>
<i
className='fa fa-open-in-new'
aria-hidden={true}
role='presentation'
/>
</StyledLink>
)}
</OptionalValue>
</>
);
};

export default ClusterDetailWidgetProviderAWS;
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ describe('ClusterDetailWidgetControlPlaneNodes', () => {
})
);

expect(screen.getAllByLabelText('Loading...').length).toEqual(2);
expect(screen.getAllByLabelText('Loading...').length).toEqual(1);
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -319,19 +319,38 @@ const formPropsProviderGCP: Record<string, FormPropsPartial> = {
const formPropsProviderVSphere: Record<string, FormPropsPartial> = {
0: {
uiSchema: {
'ui:order': ['cluster', 'controlPlane', '*'],
'ui:order': ['global', '*'],
baseDomain: {
'ui:widget': 'hidden',
},
cluster: {
'ui:order': ['name', 'organization', '*'],
name: {
'ui:widget': ClusterNameWidget,
'ui:widget': 'hidden',
},
global: {
metadata: {
'ui:order': ['name', 'description', '*'],
name: {
'ui:widget': ClusterNameWidget,
},
},
},
managementCluster: {
'ui:widget': 'hidden',
},
provider: {
'ui:widget': 'hidden',
},
'cluster-shared': {
'ui:widget': 'hidden',
},
},
formData: (clusterName, organization) => {
return {
cluster: {
name: clusterName,
organization,
global: {
metadata: {
name: clusterName,
organization,
},
},
};
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { usePermissions } from 'MAPI/permissions/usePermissions';
import { hasPermission } from 'MAPI/permissions/utils';
import { Providers } from 'model/constants';

// eslint-disable-next-line complexity
export function usePermissionsForCPNodes(
provider: PropertiesOf<typeof Providers>,
namespace: string
Expand Down Expand Up @@ -268,6 +269,45 @@ export function usePermissionsForCPNodes(
);

break;

case Providers.VSPHERE:
computed.canCreate = canCreateClusterApps;
computed.canDelete = canDeleteClusterApps;
computed.canUpdate = canUpdateClusterApps;

computed.canGet =
hasPermission(
permissions,
namespace,
'get',
'cluster.x-k8s.io',
'machines'
) &&
hasPermission(
permissions,
namespace,
'get',
'infrastructure.cluster.x-k8s.io',
'vspheremachines'
);

computed.canList =
hasPermission(
permissions,
namespace,
'list',
'cluster.x-k8s.io',
'machines'
) &&
hasPermission(
permissions,
namespace,
'list',
'infrastructure.cluster.x-k8s.io',
'vspheremachines'
);

break;
}

return computed;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,45 @@ export function usePermissionsForClusters(
);

break;

case Providers.VSPHERE:
computed.canCreate = canCreateClusterApps;
computed.canDelete = canDeleteClusterApps;
computed.canUpdate = canUpdateClusterApps;

computed.canGet =
hasPermission(
permissions,
namespace,
'get',
'cluster.x-k8s.io',
'clusters'
) &&
hasPermission(
permissions,
namespace,
'get',
'infrastructure.cluster.x-k8s.io',
'vsphereclusters'
);

computed.canList =
hasPermission(
permissions,
namespace,
'list',
'cluster.x-k8s.io',
'clusters'
) &&
hasPermission(
permissions,
namespace,
'list',
'infrastructure.cluster.x-k8s.io',
'vsphereclusters'
);

break;
}

return computed;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export function usePermissionsForControlPlanes(
switch (provider) {
case Providers.CAPA:
case Providers.CAPZ:
case Providers.VSPHERE:
computed.canCreate = canCreateClusterApps;
computed.canDelete = canDeleteClusterApps;
computed.canUpdate = canUpdateClusterApps;
Expand Down
Loading

0 comments on commit 336a567

Please sign in to comment.