Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update api server urls to use url helper. #1877

Merged
merged 2 commits into from
Jul 21, 2020
Merged
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
11 changes: 0 additions & 11 deletions dashboard/src/actions/repos.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ beforeEach(() => {
AppRepository.create = jest.fn().mockImplementationOnce(() => {
return { appRepository: { metadata: { name: "repo-abc" } } };
});
Secret.create = jest.fn();
Secret.list = jest.fn().mockReturnValue({
items: [],
});
Expand Down Expand Up @@ -327,11 +326,6 @@ describe("installRepo", () => {
);
});

it("does not create the K8s secret as API includes this", async () => {
await store.dispatch(installRepoCMDAuth);
expect(Secret.create).not.toHaveBeenCalled();
});

it("returns true", async () => {
const res = await store.dispatch(installRepoCMDAuth);
expect(res).toBe(true);
Expand Down Expand Up @@ -362,11 +356,6 @@ describe("installRepo", () => {
);
});

it("does not create the K8s secret as API includes this", async () => {
await store.dispatch(installRepoCMDAuth);
expect(Secret.create).not.toHaveBeenCalled();
});

it("returns true", async () => {
const res = await store.dispatch(installRepoCMDAuth);
expect(res).toBe(true);
Expand Down
16 changes: 12 additions & 4 deletions dashboard/src/actions/repos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ export const fetchRepoSecrets = (
// TODO(andresmgot): Create an endpoint for returning credentials related to an AppRepository
// to avoid listing secrets
// /~https://github.com/kubeapps/kubeapps/issues/1686
const secrets = await Secret.list(namespace);
const secrets = await Secret.list("default", namespace);
const repoSecrets = secrets.items?.filter(s =>
s.metadata.ownerReferences?.some(ownerRef => ownerRef.kind === "AppRepository"),
);
Expand All @@ -173,7 +173,7 @@ export const fetchRepoSecret = (
name: string,
): ThunkAction<Promise<void>, IStoreState, null, AppReposAction> => {
return async dispatch => {
const secret = await Secret.get(name, namespace);
const secret = await Secret.get("default", name, namespace);
dispatch(receiveReposSecret(secret));
};
};
Expand Down Expand Up @@ -347,7 +347,7 @@ export function fetchImagePullSecrets(
// TODO(andresmgot): Create an endpoint for returning just the list of secret names
// to avoid listing all the secrets with protected information
// /~https://github.com/kubeapps/kubeapps/issues/1686
const secrets = await Secret.list(namespace);
const secrets = await Secret.list("default", namespace);
const imgPullSecrets = secrets.items?.filter(
s => s.type === "kubernetes.io/dockerconfigjson",
);
Expand All @@ -368,7 +368,15 @@ export function createDockerRegistrySecret(
): ThunkAction<Promise<boolean>, IStoreState, null, AppReposAction> {
return async dispatch => {
try {
const secret = await Secret.createPullSecret(name, user, password, email, server, namespace);
const secret = await Secret.createPullSecret(
"default",
name,
user,
password,
email,
server,
namespace,
);
dispatch(createImagePullSecret(secret));
return true;
} catch (e) {
Expand Down
19 changes: 7 additions & 12 deletions dashboard/src/shared/Namespace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,19 @@ export default class Namespace {
}

public static async create(cluster: string, name: string) {
const { data } = await axiosWithAuth.post<IResource>(
`api/clusters/${cluster}/api/v1/namespaces/`,
{
apiVersion: "v1",
kind: "Namespace",
metadata: {
name,
},
const { data } = await axiosWithAuth.post<IResource>(url.api.k8s.namespaces(cluster), {
apiVersion: "v1",
kind: "Namespace",
metadata: {
name,
},
);
});
return data;
}

public static async get(cluster: string, name: string) {
try {
const { data } = await axiosWithAuth.get<IResource>(
`api/clusters/${cluster}/api/v1/namespaces/${name}`,
);
const { data } = await axiosWithAuth.get<IResource>(url.api.k8s.namespace(cluster, name));
return data;
} catch (err) {
switch (err.constructor) {
Expand Down
26 changes: 13 additions & 13 deletions dashboard/src/shared/Operators.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,20 @@ import {

export class Operators {
public static async isOLMInstalled(namespace: string) {
const { status } = await axiosWithAuth.get(urls.api.operators.operators(namespace));
const { status } = await axiosWithAuth.get(urls.api.k8s.operators.operators(namespace));
return status === 200;
}

public static async getOperators(namespace: string) {
const { data } = await axiosWithAuth.get<IK8sList<IPackageManifest, {}>>(
urls.api.operators.operators(namespace),
urls.api.k8s.operators.operators(namespace),
);
return data.items;
}

public static async getOperator(namespace: string, name: string) {
const { data } = await axiosWithAuth.get<IPackageManifest>(
urls.api.operators.operator(namespace, name),
urls.api.k8s.operators.operator(namespace, name),
);
return data;
}
Expand All @@ -33,14 +33,14 @@ export class Operators {
// Global operators are installed in the "operators" namespace
const reqNamespace = namespace === "_all" ? "operators" : namespace;
const { data } = await axiosWithAuth.get<IK8sList<IClusterServiceVersion, {}>>(
urls.api.operators.clusterServiceVersions(reqNamespace),
urls.api.k8s.operators.clusterServiceVersions(reqNamespace),
);
return data.items;
}

public static async getCSV(namespace: string, name: string) {
const { data } = await axiosWithAuth.get<IClusterServiceVersion>(
urls.api.operators.clusterServiceVersion(namespace, name),
urls.api.k8s.operators.clusterServiceVersion(namespace, name),
);
return data;
}
Expand All @@ -52,15 +52,15 @@ export class Operators {
body: object,
) {
const { data } = await axiosWithAuth.post<IResource>(
urls.api.operators.resources(namespace, apiVersion, resource),
urls.api.k8s.operators.resources(namespace, apiVersion, resource),
body,
);
return data;
}

public static async listResources(namespace: string, apiVersion: string, resource: string) {
const { data } = await axiosWithAuth.get<IK8sList<IResource, {}>>(
urls.api.operators.resources(namespace, apiVersion, resource),
urls.api.k8s.operators.resources(namespace, apiVersion, resource),
);
return data;
}
Expand All @@ -72,7 +72,7 @@ export class Operators {
name: string,
) {
const { data } = await axiosWithAuth.get<IResource>(
urls.api.operators.resource(namespace, apiVersion, crd, name),
urls.api.k8s.operators.resource(namespace, apiVersion, crd, name),
);
return data;
}
Expand All @@ -84,7 +84,7 @@ export class Operators {
name: string,
) {
const { data } = await axiosWithAuth.delete<any>(
urls.api.operators.resource(namespace, apiVersion, plural, name),
urls.api.k8s.operators.resource(namespace, apiVersion, plural, name),
);
return data;
}
Expand All @@ -97,7 +97,7 @@ export class Operators {
body: object,
) {
const { data } = await axiosWithAuth.put<IResource>(
urls.api.operators.resource(namespace, apiVersion, resource, name),
urls.api.k8s.operators.resource(namespace, apiVersion, resource, name),
body,
);
return data;
Expand All @@ -114,7 +114,7 @@ export class Operators {
await this.createOperatorGroupIfNotExists(namespace);
// Now create the subscription
const { data: result } = await axiosWithAuth.post<IResource>(
urls.api.operators.subscription(namespace, name),
urls.api.k8s.operators.subscription(namespace, name),
{
apiVersion: "operators.coreos.com/v1alpha1",
kind: "Subscription",
Expand Down Expand Up @@ -149,14 +149,14 @@ export class Operators {
return;
}
const { data } = await axiosWithAuth.get<IK8sList<IResource, {}>>(
urls.api.operators.operatorGroups(namespace),
urls.api.k8s.operators.operatorGroups(namespace),
);
if (data.items.length > 0) {
// An operatorgroup already exists, do nothing
return;
}
const { data: result } = await axiosWithAuth.post<IK8sList<IResource, {}>>(
urls.api.operators.operatorGroups(namespace),
urls.api.k8s.operators.operatorGroups(namespace),
{
apiVersion: "operators.coreos.com/v1",
kind: "OperatorGroup",
Expand Down
39 changes: 5 additions & 34 deletions dashboard/src/shared/Secret.test.ts
Original file line number Diff line number Diff line change
@@ -1,48 +1,17 @@
import { axiosWithAuth } from "./AxiosInstance";
import Secret from "./Secret";

it("creates a secret", async () => {
axiosWithAuth.post = jest.fn().mockReturnValue({ data: "ok" });
const secrets = {
foo: "bar",
};
const owner = {
foo: "bar",
} as any;
const name = "secret";
const namespace = "default";
expect(await Secret.create(name, secrets, owner, namespace)).toEqual("ok");
expect(axiosWithAuth.post).toHaveBeenCalledWith(
"api/clusters/default/api/v1/namespaces/default/secrets",
{
apiVersion: "v1",
data: secrets,
kind: "Secret",
metadata: { name: "secret", ownerReferences: [owner] },
type: "Opaque",
},
);
});

it("deletes a secret", async () => {
axiosWithAuth.delete = jest.fn();
await Secret.delete("foo", "bar");
expect(axiosWithAuth.delete).toHaveBeenCalledWith(
"api/clusters/default/api/v1/namespaces/bar/secrets/foo",
);
});

it("gets a secret", async () => {
axiosWithAuth.get = jest.fn().mockReturnValue({ data: "ok" });
await Secret.get("foo", "bar");
await Secret.get("default", "foo", "bar");
expect(axiosWithAuth.get).toHaveBeenCalledWith(
"api/clusters/default/api/v1/namespaces/bar/secrets/foo",
);
});

it("lists secrets", async () => {
axiosWithAuth.get = jest.fn().mockReturnValue({ data: "ok" });
await Secret.list("foo");
await Secret.list("default", "foo");
expect(axiosWithAuth.get).toHaveBeenCalledWith(
"api/clusters/default/api/v1/namespaces/foo/secrets",
);
Expand All @@ -56,7 +25,9 @@ it("creates a pull secret", async () => {
const email = "foo@bar.com";
const server = "docker.io";
const namespace = "default";
expect(await Secret.createPullSecret(name, user, password, email, server, namespace)).toBe("ok");
expect(
await Secret.createPullSecret("default", name, user, password, email, server, namespace),
).toBe("ok");
expect(axiosWithAuth.post).toHaveBeenCalledWith(
"api/clusters/default/api/v1/namespaces/default/secrets",
{
Expand Down
49 changes: 13 additions & 36 deletions dashboard/src/shared/Secret.ts
Original file line number Diff line number Diff line change
@@ -1,54 +1,35 @@
import { axiosWithAuth } from "./AxiosInstance";
import { APIBase } from "./Kube";
import { IK8sList, IOwnerReference, ISecret } from "./types";
import { IK8sList, ISecret } from "./types";
import * as url from "./url";

export default class Secret {
public static async create(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

has this function gone somewhere else?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ah, I see, this is not needed because the secrets are now being created in the backend.

name: string,
secrets: { [s: string]: string },
owner: IOwnerReference | undefined,
namespace: string,
) {
const url = Secret.getLink(namespace);
const { data } = await axiosWithAuth.post<ISecret>(url, {
apiVersion: "v1",
data: secrets,
kind: "Secret",
metadata: {
name,
ownerReferences: [owner],
},
type: "Opaque",
});
return data;
}

public static async delete(name: string, namespace: string) {
const url = this.getLink(namespace, name);
return axiosWithAuth.delete(url);
const u = url.api.k8s.secret("default", namespace, name);
return axiosWithAuth.delete(u);
}

public static async get(name: string, namespace: string) {
const url = this.getLink(namespace, name);
const { data } = await axiosWithAuth.get<ISecret>(url);
public static async get(cluster: string, name: string, namespace: string) {
const u = url.api.k8s.secret(cluster, namespace, name);
const { data } = await axiosWithAuth.get<ISecret>(u);
return data;
}

public static async list(namespace: string) {
const url = Secret.getLink(namespace);
const { data } = await axiosWithAuth.get<IK8sList<ISecret, {}>>(url);
public static async list(cluster: string, namespace: string) {
const u = url.api.k8s.secrets(cluster, namespace);
const { data } = await axiosWithAuth.get<IK8sList<ISecret, {}>>(u);
return data;
}

public static async createPullSecret(
cluster: string,
name: string,
user: string,
password: string,
email: string,
server: string,
namespace: string,
) {
const url = Secret.getLink(namespace);
const u = url.api.k8s.secrets(cluster, namespace);
const dockercfg = {
auths: {
[server]: {
Expand All @@ -59,7 +40,7 @@ export default class Secret {
},
},
};
const { data } = await axiosWithAuth.post<ISecret>(url, {
const { data } = await axiosWithAuth.post<ISecret>(u, {
apiVersion: "v1",
stringData: {
".dockerconfigjson": JSON.stringify(dockercfg),
Expand All @@ -72,8 +53,4 @@ export default class Secret {
});
return data;
}

private static getLink(namespace: string, name?: string): string {
return `${APIBase}/api/v1/namespaces/${namespace}/secrets${name ? `/${name}` : ""}`;
}
}
Loading