mirror of
https://github.com/Azure/k8s-set-context.git
synced 2026-06-28 18:29:26 +08:00
Refactor entire project (#39)
- Use more modern TypeScript conventions - Use JavaScript Kubernetes Client - Add unit tests - Add integration tests - Add TypeScript compile verify workflow - Switch codeowners
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
import { Cluster, parseCluster } from "./cluster";
|
||||
|
||||
describe("Cluster type", () => {
|
||||
test("it has required values", () => {
|
||||
const vals = <any>Object.values(Cluster);
|
||||
expect(vals.includes("arc")).toBe(true);
|
||||
expect(vals.includes("generic")).toBe(true);
|
||||
});
|
||||
|
||||
test("it can parse valid values from a string", () => {
|
||||
expect(parseCluster("arc")).toBe(Cluster.ARC);
|
||||
expect(parseCluster("Arc")).toBe(Cluster.ARC);
|
||||
expect(parseCluster("ARC")).toBe(Cluster.ARC);
|
||||
|
||||
expect(parseCluster("generic")).toBe(Cluster.GENERIC);
|
||||
expect(parseCluster("Generic")).toBe(Cluster.GENERIC);
|
||||
expect(parseCluster("GENERIC")).toBe(Cluster.GENERIC);
|
||||
});
|
||||
|
||||
test("it will return undefined if it can't parse values from a string", () => {
|
||||
expect(parseCluster("invalid")).toBe(undefined);
|
||||
expect(parseCluster("unsupportedType")).toBe(undefined);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,16 @@
|
||||
export enum Cluster {
|
||||
ARC = "arc",
|
||||
GENERIC = "generic",
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a string to the Cluster enum
|
||||
* @param str The cluster type (case insensitive)
|
||||
* @returns The Cluster enum or undefined if it can't be parsed
|
||||
*/
|
||||
export const parseCluster = (str: string): Cluster | undefined =>
|
||||
Cluster[
|
||||
Object.keys(Cluster).filter(
|
||||
(k) => Cluster[k].toString().toLowerCase() === str.toLowerCase()
|
||||
)[0] as keyof typeof Cluster
|
||||
];
|
||||
@@ -0,0 +1,33 @@
|
||||
import { parseK8sSecret, K8sSecret } from "./k8sSecret";
|
||||
|
||||
describe("K8sSecret type", () => {
|
||||
describe("Parsing from any", () => {
|
||||
test("it returns a type guarded secret", () => {
|
||||
const secret = { data: { token: "token", "ca.crt": "cert" } };
|
||||
expect(() => parseK8sSecret(secret)).not.toThrow();
|
||||
});
|
||||
|
||||
test("it throws an error when secret not provided", () => {
|
||||
expect(() => parseK8sSecret(undefined)).toThrow();
|
||||
});
|
||||
|
||||
test("it throws an error when there is no data field", () => {
|
||||
const secret = {};
|
||||
expect(() => parseK8sSecret(secret)).toThrow();
|
||||
});
|
||||
|
||||
test("it throws an error when there is no token", () => {
|
||||
const secret = {
|
||||
data: {
|
||||
"ca.crt": "cert",
|
||||
},
|
||||
};
|
||||
expect(() => parseK8sSecret(secret)).toThrow();
|
||||
});
|
||||
|
||||
test("it throws an error when there is no ca.crt field", () => {
|
||||
const secret = { data: { token: "token" } };
|
||||
expect(() => parseK8sSecret(secret)).toThrow();
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,25 @@
|
||||
import * as util from "util";
|
||||
|
||||
export interface K8sSecret {
|
||||
data: {
|
||||
token: string;
|
||||
"ca.crt": string;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Throws an error if an object does not have all required fields to be a K8sSecret
|
||||
* @param secret
|
||||
* @returns A type guarded K8sSecret
|
||||
*/
|
||||
export function parseK8sSecret(secret: any): K8sSecret {
|
||||
if (!secret) throw Error("K8s secret yaml is invalid");
|
||||
if (!secret.data) throw k8sSecretMissingFieldError("data");
|
||||
if (!secret.data.token) throw k8sSecretMissingFieldError("token");
|
||||
if (!secret.data["ca.crt"]) throw k8sSecretMissingFieldError("ca.crt");
|
||||
|
||||
return secret as K8sSecret;
|
||||
}
|
||||
|
||||
const k8sSecretMissingFieldError = (field: string): Error =>
|
||||
Error(util.format("K8s secret yaml does not contain %s field", field));
|
||||
@@ -0,0 +1,29 @@
|
||||
import { Method, parseMethod } from "./method";
|
||||
|
||||
describe("Method type", () => {
|
||||
test("it has required values", () => {
|
||||
const vals = <any>Object.values(Method);
|
||||
expect(vals.includes("kubeconfig")).toBe(true);
|
||||
expect(vals.includes("service-account")).toBe(true);
|
||||
expect(vals.includes("service-principal")).toBe(true);
|
||||
});
|
||||
|
||||
test("it can parse valid values from a string", () => {
|
||||
expect(parseMethod("kubeconfig")).toBe(Method.KUBECONFIG);
|
||||
expect(parseMethod("Kubeconfig")).toBe(Method.KUBECONFIG);
|
||||
expect(parseMethod("KUBECONFIG")).toBe(Method.KUBECONFIG);
|
||||
|
||||
expect(parseMethod("service-account")).toBe(Method.SERVICE_ACCOUNT);
|
||||
expect(parseMethod("Service-Account")).toBe(Method.SERVICE_ACCOUNT);
|
||||
expect(parseMethod("SERVICE-ACCOUNT")).toBe(Method.SERVICE_ACCOUNT);
|
||||
|
||||
expect(parseMethod("service-principal")).toBe(Method.SERVICE_PRINCIPAL);
|
||||
expect(parseMethod("Service-Principal")).toBe(Method.SERVICE_PRINCIPAL);
|
||||
expect(parseMethod("SERVICE-PRINCIPAL")).toBe(Method.SERVICE_PRINCIPAL);
|
||||
});
|
||||
|
||||
test("it will return undefined if it can't parse values from a string", () => {
|
||||
expect(parseMethod("invalid")).toBe(undefined);
|
||||
expect(parseMethod("unsupportedType")).toBe(undefined);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,17 @@
|
||||
export enum Method {
|
||||
KUBECONFIG = "kubeconfig",
|
||||
SERVICE_ACCOUNT = "service-account",
|
||||
SERVICE_PRINCIPAL = "service-principal",
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a string to the Method enum
|
||||
* @param str The method (case insensitive)
|
||||
* @returns The Method enum or undefined if it can't be parsed
|
||||
*/
|
||||
export const parseMethod = (str: string): Method | undefined =>
|
||||
Method[
|
||||
Object.keys(Method).filter(
|
||||
(k) => Method[k].toString().toLowerCase() === str.toLowerCase()
|
||||
)[0] as keyof typeof Method
|
||||
];
|
||||
Reference in New Issue
Block a user