CI/CD - CodeBuild + CodeDeploy + CodePipeline

This commit is contained in:
Zakaria
2026-10-01 09:18:04 -04:00
parent aa02cdb7f6
commit 7f0d707578
41 changed files with 1817 additions and 78 deletions
@@ -1,4 +1,5 @@
import {useState} from 'react'
import {useMutation, useQueryClient} from '@tanstack/react-query'
import { K8sEngineDetails } from "@/features/k8s/K8sEngineDetails";
import { LogsExplorerPanel } from "@/components/LogsExplorerPanel";
import { LogsQueryPanel } from "@/components/LogsQueryPanel";
@@ -6,6 +7,8 @@ import type { CloudProvider } from "@/types/cloud";
import type { CloudResource, StorageObject } from "@/types/resource";
import {formatBytes} from "@/lib/format";
import {CopyValueButton} from "@/components/CopyValueButton";
import {rebootCloudResource, startCloudResource, stopCloudResource} from "@/api/cloudProxyClient";
import {cloudQueryKeys} from "@/api/queries/cloudQueries";
interface ResourceInspectorProps {
resource?: CloudResource;
@@ -149,9 +152,9 @@ export function ResourceInspector({
)}
</section>
{isDatabase && (
<DatabaseConnectionsSection metadata={resource.metadata} engine={resource.engine} />
<DatabaseConnectionsSection metadata={resource.metadata} engine={resource.engine} status={resource.status} />
)}
{isAwsDatabase && <DatabaseLifecycleSection status={resource.status} />}
{isAwsDatabase && <DatabaseLifecycleSection resource={resource} />}
{isDatabase && !isAwsDatabase && (
<ProviderDatabaseSection cloud={resource.cloud} />
)}
@@ -283,9 +286,11 @@ function ProviderDatabaseSection({ cloud }: { cloud: string }) {
function DatabaseConnectionsSection({
metadata,
engine,
status,
}: {
metadata: Record<string, unknown>;
engine?: string | null;
status?: string | null;
}) {
const endpoint = getRecordMetadata(metadata.endpoint);
const subnetGroup = getRecordMetadata(metadata.subnetGroup);
@@ -299,6 +304,7 @@ function DatabaseConnectionsSection({
return (
<section className="inspector-section">
<p className="metric-label">Connections</p>
<DatabaseConnectionHealth status={status} hasEndpoint={Boolean(address && port !== null)} />
<div className="inspector-grid compact-grid">
<InspectorItem label="Endpoint" value={address ?? "-"} />
<InspectorItem
@@ -328,6 +334,19 @@ function DatabaseConnectionsSection({
);
}
function DatabaseConnectionHealth({status, hasEndpoint}: {status?: string | null; hasEndpoint: boolean}) {
const normalized = status?.toLowerCase()
const state = normalized === 'available' && hasEndpoint
? {label: 'Ready', detail: 'The provider reports this instance as available with a connection endpoint.'}
: normalized === 'failed'
? {label: 'Unavailable', detail: 'The provider reports the backing database as failed.'}
: !hasEndpoint
? {label: 'Endpoint unavailable', detail: 'The provider has not returned a usable database endpoint.'}
: {label: status ?? 'Unknown', detail: 'Connection readiness follows the provider-reported instance status.'}
return <p className="muted compact-text" role="status"><strong>Connection health: {state.label}.</strong> {state.detail}</p>
}
function DatabaseConnectionCommand({ engine, address, port, database, username }: { engine: string; address: string; port: number; database: string; username: string }) {
const host = address.startsWith('172.') ? 'localhost' : address
const command = engine.includes('postgres')
@@ -343,22 +362,40 @@ function DatabaseConnectionCommand({ engine, address, port, database, username }
return <div className="metadata-block"><p className="metric-label">Terminal connection</p><p className="copy-value mono">{command}<CopyValueButton value={command} label="Connection command" /></p><p className="metric-label">Client connection URI</p><p className="copy-value mono">{uri}<CopyValueButton value={uri} label="Connection URI" /></p><p className="muted compact-text">Paste the URI into a compatible database client, then replace the password placeholder. The password is never retained by the console.</p></div>
}
function DatabaseLifecycleSection({ status }: { status?: string | null }) {
function DatabaseLifecycleSection({resource}: {resource: CloudResource}) {
const queryClient = useQueryClient()
const lifecycle = useMutation({
mutationFn: async (action: "start" | "stop" | "reboot") => {
if (action === "start") return startCloudResource(resource.cloud, resource.service, resource.id)
if (action === "stop") return stopCloudResource(resource.cloud, resource.service, resource.id)
return rebootCloudResource(resource.cloud, resource.service, resource.id)
},
onSuccess: () => {
void queryClient.invalidateQueries({queryKey: cloudQueryKeys.resources(resource.cloud, resource.service)})
void queryClient.invalidateQueries({queryKey: cloudQueryKeys.resource(resource.cloud, resource.service, resource.id)})
},
})
const status = resource.status?.toLowerCase()
const isPending = lifecycle.isPending
return (
<section className="inspector-section">
<p className="metric-label">Lifecycle</p>
<div className="lifecycle-actions">
<button className="button compact" type="button" disabled>
<button className="button compact" type="button" disabled={isPending || status !== "stopped"} onClick={() => lifecycle.mutate("start")}>
Start
</button>
<button className="button compact" type="button" disabled>
<button className="button compact" type="button" disabled={isPending || status !== "available"} onClick={() => lifecycle.mutate("stop")}>
Stop
</button>
<button className="button compact" type="button" disabled={isPending || status !== "available"} onClick={() => lifecycle.mutate("reboot")}>
Reboot
</button>
</div>
<p className="muted compact-text">
Current status: {status ?? "unknown"}. Start and stop are not supported
by the local Floci RDS runtime.
Current status: {resource.status ?? "unknown"}.
</p>
{lifecycle.error && <p className="muted compact-text">{lifecycle.error instanceof Error ? lifecycle.error.message : "Unable to update DB instance lifecycle."}</p>}
</section>
);
}