refactor: full-stack restructure with multi-tenancy, workspace management, and K8s diagnostics
- Add Workspace domain (entity, repository, service, handler, DTO) - Add multi-tenant K8s client with tenant binding and quota management - Add K8s diagnostics client (instance diagnostics) - Add authorization middleware (authz package) - Restructure frontend to feature-based architecture (features/) - Add User Management page in configuration - Add AccessDenied page and route guards - Refactor shared components (form inputs, layout, UI) - Update Tailwind config for new design system - Add comprehensive documentation (docs/, tasks/, plans) - Improve cluster service with better kubeconfig handling - Add tests for crypto, config, helm client, tenant binding
This commit is contained in:
@ -76,6 +76,8 @@ import type {
|
||||
PutRegistriesRegistryIdPathParameters,
|
||||
} from './generated-orval/api.schemas';
|
||||
|
||||
import { customAxiosInstance } from './axios-mutator';
|
||||
|
||||
import {
|
||||
GithubComOcdpClusterServiceInternalAdapterInputHttpDtoInstanceResponseLastOperation as GeneratedInstanceLastOperationEnum,
|
||||
GithubComOcdpClusterServiceInternalAdapterInputHttpDtoInstanceResponseStatus as GeneratedInstanceStatusEnum,
|
||||
@ -91,9 +93,46 @@ export type * from './generated-orval/api.schemas';
|
||||
// ---------- Friendly type aliases ----------
|
||||
export type AuthResponse = GeneratedAuthResponse;
|
||||
export type RegisterBody = GeneratedRegisterRequest;
|
||||
export type AdminCreateUserRequest = RegisterBody & {
|
||||
role?: string;
|
||||
workspaceId?: string;
|
||||
namespace?: string;
|
||||
defaultClusterId?: string;
|
||||
quotaCpu?: string;
|
||||
quotaMemory?: string;
|
||||
quotaGpu?: string;
|
||||
quotaGpuMemory?: string;
|
||||
isActive?: boolean;
|
||||
mustChangePassword?: boolean;
|
||||
};
|
||||
export type LoginBody = GeneratedLoginRequest;
|
||||
export type RefreshTokenBody = GeneratedRefreshTokenRequest;
|
||||
export type UserResponse = GeneratedUserResponse;
|
||||
export type UserResponse = GeneratedUserResponse & {
|
||||
role?: string;
|
||||
workspaceId?: string;
|
||||
workspaceName?: string;
|
||||
namespace?: string;
|
||||
defaultClusterId?: string;
|
||||
quotaCpu?: string;
|
||||
quotaMemory?: string;
|
||||
quotaGpu?: string;
|
||||
quotaGpuMemory?: string;
|
||||
isActive?: boolean;
|
||||
mustChangePassword?: boolean;
|
||||
};
|
||||
export type UpdateUserRequest = {
|
||||
role?: string;
|
||||
workspaceId?: string;
|
||||
namespace?: string;
|
||||
defaultClusterId?: string;
|
||||
quotaCpu?: string;
|
||||
quotaMemory?: string;
|
||||
quotaGpu?: string;
|
||||
quotaGpuMemory?: string;
|
||||
isActive?: boolean;
|
||||
mustChangePassword?: boolean;
|
||||
};
|
||||
export type ValuesYamlResponse = { valuesYaml: string };
|
||||
|
||||
export type ClusterResponse = GeneratedClusterResponse;
|
||||
export type CreateClusterRequest = GeneratedCreateClusterRequest;
|
||||
@ -108,6 +147,49 @@ export type InstanceResponse = GeneratedInstanceResponse;
|
||||
export type CreateInstanceRequest = GeneratedCreateInstanceRequest;
|
||||
export type UpdateInstanceRequest = GeneratedUpdateInstanceRequest;
|
||||
export type InstanceEntry = GeneratedInstanceEntry;
|
||||
export type InstanceDiagnosticsResponse = {
|
||||
instanceName?: string;
|
||||
namespace?: string;
|
||||
collectedAt?: string;
|
||||
pods?: Array<{
|
||||
name?: string;
|
||||
namespace?: string;
|
||||
phase?: string;
|
||||
nodeName?: string;
|
||||
podIp?: string;
|
||||
hostIp?: string;
|
||||
restartCount?: number;
|
||||
containers?: Array<{
|
||||
name?: string;
|
||||
image?: string;
|
||||
ready?: boolean;
|
||||
restartCount?: number;
|
||||
state?: string;
|
||||
reason?: string;
|
||||
message?: string;
|
||||
}>;
|
||||
conditions?: Array<{ type?: string; status?: string; reason?: string; message?: string }>;
|
||||
creationTimestamp?: string;
|
||||
}>;
|
||||
services?: Array<{
|
||||
name?: string;
|
||||
namespace?: string;
|
||||
type?: string;
|
||||
clusterIP?: string;
|
||||
ports?: Array<{ name?: string; protocol?: string; port?: number; targetPort?: string; nodePort?: number }>;
|
||||
}>;
|
||||
events?: Array<{
|
||||
type?: string;
|
||||
reason?: string;
|
||||
message?: string;
|
||||
involvedKind?: string;
|
||||
involvedName?: string;
|
||||
count?: number;
|
||||
firstTimestamp?: string;
|
||||
lastTimestamp?: string;
|
||||
}>;
|
||||
logs?: Array<{ pod?: string; container?: string; tailLines?: number; log?: string; error?: string }>;
|
||||
};
|
||||
export const INSTANCE_STATUS = GeneratedInstanceStatusEnum;
|
||||
export type InstanceStatus = NonNullable<InstanceResponse['status']>;
|
||||
export const INSTANCE_LAST_OPERATION = GeneratedInstanceLastOperationEnum;
|
||||
@ -134,6 +216,13 @@ export type NodeMetricsResponse = GeneratedNodeMetricsResponse;
|
||||
export const login = postAuthLogin;
|
||||
export const register = postAuthRegister;
|
||||
export const refreshAuth = postAuthRefresh;
|
||||
export const listUsers = () => customAxiosInstance<UserResponse[]>({ url: "/users", method: "GET" });
|
||||
export const createUser = (data: AdminCreateUserRequest) =>
|
||||
customAxiosInstance<UserResponse>({ url: "/users", method: "POST", data });
|
||||
export const updateUser = (userId: string, data: UpdateUserRequest) =>
|
||||
customAxiosInstance<UserResponse>({ url: `/users/${encodeURIComponent(userId)}`, method: "PUT", data });
|
||||
export const deleteUser = (userId: string) =>
|
||||
customAxiosInstance<void>({ url: `/users/${encodeURIComponent(userId)}`, method: "DELETE" });
|
||||
|
||||
export const listClusters = getClusters;
|
||||
export const createCluster = postClusters;
|
||||
@ -148,6 +237,15 @@ export const getInstance = getClustersClusterIdInstancesInstanceId;
|
||||
export const updateInstance = putClustersClusterIdInstancesInstanceId;
|
||||
export const deleteInstance = deleteClustersClusterIdInstancesInstanceId;
|
||||
export const listInstanceEntries = getClustersClusterIdInstancesInstanceIdEntries;
|
||||
export const getInstanceDiagnostics = (
|
||||
params: { clusterId: string; instanceId: string },
|
||||
options?: { tailLines?: number },
|
||||
) =>
|
||||
customAxiosInstance<InstanceDiagnosticsResponse>({
|
||||
url: `/clusters/${encodeURIComponent(params.clusterId)}/instances/${encodeURIComponent(params.instanceId)}/diagnostics`,
|
||||
method: "GET",
|
||||
params: options?.tailLines ? { tailLines: options.tailLines } : undefined,
|
||||
});
|
||||
|
||||
export const listRegistries = getRegistries;
|
||||
export const createRegistry = postRegistries;
|
||||
@ -156,7 +254,13 @@ export const updateRegistry = putRegistriesRegistryId;
|
||||
export const deleteRegistry = deleteRegistriesRegistryId;
|
||||
export const checkRegistryHealth = getRegistriesRegistryIdHealth;
|
||||
|
||||
export const listRepositories = getRegistriesRegistryIdRepositories;
|
||||
export const listRepositories = (
|
||||
params: GetRegistriesRegistryIdRepositoriesPathParameters,
|
||||
options?: { artifactType?: 'chart' | 'all' },
|
||||
) =>
|
||||
getRegistriesRegistryIdRepositories(params, {
|
||||
params: options?.artifactType ? { artifact_type: options.artifactType } : undefined,
|
||||
});
|
||||
type ListArtifactsRequestOptions = AxiosOptions<typeof getRegistriesRegistryIdRepositoriesRepositoryNameArtifacts>;
|
||||
|
||||
export const listArtifacts = (
|
||||
@ -173,6 +277,11 @@ export const listArtifacts = (
|
||||
|
||||
export const getArtifact = getRegistriesRegistryIdRepositoriesRepositoryNameArtifactsReference;
|
||||
export const getValuesSchema = getRegistriesRegistryIdRepositoriesRepositoryNameArtifactsReferenceValuesSchema;
|
||||
export const getValuesYaml = (params: GetValuesSchemaPathParameters) =>
|
||||
customAxiosInstance<ValuesYamlResponse>({
|
||||
url: `/registries/${encodeURIComponent(params.registryId)}/repositories/${encodeURIComponent(params.repositoryName)}/artifacts/${encodeURIComponent(params.reference)}/values-yaml`,
|
||||
method: "GET",
|
||||
});
|
||||
|
||||
export const listClusterMonitoring = getMonitoringClusters;
|
||||
export const getClusterMonitoring = getMonitoringClustersClusterId;
|
||||
|
||||
Reference in New Issue
Block a user