Skip to content

Commit

Permalink
use user creator label to identify workspace resource instead of anno…
Browse files Browse the repository at this point in the history
…tation
  • Loading branch information
vikram-raj committed May 21, 2020
1 parent adfaf85 commit 111c830
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,24 @@ import * as React from 'react';
import { connect } from 'react-redux';
import { RootState } from '@console/internal/redux';
import { referenceForModel } from '@console/internal/module/k8s/k8s';
import { useK8sWatchResource } from '@console/internal/components/utils/k8s-watch-hook';
import {
useK8sWatchResource,
WatchK8sResource,
} from '@console/internal/components/utils/k8s-watch-hook';
import { LoadingBox, StatusBox } from '@console/internal/components/utils/status-box';
import { WorkspaceModel } from '../../models';
import CloudShellTerminalFrame from './CloudShellTerminalFrame';
import {
CLOUD_SHELL_LABEL,
CLOUD_SHELL_USER_ANNOTATION,
CloudShellResource,
CLOUD_SHELL_CREATOR_LABEL,
CLOUD_SHELL_LABEL,
CLOUD_SHELL_IMMUTABLE_ANNOTATION,
} from './cloud-shell-utils';
import CloudShellSetup from './setup/CloudShellSetup';
import { UserKind } from '@console/internal/module/k8s';

type StateProps = {
username: string;
user: UserKind;
};

