feat: EC2 UI polished + storage persisting

This commit is contained in:
Zakaria
2026-09-25 18:18:33 -04:00
parent 1b129e9dcf
commit 093afb9b2b
40 changed files with 2586 additions and 102 deletions
+65 -2
View File
@@ -22,6 +22,10 @@ export const apiEndpointKeys = {
update: "clouds.services.resources.update",
delete: "clouds.services.resources.delete",
invoke: "clouds.services.resources.invoke",
publish: "clouds.services.resources.notifications.publish",
createSnsSubscription: "clouds.services.resources.notifications.subscription.create",
listSnsSubscriptions: "clouds.services.resources.notifications.subscriptions.list",
deleteSnsSubscription: "clouds.services.resources.notifications.subscription.delete",
encrypt: "clouds.services.resources.encrypt",
decrypt: "clouds.services.resources.decrypt",
createApiGatewayRoute: "clouds.services.resources.apigateway.route.create",
@@ -33,7 +37,10 @@ export const apiEndpointKeys = {
deleteS3LambdaTrigger: "clouds.services.resources.storage.lambda-trigger.delete",
createEventBridgeLambdaTrigger: "clouds.services.resources.serverless.eventbridge-trigger.create",
listEventBridgeLambdaTriggers: "clouds.services.resources.serverless.eventbridge-triggers.list",
deleteEventBridgeLambdaTrigger: "clouds.services.resources.serverless.eventbridge-trigger.delete",
deleteEventBridgeLambdaTrigger: "clouds.services.resources.serverless.eventbridge-trigger.delete",
createEventBridgeRule: "clouds.services.resources.events.rule.create",
listEventBridgeRules: "clouds.services.resources.events.rules.list",
deleteEventBridgeRule: "clouds.services.resources.events.rule.delete",
createSqsLambdaEventSourceMapping: "clouds.services.resources.serverless.sqs-event-source-mapping.create",
listSqsLambdaEventSourceMappings: "clouds.services.resources.serverless.sqs-event-source-mappings.list",
deleteSqsLambdaEventSourceMapping: "clouds.services.resources.serverless.sqs-event-source-mapping.delete",
@@ -297,7 +304,7 @@ export const endpointRegistry: EndpointRegistry = new Map([
},
],
[
apiEndpointKeys.clouds.resources.invoke,
apiEndpointKeys.clouds.resources.invoke,
{
path: "/clouds/:cloud/services/:service/resources/:id/invoke",
method: "POST",
@@ -312,6 +319,38 @@ export const endpointRegistry: EndpointRegistry = new Map([
telemetry: { service: "apigateway" },
},
],
[
apiEndpointKeys.clouds.resources.publish,
{
path: "/clouds/:cloud/services/notifications/resources/:id/publish",
method: "POST",
telemetry: { service: "notifications" },
},
],
[
apiEndpointKeys.clouds.resources.createSnsSubscription,
{
path: "/clouds/:cloud/services/notifications/resources/:id/subscriptions",
method: "POST",
telemetry: { service: "notifications" },
},
],
[
apiEndpointKeys.clouds.resources.listSnsSubscriptions,
{
path: "/clouds/:cloud/services/notifications/resources/:id/subscriptions",
method: "GET",
telemetry: { service: "notifications" },
},
],
[
apiEndpointKeys.clouds.resources.deleteSnsSubscription,
{
path: "/clouds/:cloud/services/notifications/resources/:id/subscriptions/:subscriptionArn",
method: "DELETE",
telemetry: { service: "notifications" },
},
],
[
apiEndpointKeys.clouds.resources.listApiGatewayRoutes,
{
@@ -384,6 +423,30 @@ export const endpointRegistry: EndpointRegistry = new Map([
telemetry: { service: "serverless" },
},
],
[
apiEndpointKeys.clouds.resources.createEventBridgeRule,
{
path: "/clouds/:cloud/services/events/resources/:id/rules",
method: "POST",
telemetry: { service: "events" },
},
],
[
apiEndpointKeys.clouds.resources.listEventBridgeRules,
{
path: "/clouds/:cloud/services/events/resources/:id/rules",
method: "GET",
telemetry: { service: "events" },
},
],
[
apiEndpointKeys.clouds.resources.deleteEventBridgeRule,
{
path: "/clouds/:cloud/services/events/resources/:id/rules/:ruleName",
method: "DELETE",
telemetry: { service: "events" },
},
],
[
apiEndpointKeys.clouds.resources.createSqsLambdaEventSourceMapping,
{
+5 -3
View File
@@ -77,6 +77,8 @@ export type Ec2KeyPairMaterial = {
keyMaterial: string;
};
export type Ec2KeyPairType = "rsa" | "ed25519";
export type Ec2Vpc = {
vpcId: string;
cidrBlock: string;
@@ -344,10 +346,10 @@ export async function listEc2KeyPairs(signal?: AbortSignal): Promise<Ec2KeyPair[
return res.data;
}
export async function createEc2KeyPair(name: string): Promise<Ec2KeyPairMaterial> {
const res = await apiClient.call<Ec2KeyPairMaterial>(
export async function createEc2KeyPair(name: string, keyType: Ec2KeyPairType = "rsa"): Promise<Ec2KeyPairMaterial> {
const res = await apiClient.call<Ec2KeyPairMaterial, {name: string; keyType: Ec2KeyPairType}>(
apiEndpointKeys.aws.ec2.keyPairs.create,
{ body: JSON.stringify({ name }), headers: { "content-type": "application/json" } },
{ body: { name, keyType } },
);
return res.data;
}
@@ -204,6 +204,16 @@ export interface ServerlessInvokeResult {
executionDuration?: number;
}
export interface PublishNotificationInput {
message: string;
subject?: string;
messageAttributes?: Record<string, string>;
}
export interface PublishNotificationResult {
messageId: string | null;
}
export interface CreateApiGatewayLambdaRouteInput {
path: string;
method: string;
@@ -268,6 +278,19 @@ export interface S3LambdaTriggerOverview {
suffix: string | null;
}
export interface CreateSnsSubscriptionInput {
protocol: string;
endpoint: string;
}
export interface SnsSubscriptionOverview {
arn: string | null;
protocol: string;
endpoint: string;
status: "Confirmed" | "PendingConfirmation";
filterPolicy: string | null;
}
export interface CreateEventBridgeLambdaTriggerInput {
ruleName: string;
scheduleExpression: string;
@@ -283,6 +306,27 @@ export interface EventBridgeLambdaTriggerOverview {
state: string | null;
}
export interface EventBridgeRuleTarget {
id: string;
arn: string;
}
export interface CreateEventBridgeRuleInput {
name: string;
scheduleExpression?: string;
eventPattern?: string;
state?: "ENABLED" | "DISABLED";
description?: string;
targets: EventBridgeRuleTarget[];
}
export interface EventBridgeRuleOverview extends CreateEventBridgeRuleInput {
busName: string;
busId: string;
arn: string | null;
state: "ENABLED" | "DISABLED";
}
export interface CreateSqsLambdaEventSourceMappingInput {
queueArn: string;
batchSize?: number;
@@ -393,6 +437,46 @@ export async function deleteS3LambdaTrigger(
);
}
export async function createSnsSubscription(
cloud: CloudProvider,
topicArn: string,
input: CreateSnsSubscriptionInput,
signal?: AbortSignal,
): Promise<SnsSubscriptionOverview> {
const res = await apiClient.call<SnsSubscriptionOverview, CreateSnsSubscriptionInput>(
apiEndpointKeys.clouds.resources.createSnsSubscription,
requestOptions(cloud, "notifications", {signal, body: input}),
{cloud, id: topicArn},
);
return res.data;
}
export async function listSnsSubscriptions(
cloud: CloudProvider,
topicArn: string,
signal?: AbortSignal,
): Promise<SnsSubscriptionOverview[]> {
const res = await apiClient.call<SnsSubscriptionOverview[]>(
apiEndpointKeys.clouds.resources.listSnsSubscriptions,
requestOptions(cloud, "notifications", {signal}),
{cloud, id: topicArn},
);
return res.data;
}
export async function deleteSnsSubscription(
cloud: CloudProvider,
topicArn: string,
subscriptionArn: string,
signal?: AbortSignal,
): Promise<void> {
await apiClient.call<void>(
apiEndpointKeys.clouds.resources.deleteSnsSubscription,
requestOptions(cloud, "notifications", {signal}),
{cloud, id: topicArn, subscriptionArn},
);
}
export async function createEventBridgeLambdaTrigger(
cloud: CloudProvider,
functionName: string,
@@ -433,6 +517,46 @@ export async function deleteEventBridgeLambdaTrigger(
);
}
export async function createEventBridgeRule(
cloud: CloudProvider,
eventBusId: string,
input: CreateEventBridgeRuleInput,
signal?: AbortSignal,
): Promise<EventBridgeRuleOverview> {
const res = await apiClient.call<EventBridgeRuleOverview, CreateEventBridgeRuleInput>(
apiEndpointKeys.clouds.resources.createEventBridgeRule,
requestOptions(cloud, "events", {signal, body: input}),
{cloud, id: eventBusId},
);
return res.data;
}
export async function listEventBridgeRules(
cloud: CloudProvider,
eventBusId: string,
signal?: AbortSignal,
): Promise<EventBridgeRuleOverview[]> {
const res = await apiClient.call<EventBridgeRuleOverview[]>(
apiEndpointKeys.clouds.resources.listEventBridgeRules,
requestOptions(cloud, "events", {signal}),
{cloud, id: eventBusId},
);
return res.data;
}
export async function deleteEventBridgeRule(
cloud: CloudProvider,
eventBusId: string,
ruleName: string,
signal?: AbortSignal,
): Promise<void> {
await apiClient.call<void>(
apiEndpointKeys.clouds.resources.deleteEventBridgeRule,
requestOptions(cloud, "events", {signal}),
{cloud, id: eventBusId, ruleName},
);
}
export async function createSqsLambdaEventSourceMapping(
cloud: CloudProvider,
functionName: string,
@@ -525,6 +649,20 @@ export async function invokeCloudResource(
return res.data;
}
export async function publishNotification(
cloud: CloudProvider,
topicArn: string,
input: PublishNotificationInput,
signal?: AbortSignal,
): Promise<PublishNotificationResult> {
const res = await apiClient.call<PublishNotificationResult, PublishNotificationInput>(
apiEndpointKeys.clouds.resources.publish,
requestOptions(cloud, "notifications", { signal, body: input }),
{ cloud, id: topicArn },
);
return res.data;
}
export async function encryptKmsResource(
cloud: CloudProvider,
id: string,