first commit
This commit is contained in:
+137
@@ -0,0 +1,137 @@
|
||||
export type ServerStatus = "pending" | "active" | "offline";
|
||||
export type KeySource = "uploaded" | "generated";
|
||||
|
||||
export interface Server {
|
||||
id: string;
|
||||
server_id: string;
|
||||
hostname: string;
|
||||
ip_address: string;
|
||||
os_info: string;
|
||||
status: ServerStatus;
|
||||
last_seen: string;
|
||||
created_at: string;
|
||||
}
|
||||
|
||||
export interface Key {
|
||||
id: string;
|
||||
key_id: string;
|
||||
label: string;
|
||||
public_key: string;
|
||||
fingerprint: string;
|
||||
source: KeySource;
|
||||
generated_by_server_id?: string;
|
||||
created_at: string;
|
||||
assigned_count?: number;
|
||||
}
|
||||
|
||||
export interface Assignment {
|
||||
id: string;
|
||||
key_id: string;
|
||||
server_id: string;
|
||||
assigned_at: string;
|
||||
revoked_at: string | null;
|
||||
}
|
||||
|
||||
export interface NewServerResponse {
|
||||
server_id: string;
|
||||
pre_reg_token: string;
|
||||
install_command: string;
|
||||
}
|
||||
|
||||
export interface KeyWithAssignments extends Key {
|
||||
assignments: (Assignment & { server: Server })[];
|
||||
}
|
||||
|
||||
export interface ServerWithKeys extends Server {
|
||||
keys: (Assignment & { key: Key })[];
|
||||
}
|
||||
|
||||
class ApiError extends Error {
|
||||
constructor(
|
||||
public status: number,
|
||||
message: string
|
||||
) {
|
||||
super(message);
|
||||
this.name = "ApiError";
|
||||
}
|
||||
}
|
||||
|
||||
async function request<T>(path: string, options?: RequestInit): Promise<T> {
|
||||
const res = await fetch(`/api${path}`, {
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...options?.headers,
|
||||
},
|
||||
...options,
|
||||
});
|
||||
|
||||
if (!res.ok) {
|
||||
const text = await res.text().catch(() => res.statusText);
|
||||
throw new ApiError(res.status, text || `HTTP ${res.status}`);
|
||||
}
|
||||
|
||||
if (res.status === 204) {
|
||||
return undefined as T;
|
||||
}
|
||||
|
||||
return res.json();
|
||||
}
|
||||
|
||||
export const api = {
|
||||
// Servers
|
||||
listServers(): Promise<Server[]> {
|
||||
return request<Server[]>("/servers");
|
||||
},
|
||||
|
||||
getServer(serverId: string): Promise<ServerWithKeys> {
|
||||
return request<ServerWithKeys>(`/servers/${serverId}`);
|
||||
},
|
||||
|
||||
createServer(): Promise<NewServerResponse> {
|
||||
return request<NewServerResponse>("/servers/new", { method: "POST" });
|
||||
},
|
||||
|
||||
deleteServer(serverId: string): Promise<void> {
|
||||
return request<void>(`/servers/${serverId}`, { method: "DELETE" });
|
||||
},
|
||||
|
||||
generateKeyForServer(serverId: string): Promise<{ key_id: string }> {
|
||||
return request<{ key_id: string }>(`/servers/${serverId}/generate-key`, {
|
||||
method: "POST",
|
||||
});
|
||||
},
|
||||
|
||||
// Keys
|
||||
listKeys(): Promise<Key[]> {
|
||||
return request<Key[]>("/keys");
|
||||
},
|
||||
|
||||
getKey(keyId: string): Promise<KeyWithAssignments> {
|
||||
return request<KeyWithAssignments>(`/keys/${keyId}`);
|
||||
},
|
||||
|
||||
uploadKey(label: string, public_key: string): Promise<Key> {
|
||||
return request<Key>("/keys", {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ label, public_key }),
|
||||
});
|
||||
},
|
||||
|
||||
deleteKey(keyId: string): Promise<void> {
|
||||
return request<void>(`/keys/${keyId}`, { method: "DELETE" });
|
||||
},
|
||||
|
||||
// Assignments
|
||||
assignKey(keyId: string, serverId: string): Promise<Assignment> {
|
||||
return request<Assignment>(`/keys/${keyId}/assign`, {
|
||||
method: "POST",
|
||||
body: JSON.stringify({ server_id: serverId }),
|
||||
});
|
||||
},
|
||||
|
||||
revokeKey(keyId: string, serverId: string): Promise<void> {
|
||||
return request<void>(`/keys/${keyId}/assign/${serverId}`, {
|
||||
method: "DELETE",
|
||||
});
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user