type Props = {
Expand All @@ -23,15 +28,24 @@ type Props = {

type CloudShellTerminalProps = StateProps & Props;

const resource = {
kind: referenceForModel(WorkspaceModel),
isList: true,
selector: {
matchLabels: { [CLOUD_SHELL_LABEL]: 'true' },
},
};
const CloudShellTerminal: React.FC<CloudShellTerminalProps> = ({ user, onCancel }) => {
const uid = user?.metadata?.uid;
const name = user?.metadata?.name;
const isKubeAdmin = !uid && name === 'kube:admin';
const resource: WatchK8sResource = React.useMemo(
() => ({
kind: referenceForModel(WorkspaceModel),
isList: true,
selector: {
matchLabels: {
[CLOUD_SHELL_LABEL]: 'true',
[CLOUD_SHELL_CREATOR_LABEL]: isKubeAdmin ? '' : uid,
},
},
}),
[isKubeAdmin, uid],
);

const CloudShellTerminal: React.FC<CloudShellTerminalProps> = ({ username, onCancel }) => {
const [data, loaded, loadError] = useK8sWatchResource<CloudShellResource>(resource);

if (loadError) {
Expand All @@ -46,7 +60,7 @@ const CloudShellTerminal: React.FC<CloudShellTerminalProps> = ({ username, onCan

if (Array.isArray(data)) {
const workspace = data.find(
(d) => d?.metadata?.annotations?.[CLOUD_SHELL_USER_ANNOTATION] === username,
(d) => d?.metadata?.annotations?.[CLOUD_SHELL_IMMUTABLE_ANNOTATION] === 'true',
);
if (workspace) {
const running = workspace.status?.phase === 'Running';
Expand All @@ -59,7 +73,7 @@ const CloudShellTerminal: React.FC<CloudShellTerminalProps> = ({ username, onCan
};

const stateToProps = (state: RootState): StateProps => ({
username: state.UI.get('user')?.metadata?.name || '',
user: state.UI.get('user'),
});

// exposed for testing
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import { useK8sWatchResource } from '@console/internal/components/utils/k8s-watc
import { LoadingBox } from '@console/internal/components/utils/status-box';
import { InternalCloudShellTerminal } from '../CloudShellTerminal';
import CloudShellSetup from '../setup/CloudShellSetup';
import { CLOUD_SHELL_USER_ANNOTATION } from '../cloud-shell-utils';
import CloudShellTerminalFrame from '../CloudShellTerminalFrame';
import { user } from './cloud-shell-test-data';
import { CLOUD_SHELL_CREATOR_LABEL, CLOUD_SHELL_IMMUTABLE_ANNOTATION } from '../cloud-shell-utils';

jest.mock('@console/internal/components/utils/k8s-watch-hook', () => ({
useK8sWatchResource: jest.fn(),
Expand All @@ -14,27 +15,32 @@ jest.mock('@console/internal/components/utils/k8s-watch-hook', () => ({
describe('CloudShellTerminal', () => {
it('should display loading box', () => {
(useK8sWatchResource as jest.Mock).mockReturnValueOnce([null, false]);
const wrapper = shallow(<InternalCloudShellTerminal username="user" />);
const wrapper = shallow(<InternalCloudShellTerminal user={user} />);
expect(wrapper.find(LoadingBox)).toHaveLength(1);
});

it('should display form if loaded and no workspace', () => {
(useK8sWatchResource as jest.Mock).mockReturnValueOnce([[], true]);
const wrapper = shallow(<InternalCloudShellTerminal username="user" />);
const wrapper = shallow(<InternalCloudShellTerminal user={user} />);
expect(wrapper.find(CloudShellSetup)).toHaveLength(1);
});

it('should display terminal if loaded with matching workspace', () => {
(useK8sWatchResource as jest.Mock).mockReturnValueOnce([
[
{
metadata: { annotations: { [CLOUD_SHELL_USER_ANNOTATION]: 'user' } },
metadata: {
labels: { [CLOUD_SHELL_CREATOR_LABEL]: '53093d25-830b-4ab2-b723-ac8659b5a176' },
annotations: {
[CLOUD_SHELL_IMMUTABLE_ANNOTATION]: 'true',
},
},
status: { phase: 'Running', ideUrl: 'testURL' },
},
],
true,
]);
const wrapper = shallow(<InternalCloudShellTerminal username="user" />);
const wrapper = shallow(<InternalCloudShellTerminal user={user} />);
const frame = wrapper.find(CloudShellTerminalFrame);
expect(frame).toHaveLength(1);
expect(frame.props().loading).toBe(false);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { UserKind } from '@console/internal/module/k8s';

export const user: UserKind = {
kind: 'User',
apiVersion: 'user.openshift.io/v1',
identities: null,
metadata: {
name: 'consoledeveloper',
selfLink: '/apis/user.openshift.io/v1/users/kube%3Aadmin',
uid: '53093d25-830b-4ab2-b723-ac8659b5a176',
},
};
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
import {
newCloudShellWorkSpace,
CLOUD_SHELL_LABEL,
CLOUD_SHELL_USER_ANNOTATION,
CLOUD_SHELL_IMMUTABLE_ANNOTATION,
} from '../cloud-shell-utils';

describe('CloudShell Utils', () => {
it('should create a new workspace resource', () => {
const name = 'cloudshell';
const namespace = 'default';
const kind = 'Workspace';
const username = 'test-user';

const newResource = newCloudShellWorkSpace(name, namespace, username);
const newResource = newCloudShellWorkSpace(name, namespace);
expect(newResource.kind).toEqual(kind);
expect(newResource.metadata.name).toEqual(name);
expect(newResource.metadata.namespace).toEqual(namespace);
expect(newResource.metadata.labels[CLOUD_SHELL_LABEL]).toEqual('true');
expect(newResource.metadata.annotations[CLOUD_SHELL_USER_ANNOTATION]).toEqual(username);
expect(newResource.metadata.annotations[CLOUD_SHELL_IMMUTABLE_ANNOTATION]).toEqual('true');
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,12 @@ export type CloudShellResource = K8sResourceKind & {
};

export const CLOUD_SHELL_LABEL = 'console.openshift.io/cloudshell';
export const CLOUD_SHELL_USER_ANNOTATION = 'console.openshift.io/cloudshell-user';
export const CLOUD_SHELL_CREATOR_LABEL = 'org.eclipse.che.workspace/creator';
export const CLOUD_SHELL_IMMUTABLE_ANNOTATION = 'org.eclipse.che.workspace/immutable';

export const createCloudShellResourceName = () => `terminal-${getRandomChars(6)}`;

export const newCloudShellWorkSpace = (
name: string,
namespace: string,
username: string,
): CloudShellResource => ({
export const newCloudShellWorkSpace = (name: string, namespace: string): CloudShellResource => ({
apiVersion: 'workspace.che.eclipse.org/v1alpha1',
kind: 'Workspace',
metadata: {
Expand All @@ -53,7 +50,7 @@ export const newCloudShellWorkSpace = (
[CLOUD_SHELL_LABEL]: 'true',
},
annotations: {
[CLOUD_SHELL_USER_ANNOTATION]: username,
[CLOUD_SHELL_IMMUTABLE_ANNOTATION]: 'true',
},
},
spec: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ const CloudShellSetup: React.FunctionComponent<Props> = ({
activeNamespace,
onSubmit,
onCancel,
username,
}) => {
const initialValues: CloudShellSetupFormData = {
namespace: activeNamespace === ALL_NAMESPACES_KEY ? undefined : activeNamespace,
Expand All @@ -49,7 +48,7 @@ const CloudShellSetup: React.FunctionComponent<Props> = ({
}
await k8sCreate(
WorkspaceModel,
newCloudShellWorkSpace(createCloudShellResourceName(), namespace, username),
newCloudShellWorkSpace(createCloudShellResourceName(), namespace),
);
onSubmit && onSubmit();
} catch (err) {
Expand Down

0 comments on commit 111c830

Please sign in to comment.