mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-10-15 17:11:30 +00:00
feat(ecs): EC2 capacity provisioning + auto-EIP service tasks + task/service detail pages (#431)
* feat(ecs): provision EC2 container-instance capacity via IMDS instance-role Adds a ProvisionCapacity gateway action that launches spinifex-ecs-node EC2 instances which register as ECS container instances, fixing RESOURCE:placement when a cluster has no capacity. Agent control-plane now SigV4-signs gateway calls with instance-role credentials read from IMDS (no static keys seeded in user-data). The gateway already verifies STS/temp creds, so the instance role carries an ecs:* policy + ec2 trust; ensureECSInstanceProfile find-or-creates the ecsInstanceRole instance profile attached at launch. Backend resolves the spinifex-ecs-node AMI by spinifex:managed-by=ecs tag, renders keyless user-data, and launches via the customer RunInstances path. Frontend adds a hand-signed JSON-1.1 ProvisionCapacity call, a provision-capacity dialog on the container-instances tab, and the ECS console section nav + system-image gating. * feat: auto-assign EIPs to awsvpc service tasks; add ECS task/service detail pages Wire AssignPublicIp=ENABLED through the service reconciler so awsvpc service tasks automatically allocate and associate an Elastic IP on the RUNNING transition, and release it on STOP. assignTaskPublicIP/releaseTaskPublicIP mirror the target-group registration hooks in recordTaskState and forceStopTask; the public IP and allocation ID are persisted on the task record and surfaced in DescribeTasks attachments as publicIPv4Address. Add AWS-parity ECS task and service detail pages showing private and public endpoints, container state, and networking configuration, reachable by clicking a task or service in the cluster tabs. * test: cover natsEIPManager allocate/associate/release over NATS
This commit is contained in:
@@ -100,7 +100,7 @@ func New(cfg config) (*Agent, error) {
|
||||
runner = rt
|
||||
}
|
||||
|
||||
cp, err := newGatewayControlPlane(cfg)
|
||||
cp, err := newGatewayControlPlane(cfg, creds)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("build gateway control-plane: %w", err)
|
||||
}
|
||||
|
||||
@@ -20,8 +20,9 @@ const (
|
||||
// config holds the static settings the agent reads at boot. Cluster identity
|
||||
// (account ID, instance ID) is discovered at runtime from IMDS, not configured;
|
||||
// only the cluster *name* the instance was launched into is static. AccessKey /
|
||||
// SecretKey are the instance's seeded IAM credentials used to SigV4-sign gateway
|
||||
// calls — the agent never holds a NATS token.
|
||||
// SecretKey are legacy seeded creds, optional now that the agent SigV4-signs
|
||||
// gateway calls with instance-role credentials from IMDS; the agent never holds
|
||||
// a NATS token.
|
||||
type config struct {
|
||||
GatewayURL string
|
||||
GatewayCA string
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"time"
|
||||
@@ -8,6 +9,7 @@ import (
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/ecs"
|
||||
|
||||
"github.com/mulgadc/spinifex/cmd/ecs-agent/credentials"
|
||||
"github.com/mulgadc/spinifex/internal/ecsgw"
|
||||
handlers_ecs "github.com/mulgadc/spinifex/spinifex/handlers/ecs"
|
||||
"github.com/mulgadc/spinifex/spinifex/handlers/ecs/bus"
|
||||
@@ -39,15 +41,28 @@ var _ controlPlane = (*gatewayControlPlane)(nil)
|
||||
// timeout to leave room for a future server-side long-poll.
|
||||
const pollTimeout = 30 * time.Second
|
||||
|
||||
// newGatewayControlPlane builds the SigV4 client from seeded creds + pinned CA.
|
||||
func newGatewayControlPlane(cfg config) (*gatewayControlPlane, error) {
|
||||
client, err := ecsgw.New(cfg.GatewayURL, cfg.GatewayCA, cfg.AccessKey, cfg.SecretKey, cfg.Region, pollTimeout)
|
||||
// newGatewayControlPlane builds the SigV4 client signing with the instance-role
|
||||
// credentials from IMDS (fetched per call so rotation is transparent) + pinned CA.
|
||||
func newGatewayControlPlane(cfg config, creds credentials.CredentialsProvider) (*gatewayControlPlane, error) {
|
||||
client, err := ecsgw.New(cfg.GatewayURL, cfg.GatewayCA, credentialsFunc(creds), cfg.Region, pollTimeout)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &gatewayControlPlane{client: client}, nil
|
||||
}
|
||||
|
||||
// credentialsFunc adapts the agent's IMDS CredentialsProvider to the ecsgw
|
||||
// per-call credentials hook.
|
||||
func credentialsFunc(p credentials.CredentialsProvider) ecsgw.CredentialsFunc {
|
||||
return func(ctx context.Context) (string, string, string, error) {
|
||||
c, err := p.Retrieve(ctx)
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
}
|
||||
return c.AccessKeyID, c.SecretAccessKey, c.SessionToken, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (g *gatewayControlPlane) Register(id identity) error {
|
||||
in := &ecs.RegisterContainerInstanceInput{
|
||||
Cluster: aws.String(id.ClusterName),
|
||||
|
||||
+32
-21
@@ -1,15 +1,15 @@
|
||||
// Package ecsgw is the on-VM SigV4 client the ecs-agent uses to reach the AWS
|
||||
// gateway over HTTPS instead of connecting to NATS directly. It signs requests
|
||||
// for service "ecs" with the instance's seeded IAM credentials, keeping the NATS
|
||||
// bus host-internal (the gateway relays agent calls onto ecs.bus.* host-side).
|
||||
// for service "ecs" with the instance's IMDS instance-role credentials (fetched
|
||||
// fresh per call so rotation is transparent), keeping the NATS bus host-internal
|
||||
// (the gateway relays agent calls onto ecs.bus.* host-side).
|
||||
package ecsgw
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"crypto/x509"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
@@ -17,7 +17,9 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/mulgadc/predastore/auth"
|
||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||
v4 "github.com/aws/aws-sdk-go/aws/signer/v4"
|
||||
|
||||
"github.com/mulgadc/spinifex/internal/tlsconfig"
|
||||
)
|
||||
|
||||
@@ -26,26 +28,31 @@ import (
|
||||
// suffix); this one mirrors the AWS JSON 1.1 convention.
|
||||
const targetPrefix = "AmazonEC2ContainerServiceV20141113."
|
||||
|
||||
// CredentialsFunc yields the current SigV4 credentials. It is called once per
|
||||
// request so a provider backed by IMDS can rotate instance-role creds (and their
|
||||
// session token) transparently. Must be safe for concurrent use.
|
||||
type CredentialsFunc func(ctx context.Context) (accessKey, secretKey, sessionToken string, err error)
|
||||
|
||||
// Client posts SigV4-signed AWS JSON 1.1 requests to the gateway for service
|
||||
// "ecs". One client is reused for register/heartbeat/state/poll.
|
||||
type Client struct {
|
||||
baseURL string
|
||||
accessKey string
|
||||
secretKey string
|
||||
creds CredentialsFunc
|
||||
region string
|
||||
httpClient *http.Client
|
||||
}
|
||||
|
||||
// New builds a client. caPath optionally pins the gateway TLS CA; empty relies on
|
||||
// the system trust store. region defaults to us-east-1 when empty (SigV4 requires
|
||||
// a non-empty region). timeout bounds a single call — callers needing a long-poll
|
||||
// pass a larger value than the default register/heartbeat timeout.
|
||||
func New(baseURL, caPath, accessKey, secretKey, region string, timeout time.Duration) (*Client, error) {
|
||||
// the system trust store. creds supplies the per-call instance-role credentials.
|
||||
// region defaults to us-east-1 when empty (SigV4 requires a non-empty region).
|
||||
// timeout bounds a single call — callers needing a long-poll pass a larger value
|
||||
// than the default register/heartbeat timeout.
|
||||
func New(baseURL, caPath string, creds CredentialsFunc, region string, timeout time.Duration) (*Client, error) {
|
||||
if baseURL == "" {
|
||||
return nil, fmt.Errorf("ecsgw: baseURL is required")
|
||||
}
|
||||
if accessKey == "" || secretKey == "" {
|
||||
return nil, fmt.Errorf("ecsgw: access key and secret key are required")
|
||||
if creds == nil {
|
||||
return nil, fmt.Errorf("ecsgw: credentials func is required")
|
||||
}
|
||||
if region == "" {
|
||||
region = "us-east-1"
|
||||
@@ -71,10 +78,9 @@ func New(baseURL, caPath, accessKey, secretKey, region string, timeout time.Dura
|
||||
}
|
||||
|
||||
return &Client{
|
||||
baseURL: strings.TrimRight(baseURL, "/"),
|
||||
accessKey: accessKey,
|
||||
secretKey: secretKey,
|
||||
region: region,
|
||||
baseURL: strings.TrimRight(baseURL, "/"),
|
||||
creds: creds,
|
||||
region: region,
|
||||
httpClient: &http.Client{
|
||||
Timeout: timeout,
|
||||
Transport: &http.Transport{TLSClientConfig: tlsCfg, MaxIdleConns: 2, IdleConnTimeout: 30 * time.Second},
|
||||
@@ -83,8 +89,9 @@ func New(baseURL, caPath, accessKey, secretKey, region string, timeout time.Dura
|
||||
}
|
||||
|
||||
// Call SigV4-signs and POSTs body under X-Amz-Target "<prefix><action>" to the
|
||||
// gateway root, returning the 2xx response body. Errors carry the gateway status
|
||||
// and body. No retry; callers wrap as needed.
|
||||
// gateway root, returning the 2xx response body. Credentials are fetched per call
|
||||
// and the v4 signer emits X-Amz-Security-Token for instance-role (temporary)
|
||||
// creds, so the gateway's ASIA path verifies them. No retry; callers wrap.
|
||||
func (c *Client) Call(action string, body []byte) ([]byte, error) {
|
||||
req, err := http.NewRequest(http.MethodPost, c.baseURL+"/", bytes.NewReader(body))
|
||||
if err != nil {
|
||||
@@ -93,8 +100,12 @@ func (c *Client) Call(action string, body []byte) ([]byte, error) {
|
||||
req.Header.Set("Content-Type", "application/x-amz-json-1.1")
|
||||
req.Header.Set("X-Amz-Target", targetPrefix+action)
|
||||
|
||||
sum := sha256.Sum256(body)
|
||||
if err := auth.SignReq(req, c.accessKey, c.secretKey, hex.EncodeToString(sum[:]), "ecs", c.region); err != nil {
|
||||
akid, secret, token, err := c.creds(req.Context())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("retrieve credentials: %w", err)
|
||||
}
|
||||
signer := v4.NewSigner(credentials.NewStaticCredentials(akid, secret, token))
|
||||
if _, err := signer.Sign(req, bytes.NewReader(body), "ecs", c.region, time.Now()); err != nil {
|
||||
return nil, fmt.Errorf("sign request: %w", err)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package ecsgw
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
@@ -9,9 +10,15 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// testCreds returns a fixed temporary credential set (with a session token, as
|
||||
// IMDS instance-role creds carry).
|
||||
func testCreds(context.Context) (string, string, string, error) {
|
||||
return "ASIATEST", "secret", "session-token-xyz", nil
|
||||
}
|
||||
|
||||
func newTestClient(t *testing.T, srv *httptest.Server) *Client {
|
||||
t.Helper()
|
||||
c, err := New(srv.URL, "", "AKIDTEST", "secret", "ap-southeast-2", time.Second)
|
||||
c, err := New(srv.URL, "", testCreds, "ap-southeast-2", time.Second)
|
||||
if err != nil {
|
||||
t.Fatalf("New: %v", err)
|
||||
}
|
||||
@@ -22,10 +29,11 @@ func newTestClient(t *testing.T, srv *httptest.Server) *Client {
|
||||
// Call signs for service "ecs", sets the X-Amz-Target action, and returns the
|
||||
// 2xx body.
|
||||
func TestClient_CallSignsAndTargets(t *testing.T) {
|
||||
var gotTarget, gotAuth, gotBody string
|
||||
var gotTarget, gotAuth, gotBody, gotToken string
|
||||
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
gotTarget = r.Header.Get("X-Amz-Target")
|
||||
gotAuth = r.Header.Get("Authorization")
|
||||
gotToken = r.Header.Get("X-Amz-Security-Token")
|
||||
b, _ := io.ReadAll(r.Body)
|
||||
gotBody = string(b)
|
||||
_, _ = w.Write([]byte(`{"ok":true}`))
|
||||
@@ -49,6 +57,9 @@ func TestClient_CallSignsAndTargets(t *testing.T) {
|
||||
if !strings.Contains(gotAuth, "AWS4-HMAC-SHA256") || !strings.Contains(gotAuth, "/ecs/aws4_request") {
|
||||
t.Errorf("auth header not SigV4 for ecs: %q", gotAuth)
|
||||
}
|
||||
if gotToken != "session-token-xyz" {
|
||||
t.Errorf("X-Amz-Security-Token = %q, want the IMDS session token", gotToken)
|
||||
}
|
||||
}
|
||||
|
||||
// A non-2xx gateway response surfaces as an error carrying status + body.
|
||||
@@ -67,10 +78,10 @@ func TestClient_CallErrorStatus(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestNew_Validation(t *testing.T) {
|
||||
if _, err := New("", "", "a", "b", "r", 0); err == nil {
|
||||
if _, err := New("", "", testCreds, "r", 0); err == nil {
|
||||
t.Error("want error for empty baseURL")
|
||||
}
|
||||
if _, err := New("https://gw:9999", "", "", "b", "r", 0); err == nil {
|
||||
t.Error("want error for empty access key")
|
||||
if _, err := New("https://gw:9999", "", nil, "r", 0); err == nil {
|
||||
t.Error("want error for nil credentials func")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -979,6 +979,7 @@ func (d *Daemon) subscribeAll() error {
|
||||
natsSub{"ecs.ListServices", d.handleECSListServices, "spinifex-workers"},
|
||||
natsSub{"ecs.SubmitTaskStateChange", d.handleECSSubmitTaskStateChange, "spinifex-workers"},
|
||||
natsSub{"ecs.PollAssignments", d.handleECSPollAssignments, "spinifex-workers"},
|
||||
natsSub{"ecs.ProvisionCapacity", d.handleECSProvisionCapacity, "spinifex-workers"},
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1416,7 +1417,7 @@ func (d *Daemon) startCluster() error {
|
||||
// scheduler goroutine that owns the Layer-2 bus subscriptions and heartbeat
|
||||
// reaper. The scheduler is disabled (handlers still serve) when JetStream is
|
||||
// unavailable.
|
||||
d.ecsService = handlers_ecs.NewService(d.natsConn, d.config.Region, d.clusterConfig.AWS.InternalSuffix)
|
||||
d.ecsService = handlers_ecs.NewService(d.natsConn, d.config.Region, d.clusterConfig.AWS.InternalSuffix).WithDeps(d.buildECSServiceDeps())
|
||||
if js, jsErr := d.natsConn.JetStream(); jsErr != nil {
|
||||
slog.Warn("ECS scheduler disabled: JetStream unavailable", "err", jsErr)
|
||||
} else if _, lbErr := handlers_ecs.InitLeaderBucket(js); lbErr != nil {
|
||||
|
||||
@@ -111,3 +111,9 @@ func (d *Daemon) handleECSListTasks(msg *nats.Msg) {
|
||||
func (d *Daemon) handleECSPollAssignments(msg *nats.Msg) {
|
||||
handleNATSRequest(msg, d.ecsService.PollAssignments)
|
||||
}
|
||||
|
||||
// --- Capacity ---
|
||||
|
||||
func (d *Daemon) handleECSProvisionCapacity(msg *nats.Msg) {
|
||||
handleNATSRequest(msg, d.ecsService.ProvisionCapacity)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
package daemon
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
handlers_ecs "github.com/mulgadc/spinifex/spinifex/handlers/ecs"
|
||||
handlers_iam "github.com/mulgadc/spinifex/spinifex/handlers/iam"
|
||||
)
|
||||
|
||||
// buildECSServiceDeps assembles the ECS service Deps for ProvisionCapacity: the
|
||||
// gateway endpoint/CA seeded into container-instance user-data, the image
|
||||
// resolver, the customer RunInstances path, and (when the master key loads) a
|
||||
// KV-backed IAM service for the ecsInstanceRole instance profile.
|
||||
func (d *Daemon) buildECSServiceDeps() handlers_ecs.Deps {
|
||||
gatewayCA := ""
|
||||
if d.config.NATS.CACert != "" {
|
||||
if caBytes, readErr := os.ReadFile(d.config.NATS.CACert); readErr == nil {
|
||||
gatewayCA = string(caBytes)
|
||||
} else {
|
||||
slog.Warn("ECS: read gateway CACert failed; container instances will not verify the gateway over TLS",
|
||||
"path", d.config.NATS.CACert, "err", readErr)
|
||||
}
|
||||
}
|
||||
|
||||
deps := handlers_ecs.Deps{
|
||||
GatewayBaseURL: d.resolveGatewayBaseURL(),
|
||||
GatewayCACert: gatewayCA,
|
||||
Images: d.imageService,
|
||||
RunInstances: d.RunWorkerInstance,
|
||||
}
|
||||
|
||||
// A KV-backed IAM service (sharing the gateway's buckets over NATS) lets ECS
|
||||
// find-or-create the ecsInstanceRole instance profile container instances
|
||||
// expose over IMDS. Only wired when the master key is present; without it
|
||||
// capacity provisioning is disabled.
|
||||
masterKey, err := handlers_iam.LoadMasterKey(filepath.Join(filepath.Dir(d.configPath), "master.key"))
|
||||
if err != nil || masterKey == nil {
|
||||
slog.Warn("ECS: LoadMasterKey failed; capacity provisioning disabled until the master key is provisioned",
|
||||
"err", err)
|
||||
return deps
|
||||
}
|
||||
|
||||
clusterSize := 1
|
||||
if d.clusterConfig != nil {
|
||||
clusterSize = len(d.clusterConfig.Nodes)
|
||||
}
|
||||
if iamSvc, iamErr := handlers_iam.NewIAMServiceImpl(d.natsConn, masterKey, clusterSize); iamErr != nil {
|
||||
slog.Warn("ECS: IAM service init failed; capacity provisioning disabled", "err", iamErr)
|
||||
} else {
|
||||
deps.IAM = iamSvc
|
||||
}
|
||||
|
||||
return deps
|
||||
}
|
||||
@@ -94,6 +94,16 @@ func RegisterContainerInstance(nc *nats.Conn, accountID string, body []byte) (an
|
||||
return handlers_ecs.NewNATSECSService(nc).RegisterContainerInstance(input, accountID)
|
||||
}
|
||||
|
||||
// ProvisionCapacity launches container-instance EC2 capacity into a cluster.
|
||||
// Input/output are the custom handlers_ecs types, not aws-sdk-go ecs shapes.
|
||||
func ProvisionCapacity(nc *nats.Conn, accountID string, body []byte) (any, error) {
|
||||
input := new(handlers_ecs.ProvisionCapacityInput)
|
||||
if err := unmarshalIfBody(body, input); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return handlers_ecs.NewNATSECSService(nc).ProvisionCapacity(input, accountID)
|
||||
}
|
||||
|
||||
func DeregisterContainerInstance(nc *nats.Conn, accountID string, body []byte) (any, error) {
|
||||
input := new(ecs.DeregisterContainerInstanceInput)
|
||||
if err := unmarshalIfBody(body, input); err != nil {
|
||||
|
||||
@@ -80,6 +80,7 @@ var Actions = map[string]Handler{
|
||||
// Container instance.
|
||||
"RegisterContainerInstance": RegisterContainerInstance,
|
||||
"DeregisterContainerInstance": DeregisterContainerInstance,
|
||||
"ProvisionCapacity": ProvisionCapacity,
|
||||
"DescribeContainerInstances": DescribeContainerInstances,
|
||||
"ListContainerInstances": ListContainerInstances,
|
||||
"UpdateContainerInstancesState": UpdateContainerInstancesState,
|
||||
|
||||
@@ -25,8 +25,8 @@ var wiredActions = map[string]bool{
|
||||
"RegisterTaskDefinition": true, "DeregisterTaskDefinition": true,
|
||||
"DescribeTaskDefinition": true, "ListTaskDefinitions": true,
|
||||
"RegisterContainerInstance": true, "DeregisterContainerInstance": true,
|
||||
"UpdateContainerInstancesState": true,
|
||||
"DescribeContainerInstances": true, "ListContainerInstances": true,
|
||||
"UpdateContainerInstancesState": true, "ProvisionCapacity": true,
|
||||
"DescribeContainerInstances": true, "ListContainerInstances": true,
|
||||
"RunTask": true, "StartTask": true, "StopTask": true, "DescribeTasks": true, "ListTasks": true,
|
||||
"CreateService": true, "UpdateService": true, "DeleteService": true,
|
||||
"DescribeServices": true, "ListServices": true,
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
package handlers_ecs
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/mulgadc/spinifex/spinifex/awserrors"
|
||||
"github.com/mulgadc/spinifex/spinifex/tags"
|
||||
)
|
||||
|
||||
const (
|
||||
// defaultCapacityInstanceType is the EC2 type used when the caller omits one.
|
||||
defaultCapacityInstanceType = "t3.small"
|
||||
|
||||
// maxCapacityCount caps the instances a single ProvisionCapacity launches.
|
||||
maxCapacityCount = 10
|
||||
|
||||
// ecsClusterTagKey associates a container instance with its cluster while
|
||||
// keeping the instance customer-owned (no system ManagedBy tag).
|
||||
ecsClusterTagKey = "spinifex:ecs-cluster"
|
||||
)
|
||||
|
||||
// ErrECSNodeAMINotFound is returned when no spinifex-ecs-node AMI resolves for
|
||||
// the account. Callers translate it to the AWS shape at the service boundary.
|
||||
var ErrECSNodeAMINotFound = errors.New("ecs: spinifex-ecs-node AMI not found")
|
||||
|
||||
// ProvisionCapacityInput requests N container instances into a cluster.
|
||||
type ProvisionCapacityInput struct {
|
||||
Cluster string
|
||||
InstanceType string
|
||||
Count int
|
||||
SubnetID string
|
||||
SecurityGroupID string
|
||||
KeyName string
|
||||
}
|
||||
|
||||
// ProvisionCapacityOutput returns the launched instance IDs.
|
||||
type ProvisionCapacityOutput struct {
|
||||
InstanceIDs []string
|
||||
}
|
||||
|
||||
// ProvisionCapacity launches container instances into a cluster: it ensures the
|
||||
// ECS instance role/profile, resolves the spinifex-ecs-node AMI, renders
|
||||
// keyless user-data (IMDS instance-role creds), and launches via the customer
|
||||
// RunInstances path with the profile attached and a cluster-association tag.
|
||||
func (s *Service) ProvisionCapacity(input *ProvisionCapacityInput, accountID string) (*ProvisionCapacityOutput, error) {
|
||||
if input == nil {
|
||||
return nil, errors.New(awserrors.ErrorInvalidParameterValue)
|
||||
}
|
||||
if input.Cluster == "" || input.SubnetID == "" || input.SecurityGroupID == "" {
|
||||
return nil, errors.New(awserrors.ErrorInvalidParameterValue)
|
||||
}
|
||||
instanceType := input.InstanceType
|
||||
if instanceType == "" {
|
||||
instanceType = defaultCapacityInstanceType
|
||||
}
|
||||
count := input.Count
|
||||
if count <= 0 {
|
||||
count = 1
|
||||
}
|
||||
if count > maxCapacityCount {
|
||||
count = maxCapacityCount
|
||||
}
|
||||
|
||||
if s.deps.IAM == nil {
|
||||
return nil, errors.New("ecs: capacity provisioning requires the IAM service (master key not provisioned)")
|
||||
}
|
||||
if s.deps.Images == nil {
|
||||
return nil, errors.New("ecs: capacity provisioning requires an image resolver")
|
||||
}
|
||||
if s.deps.RunInstances == nil {
|
||||
return nil, errors.New("ecs: capacity provisioning requires a RunInstances launcher")
|
||||
}
|
||||
|
||||
profileARN, err := s.ensureECSInstanceProfile(accountID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ensure ECS instance profile: %w", err)
|
||||
}
|
||||
|
||||
amiID, err := lookupECSNodeAMI(s.deps.Images, accountID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cluster := clusterShortName(input.Cluster)
|
||||
userData := buildContainerInstanceUserData(containerInstanceUserDataInput{
|
||||
GatewayURL: s.deps.GatewayBaseURL,
|
||||
GatewayCACert: s.deps.GatewayCACert,
|
||||
Region: s.region,
|
||||
ClusterName: cluster,
|
||||
})
|
||||
|
||||
runInput := &ec2.RunInstancesInput{
|
||||
ImageId: aws.String(amiID),
|
||||
InstanceType: aws.String(instanceType),
|
||||
MinCount: aws.Int64(int64(count)),
|
||||
MaxCount: aws.Int64(int64(count)),
|
||||
SubnetId: aws.String(input.SubnetID),
|
||||
SecurityGroupIds: aws.StringSlice([]string{input.SecurityGroupID}),
|
||||
UserData: aws.String(userData),
|
||||
IamInstanceProfile: &ec2.IamInstanceProfileSpecification{Arn: aws.String(profileARN)},
|
||||
TagSpecifications: []*ec2.TagSpecification{{
|
||||
ResourceType: aws.String("instance"),
|
||||
Tags: []*ec2.Tag{
|
||||
{Key: aws.String("Name"), Value: aws.String("ecs-node-" + cluster)},
|
||||
{Key: aws.String(ecsClusterTagKey), Value: aws.String(cluster)},
|
||||
},
|
||||
}},
|
||||
}
|
||||
if input.KeyName != "" {
|
||||
runInput.KeyName = aws.String(input.KeyName)
|
||||
}
|
||||
|
||||
res, err := s.deps.RunInstances(runInput, accountID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
out := &ProvisionCapacityOutput{}
|
||||
for _, inst := range res.Instances {
|
||||
if id := aws.StringValue(inst.InstanceId); id != "" {
|
||||
out.InstanceIDs = append(out.InstanceIDs, id)
|
||||
}
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// lookupECSNodeAMI resolves the spinifex-ecs-node AMI by the
|
||||
// spinifex:managed-by=ecs tag rather than a brittle exact name. The newest
|
||||
// matching image (by CreationDate) wins.
|
||||
func lookupECSNodeAMI(amiSvc ecsImageResolver, accountID string) (string, error) {
|
||||
out, err := amiSvc.DescribeImages(&ec2.DescribeImagesInput{
|
||||
Filters: []*ec2.Filter{
|
||||
{Name: aws.String("tag:" + tags.ManagedByKey), Values: aws.StringSlice([]string{tags.ManagedByECS})},
|
||||
},
|
||||
}, accountID)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("describe ecs AMI (tag:%s=%s): %w", tags.ManagedByKey, tags.ManagedByECS, err)
|
||||
}
|
||||
|
||||
var (
|
||||
newestID string
|
||||
newestCreated string
|
||||
matches int
|
||||
)
|
||||
for _, img := range out.Images {
|
||||
if img == nil || img.ImageId == nil || *img.ImageId == "" {
|
||||
continue
|
||||
}
|
||||
matches++
|
||||
// CreationDate is a fixed-width RFC3339 timestamp, so lexicographic
|
||||
// comparison orders it correctly without parsing.
|
||||
if created := aws.StringValue(img.CreationDate); newestID == "" || created > newestCreated {
|
||||
newestID, newestCreated = *img.ImageId, created
|
||||
}
|
||||
}
|
||||
if newestID == "" {
|
||||
return "", fmt.Errorf("%w (tag:%s=%s, account %s)", ErrECSNodeAMINotFound, tags.ManagedByKey, tags.ManagedByECS, accountID)
|
||||
}
|
||||
if matches > 1 {
|
||||
slog.Warn("ecs: multiple AMIs match managed-by=ecs; using newest",
|
||||
"count", matches, "imageId", newestID, "created", newestCreated)
|
||||
}
|
||||
return newestID, nil
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
package handlers_ecs
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/aws/aws-sdk-go/service/iam"
|
||||
"github.com/mulgadc/spinifex/spinifex/awserrors"
|
||||
"github.com/mulgadc/spinifex/spinifex/tags"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// stubImages returns a single spinifex-ecs-node AMI; nil images yields none.
|
||||
type stubImages struct {
|
||||
images []*ec2.Image
|
||||
}
|
||||
|
||||
func (s *stubImages) DescribeImages(_ *ec2.DescribeImagesInput, _ string) (*ec2.DescribeImagesOutput, error) {
|
||||
return &ec2.DescribeImagesOutput{Images: s.images}, nil
|
||||
}
|
||||
|
||||
// stubIAM converges to find-or-create: Get* report NoSuchEntity, Create* succeed.
|
||||
type stubIAM struct{}
|
||||
|
||||
var (
|
||||
_ ecsIAM = stubIAM{}
|
||||
_ ecsImageResolver = (*stubImages)(nil)
|
||||
)
|
||||
|
||||
func (stubIAM) GetRole(_ string, _ *iam.GetRoleInput) (*iam.GetRoleOutput, error) {
|
||||
return nil, errors.New(awserrors.ErrorIAMNoSuchEntity)
|
||||
}
|
||||
|
||||
func (stubIAM) CreateRole(_ string, _ *iam.CreateRoleInput) (*iam.CreateRoleOutput, error) {
|
||||
return &iam.CreateRoleOutput{Role: &iam.Role{RoleName: aws.String(ecsInstanceRoleName)}}, nil
|
||||
}
|
||||
|
||||
func (stubIAM) CreatePolicy(accountID string, _ *iam.CreatePolicyInput) (*iam.CreatePolicyOutput, error) {
|
||||
arn := "arn:aws:iam::" + accountID + ":policy/" + ecsInstanceRolePolicyName
|
||||
return &iam.CreatePolicyOutput{Policy: &iam.Policy{Arn: aws.String(arn)}}, nil
|
||||
}
|
||||
|
||||
func (stubIAM) AttachRolePolicy(_ string, _ *iam.AttachRolePolicyInput) (*iam.AttachRolePolicyOutput, error) {
|
||||
return &iam.AttachRolePolicyOutput{}, nil
|
||||
}
|
||||
|
||||
func (stubIAM) GetInstanceProfile(_ string, _ *iam.GetInstanceProfileInput) (*iam.GetInstanceProfileOutput, error) {
|
||||
return nil, errors.New(awserrors.ErrorIAMNoSuchEntity)
|
||||
}
|
||||
|
||||
func (stubIAM) CreateInstanceProfile(accountID string, _ *iam.CreateInstanceProfileInput) (*iam.CreateInstanceProfileOutput, error) {
|
||||
arn := "arn:aws:iam::" + accountID + ":instance-profile/" + ecsInstanceRoleName
|
||||
return &iam.CreateInstanceProfileOutput{InstanceProfile: &iam.InstanceProfile{Arn: aws.String(arn)}}, nil
|
||||
}
|
||||
|
||||
func (stubIAM) AddRoleToInstanceProfile(_ string, _ *iam.AddRoleToInstanceProfileInput) (*iam.AddRoleToInstanceProfileOutput, error) {
|
||||
return &iam.AddRoleToInstanceProfileOutput{}, nil
|
||||
}
|
||||
|
||||
func ecsNodeImage() []*ec2.Image {
|
||||
return []*ec2.Image{{
|
||||
ImageId: aws.String("ami-ecs"),
|
||||
CreationDate: aws.String("2026-01-01T00:00:00.000Z"),
|
||||
Tags: []*ec2.Tag{
|
||||
{Key: aws.String(tags.ManagedByKey), Value: aws.String(tags.ManagedByECS)},
|
||||
},
|
||||
}}
|
||||
}
|
||||
|
||||
func TestProvisionCapacity_BuildsRunInstancesInput(t *testing.T) {
|
||||
var captured *ec2.RunInstancesInput
|
||||
svc := NewService(nil, testRegion, "internal").WithDeps(Deps{
|
||||
GatewayBaseURL: "https://10.0.0.1:9999",
|
||||
GatewayCACert: "-----BEGIN CERTIFICATE-----\nx\n-----END CERTIFICATE-----",
|
||||
IAM: stubIAM{},
|
||||
Images: &stubImages{images: ecsNodeImage()},
|
||||
RunInstances: func(in *ec2.RunInstancesInput, _ string) (*ec2.Reservation, error) {
|
||||
captured = in
|
||||
return &ec2.Reservation{Instances: []*ec2.Instance{{InstanceId: aws.String("i-123")}}}, nil
|
||||
},
|
||||
})
|
||||
|
||||
out, err := svc.ProvisionCapacity(&ProvisionCapacityInput{
|
||||
Cluster: "web",
|
||||
InstanceType: "t3.medium",
|
||||
Count: 2,
|
||||
SubnetID: "subnet-1",
|
||||
SecurityGroupID: "sg-1",
|
||||
KeyName: "kp-1",
|
||||
}, testAccountID)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, []string{"i-123"}, out.InstanceIDs)
|
||||
|
||||
require.NotNil(t, captured)
|
||||
assert.Equal(t, "ami-ecs", aws.StringValue(captured.ImageId))
|
||||
assert.Equal(t, "t3.medium", aws.StringValue(captured.InstanceType))
|
||||
assert.Equal(t, int64(2), aws.Int64Value(captured.MinCount))
|
||||
assert.Equal(t, int64(2), aws.Int64Value(captured.MaxCount))
|
||||
assert.Equal(t, "subnet-1", aws.StringValue(captured.SubnetId))
|
||||
assert.Equal(t, []string{"sg-1"}, aws.StringValueSlice(captured.SecurityGroupIds))
|
||||
assert.Equal(t, "kp-1", aws.StringValue(captured.KeyName))
|
||||
|
||||
require.NotNil(t, captured.IamInstanceProfile)
|
||||
assert.NotEmpty(t, aws.StringValue(captured.IamInstanceProfile.Arn))
|
||||
|
||||
require.NotNil(t, captured.UserData)
|
||||
assert.Contains(t, aws.StringValue(captured.UserData), "ECS_CLUSTER=web")
|
||||
assert.NotContains(t, aws.StringValue(captured.UserData), "ECS_ACCESS_KEY")
|
||||
}
|
||||
|
||||
func TestProvisionCapacity_DefaultsAndCount(t *testing.T) {
|
||||
var captured *ec2.RunInstancesInput
|
||||
svc := NewService(nil, testRegion, "internal").WithDeps(Deps{
|
||||
IAM: stubIAM{},
|
||||
Images: &stubImages{images: ecsNodeImage()},
|
||||
RunInstances: func(in *ec2.RunInstancesInput, _ string) (*ec2.Reservation, error) {
|
||||
captured = in
|
||||
return &ec2.Reservation{Instances: []*ec2.Instance{{InstanceId: aws.String("i-1")}}}, nil
|
||||
},
|
||||
})
|
||||
|
||||
_, err := svc.ProvisionCapacity(&ProvisionCapacityInput{
|
||||
Cluster: "web",
|
||||
SubnetID: "subnet-1",
|
||||
SecurityGroupID: "sg-1",
|
||||
}, testAccountID)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, captured)
|
||||
assert.Equal(t, defaultCapacityInstanceType, aws.StringValue(captured.InstanceType))
|
||||
assert.Equal(t, int64(1), aws.Int64Value(captured.MinCount))
|
||||
assert.Nil(t, captured.KeyName)
|
||||
}
|
||||
|
||||
func TestProvisionCapacity_MissingRequired(t *testing.T) {
|
||||
svc := NewService(nil, testRegion, "internal").WithDeps(Deps{
|
||||
IAM: stubIAM{}, Images: &stubImages{images: ecsNodeImage()},
|
||||
RunInstances: func(*ec2.RunInstancesInput, string) (*ec2.Reservation, error) { return nil, nil },
|
||||
})
|
||||
_, err := svc.ProvisionCapacity(&ProvisionCapacityInput{Cluster: "web"}, testAccountID)
|
||||
require.Error(t, err)
|
||||
assert.Equal(t, awserrors.ErrorInvalidParameterValue, err.Error())
|
||||
}
|
||||
|
||||
func TestProvisionCapacity_AMINotFound(t *testing.T) {
|
||||
svc := NewService(nil, testRegion, "internal").WithDeps(Deps{
|
||||
IAM: stubIAM{},
|
||||
Images: &stubImages{images: nil},
|
||||
RunInstances: func(*ec2.RunInstancesInput, string) (*ec2.Reservation, error) {
|
||||
t.Fatal("RunInstances must not be called when no AMI resolves")
|
||||
return nil, nil
|
||||
},
|
||||
})
|
||||
_, err := svc.ProvisionCapacity(&ProvisionCapacityInput{
|
||||
Cluster: "web", SubnetID: "subnet-1", SecurityGroupID: "sg-1",
|
||||
}, testAccountID)
|
||||
require.Error(t, err)
|
||||
assert.ErrorIs(t, err, ErrECSNodeAMINotFound)
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
package handlers_ecs
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// stubEIPs records auto-EIP calls so the RUNNING/STOPPED hooks can be asserted
|
||||
// without a live ec2 EIP daemon.
|
||||
type stubEIPs struct {
|
||||
allocated []string // eniIDs associated
|
||||
released []string // allocation IDs released
|
||||
publicIP string
|
||||
allocID string
|
||||
allocErr error
|
||||
releaseErr error
|
||||
}
|
||||
|
||||
func (e *stubEIPs) AllocateAndAssociate(_, eniID string) (string, string, error) {
|
||||
if e.allocErr != nil {
|
||||
return "", "", e.allocErr
|
||||
}
|
||||
e.allocated = append(e.allocated, eniID)
|
||||
return e.publicIP, e.allocID, nil
|
||||
}
|
||||
|
||||
func (e *stubEIPs) Release(_, allocationID string) error {
|
||||
e.released = append(e.released, allocationID)
|
||||
return e.releaseErr
|
||||
}
|
||||
|
||||
func TestAssignTaskPublicIP_EnabledAssociatesAndPersists(t *testing.T) {
|
||||
svc, _, kv := serviceTestRig(t)
|
||||
eips := &stubEIPs{publicIP: "192.0.2.50", allocID: "eipalloc-1"}
|
||||
svc.eips = eips
|
||||
|
||||
require.NoError(t, putJSON(kv, ServiceKey("web", "web"), &ServiceRecord{
|
||||
Name: "web", Cluster: "web", AssignPublicIP: "ENABLED",
|
||||
}))
|
||||
task := &TaskRecord{
|
||||
TaskID: "t-1", Cluster: "web", Group: serviceTaskGroup("web"),
|
||||
ENIID: "eni-1", ENIPrivateIP: "172.31.0.8",
|
||||
}
|
||||
require.NoError(t, putJSON(kv, TaskKey("web", "t-1"), task))
|
||||
|
||||
svc.assignTaskPublicIP(kv, testAccountID, task)
|
||||
|
||||
assert.Equal(t, []string{"eni-1"}, eips.allocated)
|
||||
assert.Equal(t, "192.0.2.50", task.ENIPublicIP)
|
||||
assert.Equal(t, "eipalloc-1", task.ENIEIPAllocationID)
|
||||
|
||||
var persisted TaskRecord
|
||||
found, err := getJSON(kv, TaskKey("web", "t-1"), &persisted)
|
||||
require.NoError(t, err)
|
||||
require.True(t, found)
|
||||
assert.Equal(t, "192.0.2.50", persisted.ENIPublicIP)
|
||||
}
|
||||
|
||||
func TestAssignTaskPublicIP_DisabledNoOp(t *testing.T) {
|
||||
svc, _, kv := serviceTestRig(t)
|
||||
eips := &stubEIPs{publicIP: "192.0.2.50", allocID: "eipalloc-1"}
|
||||
svc.eips = eips
|
||||
|
||||
require.NoError(t, putJSON(kv, ServiceKey("web", "web"), &ServiceRecord{
|
||||
Name: "web", Cluster: "web", // AssignPublicIP unset
|
||||
}))
|
||||
task := &TaskRecord{
|
||||
TaskID: "t-2", Cluster: "web", Group: serviceTaskGroup("web"), ENIID: "eni-2",
|
||||
}
|
||||
|
||||
svc.assignTaskPublicIP(kv, testAccountID, task)
|
||||
|
||||
assert.Empty(t, eips.allocated)
|
||||
assert.Empty(t, task.ENIPublicIP)
|
||||
}
|
||||
|
||||
func TestReleaseTaskPublicIP_ReleasesAndClears(t *testing.T) {
|
||||
svc, _, _ := serviceTestRig(t)
|
||||
eips := &stubEIPs{}
|
||||
svc.eips = eips
|
||||
|
||||
task := &TaskRecord{TaskID: "t-3", Cluster: "web", ENIPublicIP: "192.0.2.50", ENIEIPAllocationID: "eipalloc-9"}
|
||||
svc.releaseTaskPublicIP(testAccountID, task)
|
||||
|
||||
assert.Equal(t, []string{"eipalloc-9"}, eips.released)
|
||||
assert.Empty(t, task.ENIPublicIP)
|
||||
assert.Empty(t, task.ENIEIPAllocationID)
|
||||
}
|
||||
|
||||
func TestReleaseTaskPublicIP_NoAllocationNoOp(t *testing.T) {
|
||||
svc, _, _ := serviceTestRig(t)
|
||||
eips := &stubEIPs{}
|
||||
svc.eips = eips
|
||||
|
||||
task := &TaskRecord{TaskID: "t-4", Cluster: "web"}
|
||||
svc.releaseTaskPublicIP(testAccountID, task)
|
||||
|
||||
assert.Empty(t, eips.released)
|
||||
}
|
||||
@@ -0,0 +1,147 @@
|
||||
package handlers_ecs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/iam"
|
||||
"github.com/mulgadc/spinifex/spinifex/awserrors"
|
||||
)
|
||||
|
||||
const (
|
||||
// ecsInstanceRoleName is the role + instance-profile name AWS uses for ECS
|
||||
// container instances. The agent draws its creds from this role over IMDS.
|
||||
ecsInstanceRoleName = "ecsInstanceRole"
|
||||
|
||||
// ecsInstanceRolePolicyName is the customer-managed policy granting ecs:* so
|
||||
// the gateway's assumed-role ECS authz (checkPolicy) admits the agent.
|
||||
ecsInstanceRolePolicyName = "ecsInstanceRolePolicy"
|
||||
|
||||
// ecsAssumeRolePolicy is the EC2 trust the STS AssumeRoleForInstance path
|
||||
// whitelists; it must match exactly for IMDS role-cred vending to admit it.
|
||||
ecsAssumeRolePolicy = `{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"ec2.amazonaws.com"},"Action":"sts:AssumeRole"}]}`
|
||||
|
||||
// ecsInstanceRolePolicyDoc grants the container-instance agent the ECS
|
||||
// control-plane actions the gateway enforces for assumed-role principals.
|
||||
ecsInstanceRolePolicyDoc = `{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":"ecs:*","Resource":"*"}]}`
|
||||
)
|
||||
|
||||
// ensureECSInstanceProfile find-or-creates the ecsInstanceRole, its ecs:* policy
|
||||
// attachment, and the matching instance profile, returning the profile ARN.
|
||||
// Every step is idempotent so concurrent ProvisionCapacity calls converge.
|
||||
func (s *Service) ensureECSInstanceProfile(accountID string) (string, error) {
|
||||
if err := s.ensureECSRole(accountID); err != nil {
|
||||
return "", err
|
||||
}
|
||||
if err := s.ensureECSRolePolicy(accountID); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return s.ensureECSInstanceProfileBinding(accountID)
|
||||
}
|
||||
|
||||
// ensureECSRole find-or-creates ecsInstanceRole with the EC2 trust policy,
|
||||
// converging on a racing creator via re-GetRole.
|
||||
func (s *Service) ensureECSRole(accountID string) error {
|
||||
_, err := s.deps.IAM.GetRole(accountID, &iam.GetRoleInput{RoleName: aws.String(ecsInstanceRoleName)})
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
if err.Error() != awserrors.ErrorIAMNoSuchEntity {
|
||||
return fmt.Errorf("get role %q: %w", ecsInstanceRoleName, err)
|
||||
}
|
||||
|
||||
_, err = s.deps.IAM.CreateRole(accountID, &iam.CreateRoleInput{
|
||||
RoleName: aws.String(ecsInstanceRoleName),
|
||||
AssumeRolePolicyDocument: aws.String(ecsAssumeRolePolicy),
|
||||
})
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
if err.Error() != awserrors.ErrorIAMEntityAlreadyExists {
|
||||
return fmt.Errorf("create role %q: %w", ecsInstanceRoleName, err)
|
||||
}
|
||||
// A racing call created it first; re-read to converge.
|
||||
if _, gerr := s.deps.IAM.GetRole(accountID, &iam.GetRoleInput{RoleName: aws.String(ecsInstanceRoleName)}); gerr != nil {
|
||||
return fmt.Errorf("re-get role %q: %w", ecsInstanceRoleName, gerr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ensureECSRolePolicy creates the ecs:* policy (resolving an existing one on a
|
||||
// race) and attaches it to the role; an already-attached policy is success.
|
||||
func (s *Service) ensureECSRolePolicy(accountID string) error {
|
||||
policyARN := fmt.Sprintf("arn:aws:iam::%s:policy/%s", accountID, ecsInstanceRolePolicyName)
|
||||
|
||||
out, err := s.deps.IAM.CreatePolicy(accountID, &iam.CreatePolicyInput{
|
||||
PolicyName: aws.String(ecsInstanceRolePolicyName),
|
||||
PolicyDocument: aws.String(ecsInstanceRolePolicyDoc),
|
||||
})
|
||||
switch {
|
||||
case err == nil:
|
||||
if out != nil && out.Policy != nil {
|
||||
policyARN = aws.StringValue(out.Policy.Arn)
|
||||
}
|
||||
case err.Error() == awserrors.ErrorIAMEntityAlreadyExists:
|
||||
// Policy already exists; the account ARN form is deterministic.
|
||||
default:
|
||||
return fmt.Errorf("create policy %q: %w", ecsInstanceRolePolicyName, err)
|
||||
}
|
||||
|
||||
_, err = s.deps.IAM.AttachRolePolicy(accountID, &iam.AttachRolePolicyInput{
|
||||
RoleName: aws.String(ecsInstanceRoleName),
|
||||
PolicyArn: aws.String(policyARN),
|
||||
})
|
||||
if err != nil && err.Error() != awserrors.ErrorIAMEntityAlreadyExists {
|
||||
return fmt.Errorf("attach policy %q to role %q: %w", policyARN, ecsInstanceRoleName, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ensureECSInstanceProfileBinding guarantees the ecsInstanceRole instance
|
||||
// profile exists and carries the role, returning its ARN. Mirrors the EKS
|
||||
// node-profile ensure path; idempotent under concurrent launches.
|
||||
func (s *Service) ensureECSInstanceProfileBinding(accountID string) (string, error) {
|
||||
out, err := s.deps.IAM.GetInstanceProfile(accountID, &iam.GetInstanceProfileInput{
|
||||
InstanceProfileName: aws.String(ecsInstanceRoleName),
|
||||
})
|
||||
if err == nil {
|
||||
return s.attachECSRoleToProfile(accountID, aws.StringValue(out.InstanceProfile.Arn), len(out.InstanceProfile.Roles) > 0)
|
||||
}
|
||||
if err.Error() != awserrors.ErrorIAMNoSuchEntity {
|
||||
return "", fmt.Errorf("get instance profile %q: %w", ecsInstanceRoleName, err)
|
||||
}
|
||||
|
||||
created, err := s.deps.IAM.CreateInstanceProfile(accountID, &iam.CreateInstanceProfileInput{
|
||||
InstanceProfileName: aws.String(ecsInstanceRoleName),
|
||||
})
|
||||
if err != nil {
|
||||
if err.Error() != awserrors.ErrorIAMEntityAlreadyExists {
|
||||
return "", fmt.Errorf("create instance profile %q: %w", ecsInstanceRoleName, err)
|
||||
}
|
||||
got, gerr := s.deps.IAM.GetInstanceProfile(accountID, &iam.GetInstanceProfileInput{
|
||||
InstanceProfileName: aws.String(ecsInstanceRoleName),
|
||||
})
|
||||
if gerr != nil {
|
||||
return "", fmt.Errorf("re-get instance profile %q: %w", ecsInstanceRoleName, gerr)
|
||||
}
|
||||
return s.attachECSRoleToProfile(accountID, aws.StringValue(got.InstanceProfile.Arn), len(got.InstanceProfile.Roles) > 0)
|
||||
}
|
||||
return s.attachECSRoleToProfile(accountID, aws.StringValue(created.InstanceProfile.Arn), false)
|
||||
}
|
||||
|
||||
// attachECSRoleToProfile adds the role to the profile unless already attached,
|
||||
// returning the profile ARN. A LimitExceeded error means a racing launch
|
||||
// attached it first and is treated as success.
|
||||
func (s *Service) attachECSRoleToProfile(accountID, profileARN string, alreadyAttached bool) (string, error) {
|
||||
if alreadyAttached {
|
||||
return profileARN, nil
|
||||
}
|
||||
_, err := s.deps.IAM.AddRoleToInstanceProfile(accountID, &iam.AddRoleToInstanceProfileInput{
|
||||
InstanceProfileName: aws.String(ecsInstanceRoleName),
|
||||
RoleName: aws.String(ecsInstanceRoleName),
|
||||
})
|
||||
if err != nil && err.Error() != awserrors.ErrorIAMLimitExceeded {
|
||||
return "", fmt.Errorf("add role to instance profile %q: %w", ecsInstanceRoleName, err)
|
||||
}
|
||||
return profileARN, nil
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package handlers_ecs
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log/slog"
|
||||
"slices"
|
||||
"time"
|
||||
|
||||
@@ -225,17 +226,23 @@ func (s *Service) recordTaskState(msg *bus.TaskState) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Register the task's ELBv2 targets on the transition into RUNNING (Q8).
|
||||
// Register ELBv2 targets and assign a public IP on the transition into
|
||||
// RUNNING (Q8). assignTaskPublicIP persists the EIP onto the task itself.
|
||||
if msg.LastStatus == TaskStatusRunning && prev != TaskStatusRunning {
|
||||
s.registerServiceTargets(kv, msg.AccountID, &task)
|
||||
s.assignTaskPublicIP(kv, msg.AccountID, &task)
|
||||
}
|
||||
|
||||
// Deregister targets, release capacity + reclaim the task ENI once, on the
|
||||
// transition into STOPPED.
|
||||
// Deregister targets, release the public IP, release capacity + reclaim the
|
||||
// task ENI once, on the transition into STOPPED.
|
||||
if msg.LastStatus == TaskStatusStopped && prev != TaskStatusStopped {
|
||||
s.deregisterServiceTargets(kv, msg.AccountID, &task)
|
||||
s.releaseTaskPublicIP(msg.AccountID, &task)
|
||||
s.reclaimAssignInbox(kv, msg.ClusterName, task.ContainerInstanceID, msg.TaskID)
|
||||
s.reclaimTaskENI(msg.AccountID, &task)
|
||||
if perr := putJSON(kv, TaskKey(msg.ClusterName, msg.TaskID), &task); perr != nil {
|
||||
slog.Error("ECS task STOPPED: persist after EIP release failed", "task", msg.TaskID, "err", perr)
|
||||
}
|
||||
return s.releaseReservation(kv, msg.ClusterName, task.ContainerInstanceID, msg.TaskID, task.ReservedCPU, task.ReservedMemoryMiB)
|
||||
}
|
||||
return nil
|
||||
|
||||
@@ -186,14 +186,19 @@ type TaskRecord struct {
|
||||
NetworkMode string `json:"networkMode,omitempty"`
|
||||
// ENI* hold the per-task elastic network interface for awsvpc mode, allocated
|
||||
// by the scheduler at placement and reclaimed at STOPPED. Empty otherwise.
|
||||
ENIID string `json:"eniId,omitempty"`
|
||||
ENIAttachmentID string `json:"eniAttachmentId,omitempty"`
|
||||
ENIPrivateIP string `json:"eniPrivateIp,omitempty"`
|
||||
ENIMacAddress string `json:"eniMac,omitempty"`
|
||||
ENISubnetID string `json:"eniSubnetId,omitempty"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
StartedAt time.Time `json:"startedAt,omitzero"`
|
||||
StoppedAt time.Time `json:"stoppedAt,omitzero"`
|
||||
ENIID string `json:"eniId,omitempty"`
|
||||
ENIAttachmentID string `json:"eniAttachmentId,omitempty"`
|
||||
ENIPrivateIP string `json:"eniPrivateIp,omitempty"`
|
||||
ENIMacAddress string `json:"eniMac,omitempty"`
|
||||
ENISubnetID string `json:"eniSubnetId,omitempty"`
|
||||
// ENIPublicIP / ENIEIPAllocationID hold the auto-assigned Elastic IP for an
|
||||
// awsvpc task whose service has AssignPublicIp=ENABLED. Set on the RUNNING
|
||||
// transition and released on STOPPED. Empty otherwise.
|
||||
ENIPublicIP string `json:"eniPublicIp,omitempty"`
|
||||
ENIEIPAllocationID string `json:"eniEipAllocationId,omitempty"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
StartedAt time.Time `json:"startedAt,omitzero"`
|
||||
StoppedAt time.Time `json:"stoppedAt,omitzero"`
|
||||
}
|
||||
|
||||
// LoadBalancerTarget is one ELBv2 target-group attachment on a service. On task
|
||||
|
||||
@@ -10,7 +10,9 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/aws/aws-sdk-go/service/ecs"
|
||||
"github.com/aws/aws-sdk-go/service/iam"
|
||||
"github.com/mulgadc/spinifex/spinifex/awserrors"
|
||||
"github.com/nats-io/nats.go"
|
||||
)
|
||||
@@ -51,6 +53,40 @@ type ECSService interface {
|
||||
|
||||
// PollAssignments drains an instance's task-assignment inbox (agent → gateway).
|
||||
PollAssignments(input *PollAssignmentsInput, accountID string) (*PollAssignmentsOutput, error)
|
||||
|
||||
// ProvisionCapacity launches container-instance EC2 capacity into a cluster.
|
||||
ProvisionCapacity(input *ProvisionCapacityInput, accountID string) (*ProvisionCapacityOutput, error)
|
||||
}
|
||||
|
||||
// ecsImageResolver is the narrow AMI surface for resolving the spinifex-ecs-node
|
||||
// AMI by tag.
|
||||
type ecsImageResolver interface {
|
||||
DescribeImages(input *ec2.DescribeImagesInput, accountID string) (*ec2.DescribeImagesOutput, error)
|
||||
}
|
||||
|
||||
// ecsIAM is the narrow IAM surface ProvisionCapacity needs to find-or-create the
|
||||
// ecsInstanceRole, its ecs:* policy, and the instance profile workers expose
|
||||
// over IMDS. Method signatures match the daemon IAM service implementation.
|
||||
type ecsIAM interface {
|
||||
GetRole(accountID string, input *iam.GetRoleInput) (*iam.GetRoleOutput, error)
|
||||
CreateRole(accountID string, input *iam.CreateRoleInput) (*iam.CreateRoleOutput, error)
|
||||
CreatePolicy(accountID string, input *iam.CreatePolicyInput) (*iam.CreatePolicyOutput, error)
|
||||
AttachRolePolicy(accountID string, input *iam.AttachRolePolicyInput) (*iam.AttachRolePolicyOutput, error)
|
||||
GetInstanceProfile(accountID string, input *iam.GetInstanceProfileInput) (*iam.GetInstanceProfileOutput, error)
|
||||
CreateInstanceProfile(accountID string, input *iam.CreateInstanceProfileInput) (*iam.CreateInstanceProfileOutput, error)
|
||||
AddRoleToInstanceProfile(accountID string, input *iam.AddRoleToInstanceProfileInput) (*iam.AddRoleToInstanceProfileOutput, error)
|
||||
}
|
||||
|
||||
// Deps are the collaborators ProvisionCapacity needs: the gateway endpoint/CA to
|
||||
// seed the agent's config, the IAM service to back the instance profile, the
|
||||
// image resolver for the AMI, and the customer RunInstances path. Nil deps
|
||||
// disable capacity provisioning; the wired actions stay usable.
|
||||
type Deps struct {
|
||||
GatewayBaseURL string
|
||||
GatewayCACert string
|
||||
IAM ecsIAM
|
||||
Images ecsImageResolver
|
||||
RunInstances func(*ec2.RunInstancesInput, string) (*ec2.Reservation, error)
|
||||
}
|
||||
|
||||
// Service is the daemon-side ECS control-plane implementation, backed by the
|
||||
@@ -66,15 +102,29 @@ type Service struct {
|
||||
// targets registers/deregisters service tasks with ELBv2 target groups.
|
||||
// Defaults to the NATS-backed registrar; tests substitute a stub.
|
||||
targets targetRegistrar
|
||||
// eips allocates/associates and releases an Elastic IP for awsvpc tasks whose
|
||||
// service has AssignPublicIp=ENABLED. Defaults to the NATS-backed manager;
|
||||
// tests substitute a stub.
|
||||
eips eipManager
|
||||
// deps carries the collaborators ProvisionCapacity needs (gateway endpoint/CA,
|
||||
// IAM service, image resolver, customer RunInstances path). Wired via WithDeps.
|
||||
deps Deps
|
||||
}
|
||||
|
||||
var _ ECSService = (*Service)(nil)
|
||||
|
||||
// WithDeps attaches the ProvisionCapacity collaborators and returns the Service
|
||||
// for chaining. Non-breaking: NewService stays usable without deps.
|
||||
func (s *Service) WithDeps(d Deps) *Service {
|
||||
s.deps = d
|
||||
return s
|
||||
}
|
||||
|
||||
// NewService constructs a Service bound to a NATS connection. region scopes the
|
||||
// ARNs it mints; suffix is the AWS-parity internal DNS suffix (reserved for ECR
|
||||
// endpoint composition).
|
||||
func NewService(nc *nats.Conn, region, suffix string) *Service {
|
||||
return &Service{nc: nc, region: region, suffix: suffix, eni: newNATSENIController(nc), targets: newNATSTargetRegistrar(nc)}
|
||||
return &Service{nc: nc, region: region, suffix: suffix, eni: newNATSENIController(nc), targets: newNATSTargetRegistrar(nc), eips: newNATSEIPManager(nc)}
|
||||
}
|
||||
|
||||
// defaultCluster is the implicit cluster name when a request omits one.
|
||||
@@ -257,9 +307,28 @@ func (r *ClusterRecord) toAWS() *ecs.Cluster {
|
||||
ClusterName: aws.String(r.Name),
|
||||
ClusterArn: aws.String(r.ARN),
|
||||
Status: aws.String(r.Status),
|
||||
Tags: tagsToAWS(r.Tags),
|
||||
}
|
||||
}
|
||||
|
||||
// tagsToAWS converts a stored tag map into the AWS list form with a stable
|
||||
// key order so Describe output is deterministic.
|
||||
func tagsToAWS(tags map[string]string) []*ecs.Tag {
|
||||
if len(tags) == 0 {
|
||||
return nil
|
||||
}
|
||||
keys := make([]string, 0, len(tags))
|
||||
for k := range tags {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
out := make([]*ecs.Tag, 0, len(keys))
|
||||
for _, k := range keys {
|
||||
out = append(out, &ecs.Tag{Key: aws.String(k), Value: aws.String(tags[k])})
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
// --- Task definition ---
|
||||
|
||||
// RegisterTaskDefinition stores a new revision of a family, bumping latest-rev.
|
||||
|
||||
@@ -132,3 +132,9 @@ func (s *NATSECSService) ListServices(input *ecs.ListServicesInput, accountID st
|
||||
func (s *NATSECSService) PollAssignments(input *PollAssignmentsInput, accountID string) (*PollAssignmentsOutput, error) {
|
||||
return utils.NATSRequest[PollAssignmentsOutput](s.natsConn, "ecs.PollAssignments", input, defaultTimeout, accountID)
|
||||
}
|
||||
|
||||
// --- Capacity ---
|
||||
|
||||
func (s *NATSECSService) ProvisionCapacity(input *ProvisionCapacityInput, accountID string) (*ProvisionCapacityOutput, error) {
|
||||
return utils.NATSRequest[ProvisionCapacityOutput](s.natsConn, "ecs.ProvisionCapacity", input, defaultTimeout, accountID)
|
||||
}
|
||||
|
||||
@@ -52,6 +52,32 @@ func TestService_DescribeClusters_DefaultAndMissing(t *testing.T) {
|
||||
assert.Empty(t, miss.Clusters)
|
||||
}
|
||||
|
||||
func TestService_DescribeClusters_ReturnsTags(t *testing.T) {
|
||||
svc, _ := newTestService(t)
|
||||
_, err := svc.CreateCluster(&ecs.CreateClusterInput{
|
||||
ClusterName: aws.String("web"),
|
||||
Tags: []*ecs.Tag{
|
||||
{Key: aws.String("team"), Value: aws.String("infra")},
|
||||
{Key: aws.String("env"), Value: aws.String("prod")},
|
||||
},
|
||||
}, testAccountID)
|
||||
require.NoError(t, err)
|
||||
|
||||
out, err := svc.DescribeClusters(&ecs.DescribeClustersInput{
|
||||
Clusters: []*string{aws.String("web")},
|
||||
}, testAccountID)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, out.Clusters, 1)
|
||||
|
||||
tags := out.Clusters[0].Tags
|
||||
require.Len(t, tags, 2)
|
||||
// Stable key order: sorted ascending.
|
||||
assert.Equal(t, "env", aws.StringValue(tags[0].Key))
|
||||
assert.Equal(t, "prod", aws.StringValue(tags[0].Value))
|
||||
assert.Equal(t, "team", aws.StringValue(tags[1].Key))
|
||||
assert.Equal(t, "infra", aws.StringValue(tags[1].Value))
|
||||
}
|
||||
|
||||
func registerTaskDef(t *testing.T, svc *Service, family string, cpu, mem int) *ecs.RegisterTaskDefinitionOutput {
|
||||
t.Helper()
|
||||
out, err := svc.RegisterTaskDefinition(&ecs.RegisterTaskDefinitionInput{
|
||||
|
||||
@@ -7,10 +7,12 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/aws/aws-sdk-go/service/ecs"
|
||||
"github.com/aws/aws-sdk-go/service/elbv2"
|
||||
"github.com/google/uuid"
|
||||
"github.com/mulgadc/spinifex/spinifex/awserrors"
|
||||
handlers_ec2_eip "github.com/mulgadc/spinifex/spinifex/handlers/ec2/eip"
|
||||
handlers_elbv2 "github.com/mulgadc/spinifex/spinifex/handlers/elbv2"
|
||||
"github.com/nats-io/nats.go"
|
||||
)
|
||||
@@ -51,6 +53,68 @@ func (r *natsTargetRegistrar) Deregister(accountID, tgARN, ip string, port int)
|
||||
return err
|
||||
}
|
||||
|
||||
// eipManager gives an awsvpc task a public endpoint by allocating an Elastic IP
|
||||
// and associating it with the task ENI, and releases it on STOPPED. The
|
||||
// scheduler is the single writer, mirroring targetRegistrar.
|
||||
type eipManager interface {
|
||||
AllocateAndAssociate(accountID, eniID string) (publicIP, allocationID string, err error)
|
||||
Release(accountID, allocationID string) error
|
||||
}
|
||||
|
||||
// natsEIPManager drives the existing ec2 EIP NATS handlers; no new surface is
|
||||
// added for ECS.
|
||||
type natsEIPManager struct {
|
||||
nc *nats.Conn
|
||||
}
|
||||
|
||||
var _ eipManager = (*natsEIPManager)(nil)
|
||||
|
||||
func newNATSEIPManager(nc *nats.Conn) *natsEIPManager {
|
||||
return &natsEIPManager{nc: nc}
|
||||
}
|
||||
|
||||
func (m *natsEIPManager) AllocateAndAssociate(accountID, eniID string) (string, string, error) {
|
||||
svc := handlers_ec2_eip.NewNATSEIPService(m.nc)
|
||||
alloc, err := svc.AllocateAddress(&ec2.AllocateAddressInput{Domain: aws.String("vpc")}, accountID)
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
publicIP, allocationID := aws.StringValue(alloc.PublicIp), aws.StringValue(alloc.AllocationId)
|
||||
if _, err = svc.AssociateAddress(&ec2.AssociateAddressInput{
|
||||
AllocationId: alloc.AllocationId,
|
||||
NetworkInterfaceId: aws.String(eniID),
|
||||
}, accountID); err != nil {
|
||||
// Release the orphaned allocation so a failed associate leaks nothing.
|
||||
if _, rerr := svc.ReleaseAddress(&ec2.ReleaseAddressInput{AllocationId: alloc.AllocationId}, accountID); rerr != nil {
|
||||
slog.Error("ECS auto-EIP: release after failed associate", "alloc", allocationID, "err", rerr)
|
||||
}
|
||||
return "", "", err
|
||||
}
|
||||
return publicIP, allocationID, nil
|
||||
}
|
||||
|
||||
func (m *natsEIPManager) Release(accountID, allocationID string) error {
|
||||
svc := handlers_ec2_eip.NewNATSEIPService(m.nc)
|
||||
// Disassociate first (VPC EIPs cannot be released while associated); the
|
||||
// association ID is resolved from the allocation.
|
||||
desc, err := svc.DescribeAddresses(&ec2.DescribeAddressesInput{
|
||||
AllocationIds: []*string{aws.String(allocationID)},
|
||||
}, accountID)
|
||||
if err == nil {
|
||||
for _, addr := range desc.Addresses {
|
||||
if addr.AssociationId != nil && *addr.AssociationId != "" {
|
||||
if _, derr := svc.DisassociateAddress(&ec2.DisassociateAddressInput{
|
||||
AssociationId: addr.AssociationId,
|
||||
}, accountID); derr != nil {
|
||||
slog.Error("ECS auto-EIP: disassociate failed", "alloc", allocationID, "err", derr)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_, err = svc.ReleaseAddress(&ec2.ReleaseAddressInput{AllocationId: aws.String(allocationID)}, accountID)
|
||||
return err
|
||||
}
|
||||
|
||||
// --- Service API ---
|
||||
|
||||
// CreateService persists a REPLICA service and reconciles up to desiredCount.
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
package handlers_ecs
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
"github.com/aws/aws-sdk-go/service/ec2"
|
||||
"github.com/mulgadc/spinifex/spinifex/testutil"
|
||||
"github.com/mulgadc/spinifex/spinifex/utils"
|
||||
"github.com/nats-io/nats.go"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// fakeEIPBackend answers the ec2 EIP NATS subjects with canned responses so the
|
||||
// real natsEIPManager (the ec2-EIP NATS client) can be driven end to end.
|
||||
type fakeEIPBackend struct {
|
||||
mu sync.Mutex
|
||||
associateFails bool
|
||||
associatedENI string
|
||||
disassociated string
|
||||
releasedAlloc string
|
||||
}
|
||||
|
||||
const (
|
||||
fakeAllocID = "eipalloc-test1"
|
||||
fakePublicIP = "203.0.113.7"
|
||||
fakeAssocID = "eipassoc-test1"
|
||||
)
|
||||
|
||||
func (b *fakeEIPBackend) register(t *testing.T, nc *nats.Conn) {
|
||||
t.Helper()
|
||||
reply := func(msg *nats.Msg, out any) { data, _ := json.Marshal(out); _ = msg.Respond(data) }
|
||||
handlers := map[string]func(*nats.Msg){
|
||||
"ec2.AllocateAddress": func(msg *nats.Msg) {
|
||||
reply(msg, &ec2.AllocateAddressOutput{
|
||||
AllocationId: aws.String(fakeAllocID), PublicIp: aws.String(fakePublicIP), Domain: aws.String("vpc"),
|
||||
})
|
||||
},
|
||||
"ec2.AssociateAddress": func(msg *nats.Msg) {
|
||||
var in ec2.AssociateAddressInput
|
||||
_ = json.Unmarshal(msg.Data, &in)
|
||||
if b.associateFails {
|
||||
_ = msg.Respond(utils.GenerateErrorPayload("InvalidParameterValue"))
|
||||
return
|
||||
}
|
||||
b.mu.Lock()
|
||||
b.associatedENI = aws.StringValue(in.NetworkInterfaceId)
|
||||
b.mu.Unlock()
|
||||
reply(msg, &ec2.AssociateAddressOutput{AssociationId: aws.String(fakeAssocID)})
|
||||
},
|
||||
"ec2.DescribeAddresses": func(msg *nats.Msg) {
|
||||
reply(msg, &ec2.DescribeAddressesOutput{Addresses: []*ec2.Address{
|
||||
{AllocationId: aws.String(fakeAllocID), AssociationId: aws.String(fakeAssocID)},
|
||||
}})
|
||||
},
|
||||
"ec2.DisassociateAddress": func(msg *nats.Msg) {
|
||||
var in ec2.DisassociateAddressInput
|
||||
_ = json.Unmarshal(msg.Data, &in)
|
||||
b.mu.Lock()
|
||||
b.disassociated = aws.StringValue(in.AssociationId)
|
||||
b.mu.Unlock()
|
||||
reply(msg, &ec2.DisassociateAddressOutput{})
|
||||
},
|
||||
"ec2.ReleaseAddress": func(msg *nats.Msg) {
|
||||
var in ec2.ReleaseAddressInput
|
||||
_ = json.Unmarshal(msg.Data, &in)
|
||||
b.mu.Lock()
|
||||
b.releasedAlloc = aws.StringValue(in.AllocationId)
|
||||
b.mu.Unlock()
|
||||
reply(msg, &ec2.ReleaseAddressOutput{})
|
||||
},
|
||||
}
|
||||
for subj, h := range handlers {
|
||||
sub, err := nc.Subscribe(subj, h)
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() { _ = sub.Unsubscribe() })
|
||||
}
|
||||
}
|
||||
|
||||
func TestNATSEIPManager_AllocateAndAssociate(t *testing.T) {
|
||||
_, nc := testutil.StartTestNATS(t)
|
||||
backend := &fakeEIPBackend{}
|
||||
backend.register(t, nc)
|
||||
|
||||
pub, alloc, err := newNATSEIPManager(nc).AllocateAndAssociate(testAccountID, "eni-target")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, fakePublicIP, pub)
|
||||
assert.Equal(t, fakeAllocID, alloc)
|
||||
backend.mu.Lock()
|
||||
defer backend.mu.Unlock()
|
||||
assert.Equal(t, "eni-target", backend.associatedENI)
|
||||
}
|
||||
|
||||
// A failed AssociateAddress must release the orphaned allocation so nothing leaks.
|
||||
func TestNATSEIPManager_AssociateFailureReleasesAllocation(t *testing.T) {
|
||||
_, nc := testutil.StartTestNATS(t)
|
||||
backend := &fakeEIPBackend{associateFails: true}
|
||||
backend.register(t, nc)
|
||||
|
||||
_, _, err := newNATSEIPManager(nc).AllocateAndAssociate(testAccountID, "eni-target")
|
||||
require.Error(t, err)
|
||||
backend.mu.Lock()
|
||||
defer backend.mu.Unlock()
|
||||
assert.Equal(t, fakeAllocID, backend.releasedAlloc, "orphaned allocation should be released")
|
||||
}
|
||||
|
||||
func TestNATSEIPManager_ReleaseDisassociatesThenReleases(t *testing.T) {
|
||||
_, nc := testutil.StartTestNATS(t)
|
||||
backend := &fakeEIPBackend{}
|
||||
backend.register(t, nc)
|
||||
|
||||
require.NoError(t, newNATSEIPManager(nc).Release(testAccountID, fakeAllocID))
|
||||
backend.mu.Lock()
|
||||
defer backend.mu.Unlock()
|
||||
assert.Equal(t, fakeAssocID, backend.disassociated)
|
||||
assert.Equal(t, fakeAllocID, backend.releasedAlloc)
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"log/slog"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/aws/aws-sdk-go/aws"
|
||||
@@ -150,6 +151,9 @@ func (s *Service) forceStopTask(kv nats.KeyValue, accountID string, task *TaskRe
|
||||
task.DesiredStatus = TaskStatusStopped
|
||||
task.StoppedReason = reason
|
||||
task.StoppedAt = now
|
||||
// Release the auto-assigned EIP before persisting so the cleared public IP
|
||||
// lands in this single write.
|
||||
s.releaseTaskPublicIP(accountID, task)
|
||||
if perr := putJSON(kv, TaskKey(task.Cluster, task.TaskID), task); perr != nil {
|
||||
slog.Error("ECS forceStopTask: persist failed", "task", task.TaskID, "err", perr)
|
||||
return
|
||||
@@ -209,3 +213,47 @@ func (s *Service) applyServiceTargets(kv nats.KeyValue, accountID string, task *
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// assignTaskPublicIP allocates + associates an Elastic IP to a service task's
|
||||
// ENI when the owning service has AssignPublicIp=ENABLED, then persists the
|
||||
// public IP onto the task. No-op for non-service or non-awsvpc tasks, or when an
|
||||
// EIP is already assigned. Best-effort: a failure logs and leaves the task with
|
||||
// only its private endpoint.
|
||||
func (s *Service) assignTaskPublicIP(kv nats.KeyValue, accountID string, task *TaskRecord) {
|
||||
if s.eips == nil || task.ENIID == "" || task.ENIPublicIP != "" {
|
||||
return
|
||||
}
|
||||
name := serviceNameFromGroup(task.Group)
|
||||
if name == "" {
|
||||
return
|
||||
}
|
||||
var svc ServiceRecord
|
||||
found, err := getJSON(kv, ServiceKey(task.Cluster, name), &svc)
|
||||
if err != nil || !found || !strings.EqualFold(svc.AssignPublicIP, "ENABLED") {
|
||||
return
|
||||
}
|
||||
publicIP, allocID, err := s.eips.AllocateAndAssociate(accountID, task.ENIID)
|
||||
if err != nil {
|
||||
slog.Error("ECS auto-EIP assign failed", "task", task.TaskID, "eni", task.ENIID, "err", err)
|
||||
return
|
||||
}
|
||||
task.ENIPublicIP = publicIP
|
||||
task.ENIEIPAllocationID = allocID
|
||||
if perr := putJSON(kv, TaskKey(task.Cluster, task.TaskID), task); perr != nil {
|
||||
slog.Error("ECS auto-EIP: persist public IP failed", "task", task.TaskID, "err", perr)
|
||||
}
|
||||
}
|
||||
|
||||
// releaseTaskPublicIP disassociates + releases a task's auto-assigned Elastic IP
|
||||
// and clears the record. No-op when no EIP was assigned. The cleared record is
|
||||
// reflected back into task; callers on the STOPPED path persist it.
|
||||
func (s *Service) releaseTaskPublicIP(accountID string, task *TaskRecord) {
|
||||
if s.eips == nil || task.ENIEIPAllocationID == "" {
|
||||
return
|
||||
}
|
||||
if err := s.eips.Release(accountID, task.ENIEIPAllocationID); err != nil {
|
||||
slog.Error("ECS auto-EIP release failed", "task", task.TaskID, "alloc", task.ENIEIPAllocationID, "err", err)
|
||||
}
|
||||
task.ENIPublicIP = ""
|
||||
task.ENIEIPAllocationID = ""
|
||||
}
|
||||
|
||||
@@ -280,7 +280,7 @@ func (s *Service) taskToAWS(accountID string, r *TaskRecord) *ecs.Task {
|
||||
t.StoppedReason = aws.String(r.StoppedReason)
|
||||
}
|
||||
if r.ENIID != "" {
|
||||
t.Attachments = append(t.Attachments, &ecs.Attachment{
|
||||
att := &ecs.Attachment{
|
||||
Id: aws.String(r.ENIAttachmentID),
|
||||
Type: aws.String("ElasticNetworkInterface"),
|
||||
Status: aws.String(r.LastStatus),
|
||||
@@ -290,7 +290,12 @@ func (s *Service) taskToAWS(accountID string, r *TaskRecord) *ecs.Task {
|
||||
{Name: aws.String("macAddress"), Value: aws.String(r.ENIMacAddress)},
|
||||
{Name: aws.String("subnetId"), Value: aws.String(r.ENISubnetID)},
|
||||
},
|
||||
})
|
||||
}
|
||||
if r.ENIPublicIP != "" {
|
||||
att.Details = append(att.Details,
|
||||
&ecs.KeyValuePair{Name: aws.String("publicIPv4Address"), Value: aws.String(r.ENIPublicIP)})
|
||||
}
|
||||
t.Attachments = append(t.Attachments, att)
|
||||
}
|
||||
for _, c := range r.Containers {
|
||||
ctr := &ecs.Container{Name: aws.String(c.Name), LastStatus: aws.String(c.Status)}
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
package handlers_ecs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ecsGatewayCAPath is the on-VM gateway CA PEM path the agent verifies TLS against.
|
||||
const ecsGatewayCAPath = "/etc/spinifex-ecs/gateway-ca.pem"
|
||||
|
||||
// containerInstanceUserDataInput carries the control-plane endpoint a container
|
||||
// instance needs to register. No credentials: the agent draws auto-rotating
|
||||
// instance-role creds from IMDS, matching AWS ecsInstanceRole.
|
||||
type containerInstanceUserDataInput struct {
|
||||
GatewayURL string
|
||||
GatewayCACert string
|
||||
Region string
|
||||
ClusterName string
|
||||
}
|
||||
|
||||
// containerInstanceUserDataFile is one cloud-config write_files entry.
|
||||
type containerInstanceUserDataFile struct {
|
||||
Path string
|
||||
Perms string
|
||||
Body string
|
||||
}
|
||||
|
||||
// buildContainerInstanceUserData renders the #cloud-config for an ECS
|
||||
// container-instance VM. It seeds only the agent's control-plane config + the
|
||||
// gateway TLS CA; credentials come from IMDS, so no keys are written.
|
||||
func buildContainerInstanceUserData(in containerInstanceUserDataInput) string {
|
||||
agentBody := strings.Join([]string{
|
||||
"ECS_GATEWAY_URL=" + in.GatewayURL,
|
||||
"ECS_GATEWAY_CA=" + ecsGatewayCAPath,
|
||||
"ECS_REGION=" + in.Region,
|
||||
"ECS_CLUSTER=" + in.ClusterName,
|
||||
}, "\n")
|
||||
|
||||
files := []containerInstanceUserDataFile{
|
||||
{Path: "/etc/spinifex-ecs/agent.env", Perms: "0600", Body: agentBody},
|
||||
{Path: ecsGatewayCAPath, Perms: "0644", Body: strings.TrimRight(in.GatewayCACert, "\n")},
|
||||
}
|
||||
|
||||
var buf strings.Builder
|
||||
buf.WriteString("#cloud-config\n")
|
||||
buf.WriteString("write_files:\n")
|
||||
for _, f := range files {
|
||||
fmt.Fprintf(&buf, " - path: %s\n", f.Path)
|
||||
fmt.Fprintf(&buf, " permissions: '%s'\n", f.Perms)
|
||||
buf.WriteString(" content: |\n")
|
||||
for line := range strings.SplitSeq(f.Body, "\n") {
|
||||
buf.WriteString(" ")
|
||||
buf.WriteString(line)
|
||||
buf.WriteString("\n")
|
||||
}
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package handlers_ecs
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestBuildContainerInstanceUserData(t *testing.T) {
|
||||
const caPEM = "-----BEGIN CERTIFICATE-----\nMIIBfakefakefake\n-----END CERTIFICATE-----"
|
||||
udata := buildContainerInstanceUserData(containerInstanceUserDataInput{
|
||||
GatewayURL: "https://10.0.0.1:9999",
|
||||
GatewayCACert: caPEM,
|
||||
Region: "ap-southeast-2",
|
||||
ClusterName: "web",
|
||||
})
|
||||
|
||||
assert.Contains(t, udata, "#cloud-config")
|
||||
assert.Contains(t, udata, "ECS_GATEWAY_URL=https://10.0.0.1:9999")
|
||||
assert.Contains(t, udata, "ECS_GATEWAY_CA="+ecsGatewayCAPath)
|
||||
assert.Contains(t, udata, "ECS_REGION=ap-southeast-2")
|
||||
assert.Contains(t, udata, "ECS_CLUSTER=web")
|
||||
|
||||
// The CA PEM is written inline under the gateway-ca.pem file.
|
||||
assert.Contains(t, udata, "path: "+ecsGatewayCAPath)
|
||||
assert.Contains(t, udata, "-----BEGIN CERTIFICATE-----")
|
||||
assert.Contains(t, udata, "-----END CERTIFICATE-----")
|
||||
|
||||
// No credentials ever touch the instance; the agent uses IMDS role creds.
|
||||
assert.NotContains(t, udata, "ECS_ACCESS_KEY")
|
||||
assert.NotContains(t, udata, "ECS_SECRET_KEY")
|
||||
}
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{ni as r}from"./awsClient.js";import{It as i,Rt as a,Wt as o,zt as s}from"./auth.js";import{t as c}from"./back-link.js";import{n as l,r as u,t as d}from"./upload-button.js";import{r as f}from"./s3.js";import{St as p,w as m}from"./index.js";import{t as h}from"./error-banner.js";var g=t(),_=e();function v(){let e=(0,g.c)(24),{bucket:t,_splat:v}=m.useParams(),y=a(v??``),{data:b}=n(p(t,y)),x=f(),S;e[0]===b.Contents?S=e[1]:(S=b.Contents??[],e[0]=b.Contents,e[1]=S);let C=S,w;e[2]===b.CommonPrefixes?w=e[3]:(w=b.CommonPrefixes??[],e[2]=b.CommonPrefixes,e[3]=w);let T=w,E=y.split(`/`).filter(Boolean),D=[{name:t,path:`/s3/ls/${t}`},...E.map((e,n)=>({name:e,path:`/s3/ls/${t}/${`${E.slice(0,n+1).join(`/`)}/`}`}))],O=E.length>1?`/s3/ls/${t}/${E.slice(0,-1).join(`/`)}/`:`/s3/ls/${t}`,k;e[4]===O?k=e[5]:(k=(0,_.jsx)(c,{to:O,children:`Back`}),e[4]=O,e[5]=k);let A;e[6]!==t||e[7]!==y||e[8]!==x.isPending||e[9]!==x.mutateAsync?(A=(0,_.jsx)(d,{bucket:t,isPending:x.isPending,onUpload:x.mutateAsync,prefix:y}),e[6]=t,e[7]=y,e[8]=x.isPending,e[9]=x.mutateAsync,e[10]=A):A=e[10];let j;e[11]===x.error?j=e[12]:(j=x.error&&(0,_.jsx)(h,{error:x.error,msg:`Failed to upload object`}),e[11]=x.error,e[12]=j);let M;e[13]!==t||e[14]!==T||e[15]!==y?(M=T.length>0&&(0,_.jsxs)(`div`,{className:`mb-6`,children:[(0,_.jsx)(`h2`,{className:`mb-3 text-lg font-semibold`,children:`Folders`}),(0,_.jsx)(`div`,{className:`space-y-2`,children:T.map(e=>e.Prefix?(0,_.jsx)(u,{bucketName:t,folderName:o(s(e.Prefix,y)),fullPrefix:i(e.Prefix,y)},e.Prefix):null)})]}),e[13]=t,e[14]=T,e[15]=y,e[16]=M):M=e[16];let N;e[17]!==t||e[18]!==C||e[19]!==y?(N=C.length>0&&(0,_.jsxs)(`div`,{className:`space-y-2`,children:[(0,_.jsx)(`h2`,{className:`mb-3 text-lg font-semibold`,children:`Objects`}),C.map(e=>e.Key?(0,_.jsx)(l,{bucketName:t,displayName:s(e.Key,y),fullKey:i(e.Key,y),object:e},e.Key):null)]}),e[17]=t,e[18]=C,e[19]=y,e[20]=N):N=e[20];let P;return e[21]!==T.length||e[22]!==C.length?(P=C.length===0&&T.length===0&&(0,_.jsx)(`p`,{className:`text-muted-foreground`,children:`No objects found in this folder.`}),e[21]=T.length,e[22]=C.length,e[23]=P):P=e[23],(0,_.jsxs)(_.Fragment,{children:[k,(0,_.jsx)(`div`,{className:`mb-6`,children:(0,_.jsxs)(`div`,{className:`mb-2 flex items-center justify-between`,children:[(0,_.jsx)(`div`,{className:`flex items-center gap-2 text-sm text-muted-foreground`,children:D.map((e,t)=>(0,_.jsxs)(`div`,{className:`flex items-center gap-2`,children:[t>0&&(0,_.jsx)(`span`,{children:`/`}),t===D.length-1?(0,_.jsx)(`span`,{className:`text-foreground`,children:e.name}):(0,_.jsx)(r,{className:`hover:text-foreground`,to:e.path,children:e.name})]},e.path))}),A]})}),j,M,N,P]})}export{v as component};
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{ni as r}from"./awsClient.js";import{It as i,Rt as a,Wt as o,zt as s}from"./auth.js";import{t as c}from"./back-link.js";import{n as l,r as u,t as d}from"./upload-button.js";import{r as f}from"./s3.js";import{E as p,wt as m}from"./index.js";import{t as h}from"./error-banner.js";var g=t(),_=e();function v(){let e=(0,g.c)(24),{bucket:t,_splat:v}=p.useParams(),y=a(v??``),{data:b}=n(m(t,y)),x=f(),S;e[0]===b.Contents?S=e[1]:(S=b.Contents??[],e[0]=b.Contents,e[1]=S);let C=S,w;e[2]===b.CommonPrefixes?w=e[3]:(w=b.CommonPrefixes??[],e[2]=b.CommonPrefixes,e[3]=w);let T=w,E=y.split(`/`).filter(Boolean),D=[{name:t,path:`/s3/ls/${t}`},...E.map((e,n)=>({name:e,path:`/s3/ls/${t}/${`${E.slice(0,n+1).join(`/`)}/`}`}))],O=E.length>1?`/s3/ls/${t}/${E.slice(0,-1).join(`/`)}/`:`/s3/ls/${t}`,k;e[4]===O?k=e[5]:(k=(0,_.jsx)(c,{to:O,children:`Back`}),e[4]=O,e[5]=k);let A;e[6]!==t||e[7]!==y||e[8]!==x.isPending||e[9]!==x.mutateAsync?(A=(0,_.jsx)(d,{bucket:t,isPending:x.isPending,onUpload:x.mutateAsync,prefix:y}),e[6]=t,e[7]=y,e[8]=x.isPending,e[9]=x.mutateAsync,e[10]=A):A=e[10];let j;e[11]===x.error?j=e[12]:(j=x.error&&(0,_.jsx)(h,{error:x.error,msg:`Failed to upload object`}),e[11]=x.error,e[12]=j);let M;e[13]!==t||e[14]!==T||e[15]!==y?(M=T.length>0&&(0,_.jsxs)(`div`,{className:`mb-6`,children:[(0,_.jsx)(`h2`,{className:`mb-3 text-lg font-semibold`,children:`Folders`}),(0,_.jsx)(`div`,{className:`space-y-2`,children:T.map(e=>e.Prefix?(0,_.jsx)(u,{bucketName:t,folderName:o(s(e.Prefix,y)),fullPrefix:i(e.Prefix,y)},e.Prefix):null)})]}),e[13]=t,e[14]=T,e[15]=y,e[16]=M):M=e[16];let N;e[17]!==t||e[18]!==C||e[19]!==y?(N=C.length>0&&(0,_.jsxs)(`div`,{className:`space-y-2`,children:[(0,_.jsx)(`h2`,{className:`mb-3 text-lg font-semibold`,children:`Objects`}),C.map(e=>e.Key?(0,_.jsx)(l,{bucketName:t,displayName:s(e.Key,y),fullKey:i(e.Key,y),object:e},e.Key):null)]}),e[17]=t,e[18]=C,e[19]=y,e[20]=N):N=e[20];let P;return e[21]!==T.length||e[22]!==C.length?(P=C.length===0&&T.length===0&&(0,_.jsx)(`p`,{className:`text-muted-foreground`,children:`No objects found in this folder.`}),e[21]=T.length,e[22]=C.length,e[23]=P):P=e[23],(0,_.jsxs)(_.Fragment,{children:[k,(0,_.jsx)(`div`,{className:`mb-6`,children:(0,_.jsxs)(`div`,{className:`mb-2 flex items-center justify-between`,children:[(0,_.jsx)(`div`,{className:`flex items-center gap-2 text-sm text-muted-foreground`,children:D.map((e,t)=>(0,_.jsxs)(`div`,{className:`flex items-center gap-2`,children:[t>0&&(0,_.jsx)(`span`,{children:`/`}),t===D.length-1?(0,_.jsx)(`span`,{className:`text-foreground`,children:e.name}):(0,_.jsx)(r,{className:`hover:text-foreground`,to:e.path,children:e.name})]},e.path))}),A]})}),j,M,N,P]})}export{v as component};
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{Wt as r}from"./auth.js";import{t as i}from"./back-link.js";import{n as a,r as o,t as s}from"./upload-button.js";import{r as c}from"./s3.js";import{St as l,z as u}from"./index.js";import{t as d}from"./error-banner.js";import{t as f}from"./page-heading.js";var p=t(),m=e();function h(){let e=(0,p.c)(31),{bucket:t}=u.useParams(),h;e[0]===t?h=e[1]:(h=l(t),e[0]=t,e[1]=h);let{data:g}=n(h),_=c(),v;e[2]===g.Contents?v=e[3]:(v=g.Contents??[],e[2]=g.Contents,e[3]=v);let y=v,b;e[4]===g.CommonPrefixes?b=e[5]:(b=g.CommonPrefixes??[],e[4]=g.CommonPrefixes,e[5]=b);let x=b,S;e[6]===Symbol.for(`react.memo_cache_sentinel`)?(S=(0,m.jsx)(i,{to:`/s3/ls`,children:`Back to buckets`}),e[6]=S):S=e[6];let C;e[7]!==t||e[8]!==_.isPending||e[9]!==_.mutateAsync?(C=(0,m.jsx)(s,{bucket:t,isPending:_.isPending,onUpload:_.mutateAsync}),e[7]=t,e[8]=_.isPending,e[9]=_.mutateAsync,e[10]=C):C=e[10];let w;e[11]!==t||e[12]!==C?(w=(0,m.jsx)(f,{actions:C,title:t}),e[11]=t,e[12]=C,e[13]=w):w=e[13];let T;e[14]===_.error?T=e[15]:(T=_.error&&(0,m.jsx)(d,{error:_.error,msg:`Failed to upload object`}),e[14]=_.error,e[15]=T);let E;e[16]!==t||e[17]!==x?(E=x.length>0&&(0,m.jsxs)(`div`,{className:`mb-6`,children:[(0,m.jsx)(`h2`,{className:`mb-3 text-lg font-semibold`,children:`Folders`}),(0,m.jsx)(`div`,{className:`space-y-2`,children:x.map(e=>e.Prefix?(0,m.jsx)(o,{bucketName:t,folderName:r(e.Prefix),fullPrefix:e.Prefix},e.Prefix):null)})]}),e[16]=t,e[17]=x,e[18]=E):E=e[18];let D;e[19]!==t||e[20]!==y?(D=y.length>0&&(0,m.jsxs)(`div`,{className:`space-y-2`,children:[(0,m.jsx)(`h2`,{className:`mb-3 text-lg font-semibold`,children:`Objects`}),y.map(e=>e.Key?(0,m.jsx)(a,{bucketName:t,displayName:e.Key,fullKey:e.Key,object:e},e.Key):null)]}),e[19]=t,e[20]=y,e[21]=D):D=e[21];let O;e[22]!==x.length||e[23]!==y.length?(O=y.length===0&&x.length===0&&(0,m.jsx)(`p`,{className:`text-muted-foreground`,children:`No objects found in this bucket.`}),e[22]=x.length,e[23]=y.length,e[24]=O):O=e[24];let k;return e[25]!==w||e[26]!==T||e[27]!==E||e[28]!==D||e[29]!==O?(k=(0,m.jsxs)(m.Fragment,{children:[S,w,T,E,D,O]}),e[25]=w,e[26]=T,e[27]=E,e[28]=D,e[29]=O,e[30]=k):k=e[30],k}export{h as component};
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{Wt as r}from"./auth.js";import{t as i}from"./back-link.js";import{n as a,r as o,t as s}from"./upload-button.js";import{r as c}from"./s3.js";import{V as l,wt as u}from"./index.js";import{t as d}from"./error-banner.js";import{t as f}from"./page-heading.js";var p=t(),m=e();function h(){let e=(0,p.c)(31),{bucket:t}=l.useParams(),h;e[0]===t?h=e[1]:(h=u(t),e[0]=t,e[1]=h);let{data:g}=n(h),_=c(),v;e[2]===g.Contents?v=e[3]:(v=g.Contents??[],e[2]=g.Contents,e[3]=v);let y=v,b;e[4]===g.CommonPrefixes?b=e[5]:(b=g.CommonPrefixes??[],e[4]=g.CommonPrefixes,e[5]=b);let x=b,S;e[6]===Symbol.for(`react.memo_cache_sentinel`)?(S=(0,m.jsx)(i,{to:`/s3/ls`,children:`Back to buckets`}),e[6]=S):S=e[6];let C;e[7]!==t||e[8]!==_.isPending||e[9]!==_.mutateAsync?(C=(0,m.jsx)(s,{bucket:t,isPending:_.isPending,onUpload:_.mutateAsync}),e[7]=t,e[8]=_.isPending,e[9]=_.mutateAsync,e[10]=C):C=e[10];let w;e[11]!==t||e[12]!==C?(w=(0,m.jsx)(f,{actions:C,title:t}),e[11]=t,e[12]=C,e[13]=w):w=e[13];let T;e[14]===_.error?T=e[15]:(T=_.error&&(0,m.jsx)(d,{error:_.error,msg:`Failed to upload object`}),e[14]=_.error,e[15]=T);let E;e[16]!==t||e[17]!==x?(E=x.length>0&&(0,m.jsxs)(`div`,{className:`mb-6`,children:[(0,m.jsx)(`h2`,{className:`mb-3 text-lg font-semibold`,children:`Folders`}),(0,m.jsx)(`div`,{className:`space-y-2`,children:x.map(e=>e.Prefix?(0,m.jsx)(o,{bucketName:t,folderName:r(e.Prefix),fullPrefix:e.Prefix},e.Prefix):null)})]}),e[16]=t,e[17]=x,e[18]=E):E=e[18];let D;e[19]!==t||e[20]!==y?(D=y.length>0&&(0,m.jsxs)(`div`,{className:`space-y-2`,children:[(0,m.jsx)(`h2`,{className:`mb-3 text-lg font-semibold`,children:`Objects`}),y.map(e=>e.Key?(0,m.jsx)(a,{bucketName:t,displayName:e.Key,fullKey:e.Key,object:e},e.Key):null)]}),e[19]=t,e[20]=y,e[21]=D):D=e[21];let O;e[22]!==x.length||e[23]!==y.length?(O=y.length===0&&x.length===0&&(0,m.jsx)(`p`,{className:`text-muted-foreground`,children:`No objects found in this bucket.`}),e[22]=x.length,e[23]=y.length,e[24]=O):O=e[24];let k;return e[25]!==w||e[26]!==T||e[27]!==E||e[28]!==D||e[29]!==O?(k=(0,m.jsxs)(m.Fragment,{children:[S,w,T,E,D,O]}),e[25]=w,e[26]=T,e[27]=E,e[28]=D,e[29]=O,e[30]=k):k=e[30],k}export{h as component};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{n as e,o as t,r as n}from"./compiler-runtime.js";import{t as r}from"./useSuspenseQuery.js";import{Ut as i}from"./auth.js";import{t as a}from"./back-link.js";import{c as o,i as s,n as c,s as l,t as u}from"./select.js";import{t as d}from"./trash-2.js";import{t as f}from"./button.js";import{G as p,L as m,n as h}from"./ec2.js";import{Mt as g,Xr as _,t as v,wt as y}from"./index.js";import{t as b}from"./error-banner.js";import{t as x}from"./page-heading.js";import{t as S}from"./delete-confirmation-dialog.js";import{n as C,t as w}from"./detail-row.js";var T=t(n()),E=e();function D(){let{id:e}=v.useParams(),t=_(),{data:n}=r(y(e)),{data:D}=r(g),O=h(),k=m(),A=p(),[j,M]=(0,T.useState)(!1),[N,P]=(0,T.useState)(``),F=n.Addresses?.[0],I=D.Reservations?.flatMap(e=>e.Instances??[]).filter(e=>e.State?.Name===`running`||e.State?.Name===`stopped`)??[],L=async()=>{try{await A.mutateAsync(e),t({to:`/ec2/describe-addresses`})}finally{M(!1)}},R=async()=>{N&&await O.mutateAsync({allocationId:e,instanceId:N})},z=async()=>{F?.AssociationId&&await k.mutateAsync(F.AssociationId)};if(!F?.AllocationId)return(0,E.jsxs)(E.Fragment,{children:[(0,E.jsx)(a,{to:`/ec2/describe-addresses`,children:`Back to Elastic IPs`}),(0,E.jsx)(`p`,{className:`text-muted-foreground`,children:`Elastic IP not found.`})]});let B=!!F.AssociationId,V=i(F.Tags);return(0,E.jsxs)(E.Fragment,{children:[(0,E.jsx)(a,{to:`/ec2/describe-addresses`,children:`Back to Elastic IPs`}),(A.error??O.error??k.error)&&(0,E.jsx)(b,{error:A.error??O.error??k.error??void 0,msg:`Elastic IP action failed`}),(0,E.jsxs)(`div`,{className:`space-y-6`,children:[(0,E.jsx)(x,{actions:(0,E.jsxs)(f,{disabled:B||A.isPending,onClick:()=>M(!0),size:`sm`,variant:`destructive`,children:[(0,E.jsx)(d,{className:`size-4`}),`Release`]}),subtitle:`Elastic IP Details`,title:V?`${F.AllocationId} (${V})`:F.AllocationId}),(0,E.jsxs)(C,{children:[(0,E.jsx)(C.Header,{children:`Elastic IP Information`}),(0,E.jsxs)(C.Content,{children:[(0,E.jsx)(w,{label:`Allocation ID`,value:F.AllocationId}),(0,E.jsx)(w,{label:`Public IP`,value:F.PublicIp}),(0,E.jsx)(w,{label:`Domain`,value:F.Domain}),(0,E.jsx)(w,{label:`Association ID`,value:F.AssociationId??`—`}),(0,E.jsx)(w,{label:`Instance ID`,value:F.InstanceId??`—`}),(0,E.jsx)(w,{label:`Private IP`,value:F.PrivateIpAddress??`—`})]})]}),(0,E.jsxs)(C,{children:[(0,E.jsx)(C.Header,{children:`Association`}),(0,E.jsx)(C.Content,{children:B?(0,E.jsx)(f,{disabled:k.isPending,onClick:z,size:`sm`,variant:`outline`,children:`Disassociate`}):(0,E.jsxs)(`div`,{className:`flex items-end gap-2`,children:[(0,E.jsx)(`div`,{className:`flex-1`,children:(0,E.jsxs)(u,{onValueChange:e=>P(e??``),value:N,children:[(0,E.jsx)(l,{className:`w-full`,children:(0,E.jsx)(o,{placeholder:`Select an instance`})}),(0,E.jsx)(c,{children:I.map(e=>{let t=i(e.Tags);return(0,E.jsx)(s,{value:e.InstanceId??``,children:t?`${e.InstanceId} (${t})`:e.InstanceId},e.InstanceId)})})]})}),(0,E.jsx)(f,{disabled:!N||O.isPending,onClick:R,size:`sm`,children:`Associate`})]})})]})]}),(0,E.jsx)(S,{description:`Are you sure you want to release the Elastic IP "${F.AllocationId}" (${F.PublicIp})? This action cannot be undone.`,isPending:A.isPending,onConfirm:L,onOpenChange:M,open:j,title:`Release Elastic IP`})]})}export{D as component};
|
||||
import{n as e,o as t,r as n}from"./compiler-runtime.js";import{t as r}from"./useSuspenseQuery.js";import{Ut as i}from"./auth.js";import{t as a}from"./back-link.js";import{c as o,i as s,n as c,s as l,t as u}from"./select.js";import{t as d}from"./trash-2.js";import{t as f}from"./button.js";import{G as p,L as m,n as h}from"./ec2.js";import{Et as g,Pt as _,Qr as v,r as y}from"./index.js";import{t as b}from"./error-banner.js";import{t as x}from"./page-heading.js";import{t as S}from"./delete-confirmation-dialog.js";import{n as C,t as w}from"./detail-row.js";var T=t(n()),E=e();function D(){let{id:e}=y.useParams(),t=v(),{data:n}=r(g(e)),{data:D}=r(_),O=h(),k=m(),A=p(),[j,M]=(0,T.useState)(!1),[N,P]=(0,T.useState)(``),F=n.Addresses?.[0],I=D.Reservations?.flatMap(e=>e.Instances??[]).filter(e=>e.State?.Name===`running`||e.State?.Name===`stopped`)??[],L=async()=>{try{await A.mutateAsync(e),t({to:`/ec2/describe-addresses`})}finally{M(!1)}},R=async()=>{N&&await O.mutateAsync({allocationId:e,instanceId:N})},z=async()=>{F?.AssociationId&&await k.mutateAsync(F.AssociationId)};if(!F?.AllocationId)return(0,E.jsxs)(E.Fragment,{children:[(0,E.jsx)(a,{to:`/ec2/describe-addresses`,children:`Back to Elastic IPs`}),(0,E.jsx)(`p`,{className:`text-muted-foreground`,children:`Elastic IP not found.`})]});let B=!!F.AssociationId,V=i(F.Tags);return(0,E.jsxs)(E.Fragment,{children:[(0,E.jsx)(a,{to:`/ec2/describe-addresses`,children:`Back to Elastic IPs`}),(A.error??O.error??k.error)&&(0,E.jsx)(b,{error:A.error??O.error??k.error??void 0,msg:`Elastic IP action failed`}),(0,E.jsxs)(`div`,{className:`space-y-6`,children:[(0,E.jsx)(x,{actions:(0,E.jsxs)(f,{disabled:B||A.isPending,onClick:()=>M(!0),size:`sm`,variant:`destructive`,children:[(0,E.jsx)(d,{className:`size-4`}),`Release`]}),subtitle:`Elastic IP Details`,title:V?`${F.AllocationId} (${V})`:F.AllocationId}),(0,E.jsxs)(C,{children:[(0,E.jsx)(C.Header,{children:`Elastic IP Information`}),(0,E.jsxs)(C.Content,{children:[(0,E.jsx)(w,{label:`Allocation ID`,value:F.AllocationId}),(0,E.jsx)(w,{label:`Public IP`,value:F.PublicIp}),(0,E.jsx)(w,{label:`Domain`,value:F.Domain}),(0,E.jsx)(w,{label:`Association ID`,value:F.AssociationId??`—`}),(0,E.jsx)(w,{label:`Instance ID`,value:F.InstanceId??`—`}),(0,E.jsx)(w,{label:`Private IP`,value:F.PrivateIpAddress??`—`})]})]}),(0,E.jsxs)(C,{children:[(0,E.jsx)(C.Header,{children:`Association`}),(0,E.jsx)(C.Content,{children:B?(0,E.jsx)(f,{disabled:k.isPending,onClick:z,size:`sm`,variant:`outline`,children:`Disassociate`}):(0,E.jsxs)(`div`,{className:`flex items-end gap-2`,children:[(0,E.jsx)(`div`,{className:`flex-1`,children:(0,E.jsxs)(u,{onValueChange:e=>P(e??``),value:N,children:[(0,E.jsx)(l,{className:`w-full`,children:(0,E.jsx)(o,{placeholder:`Select an instance`})}),(0,E.jsx)(c,{children:I.map(e=>{let t=i(e.Tags);return(0,E.jsx)(s,{value:e.InstanceId??``,children:t?`${e.InstanceId} (${t})`:e.InstanceId},e.InstanceId)})})]})}),(0,E.jsx)(f,{disabled:!N||O.isPending,onClick:R,size:`sm`,children:`Associate`})]})})]})]}),(0,E.jsx)(S,{description:`Are you sure you want to release the Elastic IP "${F.AllocationId}" (${F.PublicIp})? This action cannot be undone.`,isPending:A.isPending,onConfirm:L,onOpenChange:M,open:j,title:`Release Elastic IP`})]})}export{D as component};
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{n as e,o as t,r as n}from"./compiler-runtime.js";import{t as r}from"./useSuspenseQuery.js";import{ni as i}from"./awsClient.js";import{Bt as a}from"./auth.js";import{t as o}from"./back-link.js";import{t as s}from"./copy.js";import{t as c}from"./trash-2.js";import{t as l}from"./button.js";import{j as u,l as d}from"./ec2.js";import{Kt as f,Vt as p,Xr as m,d as h,er as g}from"./index.js";import{t as _}from"./error-banner.js";import{t as v}from"./page-heading.js";import{a as y,t as b}from"./field.js";import{a as x,i as S,l as C,n as w,o as T,r as E,s as D,t as O}from"./alert-dialog.js";import{t as k}from"./delete-confirmation-dialog.js";import{n as A,t as j}from"./detail-row.js";import{t as M}from"./state-badge.js";var N=t(n()),P=e();function F(){let{id:e}=h.useParams(),t=m(),{data:n}=r(f(e)),{data:F}=r(p),I=n.Snapshots?.[0],L=u(),R=d(),[z,B]=(0,N.useState)(!1),[V,H]=(0,N.useState)(!1),[U,W]=(0,N.useState)(``),G=F.Regions?.[0]?.RegionName??`ap-southeast-2`,K=I?.State===`completed`,q=async()=>{try{await L.mutateAsync(e),t({to:`/ec2/describe-snapshots`})}finally{B(!1)}},J=async()=>{try{await R.mutateAsync({sourceSnapshotId:e,sourceRegion:G,description:U||void 0}),H(!1),W(``)}catch{}};if(!I?.SnapshotId)return(0,P.jsxs)(P.Fragment,{children:[(0,P.jsx)(o,{to:`/ec2/describe-snapshots`,children:`Back to snapshots`}),(0,P.jsx)(`p`,{className:`text-muted-foreground`,children:`Snapshot not found.`})]});let Y=a(I.StartTime);return(0,P.jsxs)(P.Fragment,{children:[(0,P.jsx)(o,{to:`/ec2/describe-snapshots`,children:`Back to snapshots`}),L.error&&(0,P.jsx)(_,{error:L.error,msg:`Failed to delete snapshot`}),R.error&&(0,P.jsx)(_,{error:R.error,msg:`Failed to copy snapshot`}),(0,P.jsxs)(`div`,{className:`space-y-6`,children:[(0,P.jsx)(v,{actions:(0,P.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,P.jsxs)(l,{disabled:!K,onClick:()=>B(!0),size:`sm`,variant:`destructive`,children:[(0,P.jsx)(c,{className:`size-4`}),`Delete`]}),(0,P.jsxs)(l,{disabled:!K,onClick:()=>H(!0),size:`sm`,variant:`outline`,children:[(0,P.jsx)(s,{className:`size-4`}),`Copy Snapshot`]}),(0,P.jsx)(M,{state:I.State})]}),subtitle:`Snapshot Details`,title:I.SnapshotId}),(0,P.jsxs)(A,{children:[(0,P.jsx)(A.Header,{children:`Snapshot Information`}),(0,P.jsxs)(A.Content,{children:[(0,P.jsx)(j,{label:`Snapshot ID`,value:I.SnapshotId}),(0,P.jsx)(j,{label:`Volume ID`,value:I.VolumeId?(0,P.jsx)(i,{className:`text-primary hover:underline`,params:{id:I.VolumeId},to:`/ec2/describe-volumes/$id`,children:I.VolumeId}):void 0}),(0,P.jsx)(j,{label:`Volume Size`,value:`${I.VolumeSize} GiB`}),(0,P.jsx)(j,{label:`State`,value:I.State}),(0,P.jsx)(j,{label:`Description`,value:I.Description}),(0,P.jsx)(j,{label:`Progress`,value:I.Progress}),(0,P.jsx)(j,{label:`Start Time`,value:Y}),(0,P.jsx)(j,{label:`Owner ID`,value:I.OwnerId}),(0,P.jsx)(j,{label:`Encrypted`,value:I.Encrypted?`Yes`:`No`})]})]})]}),(0,P.jsx)(k,{description:`Are you sure you want to delete the snapshot "${I.SnapshotId}"? This action cannot be undone.`,isPending:L.isPending,onConfirm:q,onOpenChange:B,open:z,title:`Delete Snapshot`}),(0,P.jsx)(O,{onOpenChange:H,open:V,children:(0,P.jsxs)(S,{children:[(0,P.jsxs)(D,{children:[(0,P.jsx)(C,{children:`Copy Snapshot`}),(0,P.jsx)(x,{children:`Create a copy of this snapshot in the current region.`})]}),(0,P.jsxs)(b,{children:[(0,P.jsx)(y,{children:(0,P.jsx)(`label`,{htmlFor:`copyDescription`,children:`Description (optional)`})}),(0,P.jsx)(g,{id:`copyDescription`,onChange:e=>W(e.target.value),placeholder:`Description for the snapshot copy`,value:U})]}),(0,P.jsxs)(T,{children:[(0,P.jsx)(E,{children:`Cancel`}),(0,P.jsx)(w,{disabled:R.isPending,onClick:J,children:R.isPending?`Copying…`:`Copy Snapshot`})]})]})})]})}export{F as component};
|
||||
import{n as e,o as t,r as n}from"./compiler-runtime.js";import{t as r}from"./useSuspenseQuery.js";import{ni as i}from"./awsClient.js";import{Bt as a}from"./auth.js";import{t as o}from"./back-link.js";import{t as s}from"./copy.js";import{t as c}from"./trash-2.js";import{t as l}from"./button.js";import{j as u,l as d}from"./ec2.js";import{Jt as f,Qr as p,Ut as m,nr as h,p as g}from"./index.js";import{t as _}from"./error-banner.js";import{t as v}from"./page-heading.js";import{a as y,t as b}from"./field.js";import{a as x,i as S,l as C,n as w,o as T,r as E,s as D,t as O}from"./alert-dialog.js";import{t as k}from"./delete-confirmation-dialog.js";import{n as A,t as j}from"./detail-row.js";import{t as M}from"./state-badge.js";var N=t(n()),P=e();function F(){let{id:e}=g.useParams(),t=p(),{data:n}=r(f(e)),{data:F}=r(m),I=n.Snapshots?.[0],L=u(),R=d(),[z,B]=(0,N.useState)(!1),[V,H]=(0,N.useState)(!1),[U,W]=(0,N.useState)(``),G=F.Regions?.[0]?.RegionName??`ap-southeast-2`,K=I?.State===`completed`,q=async()=>{try{await L.mutateAsync(e),t({to:`/ec2/describe-snapshots`})}finally{B(!1)}},J=async()=>{try{await R.mutateAsync({sourceSnapshotId:e,sourceRegion:G,description:U||void 0}),H(!1),W(``)}catch{}};if(!I?.SnapshotId)return(0,P.jsxs)(P.Fragment,{children:[(0,P.jsx)(o,{to:`/ec2/describe-snapshots`,children:`Back to snapshots`}),(0,P.jsx)(`p`,{className:`text-muted-foreground`,children:`Snapshot not found.`})]});let Y=a(I.StartTime);return(0,P.jsxs)(P.Fragment,{children:[(0,P.jsx)(o,{to:`/ec2/describe-snapshots`,children:`Back to snapshots`}),L.error&&(0,P.jsx)(_,{error:L.error,msg:`Failed to delete snapshot`}),R.error&&(0,P.jsx)(_,{error:R.error,msg:`Failed to copy snapshot`}),(0,P.jsxs)(`div`,{className:`space-y-6`,children:[(0,P.jsx)(v,{actions:(0,P.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,P.jsxs)(l,{disabled:!K,onClick:()=>B(!0),size:`sm`,variant:`destructive`,children:[(0,P.jsx)(c,{className:`size-4`}),`Delete`]}),(0,P.jsxs)(l,{disabled:!K,onClick:()=>H(!0),size:`sm`,variant:`outline`,children:[(0,P.jsx)(s,{className:`size-4`}),`Copy Snapshot`]}),(0,P.jsx)(M,{state:I.State})]}),subtitle:`Snapshot Details`,title:I.SnapshotId}),(0,P.jsxs)(A,{children:[(0,P.jsx)(A.Header,{children:`Snapshot Information`}),(0,P.jsxs)(A.Content,{children:[(0,P.jsx)(j,{label:`Snapshot ID`,value:I.SnapshotId}),(0,P.jsx)(j,{label:`Volume ID`,value:I.VolumeId?(0,P.jsx)(i,{className:`text-primary hover:underline`,params:{id:I.VolumeId},to:`/ec2/describe-volumes/$id`,children:I.VolumeId}):void 0}),(0,P.jsx)(j,{label:`Volume Size`,value:`${I.VolumeSize} GiB`}),(0,P.jsx)(j,{label:`State`,value:I.State}),(0,P.jsx)(j,{label:`Description`,value:I.Description}),(0,P.jsx)(j,{label:`Progress`,value:I.Progress}),(0,P.jsx)(j,{label:`Start Time`,value:Y}),(0,P.jsx)(j,{label:`Owner ID`,value:I.OwnerId}),(0,P.jsx)(j,{label:`Encrypted`,value:I.Encrypted?`Yes`:`No`})]})]})]}),(0,P.jsx)(k,{description:`Are you sure you want to delete the snapshot "${I.SnapshotId}"? This action cannot be undone.`,isPending:L.isPending,onConfirm:q,onOpenChange:B,open:z,title:`Delete Snapshot`}),(0,P.jsx)(O,{onOpenChange:H,open:V,children:(0,P.jsxs)(S,{children:[(0,P.jsxs)(D,{children:[(0,P.jsx)(C,{children:`Copy Snapshot`}),(0,P.jsx)(x,{children:`Create a copy of this snapshot in the current region.`})]}),(0,P.jsxs)(b,{children:[(0,P.jsx)(y,{children:(0,P.jsx)(`label`,{htmlFor:`copyDescription`,children:`Description (optional)`})}),(0,P.jsx)(h,{id:`copyDescription`,onChange:e=>W(e.target.value),placeholder:`Description for the snapshot copy`,value:U})]}),(0,P.jsxs)(T,{children:[(0,P.jsx)(E,{children:`Cancel`}),(0,P.jsx)(w,{disabled:R.isPending,onClick:J,children:R.isPending?`Copying…`:`Copy Snapshot`})]})]})})]})}export{F as component};
|
||||
@@ -1 +1 @@
|
||||
import{n as e,o as t,r as n}from"./compiler-runtime.js";import{t as r}from"./useSuspenseQuery.js";import{ni as i}from"./awsClient.js";import{Ut as a}from"./auth.js";import{t as o}from"./back-link.js";import{t as s}from"./trash-2.js";import{t as c}from"./button.js";import{M as l}from"./ec2.js";import{Jt as u,Xr as d,f}from"./index.js";import{t as p}from"./error-banner.js";import{t as m}from"./page-heading.js";import{t as h}from"./delete-confirmation-dialog.js";import{n as g,t as _}from"./detail-row.js";import{t as v}from"./state-badge.js";var y=t(n()),b=e();function x(){let{id:e}=f.useParams(),t=d(),{data:n}=r(u(e)),x=n.Subnets?.[0],S=l(),[C,w]=(0,y.useState)(!1),T=async()=>{try{await S.mutateAsync(e),t({to:`/ec2/describe-subnets`})}finally{w(!1)}};if(!x?.SubnetId)return(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(o,{to:`/ec2/describe-subnets`,children:`Back to Subnets`}),(0,b.jsx)(`p`,{className:`text-muted-foreground`,children:`Subnet not found.`})]});let E=a(x.Tags);return(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(o,{to:`/ec2/describe-subnets`,children:`Back to Subnets`}),S.error&&(0,b.jsx)(p,{error:S.error,msg:`Failed to delete subnet`}),(0,b.jsxs)(`div`,{className:`space-y-6`,children:[(0,b.jsx)(m,{actions:(0,b.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,b.jsxs)(c,{onClick:()=>w(!0),size:`sm`,variant:`destructive`,children:[(0,b.jsx)(s,{className:`size-4`}),`Delete`]}),(0,b.jsx)(v,{state:x.State})]}),subtitle:`Subnet Details`,title:E?`${x.SubnetId} (${E})`:x.SubnetId}),(0,b.jsxs)(g,{children:[(0,b.jsx)(g.Header,{children:`Subnet Information`}),(0,b.jsxs)(g.Content,{children:[(0,b.jsx)(_,{label:`Subnet ID`,value:x.SubnetId}),(0,b.jsx)(_,{label:`VPC ID`,value:x.VpcId?(0,b.jsx)(i,{className:`text-primary hover:underline`,params:{id:x.VpcId},to:`/ec2/describe-vpcs/$id`,children:x.VpcId}):`—`}),(0,b.jsx)(_,{label:`State`,value:x.State}),(0,b.jsx)(_,{label:`CIDR Block`,value:x.CidrBlock}),(0,b.jsx)(_,{label:`Availability Zone`,value:x.AvailabilityZone}),(0,b.jsx)(_,{label:`Available IP Count`,value:x.AvailableIpAddressCount?.toString()}),(0,b.jsx)(_,{label:`Map Public IP on Launch`,value:x.MapPublicIpOnLaunch?`Yes`:`No`}),(0,b.jsx)(_,{label:`Default for AZ`,value:x.DefaultForAz?`Yes`:`No`})]})]})]}),(0,b.jsx)(h,{description:`Are you sure you want to delete the subnet "${x.SubnetId}"? This action cannot be undone.`,isPending:S.isPending,onConfirm:T,onOpenChange:w,open:C,title:`Delete Subnet`})]})}export{x as component};
|
||||
import{n as e,o as t,r as n}from"./compiler-runtime.js";import{t as r}from"./useSuspenseQuery.js";import{ni as i}from"./awsClient.js";import{Ut as a}from"./auth.js";import{t as o}from"./back-link.js";import{t as s}from"./trash-2.js";import{t as c}from"./button.js";import{M as l}from"./ec2.js";import{Qr as u,Xt as d,m as f}from"./index.js";import{t as p}from"./error-banner.js";import{t as m}from"./page-heading.js";import{t as h}from"./delete-confirmation-dialog.js";import{n as g,t as _}from"./detail-row.js";import{t as v}from"./state-badge.js";var y=t(n()),b=e();function x(){let{id:e}=f.useParams(),t=u(),{data:n}=r(d(e)),x=n.Subnets?.[0],S=l(),[C,w]=(0,y.useState)(!1),T=async()=>{try{await S.mutateAsync(e),t({to:`/ec2/describe-subnets`})}finally{w(!1)}};if(!x?.SubnetId)return(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(o,{to:`/ec2/describe-subnets`,children:`Back to Subnets`}),(0,b.jsx)(`p`,{className:`text-muted-foreground`,children:`Subnet not found.`})]});let E=a(x.Tags);return(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(o,{to:`/ec2/describe-subnets`,children:`Back to Subnets`}),S.error&&(0,b.jsx)(p,{error:S.error,msg:`Failed to delete subnet`}),(0,b.jsxs)(`div`,{className:`space-y-6`,children:[(0,b.jsx)(m,{actions:(0,b.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,b.jsxs)(c,{onClick:()=>w(!0),size:`sm`,variant:`destructive`,children:[(0,b.jsx)(s,{className:`size-4`}),`Delete`]}),(0,b.jsx)(v,{state:x.State})]}),subtitle:`Subnet Details`,title:E?`${x.SubnetId} (${E})`:x.SubnetId}),(0,b.jsxs)(g,{children:[(0,b.jsx)(g.Header,{children:`Subnet Information`}),(0,b.jsxs)(g.Content,{children:[(0,b.jsx)(_,{label:`Subnet ID`,value:x.SubnetId}),(0,b.jsx)(_,{label:`VPC ID`,value:x.VpcId?(0,b.jsx)(i,{className:`text-primary hover:underline`,params:{id:x.VpcId},to:`/ec2/describe-vpcs/$id`,children:x.VpcId}):`—`}),(0,b.jsx)(_,{label:`State`,value:x.State}),(0,b.jsx)(_,{label:`CIDR Block`,value:x.CidrBlock}),(0,b.jsx)(_,{label:`Availability Zone`,value:x.AvailabilityZone}),(0,b.jsx)(_,{label:`Available IP Count`,value:x.AvailableIpAddressCount?.toString()}),(0,b.jsx)(_,{label:`Map Public IP on Launch`,value:x.MapPublicIpOnLaunch?`Yes`:`No`}),(0,b.jsx)(_,{label:`Default for AZ`,value:x.DefaultForAz?`Yes`:`No`})]})]})]}),(0,b.jsx)(h,{description:`Are you sure you want to delete the subnet "${x.SubnetId}"? This action cannot be undone.`,isPending:S.isPending,onConfirm:T,onOpenChange:w,open:C,title:`Delete Subnet`})]})}export{x as component};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{t as r}from"./back-link.js";import{U as i}from"./ec2.js";import{Xr as a,Xt as o,er as s,h as c}from"./index.js";import{i as l,t as u}from"./zod.js";import{t as d}from"./error-banner.js";import{t as f}from"./form-actions.js";import{t as p}from"./page-heading.js";import{a as m,r as h,t as g}from"./field.js";import{_}from"./ec22.js";var v=t(),y=e();function b(){let e=(0,v.c)(53),{id:t}=c.useParams(),b=a(),x;e[0]===t?x=e[1]:(x=o(t),e[0]=t,e[1]=x);let{data:S}=n(x),C=S.Volumes?.[0],w=C?.VolumeId,T=i(),E=C?.Size??1,D;e[2]===E?D=e[3]:(D=u(_.refine(e=>e.size>E,{message:`New size must be greater than current size (${E} GiB)`,path:[`size`]})),e[2]=E,e[3]=D);let O;e[4]===E?O=e[5]:(O={size:E},e[4]=E,e[5]=O);let k;e[6]!==D||e[7]!==O?(k={resolver:D,defaultValues:O},e[6]=D,e[7]=O,e[8]=k):k=e[8];let{handleSubmit:A,register:j,formState:M}=l(k),{errors:N,isSubmitting:P}=M;if(!w){let t;return e[9]===Symbol.for(`react.memo_cache_sentinel`)?(t=(0,y.jsxs)(y.Fragment,{children:[(0,y.jsx)(r,{to:`/ec2/describe-volumes`,children:`Back to volumes`}),(0,y.jsx)(`p`,{className:`text-muted-foreground`,children:`Volume not found.`})]}),e[9]=t):t=e[9],t}let F;e[10]!==T||e[11]!==b||e[12]!==w?(F=async e=>{await T.mutateAsync({...e,volumeId:w}),b({to:`/ec2/describe-volumes/$id`,params:{id:w}})},e[10]=T,e[11]=b,e[12]=w,e[13]=F):F=e[13];let I=F,L,R;e[14]===w?(L=e[15],R=e[16]):(L=(0,y.jsx)(r,{params:{id:w},to:`/ec2/describe-volumes/$id`,children:`Back to volume`}),R=(0,y.jsx)(p,{subtitle:w,title:`Resize Volume`}),e[14]=w,e[15]=L,e[16]=R);let z;e[17]===T.error?z=e[18]:(z=T.error&&(0,y.jsx)(d,{error:T.error,msg:`Failed to resize volume`}),e[17]=T.error,e[18]=z);let B;e[19]!==A||e[20]!==I?(B=A(I),e[19]=A,e[20]=I,e[21]=B):B=e[21];let V;e[22]===E?V=e[23]:(V=(0,y.jsx)(`div`,{className:`space-y-2`,children:(0,y.jsxs)(`p`,{className:`text-sm text-muted-foreground`,children:[`Current size: `,E,` GiB`]})}),e[22]=E,e[23]=V);let H;e[24]===Symbol.for(`react.memo_cache_sentinel`)?(H=(0,y.jsx)(m,{children:(0,y.jsx)(`label`,{htmlFor:`size`,children:`New size (GiB)`})}),e[24]=H):H=e[24];let U=!!N.size,W=E+1,G;e[25]===j?G=e[26]:(G=j(`size`,{valueAsNumber:!0}),e[25]=j,e[26]=G);let K;e[27]!==U||e[28]!==W||e[29]!==G?(K=(0,y.jsx)(s,{"aria-invalid":U,id:`size`,min:W,type:`number`,...G}),e[27]=U,e[28]=W,e[29]=G,e[30]=K):K=e[30];let q;e[31]===N.size?q=e[32]:(q=(0,y.jsx)(h,{errors:[N.size]}),e[31]=N.size,e[32]=q);let J;e[33]!==K||e[34]!==q?(J=(0,y.jsxs)(g,{children:[H,K,q]}),e[33]=K,e[34]=q,e[35]=J):J=e[35];let Y;e[36]!==b||e[37]!==w?(Y=async()=>await b({to:`/ec2/describe-volumes/$id`,params:{id:w}}),e[36]=b,e[37]=w,e[38]=Y):Y=e[38];let X;e[39]!==P||e[40]!==T.isPending||e[41]!==Y?(X=(0,y.jsx)(f,{isPending:T.isPending,isSubmitting:P,onCancel:Y,pendingLabel:`Resizing\\u2026`,submitLabel:`Resize Volume`}),e[39]=P,e[40]=T.isPending,e[41]=Y,e[42]=X):X=e[42];let Z;e[43]!==V||e[44]!==J||e[45]!==X||e[46]!==B?(Z=(0,y.jsxs)(`form`,{className:`max-w-4xl space-y-6`,onSubmit:B,children:[V,J,X]}),e[43]=V,e[44]=J,e[45]=X,e[46]=B,e[47]=Z):Z=e[47];let Q;return e[48]!==Z||e[49]!==L||e[50]!==R||e[51]!==z?(Q=(0,y.jsxs)(y.Fragment,{children:[L,R,z,Z]}),e[48]=Z,e[49]=L,e[50]=R,e[51]=z,e[52]=Q):Q=e[52],Q}export{b as component};
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{t as r}from"./back-link.js";import{U as i}from"./ec2.js";import{Qr as a,Qt as o,_ as s,nr as c}from"./index.js";import{i as l,t as u}from"./zod.js";import{t as d}from"./error-banner.js";import{t as f}from"./form-actions.js";import{t as p}from"./page-heading.js";import{a as m,r as h,t as g}from"./field.js";import{_}from"./ec22.js";var v=t(),y=e();function b(){let e=(0,v.c)(53),{id:t}=s.useParams(),b=a(),x;e[0]===t?x=e[1]:(x=o(t),e[0]=t,e[1]=x);let{data:S}=n(x),C=S.Volumes?.[0],w=C?.VolumeId,T=i(),E=C?.Size??1,D;e[2]===E?D=e[3]:(D=u(_.refine(e=>e.size>E,{message:`New size must be greater than current size (${E} GiB)`,path:[`size`]})),e[2]=E,e[3]=D);let O;e[4]===E?O=e[5]:(O={size:E},e[4]=E,e[5]=O);let k;e[6]!==D||e[7]!==O?(k={resolver:D,defaultValues:O},e[6]=D,e[7]=O,e[8]=k):k=e[8];let{handleSubmit:A,register:j,formState:M}=l(k),{errors:N,isSubmitting:P}=M;if(!w){let t;return e[9]===Symbol.for(`react.memo_cache_sentinel`)?(t=(0,y.jsxs)(y.Fragment,{children:[(0,y.jsx)(r,{to:`/ec2/describe-volumes`,children:`Back to volumes`}),(0,y.jsx)(`p`,{className:`text-muted-foreground`,children:`Volume not found.`})]}),e[9]=t):t=e[9],t}let F;e[10]!==T||e[11]!==b||e[12]!==w?(F=async e=>{await T.mutateAsync({...e,volumeId:w}),b({to:`/ec2/describe-volumes/$id`,params:{id:w}})},e[10]=T,e[11]=b,e[12]=w,e[13]=F):F=e[13];let I=F,L,R;e[14]===w?(L=e[15],R=e[16]):(L=(0,y.jsx)(r,{params:{id:w},to:`/ec2/describe-volumes/$id`,children:`Back to volume`}),R=(0,y.jsx)(p,{subtitle:w,title:`Resize Volume`}),e[14]=w,e[15]=L,e[16]=R);let z;e[17]===T.error?z=e[18]:(z=T.error&&(0,y.jsx)(d,{error:T.error,msg:`Failed to resize volume`}),e[17]=T.error,e[18]=z);let B;e[19]!==A||e[20]!==I?(B=A(I),e[19]=A,e[20]=I,e[21]=B):B=e[21];let V;e[22]===E?V=e[23]:(V=(0,y.jsx)(`div`,{className:`space-y-2`,children:(0,y.jsxs)(`p`,{className:`text-sm text-muted-foreground`,children:[`Current size: `,E,` GiB`]})}),e[22]=E,e[23]=V);let H;e[24]===Symbol.for(`react.memo_cache_sentinel`)?(H=(0,y.jsx)(m,{children:(0,y.jsx)(`label`,{htmlFor:`size`,children:`New size (GiB)`})}),e[24]=H):H=e[24];let U=!!N.size,W=E+1,G;e[25]===j?G=e[26]:(G=j(`size`,{valueAsNumber:!0}),e[25]=j,e[26]=G);let K;e[27]!==U||e[28]!==W||e[29]!==G?(K=(0,y.jsx)(c,{"aria-invalid":U,id:`size`,min:W,type:`number`,...G}),e[27]=U,e[28]=W,e[29]=G,e[30]=K):K=e[30];let q;e[31]===N.size?q=e[32]:(q=(0,y.jsx)(h,{errors:[N.size]}),e[31]=N.size,e[32]=q);let J;e[33]!==K||e[34]!==q?(J=(0,y.jsxs)(g,{children:[H,K,q]}),e[33]=K,e[34]=q,e[35]=J):J=e[35];let Y;e[36]!==b||e[37]!==w?(Y=async()=>await b({to:`/ec2/describe-volumes/$id`,params:{id:w}}),e[36]=b,e[37]=w,e[38]=Y):Y=e[38];let X;e[39]!==P||e[40]!==T.isPending||e[41]!==Y?(X=(0,y.jsx)(f,{isPending:T.isPending,isSubmitting:P,onCancel:Y,pendingLabel:`Resizing\\u2026`,submitLabel:`Resize Volume`}),e[39]=P,e[40]=T.isPending,e[41]=Y,e[42]=X):X=e[42];let Z;e[43]!==V||e[44]!==J||e[45]!==X||e[46]!==B?(Z=(0,y.jsxs)(`form`,{className:`max-w-4xl space-y-6`,onSubmit:B,children:[V,J,X]}),e[43]=V,e[44]=J,e[45]=X,e[46]=B,e[47]=Z):Z=e[47];let Q;return e[48]!==Z||e[49]!==L||e[50]!==R||e[51]!==z?(Q=(0,y.jsxs)(y.Fragment,{children:[L,R,z,Z]}),e[48]=Z,e[49]=L,e[50]=R,e[51]=z,e[52]=Q):Q=e[52],Q}export{b as component};
|
||||
@@ -1 +1 @@
|
||||
import{n as e,o as t,r as n}from"./compiler-runtime.js";import{t as r}from"./useSuspenseQuery.js";import{ni as i}from"./awsClient.js";import{Ut as a}from"./auth.js";import{t as o}from"./back-link.js";import{t as s}from"./trash-2.js";import{t as c}from"./button.js";import{P as l}from"./ec2.js";import{Qt as u,Xr as d,Yt as f,g as p}from"./index.js";import{t as m}from"./error-banner.js";import{t as h}from"./page-heading.js";import{t as g}from"./delete-confirmation-dialog.js";import{n as _,t as v}from"./detail-row.js";import{t as y}from"./state-badge.js";var b=t(n()),x=e();function S(){let{id:e}=p.useParams(),t=d(),{data:n}=r(u(e)),{data:S}=r(f),C=n.Vpcs?.[0],w=l(),[T,E]=(0,b.useState)(!1),D=S.Subnets?.filter(t=>t.VpcId===e)??[],O=async()=>{try{await w.mutateAsync(e),t({to:`/ec2/describe-vpcs`})}finally{E(!1)}};if(!C?.VpcId)return(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(o,{to:`/ec2/describe-vpcs`,children:`Back to VPCs`}),(0,x.jsx)(`p`,{className:`text-muted-foreground`,children:`VPC not found.`})]});let k=a(C.Tags);return(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(o,{to:`/ec2/describe-vpcs`,children:`Back to VPCs`}),w.error&&(0,x.jsx)(m,{error:w.error,msg:`Failed to delete VPC`}),(0,x.jsxs)(`div`,{className:`space-y-6`,children:[(0,x.jsx)(h,{actions:(0,x.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,x.jsxs)(c,{onClick:()=>E(!0),size:`sm`,variant:`destructive`,children:[(0,x.jsx)(s,{className:`size-4`}),`Delete`]}),(0,x.jsx)(y,{state:C.State})]}),subtitle:`VPC Details`,title:k?`${C.VpcId} (${k})`:C.VpcId}),(0,x.jsxs)(_,{children:[(0,x.jsx)(_.Header,{children:`VPC Information`}),(0,x.jsxs)(_.Content,{children:[(0,x.jsx)(v,{label:`VPC ID`,value:C.VpcId}),(0,x.jsx)(v,{label:`State`,value:C.State}),(0,x.jsx)(v,{label:`CIDR Block`,value:C.CidrBlock}),(0,x.jsx)(v,{label:`Is Default`,value:C.IsDefault?`Yes`:`No`}),(0,x.jsx)(v,{label:`DHCP Options ID`,value:C.DhcpOptionsId}),(0,x.jsx)(v,{label:`Instance Tenancy`,value:C.InstanceTenancy}),(0,x.jsx)(v,{label:`Owner ID`,value:C.OwnerId})]})]}),D.length>0&&(0,x.jsxs)(_,{children:[(0,x.jsxs)(_.Header,{children:[`Subnets (`,D.length,`)`]}),D.map(e=>e.SubnetId?(0,x.jsxs)(_.Content,{children:[(0,x.jsx)(v,{label:`Subnet ID`,value:(0,x.jsx)(i,{className:`text-primary hover:underline`,params:{id:e.SubnetId},to:`/ec2/describe-subnets/$id`,children:e.SubnetId})}),(0,x.jsx)(v,{label:`CIDR Block`,value:e.CidrBlock}),(0,x.jsx)(v,{label:`Availability Zone`,value:e.AvailabilityZone}),(0,x.jsx)(v,{label:`State`,value:e.State})]},e.SubnetId):null)]})]}),(0,x.jsx)(g,{description:`Are you sure you want to delete the VPC "${C.VpcId}"? This action cannot be undone. The VPC must have no associated subnets or internet gateways.`,isPending:w.isPending,onConfirm:O,onOpenChange:E,open:T,title:`Delete VPC`})]})}export{S as component};
|
||||
import{n as e,o as t,r as n}from"./compiler-runtime.js";import{t as r}from"./useSuspenseQuery.js";import{ni as i}from"./awsClient.js";import{Ut as a}from"./auth.js";import{t as o}from"./back-link.js";import{t as s}from"./trash-2.js";import{t as c}from"./button.js";import{P as l}from"./ec2.js";import{Qr as u,Zt as d,en as f,v as p}from"./index.js";import{t as m}from"./error-banner.js";import{t as h}from"./page-heading.js";import{t as g}from"./delete-confirmation-dialog.js";import{n as _,t as v}from"./detail-row.js";import{t as y}from"./state-badge.js";var b=t(n()),x=e();function S(){let{id:e}=p.useParams(),t=u(),{data:n}=r(f(e)),{data:S}=r(d),C=n.Vpcs?.[0],w=l(),[T,E]=(0,b.useState)(!1),D=S.Subnets?.filter(t=>t.VpcId===e)??[],O=async()=>{try{await w.mutateAsync(e),t({to:`/ec2/describe-vpcs`})}finally{E(!1)}};if(!C?.VpcId)return(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(o,{to:`/ec2/describe-vpcs`,children:`Back to VPCs`}),(0,x.jsx)(`p`,{className:`text-muted-foreground`,children:`VPC not found.`})]});let k=a(C.Tags);return(0,x.jsxs)(x.Fragment,{children:[(0,x.jsx)(o,{to:`/ec2/describe-vpcs`,children:`Back to VPCs`}),w.error&&(0,x.jsx)(m,{error:w.error,msg:`Failed to delete VPC`}),(0,x.jsxs)(`div`,{className:`space-y-6`,children:[(0,x.jsx)(h,{actions:(0,x.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,x.jsxs)(c,{onClick:()=>E(!0),size:`sm`,variant:`destructive`,children:[(0,x.jsx)(s,{className:`size-4`}),`Delete`]}),(0,x.jsx)(y,{state:C.State})]}),subtitle:`VPC Details`,title:k?`${C.VpcId} (${k})`:C.VpcId}),(0,x.jsxs)(_,{children:[(0,x.jsx)(_.Header,{children:`VPC Information`}),(0,x.jsxs)(_.Content,{children:[(0,x.jsx)(v,{label:`VPC ID`,value:C.VpcId}),(0,x.jsx)(v,{label:`State`,value:C.State}),(0,x.jsx)(v,{label:`CIDR Block`,value:C.CidrBlock}),(0,x.jsx)(v,{label:`Is Default`,value:C.IsDefault?`Yes`:`No`}),(0,x.jsx)(v,{label:`DHCP Options ID`,value:C.DhcpOptionsId}),(0,x.jsx)(v,{label:`Instance Tenancy`,value:C.InstanceTenancy}),(0,x.jsx)(v,{label:`Owner ID`,value:C.OwnerId})]})]}),D.length>0&&(0,x.jsxs)(_,{children:[(0,x.jsxs)(_.Header,{children:[`Subnets (`,D.length,`)`]}),D.map(e=>e.SubnetId?(0,x.jsxs)(_.Content,{children:[(0,x.jsx)(v,{label:`Subnet ID`,value:(0,x.jsx)(i,{className:`text-primary hover:underline`,params:{id:e.SubnetId},to:`/ec2/describe-subnets/$id`,children:e.SubnetId})}),(0,x.jsx)(v,{label:`CIDR Block`,value:e.CidrBlock}),(0,x.jsx)(v,{label:`Availability Zone`,value:e.AvailabilityZone}),(0,x.jsx)(v,{label:`State`,value:e.State})]},e.SubnetId):null)]})]}),(0,x.jsx)(g,{description:`Are you sure you want to delete the VPC "${C.VpcId}"? This action cannot be undone. The VPC must have no associated subnets or internet gateways.`,isPending:w.isPending,onConfirm:O,onOpenChange:E,open:T,title:`Delete VPC`})]})}export{S as component};
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{t as r}from"./back-link.js";import{Ot as i,n as a}from"./index.js";import{t as o}from"./page-heading.js";import{t as s}from"./state-badge.js";import{n as c}from"./system-managed.js";import{t as l}from"./ami-details.js";var u=t(),d=e();function f(){let e=(0,u.c)(14),{id:t}=a.useParams(),f;e[0]===t?f=e[1]:(f=i(t),e[0]=t,e[1]=f);let{data:p}=n(f),m=p?.Images?.[0];if(!m?.ImageId||c(m)){let t;return e[2]===Symbol.for(`react.memo_cache_sentinel`)?(t=(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(r,{to:`/ec2/describe-images`,children:`Back to images`}),(0,d.jsx)(`p`,{className:`text-muted-foreground`,children:`Image not found.`})]}),e[2]=t):t=e[2],t}let h;e[3]===Symbol.for(`react.memo_cache_sentinel`)?(h=(0,d.jsx)(r,{to:`/ec2/describe-images`,children:`Back to images`}),e[3]=h):h=e[3];let g;e[4]===m.State?g=e[5]:(g=(0,d.jsx)(s,{state:m.State}),e[4]=m.State,e[5]=g);let _;e[6]!==m.ImageId||e[7]!==g?(_=(0,d.jsx)(o,{actions:g,subtitle:`Image Details`,title:m.ImageId}),e[6]=m.ImageId,e[7]=g,e[8]=_):_=e[8];let v;e[9]===m?v=e[10]:(v=(0,d.jsx)(l,{image:m,showExtendedDetails:!0}),e[9]=m,e[10]=v);let y;return e[11]!==_||e[12]!==v?(y=(0,d.jsxs)(d.Fragment,{children:[h,(0,d.jsxs)(`div`,{className:`space-y-6`,children:[_,v]})]}),e[11]=_,e[12]=v,e[13]=y):y=e[13],y}export{f as component};
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{t as r}from"./back-link.js";import{At as i,i as a}from"./index.js";import{t as o}from"./page-heading.js";import{t as s}from"./state-badge.js";import{r as c}from"./system-managed.js";import{t as l}from"./ami-details.js";var u=t(),d=e();function f(){let e=(0,u.c)(14),{id:t}=a.useParams(),f;e[0]===t?f=e[1]:(f=i(t),e[0]=t,e[1]=f);let{data:p}=n(f),m=p?.Images?.[0];if(!m?.ImageId||c(m)){let t;return e[2]===Symbol.for(`react.memo_cache_sentinel`)?(t=(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(r,{to:`/ec2/describe-images`,children:`Back to images`}),(0,d.jsx)(`p`,{className:`text-muted-foreground`,children:`Image not found.`})]}),e[2]=t):t=e[2],t}let h;e[3]===Symbol.for(`react.memo_cache_sentinel`)?(h=(0,d.jsx)(r,{to:`/ec2/describe-images`,children:`Back to images`}),e[3]=h):h=e[3];let g;e[4]===m.State?g=e[5]:(g=(0,d.jsx)(s,{state:m.State}),e[4]=m.State,e[5]=g);let _;e[6]!==m.ImageId||e[7]!==g?(_=(0,d.jsx)(o,{actions:g,subtitle:`Image Details`,title:m.ImageId}),e[6]=m.ImageId,e[7]=g,e[8]=_):_=e[8];let v;e[9]===m?v=e[10]:(v=(0,d.jsx)(l,{image:m,showExtendedDetails:!0}),e[9]=m,e[10]=v);let y;return e[11]!==_||e[12]!==v?(y=(0,d.jsxs)(d.Fragment,{children:[h,(0,d.jsxs)(`div`,{className:`space-y-6`,children:[_,v]})]}),e[11]=_,e[12]=v,e[13]=y):y=e[13],y}export{f as component};
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{n as e,o as t,r as n}from"./compiler-runtime.js";import{t as r}from"./useSuspenseQuery.js";import{ni as i}from"./awsClient.js";import{Ut as a}from"./auth.js";import{t as o}from"./back-link.js";import{c as s,i as c,n as l,s as u,t as d}from"./select.js";import{t as f}from"./trash-2.js";import{t as p}from"./button.js";import{F as m,a as h,w as g}from"./ec2.js";import{$t as _,Nt as v,Xr as y,i as b}from"./index.js";import{t as x}from"./error-banner.js";import{t as S}from"./page-heading.js";import{t as C}from"./delete-confirmation-dialog.js";import{n as w,t as T}from"./detail-row.js";var E=t(n()),D=e();function O(){let{id:e}=b.useParams(),t=y(),{data:n}=r(v(e)),{data:O}=r(_),k=h(),A=m(),j=g(),[M,N]=(0,E.useState)(!1),[P,F]=(0,E.useState)(``),I=n.InternetGateways?.[0],L=O.Vpcs??[],R=async()=>{try{await j.mutateAsync(e),t({to:`/ec2/describe-internet-gateways`})}finally{N(!1)}},z=async()=>{P&&await k.mutateAsync({internetGatewayId:e,vpcId:P})},B=async t=>{await A.mutateAsync({internetGatewayId:e,vpcId:t})};if(!I?.InternetGatewayId)return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(o,{to:`/ec2/describe-internet-gateways`,children:`Back to Internet Gateways`}),(0,D.jsx)(`p`,{className:`text-muted-foreground`,children:`Internet Gateway not found.`})]});let V=I.Attachments?.[0],H=!!V?.VpcId,U=a(I.Tags);return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(o,{to:`/ec2/describe-internet-gateways`,children:`Back to Internet Gateways`}),(j.error??k.error??A.error)&&(0,D.jsx)(x,{error:j.error??k.error??A.error??void 0,msg:`Internet Gateway action failed`}),(0,D.jsxs)(`div`,{className:`space-y-6`,children:[(0,D.jsx)(S,{actions:(0,D.jsxs)(p,{disabled:H||j.isPending,onClick:()=>N(!0),size:`sm`,variant:`destructive`,children:[(0,D.jsx)(f,{className:`size-4`}),`Delete`]}),subtitle:`Internet Gateway Details`,title:U?`${I.InternetGatewayId} (${U})`:I.InternetGatewayId}),(0,D.jsxs)(w,{children:[(0,D.jsx)(w.Header,{children:`Internet Gateway Information`}),(0,D.jsxs)(w.Content,{children:[(0,D.jsx)(T,{label:`Internet Gateway ID`,value:I.InternetGatewayId}),(0,D.jsx)(T,{label:`Owner ID`,value:I.OwnerId??`—`}),(0,D.jsx)(T,{label:`State`,value:V?.State??`detached`})]})]}),(0,D.jsxs)(w,{children:[(0,D.jsx)(w.Header,{children:`VPC Attachment`}),(0,D.jsx)(w.Content,{children:H?(0,D.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,D.jsx)(i,{className:`text-primary hover:underline`,params:{id:V.VpcId??``},to:`/ec2/describe-vpcs/$id`,children:V.VpcId}),(0,D.jsx)(p,{disabled:A.isPending,onClick:async()=>await B(V.VpcId??``),size:`sm`,variant:`outline`,children:`Detach`})]}):(0,D.jsxs)(`div`,{className:`flex items-end gap-2`,children:[(0,D.jsx)(`div`,{className:`flex-1`,children:(0,D.jsxs)(d,{onValueChange:e=>F(e??``),value:P,children:[(0,D.jsx)(u,{className:`w-full`,children:(0,D.jsx)(s,{placeholder:`Select a VPC`})}),(0,D.jsx)(l,{children:L.map(e=>{let t=a(e.Tags);return(0,D.jsx)(c,{value:e.VpcId??``,children:t?`${e.VpcId} (${t})`:`${e.VpcId} (${e.CidrBlock})`},e.VpcId)})})]})}),(0,D.jsx)(p,{disabled:!P||k.isPending,onClick:z,size:`sm`,children:`Attach`})]})})]})]}),(0,D.jsx)(C,{description:`Are you sure you want to delete the Internet Gateway "${I.InternetGatewayId}"? This action cannot be undone.`,isPending:j.isPending,onConfirm:R,onOpenChange:N,open:M,title:`Delete Internet Gateway`})]})}export{O as component};
|
||||
import{n as e,o as t,r as n}from"./compiler-runtime.js";import{t as r}from"./useSuspenseQuery.js";import{ni as i}from"./awsClient.js";import{Ut as a}from"./auth.js";import{t as o}from"./back-link.js";import{c as s,i as c,n as l,s as u,t as d}from"./select.js";import{t as f}from"./trash-2.js";import{t as p}from"./button.js";import{F as m,a as h,w as g}from"./ec2.js";import{Ft as _,Qr as v,o as y,tn as b}from"./index.js";import{t as x}from"./error-banner.js";import{t as S}from"./page-heading.js";import{t as C}from"./delete-confirmation-dialog.js";import{n as w,t as T}from"./detail-row.js";var E=t(n()),D=e();function O(){let{id:e}=y.useParams(),t=v(),{data:n}=r(_(e)),{data:O}=r(b),k=h(),A=m(),j=g(),[M,N]=(0,E.useState)(!1),[P,F]=(0,E.useState)(``),I=n.InternetGateways?.[0],L=O.Vpcs??[],R=async()=>{try{await j.mutateAsync(e),t({to:`/ec2/describe-internet-gateways`})}finally{N(!1)}},z=async()=>{P&&await k.mutateAsync({internetGatewayId:e,vpcId:P})},B=async t=>{await A.mutateAsync({internetGatewayId:e,vpcId:t})};if(!I?.InternetGatewayId)return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(o,{to:`/ec2/describe-internet-gateways`,children:`Back to Internet Gateways`}),(0,D.jsx)(`p`,{className:`text-muted-foreground`,children:`Internet Gateway not found.`})]});let V=I.Attachments?.[0],H=!!V?.VpcId,U=a(I.Tags);return(0,D.jsxs)(D.Fragment,{children:[(0,D.jsx)(o,{to:`/ec2/describe-internet-gateways`,children:`Back to Internet Gateways`}),(j.error??k.error??A.error)&&(0,D.jsx)(x,{error:j.error??k.error??A.error??void 0,msg:`Internet Gateway action failed`}),(0,D.jsxs)(`div`,{className:`space-y-6`,children:[(0,D.jsx)(S,{actions:(0,D.jsxs)(p,{disabled:H||j.isPending,onClick:()=>N(!0),size:`sm`,variant:`destructive`,children:[(0,D.jsx)(f,{className:`size-4`}),`Delete`]}),subtitle:`Internet Gateway Details`,title:U?`${I.InternetGatewayId} (${U})`:I.InternetGatewayId}),(0,D.jsxs)(w,{children:[(0,D.jsx)(w.Header,{children:`Internet Gateway Information`}),(0,D.jsxs)(w.Content,{children:[(0,D.jsx)(T,{label:`Internet Gateway ID`,value:I.InternetGatewayId}),(0,D.jsx)(T,{label:`Owner ID`,value:I.OwnerId??`—`}),(0,D.jsx)(T,{label:`State`,value:V?.State??`detached`})]})]}),(0,D.jsxs)(w,{children:[(0,D.jsx)(w.Header,{children:`VPC Attachment`}),(0,D.jsx)(w.Content,{children:H?(0,D.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,D.jsx)(i,{className:`text-primary hover:underline`,params:{id:V.VpcId??``},to:`/ec2/describe-vpcs/$id`,children:V.VpcId}),(0,D.jsx)(p,{disabled:A.isPending,onClick:async()=>await B(V.VpcId??``),size:`sm`,variant:`outline`,children:`Detach`})]}):(0,D.jsxs)(`div`,{className:`flex items-end gap-2`,children:[(0,D.jsx)(`div`,{className:`flex-1`,children:(0,D.jsxs)(d,{onValueChange:e=>F(e??``),value:P,children:[(0,D.jsx)(u,{className:`w-full`,children:(0,D.jsx)(s,{placeholder:`Select a VPC`})}),(0,D.jsx)(l,{children:L.map(e=>{let t=a(e.Tags);return(0,D.jsx)(c,{value:e.VpcId??``,children:t?`${e.VpcId} (${t})`:`${e.VpcId} (${e.CidrBlock})`},e.VpcId)})})]})}),(0,D.jsx)(p,{disabled:!P||k.isPending,onClick:z,size:`sm`,children:`Attach`})]})})]})]}),(0,D.jsx)(C,{description:`Are you sure you want to delete the Internet Gateway "${I.InternetGatewayId}"? This action cannot be undone.`,isPending:j.isPending,onConfirm:R,onOpenChange:N,open:M,title:`Delete Internet Gateway`})]})}export{O as component};
|
||||
@@ -1 +1 @@
|
||||
import{n as e,o as t,r as n}from"./compiler-runtime.js";import{t as r}from"./useSuspenseQuery.js";import{Bt as i}from"./auth.js";import{t as a}from"./back-link.js";import{t as o}from"./trash-2.js";import{t as s}from"./button.js";import{T as c}from"./ec2.js";import{Ft as l,Xr as u,a as d}from"./index.js";import{t as f}from"./error-banner.js";import{t as p}from"./page-heading.js";import{t as m}from"./delete-confirmation-dialog.js";import{n as h,t as g}from"./detail-row.js";var _=t(n()),v=e();function y(){let{id:e}=d.useParams(),t=u(),{data:n}=r(l(e)),y=n.KeyPairs?.[0],b=c(),[x,S]=(0,_.useState)(!1),C=async()=>{try{await b.mutateAsync(e),t({to:`/ec2/describe-key-pairs`})}finally{S(!1)}};if(!y?.KeyPairId)return(0,v.jsxs)(v.Fragment,{children:[(0,v.jsx)(a,{to:`/ec2/describe-key-pairs`,children:`Back to key pairs`}),(0,v.jsx)(`p`,{className:`text-muted-foreground`,children:`Key pair not found.`})]});let w=i(y.CreateTime);return(0,v.jsxs)(v.Fragment,{children:[(0,v.jsx)(a,{to:`/ec2/describe-key-pairs`,children:`Back to key pairs`}),b.error&&(0,v.jsx)(f,{error:b.error,msg:`Failed to delete key pair`}),(0,v.jsxs)(`div`,{className:`space-y-6`,children:[(0,v.jsx)(p,{actions:(0,v.jsxs)(s,{onClick:()=>S(!0),size:`sm`,variant:`destructive`,children:[(0,v.jsx)(o,{className:`size-4`}),`Delete`]}),subtitle:`Key Pair Details`,title:y.KeyName??``}),(0,v.jsxs)(h,{children:[(0,v.jsx)(h.Header,{children:`Key Pair Information`}),(0,v.jsxs)(h.Content,{children:[(0,v.jsx)(g,{label:`Key Pair ID`,value:y.KeyPairId}),(0,v.jsx)(g,{label:`Key Name`,value:y.KeyName}),(0,v.jsx)(g,{label:`Key Type`,value:y.KeyType}),(0,v.jsx)(g,{label:`Key Fingerprint`,value:y.KeyFingerprint}),(0,v.jsx)(g,{label:`Creation Date`,value:w})]})]}),y.Tags&&y.Tags.length>0&&(0,v.jsxs)(h,{children:[(0,v.jsx)(h.Header,{children:`Tags`}),(0,v.jsx)(h.Content,{children:y.Tags.map(e=>(0,v.jsx)(g,{label:e.Key??``,value:e.Value},e.Key))})]})]}),(0,v.jsx)(m,{description:`Are you sure you want to delete the key pair "${y.KeyName}"? This action cannot be undone. Any instances using this key pair will no longer be able to be accessed with it.`,isPending:b.isPending,onConfirm:C,onOpenChange:S,open:x,title:`Delete Key Pair`})]})}export{y as component};
|
||||
import{n as e,o as t,r as n}from"./compiler-runtime.js";import{t as r}from"./useSuspenseQuery.js";import{Bt as i}from"./auth.js";import{t as a}from"./back-link.js";import{t as o}from"./trash-2.js";import{t as s}from"./button.js";import{T as c}from"./ec2.js";import{Lt as l,Qr as u,s as d}from"./index.js";import{t as f}from"./error-banner.js";import{t as p}from"./page-heading.js";import{t as m}from"./delete-confirmation-dialog.js";import{n as h,t as g}from"./detail-row.js";var _=t(n()),v=e();function y(){let{id:e}=d.useParams(),t=u(),{data:n}=r(l(e)),y=n.KeyPairs?.[0],b=c(),[x,S]=(0,_.useState)(!1),C=async()=>{try{await b.mutateAsync(e),t({to:`/ec2/describe-key-pairs`})}finally{S(!1)}};if(!y?.KeyPairId)return(0,v.jsxs)(v.Fragment,{children:[(0,v.jsx)(a,{to:`/ec2/describe-key-pairs`,children:`Back to key pairs`}),(0,v.jsx)(`p`,{className:`text-muted-foreground`,children:`Key pair not found.`})]});let w=i(y.CreateTime);return(0,v.jsxs)(v.Fragment,{children:[(0,v.jsx)(a,{to:`/ec2/describe-key-pairs`,children:`Back to key pairs`}),b.error&&(0,v.jsx)(f,{error:b.error,msg:`Failed to delete key pair`}),(0,v.jsxs)(`div`,{className:`space-y-6`,children:[(0,v.jsx)(p,{actions:(0,v.jsxs)(s,{onClick:()=>S(!0),size:`sm`,variant:`destructive`,children:[(0,v.jsx)(o,{className:`size-4`}),`Delete`]}),subtitle:`Key Pair Details`,title:y.KeyName??``}),(0,v.jsxs)(h,{children:[(0,v.jsx)(h.Header,{children:`Key Pair Information`}),(0,v.jsxs)(h.Content,{children:[(0,v.jsx)(g,{label:`Key Pair ID`,value:y.KeyPairId}),(0,v.jsx)(g,{label:`Key Name`,value:y.KeyName}),(0,v.jsx)(g,{label:`Key Type`,value:y.KeyType}),(0,v.jsx)(g,{label:`Key Fingerprint`,value:y.KeyFingerprint}),(0,v.jsx)(g,{label:`Creation Date`,value:w})]})]}),y.Tags&&y.Tags.length>0&&(0,v.jsxs)(h,{children:[(0,v.jsx)(h.Header,{children:`Tags`}),(0,v.jsx)(h.Content,{children:y.Tags.map(e=>(0,v.jsx)(g,{label:e.Key??``,value:e.Value},e.Key))})]})]}),(0,v.jsx)(m,{description:`Are you sure you want to delete the key pair "${y.KeyName}"? This action cannot be undone. Any instances using this key pair will no longer be able to be accessed with it.`,isPending:b.isPending,onConfirm:C,onOpenChange:S,open:x,title:`Delete Key Pair`})]})}export{y as component};
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{n as e,o as t,r as n}from"./compiler-runtime.js";import{t as r}from"./useSuspenseQuery.js";import{ni as i}from"./awsClient.js";import{Ut as a}from"./auth.js";import{t as o}from"./back-link.js";import{t as s}from"./trash-2.js";import{t as c}from"./button.js";import{E as l}from"./ec2.js";import{Lt as u,Xr as d,s as f}from"./index.js";import{t as p}from"./error-banner.js";import{t as m}from"./page-heading.js";import{t as h}from"./delete-confirmation-dialog.js";import{n as g,t as _}from"./detail-row.js";import{t as v}from"./state-badge.js";var y=t(n()),b=e();function x(){let{id:e}=f.useParams(),t=d(),{data:n}=r(u(e)),x=l(),[S,C]=(0,y.useState)(!1),w=n.NatGateways?.[0],T=async()=>{try{await x.mutateAsync(e),t({to:`/ec2/describe-nat-gateways`})}finally{C(!1)}};if(!w?.NatGatewayId)return(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(o,{to:`/ec2/describe-nat-gateways`,children:`Back to NAT Gateways`}),(0,b.jsx)(`p`,{className:`text-muted-foreground`,children:`NAT Gateway not found.`})]});let E=a(w.Tags),D=w.NatGatewayAddresses?.[0];return(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(o,{to:`/ec2/describe-nat-gateways`,children:`Back to NAT Gateways`}),x.error&&(0,b.jsx)(p,{error:x.error,msg:`Failed to delete NAT Gateway`}),(0,b.jsxs)(`div`,{className:`space-y-6`,children:[(0,b.jsx)(m,{actions:(0,b.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,b.jsxs)(c,{disabled:x.isPending,onClick:()=>C(!0),size:`sm`,variant:`destructive`,children:[(0,b.jsx)(s,{className:`size-4`}),`Delete`]}),(0,b.jsx)(v,{state:w.State})]}),subtitle:`NAT Gateway Details`,title:E?`${w.NatGatewayId} (${E})`:w.NatGatewayId}),(0,b.jsxs)(g,{children:[(0,b.jsx)(g.Header,{children:`NAT Gateway Information`}),(0,b.jsxs)(g.Content,{children:[(0,b.jsx)(_,{label:`NAT Gateway ID`,value:w.NatGatewayId}),(0,b.jsx)(_,{label:`State`,value:w.State}),(0,b.jsx)(_,{label:`Connectivity`,value:w.ConnectivityType}),(0,b.jsx)(_,{label:`Subnet ID`,value:w.SubnetId?(0,b.jsx)(i,{className:`text-primary hover:underline`,params:{id:w.SubnetId},to:`/ec2/describe-subnets/$id`,children:w.SubnetId}):`—`}),(0,b.jsx)(_,{label:`VPC ID`,value:w.VpcId?(0,b.jsx)(i,{className:`text-primary hover:underline`,params:{id:w.VpcId},to:`/ec2/describe-vpcs/$id`,children:w.VpcId}):`—`}),(0,b.jsx)(_,{label:`Public IP`,value:D?.PublicIp??`—`}),(0,b.jsx)(_,{label:`Allocation ID`,value:D?.AllocationId?(0,b.jsx)(i,{className:`text-primary hover:underline`,params:{id:D.AllocationId},to:`/ec2/describe-addresses/$id`,children:D.AllocationId}):`—`})]})]})]}),(0,b.jsx)(h,{description:`Are you sure you want to delete the NAT Gateway "${w.NatGatewayId}"? This action cannot be undone. The associated Elastic IP is not released.`,isPending:x.isPending,onConfirm:T,onOpenChange:C,open:S,title:`Delete NAT Gateway`})]})}export{x as component};
|
||||
import{n as e,o as t,r as n}from"./compiler-runtime.js";import{t as r}from"./useSuspenseQuery.js";import{ni as i}from"./awsClient.js";import{Ut as a}from"./auth.js";import{t as o}from"./back-link.js";import{t as s}from"./trash-2.js";import{t as c}from"./button.js";import{E as l}from"./ec2.js";import{Qr as u,l as d,zt as f}from"./index.js";import{t as p}from"./error-banner.js";import{t as m}from"./page-heading.js";import{t as h}from"./delete-confirmation-dialog.js";import{n as g,t as _}from"./detail-row.js";import{t as v}from"./state-badge.js";var y=t(n()),b=e();function x(){let{id:e}=d.useParams(),t=u(),{data:n}=r(f(e)),x=l(),[S,C]=(0,y.useState)(!1),w=n.NatGateways?.[0],T=async()=>{try{await x.mutateAsync(e),t({to:`/ec2/describe-nat-gateways`})}finally{C(!1)}};if(!w?.NatGatewayId)return(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(o,{to:`/ec2/describe-nat-gateways`,children:`Back to NAT Gateways`}),(0,b.jsx)(`p`,{className:`text-muted-foreground`,children:`NAT Gateway not found.`})]});let E=a(w.Tags),D=w.NatGatewayAddresses?.[0];return(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(o,{to:`/ec2/describe-nat-gateways`,children:`Back to NAT Gateways`}),x.error&&(0,b.jsx)(p,{error:x.error,msg:`Failed to delete NAT Gateway`}),(0,b.jsxs)(`div`,{className:`space-y-6`,children:[(0,b.jsx)(m,{actions:(0,b.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,b.jsxs)(c,{disabled:x.isPending,onClick:()=>C(!0),size:`sm`,variant:`destructive`,children:[(0,b.jsx)(s,{className:`size-4`}),`Delete`]}),(0,b.jsx)(v,{state:w.State})]}),subtitle:`NAT Gateway Details`,title:E?`${w.NatGatewayId} (${E})`:w.NatGatewayId}),(0,b.jsxs)(g,{children:[(0,b.jsx)(g.Header,{children:`NAT Gateway Information`}),(0,b.jsxs)(g.Content,{children:[(0,b.jsx)(_,{label:`NAT Gateway ID`,value:w.NatGatewayId}),(0,b.jsx)(_,{label:`State`,value:w.State}),(0,b.jsx)(_,{label:`Connectivity`,value:w.ConnectivityType}),(0,b.jsx)(_,{label:`Subnet ID`,value:w.SubnetId?(0,b.jsx)(i,{className:`text-primary hover:underline`,params:{id:w.SubnetId},to:`/ec2/describe-subnets/$id`,children:w.SubnetId}):`—`}),(0,b.jsx)(_,{label:`VPC ID`,value:w.VpcId?(0,b.jsx)(i,{className:`text-primary hover:underline`,params:{id:w.VpcId},to:`/ec2/describe-vpcs/$id`,children:w.VpcId}):`—`}),(0,b.jsx)(_,{label:`Public IP`,value:D?.PublicIp??`—`}),(0,b.jsx)(_,{label:`Allocation ID`,value:D?.AllocationId?(0,b.jsx)(i,{className:`text-primary hover:underline`,params:{id:D.AllocationId},to:`/ec2/describe-addresses/$id`,children:D.AllocationId}):`—`})]})]})]}),(0,b.jsx)(h,{description:`Are you sure you want to delete the NAT Gateway "${w.NatGatewayId}"? This action cannot be undone. The associated Elastic IP is not released.`,isPending:x.isPending,onConfirm:T,onOpenChange:C,open:S,title:`Delete NAT Gateway`})]})}export{x as component};
|
||||
@@ -1 +1 @@
|
||||
import{n as e,o as t,r as n}from"./compiler-runtime.js";import{t as r}from"./useSuspenseQuery.js";import{ni as i}from"./awsClient.js";import{t as a}from"./back-link.js";import{t as o}from"./trash-2.js";import{t as s}from"./button.js";import{D as c}from"./ec2.js";import{Mt as l,Xr as u,c as d,zt as f}from"./index.js";import{t as p}from"./error-banner.js";import{t as m}from"./page-heading.js";import{t as h}from"./delete-confirmation-dialog.js";import{n as g,t as _}from"./detail-row.js";import{t as v}from"./state-badge.js";var y=t(n()),b=e();function x(){let{id:e}=d.useParams(),t=u(),{data:n}=r(f(e)),{data:x}=r(l),S=c(),[C,w]=(0,y.useState)(!1),T=n.PlacementGroups?.[0],E=x.Reservations?.flatMap(e=>e.Instances??[]).filter(e=>e.Placement?.GroupName===T?.GroupName)??[];return T?.GroupId?(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(a,{to:`/ec2/describe-placement-groups`,children:`Back to placement groups`}),S.error&&(0,b.jsx)(p,{error:S.error,msg:`Failed to delete placement group`}),(0,b.jsxs)(`div`,{className:`space-y-6`,children:[(0,b.jsx)(m,{actions:(0,b.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,b.jsxs)(s,{onClick:()=>w(!0),size:`sm`,variant:`destructive`,children:[(0,b.jsx)(o,{className:`size-4`}),`Delete`]}),(0,b.jsx)(v,{state:T.State})]}),subtitle:`Placement Group Details`,title:T.GroupName??T.GroupId}),(0,b.jsxs)(g,{children:[(0,b.jsx)(g.Header,{children:`Placement Group Information`}),(0,b.jsxs)(g.Content,{children:[(0,b.jsx)(_,{label:`Group ID`,value:T.GroupId}),(0,b.jsx)(_,{label:`Group Name`,value:T.GroupName}),(0,b.jsx)(_,{label:`Strategy`,value:T.Strategy}),(0,b.jsx)(_,{label:`State`,value:T.State}),(0,b.jsx)(_,{label:`Spread Level`,value:T.SpreadLevel})]})]}),(0,b.jsxs)(g,{children:[(0,b.jsx)(g.Header,{children:`Instances`}),E.length>0?E.map(e=>(0,b.jsxs)(g.Content,{children:[(0,b.jsx)(_,{label:`Instance ID`,value:e.InstanceId?(0,b.jsx)(i,{className:`text-primary hover:underline`,params:{id:e.InstanceId},to:`/ec2/describe-instances/$id`,children:e.InstanceId}):void 0}),(0,b.jsx)(_,{label:`State`,value:e.State?.Name}),(0,b.jsx)(_,{label:`Instance Type`,value:e.InstanceType}),(0,b.jsx)(_,{label:`Availability Zone`,value:e.Placement?.AvailabilityZone})]},e.InstanceId)):(0,b.jsx)(g.Content,{children:(0,b.jsx)(`p`,{className:`text-muted-foreground`,children:`No instances in this placement group.`})})]})]}),(0,b.jsx)(h,{description:`Are you sure you want to delete the placement group "${T.GroupName}"? The group must have no running instances.`,isPending:S.isPending,onConfirm:async()=>{if(T?.GroupName)try{await S.mutateAsync(T.GroupName),t({to:`/ec2/describe-placement-groups`})}finally{w(!1)}},onOpenChange:w,open:C,title:`Delete Placement Group`})]}):(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(a,{to:`/ec2/describe-placement-groups`,children:`Back to placement groups`}),(0,b.jsx)(`p`,{className:`text-muted-foreground`,children:`Placement group not found.`})]})}export{x as component};
|
||||
import{n as e,o as t,r as n}from"./compiler-runtime.js";import{t as r}from"./useSuspenseQuery.js";import{ni as i}from"./awsClient.js";import{t as a}from"./back-link.js";import{t as o}from"./trash-2.js";import{t as s}from"./button.js";import{D as c}from"./ec2.js";import{Pt as l,Qr as u,Vt as d,u as f}from"./index.js";import{t as p}from"./error-banner.js";import{t as m}from"./page-heading.js";import{t as h}from"./delete-confirmation-dialog.js";import{n as g,t as _}from"./detail-row.js";import{t as v}from"./state-badge.js";var y=t(n()),b=e();function x(){let{id:e}=f.useParams(),t=u(),{data:n}=r(d(e)),{data:x}=r(l),S=c(),[C,w]=(0,y.useState)(!1),T=n.PlacementGroups?.[0],E=x.Reservations?.flatMap(e=>e.Instances??[]).filter(e=>e.Placement?.GroupName===T?.GroupName)??[];return T?.GroupId?(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(a,{to:`/ec2/describe-placement-groups`,children:`Back to placement groups`}),S.error&&(0,b.jsx)(p,{error:S.error,msg:`Failed to delete placement group`}),(0,b.jsxs)(`div`,{className:`space-y-6`,children:[(0,b.jsx)(m,{actions:(0,b.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,b.jsxs)(s,{onClick:()=>w(!0),size:`sm`,variant:`destructive`,children:[(0,b.jsx)(o,{className:`size-4`}),`Delete`]}),(0,b.jsx)(v,{state:T.State})]}),subtitle:`Placement Group Details`,title:T.GroupName??T.GroupId}),(0,b.jsxs)(g,{children:[(0,b.jsx)(g.Header,{children:`Placement Group Information`}),(0,b.jsxs)(g.Content,{children:[(0,b.jsx)(_,{label:`Group ID`,value:T.GroupId}),(0,b.jsx)(_,{label:`Group Name`,value:T.GroupName}),(0,b.jsx)(_,{label:`Strategy`,value:T.Strategy}),(0,b.jsx)(_,{label:`State`,value:T.State}),(0,b.jsx)(_,{label:`Spread Level`,value:T.SpreadLevel})]})]}),(0,b.jsxs)(g,{children:[(0,b.jsx)(g.Header,{children:`Instances`}),E.length>0?E.map(e=>(0,b.jsxs)(g.Content,{children:[(0,b.jsx)(_,{label:`Instance ID`,value:e.InstanceId?(0,b.jsx)(i,{className:`text-primary hover:underline`,params:{id:e.InstanceId},to:`/ec2/describe-instances/$id`,children:e.InstanceId}):void 0}),(0,b.jsx)(_,{label:`State`,value:e.State?.Name}),(0,b.jsx)(_,{label:`Instance Type`,value:e.InstanceType}),(0,b.jsx)(_,{label:`Availability Zone`,value:e.Placement?.AvailabilityZone})]},e.InstanceId)):(0,b.jsx)(g.Content,{children:(0,b.jsx)(`p`,{className:`text-muted-foreground`,children:`No instances in this placement group.`})})]})]}),(0,b.jsx)(h,{description:`Are you sure you want to delete the placement group "${T.GroupName}"? The group must have no running instances.`,isPending:S.isPending,onConfirm:async()=>{if(T?.GroupName)try{await S.mutateAsync(T.GroupName),t({to:`/ec2/describe-placement-groups`})}finally{w(!1)}},onOpenChange:w,open:C,title:`Delete Placement Group`})]}):(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(a,{to:`/ec2/describe-placement-groups`,children:`Back to placement groups`}),(0,b.jsx)(`p`,{className:`text-muted-foreground`,children:`Placement group not found.`})]})}export{x as component};
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{n as e,o as t,r as n}from"./compiler-runtime.js";import{t as r}from"./useSuspenseQuery.js";import{ni as i}from"./awsClient.js";import{Bt as a}from"./auth.js";import{t as o}from"./back-link.js";import{t as s}from"./trash-2.js";import{t as c}from"./button.js";import{g as l,t as u,u as d}from"./iam.js";import{Xr as f,b as p,ft as m,yt as h}from"./index.js";import{t as g}from"./error-banner.js";import{t as _}from"./page-heading.js";import{t as v}from"./delete-confirmation-dialog.js";import{n as y,t as b}from"./detail-row.js";var x=t(n()),S=e();function C(){let{instanceProfileName:e}=p.useParams(),t=f(),{data:n}=r(m(e)),{data:C}=r(h),w=d(),T=u(),E=l(),[D,O]=(0,x.useState)(!1),[k,A]=(0,x.useState)(!1),[j,M]=(0,x.useState)(null),N=n.InstanceProfile,P=N?.Roles??[],F=C.Roles??[],I=new Set(P.map(e=>e.RoleName)),L=F.filter(e=>e.RoleName&&!I.has(e.RoleName)),R=async()=>{try{await w.mutateAsync(e),t({to:`/iam/list-instance-profiles`})}finally{O(!1)}},z=async t=>{await T.mutateAsync({instanceProfileName:e,roleName:t}),A(!1)},B=async t=>{M(t);try{await E.mutateAsync({instanceProfileName:e,roleName:t})}finally{M(null)}};return N?(0,S.jsxs)(S.Fragment,{children:[(0,S.jsx)(o,{to:`/iam/list-instance-profiles`,children:`Back to instance profiles`}),w.error&&(0,S.jsx)(g,{error:w.error,msg:`Failed to delete instance profile`}),T.error&&(0,S.jsx)(g,{error:T.error,msg:`Failed to add role`}),E.error&&(0,S.jsx)(g,{error:E.error,msg:`Failed to remove role`}),(0,S.jsxs)(`div`,{className:`space-y-6`,children:[(0,S.jsx)(_,{actions:(0,S.jsxs)(c,{onClick:()=>O(!0),size:`sm`,variant:`destructive`,children:[(0,S.jsx)(s,{className:`size-4`}),`Delete`]}),subtitle:`Instance Profile Details`,title:N.InstanceProfileName??``}),(0,S.jsxs)(y,{children:[(0,S.jsx)(y.Header,{children:`Instance Profile Information`}),(0,S.jsxs)(y.Content,{children:[(0,S.jsx)(b,{label:`Name`,value:N.InstanceProfileName}),(0,S.jsx)(b,{label:`ID`,value:N.InstanceProfileId}),(0,S.jsx)(b,{label:`ARN`,value:N.Arn}),(0,S.jsx)(b,{label:`Path`,value:N.Path}),(0,S.jsx)(b,{label:`Created`,value:a(N.CreateDate)})]})]}),(0,S.jsxs)(y,{children:[(0,S.jsx)(y.Header,{children:(0,S.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,S.jsx)(`span`,{children:`Roles`}),(0,S.jsx)(c,{onClick:()=>A(!k),size:`sm`,children:`Add Role`})]})}),(0,S.jsxs)(y.Content,{children:[k&&L.length>0&&(0,S.jsxs)(`div`,{className:`col-span-2 space-y-2 rounded-md border p-3`,children:[(0,S.jsx)(`p`,{className:`text-sm font-medium`,children:`Select a role to add:`}),(0,S.jsx)(`div`,{className:`space-y-1`,children:L.map(e=>(0,S.jsxs)(`button`,{className:`flex w-full items-center justify-between rounded-md p-2 text-left text-sm hover:bg-accent`,disabled:T.isPending,onClick:()=>{e.RoleName&&z(e.RoleName)},type:`button`,children:[(0,S.jsx)(`span`,{children:e.RoleName}),(0,S.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:e.Arn})]},e.RoleName))})]}),k&&L.length===0&&(0,S.jsx)(`p`,{className:`col-span-2 text-sm text-muted-foreground`,children:`No roles available to add.`}),P.length>0?(0,S.jsx)(`div`,{className:`col-span-2 space-y-3`,children:P.map(e=>(0,S.jsxs)(`div`,{className:`flex items-center justify-between rounded-md border p-3`,children:[(0,S.jsx)(i,{className:`text-sm font-medium text-primary hover:underline`,params:{roleName:e.RoleName??``},to:`/iam/list-roles/$roleName`,children:e.RoleName}),(0,S.jsx)(c,{disabled:j===e.RoleName,onClick:()=>{e.RoleName&&B(e.RoleName)},size:`sm`,variant:`outline`,children:`Remove`})]},e.RoleName))}):(0,S.jsx)(`p`,{className:`col-span-2 text-sm text-muted-foreground`,children:`No roles in this instance profile.`})]})]})]}),(0,S.jsx)(v,{description:`Are you sure you want to delete the instance profile "${e}"? This action cannot be undone. You must remove all roles first.`,isPending:w.isPending,onConfirm:R,onOpenChange:O,open:D,title:`Delete Instance Profile`})]}):(0,S.jsxs)(S.Fragment,{children:[(0,S.jsx)(o,{to:`/iam/list-instance-profiles`,children:`Back to instance profiles`}),(0,S.jsx)(`p`,{className:`text-muted-foreground`,children:`Instance profile not found.`})]})}export{C as component};
|
||||
import{n as e,o as t,r as n}from"./compiler-runtime.js";import{t as r}from"./useSuspenseQuery.js";import{ni as i}from"./awsClient.js";import{Bt as a}from"./auth.js";import{t as o}from"./back-link.js";import{t as s}from"./trash-2.js";import{t as c}from"./button.js";import{g as l,t as u,u as d}from"./iam.js";import{Qr as f,S as p,mt as m,xt as h}from"./index.js";import{t as g}from"./error-banner.js";import{t as _}from"./page-heading.js";import{t as v}from"./delete-confirmation-dialog.js";import{n as y,t as b}from"./detail-row.js";var x=t(n()),S=e();function C(){let{instanceProfileName:e}=p.useParams(),t=f(),{data:n}=r(m(e)),{data:C}=r(h),w=d(),T=u(),E=l(),[D,O]=(0,x.useState)(!1),[k,A]=(0,x.useState)(!1),[j,M]=(0,x.useState)(null),N=n.InstanceProfile,P=N?.Roles??[],F=C.Roles??[],I=new Set(P.map(e=>e.RoleName)),L=F.filter(e=>e.RoleName&&!I.has(e.RoleName)),R=async()=>{try{await w.mutateAsync(e),t({to:`/iam/list-instance-profiles`})}finally{O(!1)}},z=async t=>{await T.mutateAsync({instanceProfileName:e,roleName:t}),A(!1)},B=async t=>{M(t);try{await E.mutateAsync({instanceProfileName:e,roleName:t})}finally{M(null)}};return N?(0,S.jsxs)(S.Fragment,{children:[(0,S.jsx)(o,{to:`/iam/list-instance-profiles`,children:`Back to instance profiles`}),w.error&&(0,S.jsx)(g,{error:w.error,msg:`Failed to delete instance profile`}),T.error&&(0,S.jsx)(g,{error:T.error,msg:`Failed to add role`}),E.error&&(0,S.jsx)(g,{error:E.error,msg:`Failed to remove role`}),(0,S.jsxs)(`div`,{className:`space-y-6`,children:[(0,S.jsx)(_,{actions:(0,S.jsxs)(c,{onClick:()=>O(!0),size:`sm`,variant:`destructive`,children:[(0,S.jsx)(s,{className:`size-4`}),`Delete`]}),subtitle:`Instance Profile Details`,title:N.InstanceProfileName??``}),(0,S.jsxs)(y,{children:[(0,S.jsx)(y.Header,{children:`Instance Profile Information`}),(0,S.jsxs)(y.Content,{children:[(0,S.jsx)(b,{label:`Name`,value:N.InstanceProfileName}),(0,S.jsx)(b,{label:`ID`,value:N.InstanceProfileId}),(0,S.jsx)(b,{label:`ARN`,value:N.Arn}),(0,S.jsx)(b,{label:`Path`,value:N.Path}),(0,S.jsx)(b,{label:`Created`,value:a(N.CreateDate)})]})]}),(0,S.jsxs)(y,{children:[(0,S.jsx)(y.Header,{children:(0,S.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,S.jsx)(`span`,{children:`Roles`}),(0,S.jsx)(c,{onClick:()=>A(!k),size:`sm`,children:`Add Role`})]})}),(0,S.jsxs)(y.Content,{children:[k&&L.length>0&&(0,S.jsxs)(`div`,{className:`col-span-2 space-y-2 rounded-md border p-3`,children:[(0,S.jsx)(`p`,{className:`text-sm font-medium`,children:`Select a role to add:`}),(0,S.jsx)(`div`,{className:`space-y-1`,children:L.map(e=>(0,S.jsxs)(`button`,{className:`flex w-full items-center justify-between rounded-md p-2 text-left text-sm hover:bg-accent`,disabled:T.isPending,onClick:()=>{e.RoleName&&z(e.RoleName)},type:`button`,children:[(0,S.jsx)(`span`,{children:e.RoleName}),(0,S.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:e.Arn})]},e.RoleName))})]}),k&&L.length===0&&(0,S.jsx)(`p`,{className:`col-span-2 text-sm text-muted-foreground`,children:`No roles available to add.`}),P.length>0?(0,S.jsx)(`div`,{className:`col-span-2 space-y-3`,children:P.map(e=>(0,S.jsxs)(`div`,{className:`flex items-center justify-between rounded-md border p-3`,children:[(0,S.jsx)(i,{className:`text-sm font-medium text-primary hover:underline`,params:{roleName:e.RoleName??``},to:`/iam/list-roles/$roleName`,children:e.RoleName}),(0,S.jsx)(c,{disabled:j===e.RoleName,onClick:()=>{e.RoleName&&B(e.RoleName)},size:`sm`,variant:`outline`,children:`Remove`})]},e.RoleName))}):(0,S.jsx)(`p`,{className:`col-span-2 text-sm text-muted-foreground`,children:`No roles in this instance profile.`})]})]})]}),(0,S.jsx)(v,{description:`Are you sure you want to delete the instance profile "${e}"? This action cannot be undone. You must remove all roles first.`,isPending:w.isPending,onConfirm:R,onOpenChange:O,open:D,title:`Delete Instance Profile`})]}):(0,S.jsxs)(S.Fragment,{children:[(0,S.jsx)(o,{to:`/iam/list-instance-profiles`,children:`Back to instance profiles`}),(0,S.jsx)(`p`,{className:`text-muted-foreground`,children:`Instance profile not found.`})]})}export{C as component};
|
||||
@@ -1 +1 @@
|
||||
import{n as e,o as t,r as n}from"./compiler-runtime.js";import{t as r}from"./useSuspenseQuery.js";import{Bt as i}from"./auth.js";import{t as a}from"./back-link.js";import{t as o}from"./trash-2.js";import{t as s}from"./button.js";import{d as c}from"./iam.js";import{Xr as l,_t as u,gt as d,x as f}from"./index.js";import{t as p}from"./error-banner.js";import{t as m}from"./page-heading.js";import{t as h}from"./delete-confirmation-dialog.js";import{n as g,t as _}from"./detail-row.js";import{t as v}from"./policy-document-viewer.js";var y=t(n()),b=e();function x(){let{policyArn:e}=f.useParams(),t=decodeURIComponent(e),n=l(),{data:x}=r(d(t)),S=x.Policy,C=c(),[w,T]=(0,y.useState)(!1),{data:E}=r(u(t,S?.DefaultVersionId??`v1`)),D=E?.PolicyVersion?.Document?decodeURIComponent(E.PolicyVersion.Document):null;return S?(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(a,{to:`/iam/list-policies`,children:`Back to policies`}),C.error&&(0,b.jsx)(p,{error:C.error,msg:`Failed to delete policy`}),(0,b.jsxs)(`div`,{className:`space-y-6`,children:[(0,b.jsx)(m,{actions:(0,b.jsxs)(s,{onClick:()=>T(!0),size:`sm`,variant:`destructive`,children:[(0,b.jsx)(o,{className:`size-4`}),`Delete`]}),subtitle:`Policy Details`,title:S.PolicyName??``}),(0,b.jsxs)(g,{children:[(0,b.jsx)(g.Header,{children:`Policy Information`}),(0,b.jsxs)(g.Content,{children:[(0,b.jsx)(_,{label:`Policy Name`,value:S.PolicyName}),(0,b.jsx)(_,{label:`Policy ID`,value:S.PolicyId}),(0,b.jsx)(_,{label:`ARN`,value:S.Arn}),(0,b.jsx)(_,{label:`Path`,value:S.Path}),(0,b.jsx)(_,{label:`Description`,value:S.Description??`-`}),(0,b.jsx)(_,{label:`Created`,value:i(S.CreateDate)})]})]}),D&&(0,b.jsxs)(g,{children:[(0,b.jsx)(g.Header,{children:`Policy Document`}),(0,b.jsx)(`div`,{className:`p-4`,children:(0,b.jsx)(v,{document:D})})]})]}),(0,b.jsx)(h,{description:`Are you sure you want to delete the policy "${S.PolicyName}"? This action cannot be undone.`,isPending:C.isPending,onConfirm:async()=>{try{await C.mutateAsync(t),n({to:`/iam/list-policies`})}finally{T(!1)}},onOpenChange:T,open:w,title:`Delete Policy`})]}):(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(a,{to:`/iam/list-policies`,children:`Back to policies`}),(0,b.jsx)(`p`,{className:`text-muted-foreground`,children:`Policy not found.`})]})}export{x as component};
|
||||
import{n as e,o as t,r as n}from"./compiler-runtime.js";import{t as r}from"./useSuspenseQuery.js";import{Bt as i}from"./auth.js";import{t as a}from"./back-link.js";import{t as o}from"./trash-2.js";import{t as s}from"./button.js";import{d as c}from"./iam.js";import{C as l,Qr as u,vt as d,yt as f}from"./index.js";import{t as p}from"./error-banner.js";import{t as m}from"./page-heading.js";import{t as h}from"./delete-confirmation-dialog.js";import{n as g,t as _}from"./detail-row.js";import{t as v}from"./policy-document-viewer.js";var y=t(n()),b=e();function x(){let{policyArn:e}=l.useParams(),t=decodeURIComponent(e),n=u(),{data:x}=r(d(t)),S=x.Policy,C=c(),[w,T]=(0,y.useState)(!1),{data:E}=r(f(t,S?.DefaultVersionId??`v1`)),D=E?.PolicyVersion?.Document?decodeURIComponent(E.PolicyVersion.Document):null;return S?(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(a,{to:`/iam/list-policies`,children:`Back to policies`}),C.error&&(0,b.jsx)(p,{error:C.error,msg:`Failed to delete policy`}),(0,b.jsxs)(`div`,{className:`space-y-6`,children:[(0,b.jsx)(m,{actions:(0,b.jsxs)(s,{onClick:()=>T(!0),size:`sm`,variant:`destructive`,children:[(0,b.jsx)(o,{className:`size-4`}),`Delete`]}),subtitle:`Policy Details`,title:S.PolicyName??``}),(0,b.jsxs)(g,{children:[(0,b.jsx)(g.Header,{children:`Policy Information`}),(0,b.jsxs)(g.Content,{children:[(0,b.jsx)(_,{label:`Policy Name`,value:S.PolicyName}),(0,b.jsx)(_,{label:`Policy ID`,value:S.PolicyId}),(0,b.jsx)(_,{label:`ARN`,value:S.Arn}),(0,b.jsx)(_,{label:`Path`,value:S.Path}),(0,b.jsx)(_,{label:`Description`,value:S.Description??`-`}),(0,b.jsx)(_,{label:`Created`,value:i(S.CreateDate)})]})]}),D&&(0,b.jsxs)(g,{children:[(0,b.jsx)(g.Header,{children:`Policy Document`}),(0,b.jsx)(`div`,{className:`p-4`,children:(0,b.jsx)(v,{document:D})})]})]}),(0,b.jsx)(h,{description:`Are you sure you want to delete the policy "${S.PolicyName}"? This action cannot be undone.`,isPending:C.isPending,onConfirm:async()=>{try{await C.mutateAsync(t),n({to:`/iam/list-policies`})}finally{T(!1)}},onOpenChange:T,open:w,title:`Delete Policy`})]}):(0,b.jsxs)(b.Fragment,{children:[(0,b.jsx)(a,{to:`/iam/list-policies`,children:`Back to policies`}),(0,b.jsx)(`p`,{className:`text-muted-foreground`,children:`Policy not found.`})]})}export{x as component};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{t as e}from"./queryOptions.js";import{r as t}from"./auth.js";import{rn as n}from"./index.js";var r=e({queryKey:[`admin`,`nodes`],queryFn:async()=>{let e=t();if(!e)throw Error(`Not authenticated`);return await n({action:`GetNodes`,credentials:e})},staleTime:1e4}),i=e({queryKey:[`admin`,`vms`],queryFn:async()=>{let e=t();if(!e)throw Error(`Not authenticated`);return await n({action:`GetVMs`,credentials:e})},staleTime:1e4}),a=e({queryKey:[`admin`,`storageStatus`],queryFn:async()=>{let e=t();if(!e)throw Error(`Not authenticated`);return await n({action:`GetStorageStatus`,credentials:e})},staleTime:1e4});export{a as n,i as r,r as t};
|
||||
import{t as e}from"./queryOptions.js";import{r as t}from"./auth.js";import{an as n}from"./index.js";var r=e({queryKey:[`admin`,`nodes`],queryFn:async()=>{let e=t();if(!e)throw Error(`Not authenticated`);return await n({action:`GetNodes`,credentials:e})},staleTime:1e4}),i=e({queryKey:[`admin`,`vms`],queryFn:async()=>{let e=t();if(!e)throw Error(`Not authenticated`);return await n({action:`GetVMs`,credentials:e})},staleTime:1e4}),a=e({queryKey:[`admin`,`storageStatus`],queryFn:async()=>{let e=t();if(!e)throw Error(`Not authenticated`);return await n({action:`GetStorageStatus`,credentials:e})},staleTime:1e4});export{a as n,i as r,r as t};
|
||||
File diff suppressed because one or more lines are too long
@@ -1,3 +1,3 @@
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./back-link.js";import{t as r}from"./cli-command-panel.js";import{t as i}from"./ec2.js";import{Xr as a,er as o}from"./index.js";import{a as s,i as c,t as l}from"./zod.js";import{t as u}from"./error-banner.js";import{t as d}from"./form-actions.js";import{t as f}from"./page-heading.js";import{a as p,t as m}from"./field.js";import{n as h}from"./ec22.js";var g=t(),_=e();function v(){let e=(0,g.c)(36),t=a(),v=i(),b;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(b={resolver:l(h),defaultValues:{name:``}},e[0]=b):b=e[0];let{control:x,handleSubmit:S,register:C,formState:w}=c(b),{isSubmitting:T}=w,E;e[1]===x?E=e[2]:(E={control:x},e[1]=x,e[2]=E);let D=s(E),O;e[3]!==v||e[4]!==t?(O=async e=>{let n=(await v.mutateAsync({name:e.name?.trim()??void 0})).AllocationId;t(n?{to:`/ec2/describe-addresses/$id`,params:{id:n}}:{to:`/ec2/describe-addresses`})},e[3]=v,e[4]=t,e[5]=O):O=e[5];let k=O,A,j;e[6]===Symbol.for(`react.memo_cache_sentinel`)?(A=(0,_.jsx)(n,{to:`/ec2/describe-addresses`,children:`Back to Elastic IPs`}),j=(0,_.jsx)(f,{title:`Allocate Elastic IP`}),e[6]=A,e[7]=j):(A=e[6],j=e[7]);let M;e[8]===v.error?M=e[9]:(M=v.error&&(0,_.jsx)(u,{error:v.error,msg:`Failed to allocate Elastic IP`}),e[8]=v.error,e[9]=M);let N;e[10]!==S||e[11]!==k?(N=S(k),e[10]=S,e[11]=k,e[12]=N):N=e[12];let P;e[13]===Symbol.for(`react.memo_cache_sentinel`)?(P=(0,_.jsx)(p,{children:(0,_.jsx)(`label`,{htmlFor:`name`,children:`Name (optional)`})}),e[13]=P):P=e[13];let F;e[14]===C?F=e[15]:(F=C(`name`),e[14]=C,e[15]=F);let I;e[16]===F?I=e[17]:(I=(0,_.jsxs)(m,{children:[P,(0,_.jsx)(o,{id:`name`,placeholder:`my-elastic-ip`,...F})]}),e[16]=F,e[17]=I);let L=D.name??``,R;e[18]===L?R=e[19]:(R=y(L),e[18]=L,e[19]=R);let z;e[20]===R?z=e[21]:(z=(0,_.jsx)(r,{commands:R}),e[20]=R,e[21]=z);let B;e[22]===t?B=e[23]:(B=async()=>await t({to:`/ec2/describe-addresses`}),e[22]=t,e[23]=B);let V;e[24]!==v.isPending||e[25]!==T||e[26]!==B?(V=(0,_.jsx)(d,{isPending:v.isPending,isSubmitting:T,onCancel:B,pendingLabel:`Allocating…`,submitLabel:`Allocate`}),e[24]=v.isPending,e[25]=T,e[26]=B,e[27]=V):V=e[27];let H;e[28]!==I||e[29]!==z||e[30]!==V||e[31]!==N?(H=(0,_.jsxs)(`form`,{className:`max-w-4xl space-y-6`,onSubmit:N,children:[I,z,V]}),e[28]=I,e[29]=z,e[30]=V,e[31]=N,e[32]=H):H=e[32];let U;return e[33]!==H||e[34]!==M?(U=(0,_.jsxs)(_.Fragment,{children:[A,j,M,H]}),e[33]=H,e[34]=M,e[35]=U):U=e[35],U}function y(e){let t=[{type:`bin`,value:`AWS_PROFILE=spinifex aws ec2 allocate-address`},{type:`flag`,value:` \\
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./back-link.js";import{t as r}from"./cli-command-panel.js";import{t as i}from"./ec2.js";import{Qr as a,nr as o}from"./index.js";import{a as s,i as c,t as l}from"./zod.js";import{t as u}from"./error-banner.js";import{t as d}from"./form-actions.js";import{t as f}from"./page-heading.js";import{a as p,t as m}from"./field.js";import{n as h}from"./ec22.js";var g=t(),_=e();function v(){let e=(0,g.c)(36),t=a(),v=i(),b;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(b={resolver:l(h),defaultValues:{name:``}},e[0]=b):b=e[0];let{control:x,handleSubmit:S,register:C,formState:w}=c(b),{isSubmitting:T}=w,E;e[1]===x?E=e[2]:(E={control:x},e[1]=x,e[2]=E);let D=s(E),O;e[3]!==v||e[4]!==t?(O=async e=>{let n=(await v.mutateAsync({name:e.name?.trim()??void 0})).AllocationId;t(n?{to:`/ec2/describe-addresses/$id`,params:{id:n}}:{to:`/ec2/describe-addresses`})},e[3]=v,e[4]=t,e[5]=O):O=e[5];let k=O,A,j;e[6]===Symbol.for(`react.memo_cache_sentinel`)?(A=(0,_.jsx)(n,{to:`/ec2/describe-addresses`,children:`Back to Elastic IPs`}),j=(0,_.jsx)(f,{title:`Allocate Elastic IP`}),e[6]=A,e[7]=j):(A=e[6],j=e[7]);let M;e[8]===v.error?M=e[9]:(M=v.error&&(0,_.jsx)(u,{error:v.error,msg:`Failed to allocate Elastic IP`}),e[8]=v.error,e[9]=M);let N;e[10]!==S||e[11]!==k?(N=S(k),e[10]=S,e[11]=k,e[12]=N):N=e[12];let P;e[13]===Symbol.for(`react.memo_cache_sentinel`)?(P=(0,_.jsx)(p,{children:(0,_.jsx)(`label`,{htmlFor:`name`,children:`Name (optional)`})}),e[13]=P):P=e[13];let F;e[14]===C?F=e[15]:(F=C(`name`),e[14]=C,e[15]=F);let I;e[16]===F?I=e[17]:(I=(0,_.jsxs)(m,{children:[P,(0,_.jsx)(o,{id:`name`,placeholder:`my-elastic-ip`,...F})]}),e[16]=F,e[17]=I);let L=D.name??``,R;e[18]===L?R=e[19]:(R=y(L),e[18]=L,e[19]=R);let z;e[20]===R?z=e[21]:(z=(0,_.jsx)(r,{commands:R}),e[20]=R,e[21]=z);let B;e[22]===t?B=e[23]:(B=async()=>await t({to:`/ec2/describe-addresses`}),e[22]=t,e[23]=B);let V;e[24]!==v.isPending||e[25]!==T||e[26]!==B?(V=(0,_.jsx)(d,{isPending:v.isPending,isSubmitting:T,onCancel:B,pendingLabel:`Allocating…`,submitLabel:`Allocate`}),e[24]=v.isPending,e[25]=T,e[26]=B,e[27]=V):V=e[27];let H;e[28]!==I||e[29]!==z||e[30]!==V||e[31]!==N?(H=(0,_.jsxs)(`form`,{className:`max-w-4xl space-y-6`,onSubmit:N,children:[I,z,V]}),e[28]=I,e[29]=z,e[30]=V,e[31]=N,e[32]=H):H=e[32];let U;return e[33]!==H||e[34]!==M?(U=(0,_.jsxs)(_.Fragment,{children:[A,j,M,H]}),e[33]=H,e[34]=M,e[35]=U):U=e[35],U}function y(e){let t=[{type:`bin`,value:`AWS_PROFILE=spinifex aws ec2 allocate-address`},{type:`flag`,value:` \\
|
||||
--domain`},{type:`value`,value:` vpc`}];return e.trim()&&t.push({type:`flag`,value:` \\
|
||||
--tag-specifications`},{type:`value`,value:` 'ResourceType=elastic-ip,Tags=[{Key=Name,Value=${e.trim()}}]'`}),[{label:`Allocate Elastic IP`,parts:t}]}export{v as component};
|
||||
@@ -1 +1 @@
|
||||
import{n as e,t}from"./compiler-runtime.js";import{ni as n}from"./awsClient.js";import{qr as r}from"./index.js";var i=r(`arrow-left`,[[`path`,{d:`m12 19-7-7 7-7`,key:`1l729n`}],[`path`,{d:`M19 12H5`,key:`x3x0zl`}]]),a=t(),o=e();function s(e){let t=(0,a.c)(7),r,s;t[0]===e?(r=t[1],s=t[2]):({children:r,...s}=e,t[0]=e,t[1]=r,t[2]=s);let c;t[3]===Symbol.for(`react.memo_cache_sentinel`)?(c=(0,o.jsx)(i,{className:`size-4`}),t[3]=c):c=t[3];let l;return t[4]!==r||t[5]!==s?(l=(0,o.jsxs)(n,{className:`mb-6 inline-flex items-center gap-2 text-sm`,...s,children:[c,r]}),t[4]=r,t[5]=s,t[6]=l):l=t[6],l}export{s as t};
|
||||
import{n as e,t}from"./compiler-runtime.js";import{ni as n}from"./awsClient.js";import{Yr as r}from"./index.js";var i=r(`arrow-left`,[[`path`,{d:`m12 19-7-7 7-7`,key:`1l729n`}],[`path`,{d:`M19 12H5`,key:`x3x0zl`}]]),a=t(),o=e();function s(e){let t=(0,a.c)(7),r,s;t[0]===e?(r=t[1],s=t[2]):({children:r,...s}=e,t[0]=e,t[1]=r,t[2]=s);let c;t[3]===Symbol.for(`react.memo_cache_sentinel`)?(c=(0,o.jsx)(i,{className:`size-4`}),t[3]=c):c=t[3];let l;return t[4]!==r||t[5]!==s?(l=(0,o.jsxs)(n,{className:`mb-6 inline-flex items-center gap-2 text-sm`,...s,children:[c,r]}),t[4]=r,t[5]=s,t[6]=l):l=t[6],l}export{s as t};
|
||||
@@ -1 +1 @@
|
||||
import{t as e}from"./compiler-runtime.js";import{f as t,t as n}from"./dist.js";import{Lt as r}from"./auth.js";import{Jr as i}from"./index.js";var a=e(),o=n(`group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-full border border-transparent px-2 py-0.5 text-[0.625rem] font-medium whitespace-nowrap transition-all transition-colors focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-2.5!`,{variants:{variant:{default:`bg-primary text-primary-foreground [a]:hover:bg-primary/80`,secondary:`bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80`,destructive:`bg-destructive/10 text-destructive focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:focus-visible:ring-destructive/40 [a]:hover:bg-destructive/20`,outline:`border-border bg-input/20 text-foreground dark:bg-input/30 [a]:hover:bg-muted [a]:hover:text-muted-foreground`,ghost:`hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50`,link:`text-primary underline-offset-4 hover:underline`}},defaultVariants:{variant:`default`}});function s(e){let n=(0,a.c)(13),s,c,l,u,d;if(n[0]!==e){let{className:a,variant:f,render:p,...m}=e;s=p,d=f===void 0?`default`:f,u=i,c=`span`,l=t({className:r(o({className:a,variant:d}))},m),n[0]=e,n[1]=s,n[2]=c,n[3]=l,n[4]=u,n[5]=d}else s=n[1],c=n[2],l=n[3],u=n[4],d=n[5];let f;n[6]===d?f=n[7]:(f={slot:`badge`,variant:d},n[6]=d,n[7]=f);let p;return n[8]!==s||n[9]!==c||n[10]!==l||n[11]!==f?(p={defaultTagName:c,props:l,render:s,state:f},n[8]=s,n[9]=c,n[10]=l,n[11]=f,n[12]=p):p=n[12],u(p)}export{s as t};
|
||||
import{t as e}from"./compiler-runtime.js";import{f as t,t as n}from"./dist.js";import{Lt as r}from"./auth.js";import{Xr as i}from"./index.js";var a=e(),o=n(`group/badge inline-flex h-5 w-fit shrink-0 items-center justify-center gap-1 overflow-hidden rounded-full border border-transparent px-2 py-0.5 text-[0.625rem] font-medium whitespace-nowrap transition-all transition-colors focus-visible:border-ring focus-visible:ring-[3px] focus-visible:ring-ring/50 has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 [&>svg]:pointer-events-none [&>svg]:size-2.5!`,{variants:{variant:{default:`bg-primary text-primary-foreground [a]:hover:bg-primary/80`,secondary:`bg-secondary text-secondary-foreground [a]:hover:bg-secondary/80`,destructive:`bg-destructive/10 text-destructive focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:focus-visible:ring-destructive/40 [a]:hover:bg-destructive/20`,outline:`border-border bg-input/20 text-foreground dark:bg-input/30 [a]:hover:bg-muted [a]:hover:text-muted-foreground`,ghost:`hover:bg-muted hover:text-muted-foreground dark:hover:bg-muted/50`,link:`text-primary underline-offset-4 hover:underline`}},defaultVariants:{variant:`default`}});function s(e){let n=(0,a.c)(13),s,c,l,u,d;if(n[0]!==e){let{className:a,variant:f,render:p,...m}=e;s=p,d=f===void 0?`default`:f,u=i,c=`span`,l=t({className:r(o({className:a,variant:d}))},m),n[0]=e,n[1]=s,n[2]=c,n[3]=l,n[4]=u,n[5]=d}else s=n[1],c=n[2],l=n[3],u=n[4],d=n[5];let f;n[6]===d?f=n[7]:(f={slot:`badge`,variant:d},n[6]=d,n[7]=f);let p;return n[8]!==s||n[9]!==c||n[10]!==l||n[11]!==f?(p={defaultTagName:c,props:l,render:s,state:f},n[8]=s,n[9]=c,n[10]=l,n[11]=f,n[12]=p):p=n[12],u(p)}export{s as t};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{n as e,o as t,r as n,t as r}from"./compiler-runtime.js";import{t as i}from"./useMutation.js";import{$r as a,n as o,ti as s}from"./awsClient.js";import{St as c,ut as l}from"./auth.js";import{Zr as u}from"./index.js";import{t as d}from"./error-banner.js";import{a as f,t as p}from"./field.js";import{a as m,i as ee,l as te,n as h,o as g,r as _,s as v,t as y}from"./alert-dialog.js";import{t as b}from"./textarea.js";var x=class extends c.classBuilder().ep(s).m(function(e,t,n,r){return[l(n,e.getEndpointParameterInstructions())]}).s(`CertificateManager`,`ImportCertificate`,{}).n(`ACMClient`,`ImportCertificateCommand`).sc(a).build(){},S=t(n(),1),C=r(),w=new TextEncoder;function T(){let e=(0,C.c)(2),t=u(),n;return e[0]===t?n=e[1]:(n={mutationFn:E,onSuccess:()=>{t.invalidateQueries({queryKey:[`acm`,`certificates`]})}},e[0]=t,e[1]=n),i(n)}async function E(e){let t=new x({Certificate:w.encode(e.certificate),PrivateKey:w.encode(e.privateKey),CertificateChain:e.certificateChain&&e.certificateChain.length>0?w.encode(e.certificateChain):void 0});return await o().send(t)}var D=e();function O(e){let t=(0,C.c)(54),{open:n,onOpenChange:r,onImported:i}=e,[a,o]=(0,S.useState)(``),[s,c]=(0,S.useState)(``),[l,u]=(0,S.useState)(``),x=T(),w;t[0]===x?w=t[1]:(w=()=>{o(``),c(``),u(``),x.reset()},t[0]=x,t[1]=w);let E=w,O;t[2]!==r||t[3]!==E?(O=e=>{e||E(),r(e)},t[2]=r,t[3]=E,t[4]=O):O=t[4];let k=O,A;t[5]!==a||t[6]!==s?(A=a.trim().length>0&&s.trim().length>0,t[5]=a,t[6]=s,t[7]=A):A=t[7];let j=A,M;t[8]!==j||t[9]!==a||t[10]!==l||t[11]!==x||t[12]!==i||t[13]!==r||t[14]!==s||t[15]!==E?(M=async()=>{if(j)try{let e=await x.mutateAsync({certificate:a,privateKey:s,certificateChain:l});e.CertificateArn&&i(e.CertificateArn),E(),r(!1)}catch{}},t[8]=j,t[9]=a,t[10]=l,t[11]=x,t[12]=i,t[13]=r,t[14]=s,t[15]=E,t[16]=M):M=t[16];let N=M,P;t[17]===Symbol.for(`react.memo_cache_sentinel`)?(P={maxWidth:`36rem`,width:`calc(100vw - 2rem)`},t[17]=P):P=t[17];let F;t[18]===Symbol.for(`react.memo_cache_sentinel`)?(F=(0,D.jsxs)(v,{children:[(0,D.jsx)(te,{children:`Import certificate`}),(0,D.jsx)(m,{children:`Paste a PEM-encoded certificate and its private key. The optional chain is appended for intermediate CAs.`})]}),t[18]=F):F=t[18];let I;t[19]===x.error?I=t[20]:(I=x.error&&(0,D.jsx)(d,{error:x.error,msg:`Failed to import certificate`}),t[19]=x.error,t[20]=I);let L;t[21]===Symbol.for(`react.memo_cache_sentinel`)?(L=(0,D.jsx)(f,{children:(0,D.jsx)(`label`,{htmlFor:`cert-body`,children:`Certificate body`})}),t[21]=L):L=t[21];let R;t[22]===Symbol.for(`react.memo_cache_sentinel`)?(R=e=>o(e.target.value),t[22]=R):R=t[22];let z;t[23]===a?z=t[24]:(z=(0,D.jsxs)(p,{children:[L,(0,D.jsx)(b,{className:`font-mono text-xs`,id:`cert-body`,onChange:R,placeholder:`-----BEGIN CERTIFICATE-----`,rows:5,value:a})]}),t[23]=a,t[24]=z);let B;t[25]===Symbol.for(`react.memo_cache_sentinel`)?(B=(0,D.jsx)(f,{children:(0,D.jsx)(`label`,{htmlFor:`cert-key`,children:`Private key`})}),t[25]=B):B=t[25];let V;t[26]===Symbol.for(`react.memo_cache_sentinel`)?(V=e=>c(e.target.value),t[26]=V):V=t[26];let H;t[27]===s?H=t[28]:(H=(0,D.jsxs)(p,{children:[B,(0,D.jsx)(b,{className:`font-mono text-xs`,id:`cert-key`,onChange:V,placeholder:`-----BEGIN PRIVATE KEY-----`,rows:5,value:s})]}),t[27]=s,t[28]=H);let U;t[29]===Symbol.for(`react.memo_cache_sentinel`)?(U=(0,D.jsx)(f,{children:(0,D.jsx)(`label`,{htmlFor:`cert-chain`,children:`Certificate chain (optional)`})}),t[29]=U):U=t[29];let W;t[30]===Symbol.for(`react.memo_cache_sentinel`)?(W=e=>u(e.target.value),t[30]=W):W=t[30];let G;t[31]===l?G=t[32]:(G=(0,D.jsxs)(p,{children:[U,(0,D.jsx)(b,{className:`font-mono text-xs`,id:`cert-chain`,onChange:W,placeholder:`-----BEGIN CERTIFICATE-----`,rows:4,value:l})]}),t[31]=l,t[32]=G);let K;t[33]!==z||t[34]!==H||t[35]!==G?(K=(0,D.jsxs)(`div`,{className:`min-w-0 space-y-4`,children:[z,H,G]}),t[33]=z,t[34]=H,t[35]=G,t[36]=K):K=t[36];let q;t[37]===x.isPending?q=t[38]:(q=(0,D.jsx)(_,{disabled:x.isPending,children:`Cancel`}),t[37]=x.isPending,t[38]=q);let J=!j||x.isPending,Y=x.isPending?`Importing…`:`Import`,X;t[39]!==N||t[40]!==J||t[41]!==Y?(X=(0,D.jsx)(h,{disabled:J,onClick:N,children:Y}),t[39]=N,t[40]=J,t[41]=Y,t[42]=X):X=t[42];let Z;t[43]!==q||t[44]!==X?(Z=(0,D.jsxs)(g,{children:[q,X]}),t[43]=q,t[44]=X,t[45]=Z):Z=t[45];let Q;t[46]!==K||t[47]!==Z||t[48]!==I?(Q=(0,D.jsxs)(ee,{className:`grid-cols-[minmax(0,1fr)]`,style:P,children:[F,I,K,Z]}),t[46]=K,t[47]=Z,t[48]=I,t[49]=Q):Q=t[49];let $;return t[50]!==k||t[51]!==n||t[52]!==Q?($=(0,D.jsx)(y,{onOpenChange:k,open:n,children:Q}),t[50]=k,t[51]=n,t[52]=Q,t[53]=$):$=t[53],$}export{O as t};
|
||||
import{n as e,o as t,r as n,t as r}from"./compiler-runtime.js";import{t as i}from"./useMutation.js";import{$r as a,n as o,ti as s}from"./awsClient.js";import{St as c,ut as l}from"./auth.js";import{$r as u}from"./index.js";import{t as d}from"./error-banner.js";import{a as f,t as p}from"./field.js";import{a as m,i as ee,l as te,n as h,o as g,r as _,s as v,t as y}from"./alert-dialog.js";import{t as b}from"./textarea.js";var x=class extends c.classBuilder().ep(s).m(function(e,t,n,r){return[l(n,e.getEndpointParameterInstructions())]}).s(`CertificateManager`,`ImportCertificate`,{}).n(`ACMClient`,`ImportCertificateCommand`).sc(a).build(){},S=t(n(),1),C=r(),w=new TextEncoder;function T(){let e=(0,C.c)(2),t=u(),n;return e[0]===t?n=e[1]:(n={mutationFn:E,onSuccess:()=>{t.invalidateQueries({queryKey:[`acm`,`certificates`]})}},e[0]=t,e[1]=n),i(n)}async function E(e){let t=new x({Certificate:w.encode(e.certificate),PrivateKey:w.encode(e.privateKey),CertificateChain:e.certificateChain&&e.certificateChain.length>0?w.encode(e.certificateChain):void 0});return await o().send(t)}var D=e();function O(e){let t=(0,C.c)(54),{open:n,onOpenChange:r,onImported:i}=e,[a,o]=(0,S.useState)(``),[s,c]=(0,S.useState)(``),[l,u]=(0,S.useState)(``),x=T(),w;t[0]===x?w=t[1]:(w=()=>{o(``),c(``),u(``),x.reset()},t[0]=x,t[1]=w);let E=w,O;t[2]!==r||t[3]!==E?(O=e=>{e||E(),r(e)},t[2]=r,t[3]=E,t[4]=O):O=t[4];let k=O,A;t[5]!==a||t[6]!==s?(A=a.trim().length>0&&s.trim().length>0,t[5]=a,t[6]=s,t[7]=A):A=t[7];let j=A,M;t[8]!==j||t[9]!==a||t[10]!==l||t[11]!==x||t[12]!==i||t[13]!==r||t[14]!==s||t[15]!==E?(M=async()=>{if(j)try{let e=await x.mutateAsync({certificate:a,privateKey:s,certificateChain:l});e.CertificateArn&&i(e.CertificateArn),E(),r(!1)}catch{}},t[8]=j,t[9]=a,t[10]=l,t[11]=x,t[12]=i,t[13]=r,t[14]=s,t[15]=E,t[16]=M):M=t[16];let N=M,P;t[17]===Symbol.for(`react.memo_cache_sentinel`)?(P={maxWidth:`36rem`,width:`calc(100vw - 2rem)`},t[17]=P):P=t[17];let F;t[18]===Symbol.for(`react.memo_cache_sentinel`)?(F=(0,D.jsxs)(v,{children:[(0,D.jsx)(te,{children:`Import certificate`}),(0,D.jsx)(m,{children:`Paste a PEM-encoded certificate and its private key. The optional chain is appended for intermediate CAs.`})]}),t[18]=F):F=t[18];let I;t[19]===x.error?I=t[20]:(I=x.error&&(0,D.jsx)(d,{error:x.error,msg:`Failed to import certificate`}),t[19]=x.error,t[20]=I);let L;t[21]===Symbol.for(`react.memo_cache_sentinel`)?(L=(0,D.jsx)(f,{children:(0,D.jsx)(`label`,{htmlFor:`cert-body`,children:`Certificate body`})}),t[21]=L):L=t[21];let R;t[22]===Symbol.for(`react.memo_cache_sentinel`)?(R=e=>o(e.target.value),t[22]=R):R=t[22];let z;t[23]===a?z=t[24]:(z=(0,D.jsxs)(p,{children:[L,(0,D.jsx)(b,{className:`font-mono text-xs`,id:`cert-body`,onChange:R,placeholder:`-----BEGIN CERTIFICATE-----`,rows:5,value:a})]}),t[23]=a,t[24]=z);let B;t[25]===Symbol.for(`react.memo_cache_sentinel`)?(B=(0,D.jsx)(f,{children:(0,D.jsx)(`label`,{htmlFor:`cert-key`,children:`Private key`})}),t[25]=B):B=t[25];let V;t[26]===Symbol.for(`react.memo_cache_sentinel`)?(V=e=>c(e.target.value),t[26]=V):V=t[26];let H;t[27]===s?H=t[28]:(H=(0,D.jsxs)(p,{children:[B,(0,D.jsx)(b,{className:`font-mono text-xs`,id:`cert-key`,onChange:V,placeholder:`-----BEGIN PRIVATE KEY-----`,rows:5,value:s})]}),t[27]=s,t[28]=H);let U;t[29]===Symbol.for(`react.memo_cache_sentinel`)?(U=(0,D.jsx)(f,{children:(0,D.jsx)(`label`,{htmlFor:`cert-chain`,children:`Certificate chain (optional)`})}),t[29]=U):U=t[29];let W;t[30]===Symbol.for(`react.memo_cache_sentinel`)?(W=e=>u(e.target.value),t[30]=W):W=t[30];let G;t[31]===l?G=t[32]:(G=(0,D.jsxs)(p,{children:[U,(0,D.jsx)(b,{className:`font-mono text-xs`,id:`cert-chain`,onChange:W,placeholder:`-----BEGIN CERTIFICATE-----`,rows:4,value:l})]}),t[31]=l,t[32]=G);let K;t[33]!==z||t[34]!==H||t[35]!==G?(K=(0,D.jsxs)(`div`,{className:`min-w-0 space-y-4`,children:[z,H,G]}),t[33]=z,t[34]=H,t[35]=G,t[36]=K):K=t[36];let q;t[37]===x.isPending?q=t[38]:(q=(0,D.jsx)(_,{disabled:x.isPending,children:`Cancel`}),t[37]=x.isPending,t[38]=q);let J=!j||x.isPending,Y=x.isPending?`Importing…`:`Import`,X;t[39]!==N||t[40]!==J||t[41]!==Y?(X=(0,D.jsx)(h,{disabled:J,onClick:N,children:Y}),t[39]=N,t[40]=J,t[41]=Y,t[42]=X):X=t[42];let Z;t[43]!==q||t[44]!==X?(Z=(0,D.jsxs)(g,{children:[q,X]}),t[43]=q,t[44]=X,t[45]=Z):Z=t[45];let Q;t[46]!==K||t[47]!==Z||t[48]!==I?(Q=(0,D.jsxs)(ee,{className:`grid-cols-[minmax(0,1fr)]`,style:P,children:[F,I,K,Z]}),t[46]=K,t[47]=Z,t[48]=I,t[49]=Q):Q=t[49];let $;return t[50]!==k||t[51]!==n||t[52]!==Q?($=(0,D.jsx)(y,{onOpenChange:k,open:n,children:Q}),t[50]=k,t[51]=n,t[52]=Q,t[53]=$):$=t[53],$}export{O as t};
|
||||
@@ -1 +1 @@
|
||||
import{qr as e}from"./index.js";var t=e(`check`,[[`path`,{d:`M20 6 9 17l-5-5`,key:`1gmf2c`}]]);export{t};
|
||||
import{Yr as e}from"./index.js";var t=e(`check`,[[`path`,{d:`M20 6 9 17l-5-5`,key:`1gmf2c`}]]);export{t};
|
||||
@@ -1 +1 @@
|
||||
import{qr as e}from"./index.js";var t=e(`chevron-down`,[[`path`,{d:`m6 9 6 6 6-6`,key:`qrunsl`}]]);export{t};
|
||||
import{Yr as e}from"./index.js";var t=e(`chevron-down`,[[`path`,{d:`m6 9 6 6 6-6`,key:`qrunsl`}]]);export{t};
|
||||
@@ -1 +1 @@
|
||||
import{qr as e}from"./index.js";var t=e(`chevron-right`,[[`path`,{d:`m9 18 6-6-6-6`,key:`mthhwq`}]]);export{t};
|
||||
import{Yr as e}from"./index.js";var t=e(`chevron-right`,[[`path`,{d:`m9 18 6-6-6-6`,key:`mthhwq`}]]);export{t};
|
||||
@@ -1,3 +1,3 @@
|
||||
import{n as e,o as t,r as n,t as r}from"./compiler-runtime.js";import{Lt as i}from"./auth.js";import{t as a}from"./check.js";import{t as o}from"./chevron-down.js";import{t as s}from"./copy.js";import{t as c}from"./button.js";import{qr as l}from"./index.js";import{t as u}from"./use-copy-to-clipboard.js";var d=l(`square-terminal`,[[`path`,{d:`m7 11 2-2-2-2`,key:`1lz0vl`}],[`path`,{d:`M11 13h4`,key:`1p7l4v`}],[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`,ry:`2`,key:`1m3agn`}]]),f=r(),p=t(n(),1),m=e(),h={bin:`text-tactical-cyan font-semibold`,flag:`text-tactical-amber`,value:`text-foreground`,comment:`text-muted-foreground italic`,variable:`text-tactical-green font-semibold`};function g(e){return e.map(e=>e.parts.map(e=>e.value).join(``)).join(`
|
||||
import{n as e,o as t,r as n,t as r}from"./compiler-runtime.js";import{Lt as i}from"./auth.js";import{t as a}from"./check.js";import{t as o}from"./chevron-down.js";import{t as s}from"./copy.js";import{t as c}from"./button.js";import{Yr as l}from"./index.js";import{t as u}from"./use-copy-to-clipboard.js";var d=l(`square-terminal`,[[`path`,{d:`m7 11 2-2-2-2`,key:`1lz0vl`}],[`path`,{d:`M11 13h4`,key:`1p7l4v`}],[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`,ry:`2`,key:`1m3agn`}]]),f=r(),p=t(n(),1),m=e(),h={bin:`text-tactical-cyan font-semibold`,flag:`text-tactical-amber`,value:`text-foreground`,comment:`text-muted-foreground italic`,variable:`text-tactical-green font-semibold`};function g(e){return e.map(e=>e.parts.map(e=>e.value).join(``)).join(`
|
||||
|
||||
`)}function _(e){let t=(0,f.c)(18),{commands:n}=e,[r,l]=(0,p.useState)(!1),{copied:h,copy:_}=u();if(n.length===0)return null;let b;t[0]===Symbol.for(`react.memo_cache_sentinel`)?(b=()=>l(y),t[0]=b):b=t[0];let x,S;t[1]===Symbol.for(`react.memo_cache_sentinel`)?(x=(0,m.jsx)(d,{className:`size-3.5`}),S=(0,m.jsx)(`span`,{children:`AWS CLI`}),t[1]=x,t[2]=S):(x=t[1],S=t[2]);let C=r&&`rotate-180`,w;t[3]===C?w=t[4]:(w=i(`ml-auto size-3.5 transition-transform`,C),t[3]=C,t[4]=w);let T;t[5]===w?T=t[6]:(T=(0,m.jsx)(o,{className:w}),t[5]=w,t[6]=T);let E;t[7]!==r||t[8]!==T?(E=(0,m.jsxs)(`button`,{type:`button`,onClick:b,className:`flex w-full items-center gap-2 px-3 py-2 text-xs font-medium text-muted-foreground transition-colors hover:text-foreground`,"aria-expanded":r,children:[x,S,T]}),t[7]=r,t[8]=T,t[9]=E):E=t[9];let D;t[10]!==n||t[11]!==h||t[12]!==_||t[13]!==r?(D=r&&(0,m.jsxs)(`div`,{className:`border-t border-border`,children:[(0,m.jsxs)(`div`,{className:`flex items-center justify-between border-b border-border px-3 py-1.5`,children:[(0,m.jsx)(`span`,{className:`text-[0.625rem] text-muted-foreground`,children:n.length>1?`${n.length} commands`:`command`}),(0,m.jsxs)(c,{type:`button`,variant:`ghost`,size:`xs`,onClick:async()=>await _(g(n)),children:[h?(0,m.jsx)(a,{className:`size-2.5`}):(0,m.jsx)(s,{className:`size-2.5`}),h?`Copied`:`Copy`]})]}),(0,m.jsx)(`div`,{className:`overflow-x-auto p-3`,children:n.map((e,t)=>(0,m.jsxs)(`div`,{children:[n.length>1&&(0,m.jsx)(`div`,{className:`mb-1 text-[0.625rem] font-medium text-muted-foreground`,children:e.label}),(0,m.jsx)(`pre`,{className:`font-mono text-xs/relaxed`,children:(0,m.jsx)(`code`,{children:e.parts.map(v)})}),t<n.length-1&&(0,m.jsx)(`div`,{className:`my-2`})]},e.label))})]}),t[10]=n,t[11]=h,t[12]=_,t[13]=r,t[14]=D):D=t[14];let O;return t[15]!==E||t[16]!==D?(O=(0,m.jsxs)(`div`,{className:`rounded-md border border-border`,children:[E,D]}),t[15]=E,t[16]=D,t[17]=O):O=t[17],O}function v(e,t){return(0,m.jsx)(`span`,{className:h[e.type],children:e.value},t)}function y(e){return!e}export{_ as t};
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{qr as e}from"./index.js";var t=e(`copy`,[[`rect`,{width:`14`,height:`14`,x:`8`,y:`8`,rx:`2`,ry:`2`,key:`17jyea`}],[`path`,{d:`M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2`,key:`zix9uf`}]]);export{t};
|
||||
import{Yr as e}from"./index.js";var t=e(`copy`,[[`rect`,{width:`14`,height:`14`,x:`8`,y:`8`,rx:`2`,ry:`2`,key:`17jyea`}],[`path`,{d:`M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2`,key:`zix9uf`}]]);export{t};
|
||||
@@ -1 +1 @@
|
||||
import{n as e,t}from"./compiler-runtime.js";import{f as n,u as r}from"./auth.js";import{t as i}from"./back-link.js";import{t as a}from"./cli-command-panel.js";import{t as o}from"./s3.js";import{Xr as s,er as c}from"./index.js";import{a as l,i as u,t as d}from"./zod.js";import{t as f}from"./error-banner.js";import{t as p}from"./form-actions.js";import{t as m}from"./page-heading.js";import{a as h,r as g,t as _}from"./field.js";var v=t(),y=r({bucketName:n().min(3,`Bucket name must be at least 3 characters`).max(63,`Bucket name must be at most 63 characters`).regex(/^[a-z0-9][a-z0-9.-]*[a-z0-9]$/,`Must start and end with a lowercase letter or number`).regex(/^[a-z0-9.-]+$/,`Only lowercase letters, numbers, hyphens, and periods allowed`).refine(e=>!e.includes(`..`),`Must not contain consecutive periods`).refine(e=>!(e.includes(`.-`)||e.includes(`-.`)),`Must not contain adjacent period and hyphen`)}),b=e();function x(){let e=(0,v.c)(44),t=s(),n=o(),r;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(r={resolver:d(y)},e[0]=r):r=e[0];let{handleSubmit:x,register:C,control:w,formState:T}=u(r),{errors:E,isSubmitting:D}=T,O;e[1]===w?O=e[2]:(O={control:w},e[1]=w,e[2]=O);let k=l(O),A;e[3]===k?A=e[4]:(A=e=>e?k[e]:void 0,e[3]=k,e[4]=A);let j=A,M;e[5]!==n||e[6]!==t?(M=async e=>{await n.mutateAsync(e),t({to:`/s3/ls`})},e[5]=n,e[6]=t,e[7]=M):M=e[7];let N=M,P,F;e[8]===Symbol.for(`react.memo_cache_sentinel`)?(P=(0,b.jsx)(i,{to:`/s3/ls`,children:`Back to buckets`}),F=(0,b.jsx)(m,{title:`Create Bucket`}),e[8]=P,e[9]=F):(P=e[8],F=e[9]);let I;e[10]===n.error?I=e[11]:(I=n.error&&(0,b.jsx)(f,{error:n.error,msg:`Failed to create bucket`}),e[10]=n.error,e[11]=I);let L;e[12]!==x||e[13]!==N?(L=x(N),e[12]=x,e[13]=N,e[14]=L):L=e[14];let R;e[15]===Symbol.for(`react.memo_cache_sentinel`)?(R=(0,b.jsx)(h,{children:(0,b.jsx)(`label`,{htmlFor:`bucketName`,children:`Bucket Name`})}),e[15]=R):R=e[15];let z=!!E.bucketName,B;e[16]===C?B=e[17]:(B=C(`bucketName`),e[16]=C,e[17]=B);let V;e[18]!==z||e[19]!==B?(V=(0,b.jsx)(c,{"aria-invalid":z,id:`bucketName`,placeholder:`my-bucket`,type:`text`,...B}),e[18]=z,e[19]=B,e[20]=V):V=e[20];let H;e[21]===E.bucketName?H=e[22]:(H=(0,b.jsx)(g,{errors:[E.bucketName]}),e[21]=E.bucketName,e[22]=H);let U;e[23]!==V||e[24]!==H?(U=(0,b.jsxs)(_,{children:[R,V,H]}),e[23]=V,e[24]=H,e[25]=U):U=e[25];let W;e[26]===j?W=e[27]:(W=S(j),e[26]=j,e[27]=W);let G;e[28]===W?G=e[29]:(G=(0,b.jsx)(a,{commands:W}),e[28]=W,e[29]=G);let K;e[30]===t?K=e[31]:(K=async()=>await t({to:`/s3/ls`}),e[30]=t,e[31]=K);let q;e[32]!==n.isPending||e[33]!==D||e[34]!==K?(q=(0,b.jsx)(p,{isPending:n.isPending,isSubmitting:D,onCancel:K,pendingLabel:`Creating…`,submitLabel:`Create Bucket`}),e[32]=n.isPending,e[33]=D,e[34]=K,e[35]=q):q=e[35];let J;e[36]!==U||e[37]!==G||e[38]!==q||e[39]!==L?(J=(0,b.jsxs)(`form`,{className:`max-w-4xl space-y-6`,onSubmit:L,children:[U,G,q]}),e[36]=U,e[37]=G,e[38]=q,e[39]=L,e[40]=J):J=e[40];let Y;return e[41]!==J||e[42]!==I?(Y=(0,b.jsxs)(b.Fragment,{children:[P,F,I,J]}),e[41]=J,e[42]=I,e[43]=Y):Y=e[43],Y}function S(e){let t=e(`bucketName`);return[{label:`Create Bucket`,parts:[{type:`bin`,value:`AWS_PROFILE=spinifex aws s3api create-bucket`},{type:`flag`,value:` --bucket`},{type:`value`,value:` ${(typeof t==`string`?t:``)||`<BucketName>`}`}]}]}export{x as component};
|
||||
import{n as e,t}from"./compiler-runtime.js";import{f as n,u as r}from"./auth.js";import{t as i}from"./back-link.js";import{t as a}from"./cli-command-panel.js";import{t as o}from"./s3.js";import{Qr as s,nr as c}from"./index.js";import{a as l,i as u,t as d}from"./zod.js";import{t as f}from"./error-banner.js";import{t as p}from"./form-actions.js";import{t as m}from"./page-heading.js";import{a as h,r as g,t as _}from"./field.js";var v=t(),y=r({bucketName:n().min(3,`Bucket name must be at least 3 characters`).max(63,`Bucket name must be at most 63 characters`).regex(/^[a-z0-9][a-z0-9.-]*[a-z0-9]$/,`Must start and end with a lowercase letter or number`).regex(/^[a-z0-9.-]+$/,`Only lowercase letters, numbers, hyphens, and periods allowed`).refine(e=>!e.includes(`..`),`Must not contain consecutive periods`).refine(e=>!(e.includes(`.-`)||e.includes(`-.`)),`Must not contain adjacent period and hyphen`)}),b=e();function x(){let e=(0,v.c)(44),t=s(),n=o(),r;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(r={resolver:d(y)},e[0]=r):r=e[0];let{handleSubmit:x,register:C,control:w,formState:T}=u(r),{errors:E,isSubmitting:D}=T,O;e[1]===w?O=e[2]:(O={control:w},e[1]=w,e[2]=O);let k=l(O),A;e[3]===k?A=e[4]:(A=e=>e?k[e]:void 0,e[3]=k,e[4]=A);let j=A,M;e[5]!==n||e[6]!==t?(M=async e=>{await n.mutateAsync(e),t({to:`/s3/ls`})},e[5]=n,e[6]=t,e[7]=M):M=e[7];let N=M,P,F;e[8]===Symbol.for(`react.memo_cache_sentinel`)?(P=(0,b.jsx)(i,{to:`/s3/ls`,children:`Back to buckets`}),F=(0,b.jsx)(m,{title:`Create Bucket`}),e[8]=P,e[9]=F):(P=e[8],F=e[9]);let I;e[10]===n.error?I=e[11]:(I=n.error&&(0,b.jsx)(f,{error:n.error,msg:`Failed to create bucket`}),e[10]=n.error,e[11]=I);let L;e[12]!==x||e[13]!==N?(L=x(N),e[12]=x,e[13]=N,e[14]=L):L=e[14];let R;e[15]===Symbol.for(`react.memo_cache_sentinel`)?(R=(0,b.jsx)(h,{children:(0,b.jsx)(`label`,{htmlFor:`bucketName`,children:`Bucket Name`})}),e[15]=R):R=e[15];let z=!!E.bucketName,B;e[16]===C?B=e[17]:(B=C(`bucketName`),e[16]=C,e[17]=B);let V;e[18]!==z||e[19]!==B?(V=(0,b.jsx)(c,{"aria-invalid":z,id:`bucketName`,placeholder:`my-bucket`,type:`text`,...B}),e[18]=z,e[19]=B,e[20]=V):V=e[20];let H;e[21]===E.bucketName?H=e[22]:(H=(0,b.jsx)(g,{errors:[E.bucketName]}),e[21]=E.bucketName,e[22]=H);let U;e[23]!==V||e[24]!==H?(U=(0,b.jsxs)(_,{children:[R,V,H]}),e[23]=V,e[24]=H,e[25]=U):U=e[25];let W;e[26]===j?W=e[27]:(W=S(j),e[26]=j,e[27]=W);let G;e[28]===W?G=e[29]:(G=(0,b.jsx)(a,{commands:W}),e[28]=W,e[29]=G);let K;e[30]===t?K=e[31]:(K=async()=>await t({to:`/s3/ls`}),e[30]=t,e[31]=K);let q;e[32]!==n.isPending||e[33]!==D||e[34]!==K?(q=(0,b.jsx)(p,{isPending:n.isPending,isSubmitting:D,onCancel:K,pendingLabel:`Creating…`,submitLabel:`Create Bucket`}),e[32]=n.isPending,e[33]=D,e[34]=K,e[35]=q):q=e[35];let J;e[36]!==U||e[37]!==G||e[38]!==q||e[39]!==L?(J=(0,b.jsxs)(`form`,{className:`max-w-4xl space-y-6`,onSubmit:L,children:[U,G,q]}),e[36]=U,e[37]=G,e[38]=q,e[39]=L,e[40]=J):J=e[40];let Y;return e[41]!==J||e[42]!==I?(Y=(0,b.jsxs)(b.Fragment,{children:[P,F,I,J]}),e[41]=J,e[42]=I,e[43]=Y):Y=e[43],Y}function S(e){let t=e(`bucketName`);return[{label:`Create Bucket`,parts:[{type:`bin`,value:`AWS_PROFILE=spinifex aws s3api create-bucket`},{type:`flag`,value:` --bucket`},{type:`value`,value:` ${(typeof t==`string`?t:``)||`<BucketName>`}`}]}]}export{x as component};
|
||||
File diff suppressed because one or more lines are too long
+1
-1
@@ -1 +1 @@
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./back-link.js";import{t as r}from"./cli-command-panel.js";import{a as i}from"./iam.js";import{Xr as a,er as o}from"./index.js";import{a as s,i as c,t as l}from"./zod.js";import{t as u}from"./error-banner.js";import{t as d}from"./form-actions.js";import{t as f}from"./page-heading.js";import{a as p,r as m,t as h}from"./field.js";import{n as g}from"./iam2.js";var _=t(),v=e();function y(){let e=(0,_.c)(55),t=a(),y=i(),b;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(b={resolver:l(g)},e[0]=b):b=e[0];let{handleSubmit:x,register:S,control:C,formState:w}=c(b),{errors:T,isSubmitting:E}=w,D;e[1]===C?D=e[2]:(D={control:C},e[1]=C,e[2]=D);let O=s(D),k;e[3]===O?k=e[4]:(k=e=>e?O[e]:void 0,e[3]=O,e[4]=k);let A=k,j;e[5]!==y||e[6]!==t?(j=async e=>{await y.mutateAsync(e),t({to:`/iam/list-instance-profiles`})},e[5]=y,e[6]=t,e[7]=j):j=e[7];let M=j,N,P;e[8]===Symbol.for(`react.memo_cache_sentinel`)?(N=(0,v.jsx)(n,{to:`/iam/list-instance-profiles`,children:`Back to instance profiles`}),P=(0,v.jsx)(f,{title:`Create Instance Profile`}),e[8]=N,e[9]=P):(N=e[8],P=e[9]);let F;e[10]===y.error?F=e[11]:(F=y.error&&(0,v.jsx)(u,{error:y.error,msg:`Failed to create instance profile`}),e[10]=y.error,e[11]=F);let I;e[12]!==x||e[13]!==M?(I=x(M),e[12]=x,e[13]=M,e[14]=I):I=e[14];let L;e[15]===Symbol.for(`react.memo_cache_sentinel`)?(L=(0,v.jsx)(p,{children:(0,v.jsx)(`label`,{htmlFor:`instanceProfileName`,children:`Instance Profile Name`})}),e[15]=L):L=e[15];let R=!!T.instanceProfileName,z;e[16]===S?z=e[17]:(z=S(`instanceProfileName`),e[16]=S,e[17]=z);let B;e[18]!==R||e[19]!==z?(B=(0,v.jsx)(o,{"aria-invalid":R,id:`instanceProfileName`,placeholder:`my-instance-profile...`,...z}),e[18]=R,e[19]=z,e[20]=B):B=e[20];let V;e[21]===T.instanceProfileName?V=e[22]:(V=(0,v.jsx)(m,{errors:[T.instanceProfileName]}),e[21]=T.instanceProfileName,e[22]=V);let H;e[23]!==B||e[24]!==V?(H=(0,v.jsxs)(h,{children:[L,B,V]}),e[23]=B,e[24]=V,e[25]=H):H=e[25];let U;e[26]===Symbol.for(`react.memo_cache_sentinel`)?(U=(0,v.jsx)(p,{children:(0,v.jsx)(`label`,{htmlFor:`path`,children:`Path (optional)`})}),e[26]=U):U=e[26];let W;e[27]===S?W=e[28]:(W=S(`path`),e[27]=S,e[28]=W);let G;e[29]===W?G=e[30]:(G=(0,v.jsx)(o,{id:`path`,placeholder:`/`,...W}),e[29]=W,e[30]=G);let K;e[31]===T.path?K=e[32]:(K=(0,v.jsx)(m,{errors:[T.path]}),e[31]=T.path,e[32]=K);let q;e[33]!==G||e[34]!==K?(q=(0,v.jsxs)(h,{children:[U,G,K]}),e[33]=G,e[34]=K,e[35]=q):q=e[35];let J;e[36]===A?J=e[37]:(J=ee(A),e[36]=A,e[37]=J);let Y;e[38]===J?Y=e[39]:(Y=(0,v.jsx)(r,{commands:J}),e[38]=J,e[39]=Y);let X;e[40]===t?X=e[41]:(X=async()=>await t({to:`/iam/list-instance-profiles`}),e[40]=t,e[41]=X);let Z;e[42]!==y.isPending||e[43]!==E||e[44]!==X?(Z=(0,v.jsx)(d,{isPending:y.isPending,isSubmitting:E,onCancel:X,pendingLabel:`Creating...`,submitLabel:`Create Instance Profile`}),e[42]=y.isPending,e[43]=E,e[44]=X,e[45]=Z):Z=e[45];let Q;e[46]!==H||e[47]!==q||e[48]!==Y||e[49]!==Z||e[50]!==I?(Q=(0,v.jsxs)(`form`,{className:`max-w-4xl space-y-6`,onSubmit:I,children:[H,q,Y,Z]}),e[46]=H,e[47]=q,e[48]=Y,e[49]=Z,e[50]=I,e[51]=Q):Q=e[51];let $;return e[52]!==Q||e[53]!==F?($=(0,v.jsxs)(v.Fragment,{children:[N,P,F,Q]}),e[52]=Q,e[53]=F,e[54]=$):$=e[54],$}function ee(e){let t=e(`instanceProfileName`),n=typeof t==`string`?t:``,r=e(`path`),i=typeof r==`string`?r:``,a=[{type:`bin`,value:`AWS_PROFILE=spinifex aws iam create-instance-profile`},{type:`flag`,value:` --instance-profile-name`},{type:`value`,value:` ${n||`<InstanceProfileName>`}`}];return i&&i!==`/`&&a.push({type:`flag`,value:` --path`},{type:`value`,value:` ${i}`}),[{label:`Create Instance Profile`,parts:a}]}export{y as component};
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./back-link.js";import{t as r}from"./cli-command-panel.js";import{a as i}from"./iam.js";import{Qr as a,nr as o}from"./index.js";import{a as s,i as c,t as l}from"./zod.js";import{t as u}from"./error-banner.js";import{t as d}from"./form-actions.js";import{t as f}from"./page-heading.js";import{a as p,r as m,t as h}from"./field.js";import{n as g}from"./iam2.js";var _=t(),v=e();function y(){let e=(0,_.c)(55),t=a(),y=i(),b;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(b={resolver:l(g)},e[0]=b):b=e[0];let{handleSubmit:x,register:S,control:C,formState:w}=c(b),{errors:T,isSubmitting:E}=w,D;e[1]===C?D=e[2]:(D={control:C},e[1]=C,e[2]=D);let O=s(D),k;e[3]===O?k=e[4]:(k=e=>e?O[e]:void 0,e[3]=O,e[4]=k);let A=k,j;e[5]!==y||e[6]!==t?(j=async e=>{await y.mutateAsync(e),t({to:`/iam/list-instance-profiles`})},e[5]=y,e[6]=t,e[7]=j):j=e[7];let M=j,N,P;e[8]===Symbol.for(`react.memo_cache_sentinel`)?(N=(0,v.jsx)(n,{to:`/iam/list-instance-profiles`,children:`Back to instance profiles`}),P=(0,v.jsx)(f,{title:`Create Instance Profile`}),e[8]=N,e[9]=P):(N=e[8],P=e[9]);let F;e[10]===y.error?F=e[11]:(F=y.error&&(0,v.jsx)(u,{error:y.error,msg:`Failed to create instance profile`}),e[10]=y.error,e[11]=F);let I;e[12]!==x||e[13]!==M?(I=x(M),e[12]=x,e[13]=M,e[14]=I):I=e[14];let L;e[15]===Symbol.for(`react.memo_cache_sentinel`)?(L=(0,v.jsx)(p,{children:(0,v.jsx)(`label`,{htmlFor:`instanceProfileName`,children:`Instance Profile Name`})}),e[15]=L):L=e[15];let R=!!T.instanceProfileName,z;e[16]===S?z=e[17]:(z=S(`instanceProfileName`),e[16]=S,e[17]=z);let B;e[18]!==R||e[19]!==z?(B=(0,v.jsx)(o,{"aria-invalid":R,id:`instanceProfileName`,placeholder:`my-instance-profile...`,...z}),e[18]=R,e[19]=z,e[20]=B):B=e[20];let V;e[21]===T.instanceProfileName?V=e[22]:(V=(0,v.jsx)(m,{errors:[T.instanceProfileName]}),e[21]=T.instanceProfileName,e[22]=V);let H;e[23]!==B||e[24]!==V?(H=(0,v.jsxs)(h,{children:[L,B,V]}),e[23]=B,e[24]=V,e[25]=H):H=e[25];let U;e[26]===Symbol.for(`react.memo_cache_sentinel`)?(U=(0,v.jsx)(p,{children:(0,v.jsx)(`label`,{htmlFor:`path`,children:`Path (optional)`})}),e[26]=U):U=e[26];let W;e[27]===S?W=e[28]:(W=S(`path`),e[27]=S,e[28]=W);let G;e[29]===W?G=e[30]:(G=(0,v.jsx)(o,{id:`path`,placeholder:`/`,...W}),e[29]=W,e[30]=G);let K;e[31]===T.path?K=e[32]:(K=(0,v.jsx)(m,{errors:[T.path]}),e[31]=T.path,e[32]=K);let q;e[33]!==G||e[34]!==K?(q=(0,v.jsxs)(h,{children:[U,G,K]}),e[33]=G,e[34]=K,e[35]=q):q=e[35];let J;e[36]===A?J=e[37]:(J=ee(A),e[36]=A,e[37]=J);let Y;e[38]===J?Y=e[39]:(Y=(0,v.jsx)(r,{commands:J}),e[38]=J,e[39]=Y);let X;e[40]===t?X=e[41]:(X=async()=>await t({to:`/iam/list-instance-profiles`}),e[40]=t,e[41]=X);let Z;e[42]!==y.isPending||e[43]!==E||e[44]!==X?(Z=(0,v.jsx)(d,{isPending:y.isPending,isSubmitting:E,onCancel:X,pendingLabel:`Creating...`,submitLabel:`Create Instance Profile`}),e[42]=y.isPending,e[43]=E,e[44]=X,e[45]=Z):Z=e[45];let Q;e[46]!==H||e[47]!==q||e[48]!==Y||e[49]!==Z||e[50]!==I?(Q=(0,v.jsxs)(`form`,{className:`max-w-4xl space-y-6`,onSubmit:I,children:[H,q,Y,Z]}),e[46]=H,e[47]=q,e[48]=Y,e[49]=Z,e[50]=I,e[51]=Q):Q=e[51];let $;return e[52]!==Q||e[53]!==F?($=(0,v.jsxs)(v.Fragment,{children:[N,P,F,Q]}),e[52]=Q,e[53]=F,e[54]=$):$=e[54],$}function ee(e){let t=e(`instanceProfileName`),n=typeof t==`string`?t:``,r=e(`path`),i=typeof r==`string`?r:``,a=[{type:`bin`,value:`AWS_PROFILE=spinifex aws iam create-instance-profile`},{type:`flag`,value:` --instance-profile-name`},{type:`value`,value:` ${n||`<InstanceProfileName>`}`}];return i&&i!==`/`&&a.push({type:`flag`,value:` --path`},{type:`value`,value:` ${i}`}),[{label:`Create Instance Profile`,parts:a}]}export{y as component};
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./back-link.js";import{t as r}from"./cli-command-panel.js";import{f as i}from"./ec2.js";import{Xr as a,er as o}from"./index.js";import{a as s,i as c,t as l}from"./zod.js";import{t as u}from"./error-banner.js";import{t as d}from"./form-actions.js";import{t as f}from"./page-heading.js";import{a as p,t as m}from"./field.js";import{a as h}from"./ec22.js";var g=t(),_=e();function v(){let e=(0,g.c)(36),t=a(),v=i(),b;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(b={resolver:l(h),defaultValues:{name:``}},e[0]=b):b=e[0];let{control:x,handleSubmit:S,register:C,formState:w}=c(b),{isSubmitting:T}=w,E;e[1]===x?E=e[2]:(E={control:x},e[1]=x,e[2]=E);let D=s(E),O;e[3]!==v||e[4]!==t?(O=async e=>{let n=(await v.mutateAsync({name:e.name?.trim()??void 0})).InternetGateway?.InternetGatewayId;t(n?{to:`/ec2/describe-internet-gateways/$id`,params:{id:n}}:{to:`/ec2/describe-internet-gateways`})},e[3]=v,e[4]=t,e[5]=O):O=e[5];let k=O,A,j;e[6]===Symbol.for(`react.memo_cache_sentinel`)?(A=(0,_.jsx)(n,{to:`/ec2/describe-internet-gateways`,children:`Back to Internet Gateways`}),j=(0,_.jsx)(f,{title:`Create Internet Gateway`}),e[6]=A,e[7]=j):(A=e[6],j=e[7]);let M;e[8]===v.error?M=e[9]:(M=v.error&&(0,_.jsx)(u,{error:v.error,msg:`Failed to create Internet Gateway`}),e[8]=v.error,e[9]=M);let N;e[10]!==S||e[11]!==k?(N=S(k),e[10]=S,e[11]=k,e[12]=N):N=e[12];let P;e[13]===Symbol.for(`react.memo_cache_sentinel`)?(P=(0,_.jsx)(p,{children:(0,_.jsx)(`label`,{htmlFor:`name`,children:`Name (optional)`})}),e[13]=P):P=e[13];let F;e[14]===C?F=e[15]:(F=C(`name`),e[14]=C,e[15]=F);let I;e[16]===F?I=e[17]:(I=(0,_.jsxs)(m,{children:[P,(0,_.jsx)(o,{id:`name`,placeholder:`my-internet-gateway`,...F})]}),e[16]=F,e[17]=I);let L=D.name??``,R;e[18]===L?R=e[19]:(R=y(L),e[18]=L,e[19]=R);let z;e[20]===R?z=e[21]:(z=(0,_.jsx)(r,{commands:R}),e[20]=R,e[21]=z);let B;e[22]===t?B=e[23]:(B=async()=>await t({to:`/ec2/describe-internet-gateways`}),e[22]=t,e[23]=B);let V;e[24]!==v.isPending||e[25]!==T||e[26]!==B?(V=(0,_.jsx)(d,{isPending:v.isPending,isSubmitting:T,onCancel:B,pendingLabel:`Creating…`,submitLabel:`Create`}),e[24]=v.isPending,e[25]=T,e[26]=B,e[27]=V):V=e[27];let H;e[28]!==I||e[29]!==z||e[30]!==V||e[31]!==N?(H=(0,_.jsxs)(`form`,{className:`max-w-4xl space-y-6`,onSubmit:N,children:[I,z,V]}),e[28]=I,e[29]=z,e[30]=V,e[31]=N,e[32]=H):H=e[32];let U;return e[33]!==H||e[34]!==M?(U=(0,_.jsxs)(_.Fragment,{children:[A,j,M,H]}),e[33]=H,e[34]=M,e[35]=U):U=e[35],U}function y(e){let t=[{type:`bin`,value:`AWS_PROFILE=spinifex aws ec2 create-internet-gateway`}];return e.trim()&&t.push({type:`flag`,value:` \\
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./back-link.js";import{t as r}from"./cli-command-panel.js";import{f as i}from"./ec2.js";import{Qr as a,nr as o}from"./index.js";import{a as s,i as c,t as l}from"./zod.js";import{t as u}from"./error-banner.js";import{t as d}from"./form-actions.js";import{t as f}from"./page-heading.js";import{a as p,t as m}from"./field.js";import{a as h}from"./ec22.js";var g=t(),_=e();function v(){let e=(0,g.c)(36),t=a(),v=i(),b;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(b={resolver:l(h),defaultValues:{name:``}},e[0]=b):b=e[0];let{control:x,handleSubmit:S,register:C,formState:w}=c(b),{isSubmitting:T}=w,E;e[1]===x?E=e[2]:(E={control:x},e[1]=x,e[2]=E);let D=s(E),O;e[3]!==v||e[4]!==t?(O=async e=>{let n=(await v.mutateAsync({name:e.name?.trim()??void 0})).InternetGateway?.InternetGatewayId;t(n?{to:`/ec2/describe-internet-gateways/$id`,params:{id:n}}:{to:`/ec2/describe-internet-gateways`})},e[3]=v,e[4]=t,e[5]=O):O=e[5];let k=O,A,j;e[6]===Symbol.for(`react.memo_cache_sentinel`)?(A=(0,_.jsx)(n,{to:`/ec2/describe-internet-gateways`,children:`Back to Internet Gateways`}),j=(0,_.jsx)(f,{title:`Create Internet Gateway`}),e[6]=A,e[7]=j):(A=e[6],j=e[7]);let M;e[8]===v.error?M=e[9]:(M=v.error&&(0,_.jsx)(u,{error:v.error,msg:`Failed to create Internet Gateway`}),e[8]=v.error,e[9]=M);let N;e[10]!==S||e[11]!==k?(N=S(k),e[10]=S,e[11]=k,e[12]=N):N=e[12];let P;e[13]===Symbol.for(`react.memo_cache_sentinel`)?(P=(0,_.jsx)(p,{children:(0,_.jsx)(`label`,{htmlFor:`name`,children:`Name (optional)`})}),e[13]=P):P=e[13];let F;e[14]===C?F=e[15]:(F=C(`name`),e[14]=C,e[15]=F);let I;e[16]===F?I=e[17]:(I=(0,_.jsxs)(m,{children:[P,(0,_.jsx)(o,{id:`name`,placeholder:`my-internet-gateway`,...F})]}),e[16]=F,e[17]=I);let L=D.name??``,R;e[18]===L?R=e[19]:(R=y(L),e[18]=L,e[19]=R);let z;e[20]===R?z=e[21]:(z=(0,_.jsx)(r,{commands:R}),e[20]=R,e[21]=z);let B;e[22]===t?B=e[23]:(B=async()=>await t({to:`/ec2/describe-internet-gateways`}),e[22]=t,e[23]=B);let V;e[24]!==v.isPending||e[25]!==T||e[26]!==B?(V=(0,_.jsx)(d,{isPending:v.isPending,isSubmitting:T,onCancel:B,pendingLabel:`Creating…`,submitLabel:`Create`}),e[24]=v.isPending,e[25]=T,e[26]=B,e[27]=V):V=e[27];let H;e[28]!==I||e[29]!==z||e[30]!==V||e[31]!==N?(H=(0,_.jsxs)(`form`,{className:`max-w-4xl space-y-6`,onSubmit:N,children:[I,z,V]}),e[28]=I,e[29]=z,e[30]=V,e[31]=N,e[32]=H):H=e[32];let U;return e[33]!==H||e[34]!==M?(U=(0,_.jsxs)(_.Fragment,{children:[A,j,M,H]}),e[33]=H,e[34]=M,e[35]=U):U=e[35],U}function y(e){let t=[{type:`bin`,value:`AWS_PROFILE=spinifex aws ec2 create-internet-gateway`}];return e.trim()&&t.push({type:`flag`,value:` \\
|
||||
--tag-specifications`},{type:`value`,value:` 'ResourceType=internet-gateway,Tags=[{Key=Name,Value=${e.trim()}}]'`}),[{label:`Create Internet Gateway`,parts:t}]}export{v as component};
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1
-1
@@ -1,3 +1,3 @@
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./back-link.js";import{c as r,i,n as a,s as ee,t as o}from"./select.js";import{t as te}from"./cli-command-panel.js";import{h as ne}from"./ec2.js";import{Xr as s,er as c}from"./index.js";import{a as l,i as u,n as d,t as f}from"./zod.js";import{t as p}from"./error-banner.js";import{t as m}from"./form-actions.js";import{t as h}from"./page-heading.js";import{a as g,r as _,t as v}from"./field.js";import{c as re}from"./ec22.js";var ie=t(),y=e();function b(){let e=(0,ie.c)(56),t=s(),b=ne(),x;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(x={resolver:f(re),defaultValues:{groupName:``,strategy:`spread`}},e[0]=x):x=e[0];let{control:S,handleSubmit:C,register:w,formState:oe}=u(x),{errors:T,isSubmitting:E}=oe,D;e[1]===S?D=e[2]:(D={control:S},e[1]=S,e[2]=D);let O=l(D),k;e[3]===O?k=e[4]:(k=e=>e?O[e]:void 0,e[3]=O,e[4]=k);let A=k,j;e[5]!==b||e[6]!==t?(j=async e=>{t({to:`/ec2/describe-placement-groups/$id`,params:{id:(await b.mutateAsync(e)).PlacementGroup?.GroupId??``}})},e[5]=b,e[6]=t,e[7]=j):j=e[7];let M=j,N,P;e[8]===Symbol.for(`react.memo_cache_sentinel`)?(N=(0,y.jsx)(n,{to:`/ec2/describe-placement-groups`,children:`Back to placement groups`}),P=(0,y.jsx)(h,{title:`Create Placement Group`}),e[8]=N,e[9]=P):(N=e[8],P=e[9]);let F;e[10]===b.error?F=e[11]:(F=b.error&&(0,y.jsx)(p,{error:b.error,msg:`Failed to create placement group`}),e[10]=b.error,e[11]=F);let I;e[12]!==C||e[13]!==M?(I=C(M),e[12]=C,e[13]=M,e[14]=I):I=e[14];let L;e[15]===Symbol.for(`react.memo_cache_sentinel`)?(L=(0,y.jsx)(g,{children:(0,y.jsx)(`label`,{htmlFor:`groupName`,children:`Group Name`})}),e[15]=L):L=e[15];let R=!!T.groupName,z;e[16]===w?z=e[17]:(z=w(`groupName`),e[16]=w,e[17]=z);let B;e[18]!==R||e[19]!==z?(B=(0,y.jsx)(c,{"aria-invalid":R,id:`groupName`,placeholder:`my-placement-group`,...z}),e[18]=R,e[19]=z,e[20]=B):B=e[20];let V;e[21]===T.groupName?V=e[22]:(V=(0,y.jsx)(_,{errors:[T.groupName]}),e[21]=T.groupName,e[22]=V);let H;e[23]!==B||e[24]!==V?(H=(0,y.jsxs)(v,{children:[L,B,V]}),e[23]=B,e[24]=V,e[25]=H):H=e[25];let U;e[26]===Symbol.for(`react.memo_cache_sentinel`)?(U=(0,y.jsx)(g,{children:(0,y.jsx)(`label`,{htmlFor:`strategy`,children:`Strategy`})}),e[26]=U):U=e[26];let W;e[27]===T.strategy?W=e[28]:(W=e=>{let{field:t}=e;return(0,y.jsxs)(o,{onValueChange:e=>t.onChange(e),value:t.value??``,children:[(0,y.jsx)(ee,{"aria-invalid":!!T.strategy,className:`w-full`,id:`strategy`,children:(0,y.jsx)(r,{})}),(0,y.jsxs)(a,{children:[(0,y.jsx)(i,{value:`spread`,children:`spread`}),(0,y.jsx)(i,{value:`cluster`,children:`cluster`})]})]})},e[27]=T.strategy,e[28]=W);let G;e[29]!==S||e[30]!==W?(G=(0,y.jsx)(d,{control:S,name:`strategy`,render:W}),e[29]=S,e[30]=W,e[31]=G):G=e[31];let K;e[32]===T.strategy?K=e[33]:(K=(0,y.jsx)(_,{errors:[T.strategy]}),e[32]=T.strategy,e[33]=K);let q;e[34]!==G||e[35]!==K?(q=(0,y.jsxs)(v,{children:[U,G,K]}),e[34]=G,e[35]=K,e[36]=q):q=e[36];let J;e[37]===A?J=e[38]:(J=ae(A),e[37]=A,e[38]=J);let Y;e[39]===J?Y=e[40]:(Y=(0,y.jsx)(te,{commands:J}),e[39]=J,e[40]=Y);let X;e[41]===t?X=e[42]:(X=async()=>await t({to:`/ec2/describe-placement-groups`}),e[41]=t,e[42]=X);let Z;e[43]!==b.isPending||e[44]!==E||e[45]!==X?(Z=(0,y.jsx)(m,{isPending:b.isPending,isSubmitting:E,onCancel:X,pendingLabel:`Creating…`,submitLabel:`Create Placement Group`}),e[43]=b.isPending,e[44]=E,e[45]=X,e[46]=Z):Z=e[46];let Q;e[47]!==H||e[48]!==q||e[49]!==Y||e[50]!==Z||e[51]!==I?(Q=(0,y.jsxs)(`form`,{className:`max-w-4xl space-y-6`,onSubmit:I,children:[H,q,Y,Z]}),e[47]=H,e[48]=q,e[49]=Y,e[50]=Z,e[51]=I,e[52]=Q):Q=e[52];let $;return e[53]!==Q||e[54]!==F?($=(0,y.jsxs)(y.Fragment,{children:[N,P,F,Q]}),e[53]=Q,e[54]=F,e[55]=$):$=e[55],$}function x(e){return`'${e.replaceAll(`'`,`'"'"'`)}'`}function ae(e){let t=e(`groupName`),n=typeof t==`string`?t:``,r=e(`strategy`),i=typeof r==`string`?r:``;return[{label:`Create Placement Group`,parts:[{type:`bin`,value:`AWS_PROFILE=spinifex aws ec2 create-placement-group`},{type:`flag`,value:` \\
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./back-link.js";import{c as r,i,n as a,s as ee,t as o}from"./select.js";import{t as te}from"./cli-command-panel.js";import{h as ne}from"./ec2.js";import{Qr as s,nr as c}from"./index.js";import{a as l,i as u,n as d,t as f}from"./zod.js";import{t as p}from"./error-banner.js";import{t as m}from"./form-actions.js";import{t as h}from"./page-heading.js";import{a as g,r as _,t as v}from"./field.js";import{c as re}from"./ec22.js";var ie=t(),y=e();function b(){let e=(0,ie.c)(56),t=s(),b=ne(),x;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(x={resolver:f(re),defaultValues:{groupName:``,strategy:`spread`}},e[0]=x):x=e[0];let{control:S,handleSubmit:C,register:w,formState:oe}=u(x),{errors:T,isSubmitting:E}=oe,D;e[1]===S?D=e[2]:(D={control:S},e[1]=S,e[2]=D);let O=l(D),k;e[3]===O?k=e[4]:(k=e=>e?O[e]:void 0,e[3]=O,e[4]=k);let A=k,j;e[5]!==b||e[6]!==t?(j=async e=>{t({to:`/ec2/describe-placement-groups/$id`,params:{id:(await b.mutateAsync(e)).PlacementGroup?.GroupId??``}})},e[5]=b,e[6]=t,e[7]=j):j=e[7];let M=j,N,P;e[8]===Symbol.for(`react.memo_cache_sentinel`)?(N=(0,y.jsx)(n,{to:`/ec2/describe-placement-groups`,children:`Back to placement groups`}),P=(0,y.jsx)(h,{title:`Create Placement Group`}),e[8]=N,e[9]=P):(N=e[8],P=e[9]);let F;e[10]===b.error?F=e[11]:(F=b.error&&(0,y.jsx)(p,{error:b.error,msg:`Failed to create placement group`}),e[10]=b.error,e[11]=F);let I;e[12]!==C||e[13]!==M?(I=C(M),e[12]=C,e[13]=M,e[14]=I):I=e[14];let L;e[15]===Symbol.for(`react.memo_cache_sentinel`)?(L=(0,y.jsx)(g,{children:(0,y.jsx)(`label`,{htmlFor:`groupName`,children:`Group Name`})}),e[15]=L):L=e[15];let R=!!T.groupName,z;e[16]===w?z=e[17]:(z=w(`groupName`),e[16]=w,e[17]=z);let B;e[18]!==R||e[19]!==z?(B=(0,y.jsx)(c,{"aria-invalid":R,id:`groupName`,placeholder:`my-placement-group`,...z}),e[18]=R,e[19]=z,e[20]=B):B=e[20];let V;e[21]===T.groupName?V=e[22]:(V=(0,y.jsx)(_,{errors:[T.groupName]}),e[21]=T.groupName,e[22]=V);let H;e[23]!==B||e[24]!==V?(H=(0,y.jsxs)(v,{children:[L,B,V]}),e[23]=B,e[24]=V,e[25]=H):H=e[25];let U;e[26]===Symbol.for(`react.memo_cache_sentinel`)?(U=(0,y.jsx)(g,{children:(0,y.jsx)(`label`,{htmlFor:`strategy`,children:`Strategy`})}),e[26]=U):U=e[26];let W;e[27]===T.strategy?W=e[28]:(W=e=>{let{field:t}=e;return(0,y.jsxs)(o,{onValueChange:e=>t.onChange(e),value:t.value??``,children:[(0,y.jsx)(ee,{"aria-invalid":!!T.strategy,className:`w-full`,id:`strategy`,children:(0,y.jsx)(r,{})}),(0,y.jsxs)(a,{children:[(0,y.jsx)(i,{value:`spread`,children:`spread`}),(0,y.jsx)(i,{value:`cluster`,children:`cluster`})]})]})},e[27]=T.strategy,e[28]=W);let G;e[29]!==S||e[30]!==W?(G=(0,y.jsx)(d,{control:S,name:`strategy`,render:W}),e[29]=S,e[30]=W,e[31]=G):G=e[31];let K;e[32]===T.strategy?K=e[33]:(K=(0,y.jsx)(_,{errors:[T.strategy]}),e[32]=T.strategy,e[33]=K);let q;e[34]!==G||e[35]!==K?(q=(0,y.jsxs)(v,{children:[U,G,K]}),e[34]=G,e[35]=K,e[36]=q):q=e[36];let J;e[37]===A?J=e[38]:(J=ae(A),e[37]=A,e[38]=J);let Y;e[39]===J?Y=e[40]:(Y=(0,y.jsx)(te,{commands:J}),e[39]=J,e[40]=Y);let X;e[41]===t?X=e[42]:(X=async()=>await t({to:`/ec2/describe-placement-groups`}),e[41]=t,e[42]=X);let Z;e[43]!==b.isPending||e[44]!==E||e[45]!==X?(Z=(0,y.jsx)(m,{isPending:b.isPending,isSubmitting:E,onCancel:X,pendingLabel:`Creating…`,submitLabel:`Create Placement Group`}),e[43]=b.isPending,e[44]=E,e[45]=X,e[46]=Z):Z=e[46];let Q;e[47]!==H||e[48]!==q||e[49]!==Y||e[50]!==Z||e[51]!==I?(Q=(0,y.jsxs)(`form`,{className:`max-w-4xl space-y-6`,onSubmit:I,children:[H,q,Y,Z]}),e[47]=H,e[48]=q,e[49]=Y,e[50]=Z,e[51]=I,e[52]=Q):Q=e[52];let $;return e[53]!==Q||e[54]!==F?($=(0,y.jsxs)(y.Fragment,{children:[N,P,F,Q]}),e[53]=Q,e[54]=F,e[55]=$):$=e[55],$}function x(e){return`'${e.replaceAll(`'`,`'"'"'`)}'`}function ae(e){let t=e(`groupName`),n=typeof t==`string`?t:``,r=e(`strategy`),i=typeof r==`string`?r:``;return[{label:`Create Placement Group`,parts:[{type:`bin`,value:`AWS_PROFILE=spinifex aws ec2 create-placement-group`},{type:`flag`,value:` \\
|
||||
--group-name`},{type:`value`,value:` ${n?x(n):`<GroupName>`}`},{type:`flag`,value:` \\
|
||||
--strategy`},{type:`value`,value:` ${i||`spread`}`}]}]}export{b as component};
|
||||
@@ -1,4 +1,4 @@
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./back-link.js";import{t as r}from"./cli-command-panel.js";import{o as i}from"./iam.js";import{Xr as a,er as o}from"./index.js";import{a as s,i as c,n as ee,t as te}from"./zod.js";import{t as ne}from"./error-banner.js";import{t as re}from"./form-actions.js";import{t as ie}from"./page-heading.js";import{a as l,r as u,t as d}from"./field.js";import{t as ae}from"./json-editor.js";import{r as oe}from"./iam2.js";var se=t(),f=e(),p=JSON.stringify({Version:`2012-10-17`,Statement:[{Effect:`Allow`,Action:`*`,Resource:`*`}]},null,2);function m(){let e=(0,se.c)(67),t=a(),m=i(),g;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(g={resolver:te(oe),defaultValues:{policyDocument:p}},e[0]=g):g=e[0];let{handleSubmit:_,register:v,control:y,formState:ce}=c(g),{errors:b,isSubmitting:x}=ce,S;e[1]===y?S=e[2]:(S={control:y},e[1]=y,e[2]=S);let C=s(S),w;e[3]===C?w=e[4]:(w=e=>e?C[e]:void 0,e[3]=C,e[4]=w);let T=w,E;e[5]!==m||e[6]!==t?(E=async e=>{await m.mutateAsync(e),t({to:`/iam/list-policies`})},e[5]=m,e[6]=t,e[7]=E):E=e[7];let D=E,O,k;e[8]===Symbol.for(`react.memo_cache_sentinel`)?(O=(0,f.jsx)(n,{to:`/iam/list-policies`,children:`Back to policies`}),k=(0,f.jsx)(ie,{title:`Create Policy`}),e[8]=O,e[9]=k):(O=e[8],k=e[9]);let A;e[10]===m.error?A=e[11]:(A=m.error&&(0,f.jsx)(ne,{error:m.error,msg:`Failed to create policy`}),e[10]=m.error,e[11]=A);let j;e[12]!==_||e[13]!==D?(j=_(D),e[12]=_,e[13]=D,e[14]=j):j=e[14];let M;e[15]===Symbol.for(`react.memo_cache_sentinel`)?(M=(0,f.jsx)(l,{children:(0,f.jsx)(`label`,{htmlFor:`policyName`,children:`Policy Name`})}),e[15]=M):M=e[15];let N=!!b.policyName,P;e[16]===v?P=e[17]:(P=v(`policyName`),e[16]=v,e[17]=P);let F;e[18]!==N||e[19]!==P?(F=(0,f.jsx)(o,{"aria-invalid":N,id:`policyName`,placeholder:`my-policy...`,...P}),e[18]=N,e[19]=P,e[20]=F):F=e[20];let I;e[21]===b.policyName?I=e[22]:(I=(0,f.jsx)(u,{errors:[b.policyName]}),e[21]=b.policyName,e[22]=I);let L;e[23]!==F||e[24]!==I?(L=(0,f.jsxs)(d,{children:[M,F,I]}),e[23]=F,e[24]=I,e[25]=L):L=e[25];let R;e[26]===Symbol.for(`react.memo_cache_sentinel`)?(R=(0,f.jsx)(l,{children:(0,f.jsx)(`label`,{htmlFor:`description`,children:`Description (optional)`})}),e[26]=R):R=e[26];let z;e[27]===v?z=e[28]:(z=v(`description`),e[27]=v,e[28]=z);let B;e[29]===z?B=e[30]:(B=(0,f.jsx)(o,{id:`description`,placeholder:`A brief description of this policy...`,...z}),e[29]=z,e[30]=B);let V;e[31]===b.description?V=e[32]:(V=(0,f.jsx)(u,{errors:[b.description]}),e[31]=b.description,e[32]=V);let H;e[33]!==B||e[34]!==V?(H=(0,f.jsxs)(d,{children:[R,B,V]}),e[33]=B,e[34]=V,e[35]=H):H=e[35];let U;e[36]===Symbol.for(`react.memo_cache_sentinel`)?(U=(0,f.jsx)(l,{children:(0,f.jsx)(`label`,{htmlFor:`policyDocument`,children:`Policy Document (JSON)`})}),e[36]=U):U=e[36];let W;e[37]===b.policyDocument?W=e[38]:(W=e=>{let{field:t}=e,{onBlur:n,onChange:r,ref:i,value:a}=t;return(0,f.jsx)(ae,{error:!!b.policyDocument,id:`policyDocument`,onBlur:n,onChange:r,ref:i,rows:15,value:a})},e[37]=b.policyDocument,e[38]=W);let G;e[39]!==y||e[40]!==W?(G=(0,f.jsx)(ee,{control:y,name:`policyDocument`,render:W}),e[39]=y,e[40]=W,e[41]=G):G=e[41];let K;e[42]===b.policyDocument?K=e[43]:(K=(0,f.jsx)(u,{errors:[b.policyDocument]}),e[42]=b.policyDocument,e[43]=K);let q;e[44]!==G||e[45]!==K?(q=(0,f.jsxs)(d,{children:[U,G,K]}),e[44]=G,e[45]=K,e[46]=q):q=e[46];let J;e[47]===T?J=e[48]:(J=h(T),e[47]=T,e[48]=J);let Y;e[49]===J?Y=e[50]:(Y=(0,f.jsx)(r,{commands:J}),e[49]=J,e[50]=Y);let X;e[51]===t?X=e[52]:(X=async()=>await t({to:`/iam/list-policies`}),e[51]=t,e[52]=X);let Z;e[53]!==m.isPending||e[54]!==x||e[55]!==X?(Z=(0,f.jsx)(re,{isPending:m.isPending,isSubmitting:x,onCancel:X,pendingLabel:`Creating...`,submitLabel:`Create Policy`}),e[53]=m.isPending,e[54]=x,e[55]=X,e[56]=Z):Z=e[56];let Q;e[57]!==L||e[58]!==H||e[59]!==q||e[60]!==Y||e[61]!==Z||e[62]!==j?(Q=(0,f.jsxs)(`form`,{className:`max-w-4xl space-y-6`,onSubmit:j,children:[L,H,q,Y,Z]}),e[57]=L,e[58]=H,e[59]=q,e[60]=Y,e[61]=Z,e[62]=j,e[63]=Q):Q=e[63];let $;return e[64]!==Q||e[65]!==A?($=(0,f.jsxs)(f.Fragment,{children:[O,k,A,Q]}),e[64]=Q,e[65]=A,e[66]=$):$=e[66],$}function h(e){let t=e(`policyName`),n=typeof t==`string`?t:``,r=e(`description`),i=typeof r==`string`?r:``,a=e(`policyDocument`),o=typeof a==`string`?a:``,s=[{type:`bin`,value:`AWS_PROFILE=spinifex aws iam create-policy`},{type:`flag`,value:` \\
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./back-link.js";import{t as r}from"./cli-command-panel.js";import{o as i}from"./iam.js";import{Qr as a,nr as o}from"./index.js";import{a as s,i as c,n as ee,t as te}from"./zod.js";import{t as ne}from"./error-banner.js";import{t as re}from"./form-actions.js";import{t as ie}from"./page-heading.js";import{a as l,r as u,t as d}from"./field.js";import{t as ae}from"./json-editor.js";import{r as oe}from"./iam2.js";var se=t(),f=e(),p=JSON.stringify({Version:`2012-10-17`,Statement:[{Effect:`Allow`,Action:`*`,Resource:`*`}]},null,2);function m(){let e=(0,se.c)(67),t=a(),m=i(),g;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(g={resolver:te(oe),defaultValues:{policyDocument:p}},e[0]=g):g=e[0];let{handleSubmit:_,register:v,control:y,formState:ce}=c(g),{errors:b,isSubmitting:x}=ce,S;e[1]===y?S=e[2]:(S={control:y},e[1]=y,e[2]=S);let C=s(S),w;e[3]===C?w=e[4]:(w=e=>e?C[e]:void 0,e[3]=C,e[4]=w);let T=w,E;e[5]!==m||e[6]!==t?(E=async e=>{await m.mutateAsync(e),t({to:`/iam/list-policies`})},e[5]=m,e[6]=t,e[7]=E):E=e[7];let D=E,O,k;e[8]===Symbol.for(`react.memo_cache_sentinel`)?(O=(0,f.jsx)(n,{to:`/iam/list-policies`,children:`Back to policies`}),k=(0,f.jsx)(ie,{title:`Create Policy`}),e[8]=O,e[9]=k):(O=e[8],k=e[9]);let A;e[10]===m.error?A=e[11]:(A=m.error&&(0,f.jsx)(ne,{error:m.error,msg:`Failed to create policy`}),e[10]=m.error,e[11]=A);let j;e[12]!==_||e[13]!==D?(j=_(D),e[12]=_,e[13]=D,e[14]=j):j=e[14];let M;e[15]===Symbol.for(`react.memo_cache_sentinel`)?(M=(0,f.jsx)(l,{children:(0,f.jsx)(`label`,{htmlFor:`policyName`,children:`Policy Name`})}),e[15]=M):M=e[15];let N=!!b.policyName,P;e[16]===v?P=e[17]:(P=v(`policyName`),e[16]=v,e[17]=P);let F;e[18]!==N||e[19]!==P?(F=(0,f.jsx)(o,{"aria-invalid":N,id:`policyName`,placeholder:`my-policy...`,...P}),e[18]=N,e[19]=P,e[20]=F):F=e[20];let I;e[21]===b.policyName?I=e[22]:(I=(0,f.jsx)(u,{errors:[b.policyName]}),e[21]=b.policyName,e[22]=I);let L;e[23]!==F||e[24]!==I?(L=(0,f.jsxs)(d,{children:[M,F,I]}),e[23]=F,e[24]=I,e[25]=L):L=e[25];let R;e[26]===Symbol.for(`react.memo_cache_sentinel`)?(R=(0,f.jsx)(l,{children:(0,f.jsx)(`label`,{htmlFor:`description`,children:`Description (optional)`})}),e[26]=R):R=e[26];let z;e[27]===v?z=e[28]:(z=v(`description`),e[27]=v,e[28]=z);let B;e[29]===z?B=e[30]:(B=(0,f.jsx)(o,{id:`description`,placeholder:`A brief description of this policy...`,...z}),e[29]=z,e[30]=B);let V;e[31]===b.description?V=e[32]:(V=(0,f.jsx)(u,{errors:[b.description]}),e[31]=b.description,e[32]=V);let H;e[33]!==B||e[34]!==V?(H=(0,f.jsxs)(d,{children:[R,B,V]}),e[33]=B,e[34]=V,e[35]=H):H=e[35];let U;e[36]===Symbol.for(`react.memo_cache_sentinel`)?(U=(0,f.jsx)(l,{children:(0,f.jsx)(`label`,{htmlFor:`policyDocument`,children:`Policy Document (JSON)`})}),e[36]=U):U=e[36];let W;e[37]===b.policyDocument?W=e[38]:(W=e=>{let{field:t}=e,{onBlur:n,onChange:r,ref:i,value:a}=t;return(0,f.jsx)(ae,{error:!!b.policyDocument,id:`policyDocument`,onBlur:n,onChange:r,ref:i,rows:15,value:a})},e[37]=b.policyDocument,e[38]=W);let G;e[39]!==y||e[40]!==W?(G=(0,f.jsx)(ee,{control:y,name:`policyDocument`,render:W}),e[39]=y,e[40]=W,e[41]=G):G=e[41];let K;e[42]===b.policyDocument?K=e[43]:(K=(0,f.jsx)(u,{errors:[b.policyDocument]}),e[42]=b.policyDocument,e[43]=K);let q;e[44]!==G||e[45]!==K?(q=(0,f.jsxs)(d,{children:[U,G,K]}),e[44]=G,e[45]=K,e[46]=q):q=e[46];let J;e[47]===T?J=e[48]:(J=h(T),e[47]=T,e[48]=J);let Y;e[49]===J?Y=e[50]:(Y=(0,f.jsx)(r,{commands:J}),e[49]=J,e[50]=Y);let X;e[51]===t?X=e[52]:(X=async()=>await t({to:`/iam/list-policies`}),e[51]=t,e[52]=X);let Z;e[53]!==m.isPending||e[54]!==x||e[55]!==X?(Z=(0,f.jsx)(re,{isPending:m.isPending,isSubmitting:x,onCancel:X,pendingLabel:`Creating...`,submitLabel:`Create Policy`}),e[53]=m.isPending,e[54]=x,e[55]=X,e[56]=Z):Z=e[56];let Q;e[57]!==L||e[58]!==H||e[59]!==q||e[60]!==Y||e[61]!==Z||e[62]!==j?(Q=(0,f.jsxs)(`form`,{className:`max-w-4xl space-y-6`,onSubmit:j,children:[L,H,q,Y,Z]}),e[57]=L,e[58]=H,e[59]=q,e[60]=Y,e[61]=Z,e[62]=j,e[63]=Q):Q=e[63];let $;return e[64]!==Q||e[65]!==A?($=(0,f.jsxs)(f.Fragment,{children:[O,k,A,Q]}),e[64]=Q,e[65]=A,e[66]=$):$=e[66],$}function h(e){let t=e(`policyName`),n=typeof t==`string`?t:``,r=e(`description`),i=typeof r==`string`?r:``,a=e(`policyDocument`),o=typeof a==`string`?a:``,s=[{type:`bin`,value:`AWS_PROFILE=spinifex aws iam create-policy`},{type:`flag`,value:` \\
|
||||
--policy-name`},{type:`value`,value:` ${n||`<PolicyName>`}`}];return i&&s.push({type:`flag`,value:` \\
|
||||
--description`},{type:`value`,value:` "${i}"`}),s.push({type:`flag`,value:` \\
|
||||
--policy-document`},{type:`value`,value:` '${o||`<PolicyDocument>`}'`}),[{label:`Create Policy`,parts:s}]}export{m as component};
|
||||
@@ -1,4 +1,4 @@
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./back-link.js";import{t as r}from"./cli-command-panel.js";import{s as i}from"./iam.js";import{Xr as a,er as o}from"./index.js";import{a as s,i as c,n as ee,t as te}from"./zod.js";import{t as ne}from"./error-banner.js";import{t as re}from"./form-actions.js";import{t as ie}from"./page-heading.js";import{a as l,r as u,t as d}from"./field.js";import{t as ae}from"./json-editor.js";import{i as oe,t as se}from"./iam2.js";var f=t(),p=e();function m(){let e=(0,f.c)(67),t=a(),m=i(),g;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(g={resolver:te(oe),defaultValues:{assumeRolePolicyDocument:se}},e[0]=g):g=e[0];let{handleSubmit:_,register:v,control:y,formState:ce}=c(g),{errors:b,isSubmitting:x}=ce,S;e[1]===y?S=e[2]:(S={control:y},e[1]=y,e[2]=S);let C=s(S),w;e[3]===C?w=e[4]:(w=e=>e?C[e]:void 0,e[3]=C,e[4]=w);let T=w,E;e[5]!==m||e[6]!==t?(E=async e=>{await m.mutateAsync(e),t({to:`/iam/list-roles`})},e[5]=m,e[6]=t,e[7]=E):E=e[7];let D=E,O,k;e[8]===Symbol.for(`react.memo_cache_sentinel`)?(O=(0,p.jsx)(n,{to:`/iam/list-roles`,children:`Back to roles`}),k=(0,p.jsx)(ie,{title:`Create Role`}),e[8]=O,e[9]=k):(O=e[8],k=e[9]);let A;e[10]===m.error?A=e[11]:(A=m.error&&(0,p.jsx)(ne,{error:m.error,msg:`Failed to create role`}),e[10]=m.error,e[11]=A);let j;e[12]!==_||e[13]!==D?(j=_(D),e[12]=_,e[13]=D,e[14]=j):j=e[14];let M;e[15]===Symbol.for(`react.memo_cache_sentinel`)?(M=(0,p.jsx)(l,{children:(0,p.jsx)(`label`,{htmlFor:`roleName`,children:`Role Name`})}),e[15]=M):M=e[15];let N=!!b.roleName,P;e[16]===v?P=e[17]:(P=v(`roleName`),e[16]=v,e[17]=P);let F;e[18]!==N||e[19]!==P?(F=(0,p.jsx)(o,{"aria-invalid":N,id:`roleName`,placeholder:`my-role...`,...P}),e[18]=N,e[19]=P,e[20]=F):F=e[20];let I;e[21]===b.roleName?I=e[22]:(I=(0,p.jsx)(u,{errors:[b.roleName]}),e[21]=b.roleName,e[22]=I);let L;e[23]!==F||e[24]!==I?(L=(0,p.jsxs)(d,{children:[M,F,I]}),e[23]=F,e[24]=I,e[25]=L):L=e[25];let R;e[26]===Symbol.for(`react.memo_cache_sentinel`)?(R=(0,p.jsx)(l,{children:(0,p.jsx)(`label`,{htmlFor:`description`,children:`Description (optional)`})}),e[26]=R):R=e[26];let z;e[27]===v?z=e[28]:(z=v(`description`),e[27]=v,e[28]=z);let B;e[29]===z?B=e[30]:(B=(0,p.jsx)(o,{id:`description`,placeholder:`A brief description of this role...`,...z}),e[29]=z,e[30]=B);let V;e[31]===b.description?V=e[32]:(V=(0,p.jsx)(u,{errors:[b.description]}),e[31]=b.description,e[32]=V);let H;e[33]!==B||e[34]!==V?(H=(0,p.jsxs)(d,{children:[R,B,V]}),e[33]=B,e[34]=V,e[35]=H):H=e[35];let U;e[36]===Symbol.for(`react.memo_cache_sentinel`)?(U=(0,p.jsx)(l,{children:(0,p.jsx)(`label`,{htmlFor:`assumeRolePolicyDocument`,children:`Trust Policy (JSON)`})}),e[36]=U):U=e[36];let W;e[37]===b.assumeRolePolicyDocument?W=e[38]:(W=e=>{let{field:t}=e,{onBlur:n,onChange:r,ref:i,value:a}=t;return(0,p.jsx)(ae,{error:!!b.assumeRolePolicyDocument,id:`assumeRolePolicyDocument`,onBlur:n,onChange:r,ref:i,rows:15,value:a})},e[37]=b.assumeRolePolicyDocument,e[38]=W);let G;e[39]!==y||e[40]!==W?(G=(0,p.jsx)(ee,{control:y,name:`assumeRolePolicyDocument`,render:W}),e[39]=y,e[40]=W,e[41]=G):G=e[41];let K;e[42]===b.assumeRolePolicyDocument?K=e[43]:(K=(0,p.jsx)(u,{errors:[b.assumeRolePolicyDocument]}),e[42]=b.assumeRolePolicyDocument,e[43]=K);let q;e[44]!==G||e[45]!==K?(q=(0,p.jsxs)(d,{children:[U,G,K]}),e[44]=G,e[45]=K,e[46]=q):q=e[46];let J;e[47]===T?J=e[48]:(J=h(T),e[47]=T,e[48]=J);let Y;e[49]===J?Y=e[50]:(Y=(0,p.jsx)(r,{commands:J}),e[49]=J,e[50]=Y);let X;e[51]===t?X=e[52]:(X=async()=>await t({to:`/iam/list-roles`}),e[51]=t,e[52]=X);let Z;e[53]!==m.isPending||e[54]!==x||e[55]!==X?(Z=(0,p.jsx)(re,{isPending:m.isPending,isSubmitting:x,onCancel:X,pendingLabel:`Creating...`,submitLabel:`Create Role`}),e[53]=m.isPending,e[54]=x,e[55]=X,e[56]=Z):Z=e[56];let Q;e[57]!==L||e[58]!==H||e[59]!==q||e[60]!==Y||e[61]!==Z||e[62]!==j?(Q=(0,p.jsxs)(`form`,{className:`max-w-4xl space-y-6`,onSubmit:j,children:[L,H,q,Y,Z]}),e[57]=L,e[58]=H,e[59]=q,e[60]=Y,e[61]=Z,e[62]=j,e[63]=Q):Q=e[63];let $;return e[64]!==Q||e[65]!==A?($=(0,p.jsxs)(p.Fragment,{children:[O,k,A,Q]}),e[64]=Q,e[65]=A,e[66]=$):$=e[66],$}function h(e){let t=e(`roleName`),n=typeof t==`string`?t:``,r=e(`description`),i=typeof r==`string`?r:``,a=e(`assumeRolePolicyDocument`),o=typeof a==`string`?a:``,s=[{type:`bin`,value:`AWS_PROFILE=spinifex aws iam create-role`},{type:`flag`,value:` \\
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./back-link.js";import{t as r}from"./cli-command-panel.js";import{s as i}from"./iam.js";import{Qr as a,nr as o}from"./index.js";import{a as s,i as c,n as ee,t as te}from"./zod.js";import{t as ne}from"./error-banner.js";import{t as re}from"./form-actions.js";import{t as ie}from"./page-heading.js";import{a as l,r as u,t as d}from"./field.js";import{t as ae}from"./json-editor.js";import{i as oe,t as se}from"./iam2.js";var f=t(),p=e();function m(){let e=(0,f.c)(67),t=a(),m=i(),g;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(g={resolver:te(oe),defaultValues:{assumeRolePolicyDocument:se}},e[0]=g):g=e[0];let{handleSubmit:_,register:v,control:y,formState:ce}=c(g),{errors:b,isSubmitting:x}=ce,S;e[1]===y?S=e[2]:(S={control:y},e[1]=y,e[2]=S);let C=s(S),w;e[3]===C?w=e[4]:(w=e=>e?C[e]:void 0,e[3]=C,e[4]=w);let T=w,E;e[5]!==m||e[6]!==t?(E=async e=>{await m.mutateAsync(e),t({to:`/iam/list-roles`})},e[5]=m,e[6]=t,e[7]=E):E=e[7];let D=E,O,k;e[8]===Symbol.for(`react.memo_cache_sentinel`)?(O=(0,p.jsx)(n,{to:`/iam/list-roles`,children:`Back to roles`}),k=(0,p.jsx)(ie,{title:`Create Role`}),e[8]=O,e[9]=k):(O=e[8],k=e[9]);let A;e[10]===m.error?A=e[11]:(A=m.error&&(0,p.jsx)(ne,{error:m.error,msg:`Failed to create role`}),e[10]=m.error,e[11]=A);let j;e[12]!==_||e[13]!==D?(j=_(D),e[12]=_,e[13]=D,e[14]=j):j=e[14];let M;e[15]===Symbol.for(`react.memo_cache_sentinel`)?(M=(0,p.jsx)(l,{children:(0,p.jsx)(`label`,{htmlFor:`roleName`,children:`Role Name`})}),e[15]=M):M=e[15];let N=!!b.roleName,P;e[16]===v?P=e[17]:(P=v(`roleName`),e[16]=v,e[17]=P);let F;e[18]!==N||e[19]!==P?(F=(0,p.jsx)(o,{"aria-invalid":N,id:`roleName`,placeholder:`my-role...`,...P}),e[18]=N,e[19]=P,e[20]=F):F=e[20];let I;e[21]===b.roleName?I=e[22]:(I=(0,p.jsx)(u,{errors:[b.roleName]}),e[21]=b.roleName,e[22]=I);let L;e[23]!==F||e[24]!==I?(L=(0,p.jsxs)(d,{children:[M,F,I]}),e[23]=F,e[24]=I,e[25]=L):L=e[25];let R;e[26]===Symbol.for(`react.memo_cache_sentinel`)?(R=(0,p.jsx)(l,{children:(0,p.jsx)(`label`,{htmlFor:`description`,children:`Description (optional)`})}),e[26]=R):R=e[26];let z;e[27]===v?z=e[28]:(z=v(`description`),e[27]=v,e[28]=z);let B;e[29]===z?B=e[30]:(B=(0,p.jsx)(o,{id:`description`,placeholder:`A brief description of this role...`,...z}),e[29]=z,e[30]=B);let V;e[31]===b.description?V=e[32]:(V=(0,p.jsx)(u,{errors:[b.description]}),e[31]=b.description,e[32]=V);let H;e[33]!==B||e[34]!==V?(H=(0,p.jsxs)(d,{children:[R,B,V]}),e[33]=B,e[34]=V,e[35]=H):H=e[35];let U;e[36]===Symbol.for(`react.memo_cache_sentinel`)?(U=(0,p.jsx)(l,{children:(0,p.jsx)(`label`,{htmlFor:`assumeRolePolicyDocument`,children:`Trust Policy (JSON)`})}),e[36]=U):U=e[36];let W;e[37]===b.assumeRolePolicyDocument?W=e[38]:(W=e=>{let{field:t}=e,{onBlur:n,onChange:r,ref:i,value:a}=t;return(0,p.jsx)(ae,{error:!!b.assumeRolePolicyDocument,id:`assumeRolePolicyDocument`,onBlur:n,onChange:r,ref:i,rows:15,value:a})},e[37]=b.assumeRolePolicyDocument,e[38]=W);let G;e[39]!==y||e[40]!==W?(G=(0,p.jsx)(ee,{control:y,name:`assumeRolePolicyDocument`,render:W}),e[39]=y,e[40]=W,e[41]=G):G=e[41];let K;e[42]===b.assumeRolePolicyDocument?K=e[43]:(K=(0,p.jsx)(u,{errors:[b.assumeRolePolicyDocument]}),e[42]=b.assumeRolePolicyDocument,e[43]=K);let q;e[44]!==G||e[45]!==K?(q=(0,p.jsxs)(d,{children:[U,G,K]}),e[44]=G,e[45]=K,e[46]=q):q=e[46];let J;e[47]===T?J=e[48]:(J=h(T),e[47]=T,e[48]=J);let Y;e[49]===J?Y=e[50]:(Y=(0,p.jsx)(r,{commands:J}),e[49]=J,e[50]=Y);let X;e[51]===t?X=e[52]:(X=async()=>await t({to:`/iam/list-roles`}),e[51]=t,e[52]=X);let Z;e[53]!==m.isPending||e[54]!==x||e[55]!==X?(Z=(0,p.jsx)(re,{isPending:m.isPending,isSubmitting:x,onCancel:X,pendingLabel:`Creating...`,submitLabel:`Create Role`}),e[53]=m.isPending,e[54]=x,e[55]=X,e[56]=Z):Z=e[56];let Q;e[57]!==L||e[58]!==H||e[59]!==q||e[60]!==Y||e[61]!==Z||e[62]!==j?(Q=(0,p.jsxs)(`form`,{className:`max-w-4xl space-y-6`,onSubmit:j,children:[L,H,q,Y,Z]}),e[57]=L,e[58]=H,e[59]=q,e[60]=Y,e[61]=Z,e[62]=j,e[63]=Q):Q=e[63];let $;return e[64]!==Q||e[65]!==A?($=(0,p.jsxs)(p.Fragment,{children:[O,k,A,Q]}),e[64]=Q,e[65]=A,e[66]=$):$=e[66],$}function h(e){let t=e(`roleName`),n=typeof t==`string`?t:``,r=e(`description`),i=typeof r==`string`?r:``,a=e(`assumeRolePolicyDocument`),o=typeof a==`string`?a:``,s=[{type:`bin`,value:`AWS_PROFILE=spinifex aws iam create-role`},{type:`flag`,value:` \\
|
||||
--role-name`},{type:`value`,value:` ${n||`<RoleName>`}`}];return i&&s.push({type:`flag`,value:` \\
|
||||
--description`},{type:`value`,value:` "${i}"`}),s.push({type:`flag`,value:` \\
|
||||
--assume-role-policy-document`},{type:`value`,value:` '${o||`<TrustPolicy>`}'`}),[{label:`Create Role`,parts:s}]}export{m as component};
|
||||
@@ -1 +1 @@
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{Ut as r}from"./auth.js";import{t as i}from"./back-link.js";import{c as a,i as o,n as s,s as c,t as l}from"./select.js";import{_ as u}from"./ec2.js";import{$t as d,Xr as f,er as p}from"./index.js";import{i as m,n as h,t as g}from"./zod.js";import{t as _}from"./error-banner.js";import{t as v}from"./form-actions.js";import{t as y}from"./page-heading.js";import{a as b,r as x,t as S}from"./field.js";import{u as C}from"./ec22.js";var w=t(),T=e();function E(){let e=(0,w.c)(44),t=f(),{data:r}=n(d),o=u(),E;e[0]===r.Vpcs?E=e[1]:(E=r.Vpcs??[],e[0]=r.Vpcs,e[1]=E);let O=E,k;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(k={resolver:g(C),defaultValues:{vpcId:``,name:``}},e[2]=k):k=e[2];let{control:A,handleSubmit:j,register:M,formState:N}=m(k),{errors:P,isSubmitting:F}=N,I;e[3]!==o||e[4]!==t?(I=async e=>{let n=(await o.mutateAsync({vpcId:e.vpcId,name:e.name?.trim()?e.name.trim():void 0})).RouteTable?.RouteTableId;t(n?{to:`/ec2/describe-route-tables/$id`,params:{id:n}}:{to:`/ec2/describe-route-tables`})},e[3]=o,e[4]=t,e[5]=I):I=e[5];let L=I,R,z;e[6]===Symbol.for(`react.memo_cache_sentinel`)?(R=(0,T.jsx)(i,{to:`/ec2/describe-route-tables`,children:`Back to Route Tables`}),z=(0,T.jsx)(y,{title:`Create Route Table`}),e[6]=R,e[7]=z):(R=e[6],z=e[7]);let B;e[8]===o.error?B=e[9]:(B=o.error&&(0,T.jsx)(_,{error:o.error,msg:`Failed to create Route Table`}),e[8]=o.error,e[9]=B);let V;e[10]!==j||e[11]!==L?(V=j(L),e[10]=j,e[11]=L,e[12]=V):V=e[12];let H;e[13]===Symbol.for(`react.memo_cache_sentinel`)?(H=(0,T.jsx)(b,{children:(0,T.jsx)(`label`,{htmlFor:`name`,children:`Name (optional)`})}),e[13]=H):H=e[13];let U;e[14]===M?U=e[15]:(U=M(`name`),e[14]=M,e[15]=U);let W;e[16]===U?W=e[17]:(W=(0,T.jsxs)(S,{children:[H,(0,T.jsx)(p,{id:`name`,placeholder:`my-route-table`,...U})]}),e[16]=U,e[17]=W);let G;e[18]===Symbol.for(`react.memo_cache_sentinel`)?(G=(0,T.jsx)(b,{children:(0,T.jsx)(`label`,{htmlFor:`vpcId`,children:`VPC`})}),e[18]=G):G=e[18];let K;e[19]!==P.vpcId||e[20]!==O?(K=e=>{let{field:t}=e;return(0,T.jsxs)(l,{onValueChange:e=>t.onChange(e),value:t.value??``,children:[(0,T.jsx)(c,{"aria-invalid":!!P.vpcId,className:`w-full`,id:`vpcId`,children:(0,T.jsx)(a,{placeholder:`Select a VPC`})}),(0,T.jsx)(s,{children:O.map(D)})]})},e[19]=P.vpcId,e[20]=O,e[21]=K):K=e[21];let q;e[22]!==A||e[23]!==K?(q=(0,T.jsx)(h,{control:A,name:`vpcId`,render:K}),e[22]=A,e[23]=K,e[24]=q):q=e[24];let J;e[25]===P.vpcId?J=e[26]:(J=(0,T.jsx)(x,{errors:[P.vpcId]}),e[25]=P.vpcId,e[26]=J);let Y;e[27]!==q||e[28]!==J?(Y=(0,T.jsxs)(S,{children:[G,q,J]}),e[27]=q,e[28]=J,e[29]=Y):Y=e[29];let X;e[30]===t?X=e[31]:(X=async()=>await t({to:`/ec2/describe-route-tables`}),e[30]=t,e[31]=X);let Z;e[32]!==o.isPending||e[33]!==F||e[34]!==X?(Z=(0,T.jsx)(v,{isPending:o.isPending,isSubmitting:F,onCancel:X,pendingLabel:`Creating…`,submitLabel:`Create Route Table`}),e[32]=o.isPending,e[33]=F,e[34]=X,e[35]=Z):Z=e[35];let Q;e[36]!==W||e[37]!==Y||e[38]!==Z||e[39]!==V?(Q=(0,T.jsxs)(`form`,{className:`max-w-4xl space-y-6`,onSubmit:V,children:[W,Y,Z]}),e[36]=W,e[37]=Y,e[38]=Z,e[39]=V,e[40]=Q):Q=e[40];let $;return e[41]!==Q||e[42]!==B?($=(0,T.jsxs)(T.Fragment,{children:[R,z,B,Q]}),e[41]=Q,e[42]=B,e[43]=$):$=e[43],$}function D(e){let t=r(e.Tags);return(0,T.jsx)(o,{value:e.VpcId??``,children:t?`${e.VpcId} (${t})`:`${e.VpcId} (${e.CidrBlock})`},e.VpcId)}export{E as component};
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{Ut as r}from"./auth.js";import{t as i}from"./back-link.js";import{c as a,i as o,n as s,s as c,t as l}from"./select.js";import{_ as u}from"./ec2.js";import{Qr as d,nr as f,tn as p}from"./index.js";import{i as m,n as h,t as g}from"./zod.js";import{t as _}from"./error-banner.js";import{t as v}from"./form-actions.js";import{t as y}from"./page-heading.js";import{a as b,r as x,t as S}from"./field.js";import{u as C}from"./ec22.js";var w=t(),T=e();function E(){let e=(0,w.c)(44),t=d(),{data:r}=n(p),o=u(),E;e[0]===r.Vpcs?E=e[1]:(E=r.Vpcs??[],e[0]=r.Vpcs,e[1]=E);let O=E,k;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(k={resolver:g(C),defaultValues:{vpcId:``,name:``}},e[2]=k):k=e[2];let{control:A,handleSubmit:j,register:M,formState:N}=m(k),{errors:P,isSubmitting:F}=N,I;e[3]!==o||e[4]!==t?(I=async e=>{let n=(await o.mutateAsync({vpcId:e.vpcId,name:e.name?.trim()?e.name.trim():void 0})).RouteTable?.RouteTableId;t(n?{to:`/ec2/describe-route-tables/$id`,params:{id:n}}:{to:`/ec2/describe-route-tables`})},e[3]=o,e[4]=t,e[5]=I):I=e[5];let L=I,R,z;e[6]===Symbol.for(`react.memo_cache_sentinel`)?(R=(0,T.jsx)(i,{to:`/ec2/describe-route-tables`,children:`Back to Route Tables`}),z=(0,T.jsx)(y,{title:`Create Route Table`}),e[6]=R,e[7]=z):(R=e[6],z=e[7]);let B;e[8]===o.error?B=e[9]:(B=o.error&&(0,T.jsx)(_,{error:o.error,msg:`Failed to create Route Table`}),e[8]=o.error,e[9]=B);let V;e[10]!==j||e[11]!==L?(V=j(L),e[10]=j,e[11]=L,e[12]=V):V=e[12];let H;e[13]===Symbol.for(`react.memo_cache_sentinel`)?(H=(0,T.jsx)(b,{children:(0,T.jsx)(`label`,{htmlFor:`name`,children:`Name (optional)`})}),e[13]=H):H=e[13];let U;e[14]===M?U=e[15]:(U=M(`name`),e[14]=M,e[15]=U);let W;e[16]===U?W=e[17]:(W=(0,T.jsxs)(S,{children:[H,(0,T.jsx)(f,{id:`name`,placeholder:`my-route-table`,...U})]}),e[16]=U,e[17]=W);let G;e[18]===Symbol.for(`react.memo_cache_sentinel`)?(G=(0,T.jsx)(b,{children:(0,T.jsx)(`label`,{htmlFor:`vpcId`,children:`VPC`})}),e[18]=G):G=e[18];let K;e[19]!==P.vpcId||e[20]!==O?(K=e=>{let{field:t}=e;return(0,T.jsxs)(l,{onValueChange:e=>t.onChange(e),value:t.value??``,children:[(0,T.jsx)(c,{"aria-invalid":!!P.vpcId,className:`w-full`,id:`vpcId`,children:(0,T.jsx)(a,{placeholder:`Select a VPC`})}),(0,T.jsx)(s,{children:O.map(D)})]})},e[19]=P.vpcId,e[20]=O,e[21]=K):K=e[21];let q;e[22]!==A||e[23]!==K?(q=(0,T.jsx)(h,{control:A,name:`vpcId`,render:K}),e[22]=A,e[23]=K,e[24]=q):q=e[24];let J;e[25]===P.vpcId?J=e[26]:(J=(0,T.jsx)(x,{errors:[P.vpcId]}),e[25]=P.vpcId,e[26]=J);let Y;e[27]!==q||e[28]!==J?(Y=(0,T.jsxs)(S,{children:[G,q,J]}),e[27]=q,e[28]=J,e[29]=Y):Y=e[29];let X;e[30]===t?X=e[31]:(X=async()=>await t({to:`/ec2/describe-route-tables`}),e[30]=t,e[31]=X);let Z;e[32]!==o.isPending||e[33]!==F||e[34]!==X?(Z=(0,T.jsx)(v,{isPending:o.isPending,isSubmitting:F,onCancel:X,pendingLabel:`Creating…`,submitLabel:`Create Route Table`}),e[32]=o.isPending,e[33]=F,e[34]=X,e[35]=Z):Z=e[35];let Q;e[36]!==W||e[37]!==Y||e[38]!==Z||e[39]!==V?(Q=(0,T.jsxs)(`form`,{className:`max-w-4xl space-y-6`,onSubmit:V,children:[W,Y,Z]}),e[36]=W,e[37]=Y,e[38]=Z,e[39]=V,e[40]=Q):Q=e[40];let $;return e[41]!==Q||e[42]!==B?($=(0,T.jsxs)(T.Fragment,{children:[R,z,B,Q]}),e[41]=Q,e[42]=B,e[43]=$):$=e[43],$}function D(e){let t=r(e.Tags);return(0,T.jsx)(o,{value:e.VpcId??``,children:t?`${e.VpcId} (${t})`:`${e.VpcId} (${e.CidrBlock})`},e.VpcId)}export{E as component};
|
||||
@@ -1,4 +1,4 @@
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{Ut as r}from"./auth.js";import{t as ee}from"./back-link.js";import{c as i,i as a,n as o,s as te,t as ne}from"./select.js";import{t as re}from"./cli-command-panel.js";import{v as ie}from"./ec2.js";import{$t as ae,Xr as oe,er as se}from"./index.js";import{a as ce,i as le,n as ue,t as de}from"./zod.js";import{t as fe}from"./error-banner.js";import{t as pe}from"./form-actions.js";import{t as me}from"./page-heading.js";import{a as s,r as c,t as l}from"./field.js";import{d as he}from"./ec22.js";var ge=t(),u=e();function d(){let e=(0,ge.c)(73),t=oe(),{data:r}=n(ae),a=ie(),d;e[0]===r.Vpcs?d=e[1]:(d=r.Vpcs??[],e[0]=r.Vpcs,e[1]=d);let f=d,p;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(p=de(he),e[2]=p):p=e[2];let m=f[0]?.VpcId??``,h;e[3]===m?h=e[4]:(h={resolver:p,defaultValues:{groupName:``,description:``,vpcId:m}},e[3]=m,e[4]=h);let{control:g,handleSubmit:_,register:v,formState:ye}=le(h),{errors:y,isSubmitting:b}=ye,x;e[5]===g?x=e[6]:(x={control:g},e[5]=g,e[6]=x);let S=ce(x),C;e[7]===S?C=e[8]:(C=e=>e?S[e]:void 0,e[7]=S,e[8]=C);let w=C,T;e[9]!==a||e[10]!==t?(T=async e=>{let n=(await a.mutateAsync(e)).GroupId;t(n?{to:`/ec2/describe-security-groups/$id`,params:{id:n}}:{to:`/ec2/describe-security-groups`})},e[9]=a,e[10]=t,e[11]=T):T=e[11];let E=T,D,O;e[12]===Symbol.for(`react.memo_cache_sentinel`)?(D=(0,u.jsx)(ee,{to:`/ec2/describe-security-groups`,children:`Back to Security Groups`}),O=(0,u.jsx)(me,{title:`Create Security Group`}),e[12]=D,e[13]=O):(D=e[12],O=e[13]);let k;e[14]===a.error?k=e[15]:(k=a.error&&(0,u.jsx)(fe,{error:a.error,msg:`Failed to create security group`}),e[14]=a.error,e[15]=k);let A;e[16]!==_||e[17]!==E?(A=_(E),e[16]=_,e[17]=E,e[18]=A):A=e[18];let j;e[19]===Symbol.for(`react.memo_cache_sentinel`)?(j=(0,u.jsx)(s,{children:(0,u.jsx)(`label`,{htmlFor:`groupName`,children:`Group Name`})}),e[19]=j):j=e[19];let M=!!y.groupName,N;e[20]===v?N=e[21]:(N=v(`groupName`),e[20]=v,e[21]=N);let P;e[22]!==M||e[23]!==N?(P=(0,u.jsx)(se,{"aria-invalid":M,id:`groupName`,placeholder:`my-security-group`,...N}),e[22]=M,e[23]=N,e[24]=P):P=e[24];let F;e[25]===y.groupName?F=e[26]:(F=(0,u.jsx)(c,{errors:[y.groupName]}),e[25]=y.groupName,e[26]=F);let I;e[27]!==P||e[28]!==F?(I=(0,u.jsxs)(l,{children:[j,P,F]}),e[27]=P,e[28]=F,e[29]=I):I=e[29];let L;e[30]===Symbol.for(`react.memo_cache_sentinel`)?(L=(0,u.jsx)(s,{children:(0,u.jsx)(`label`,{htmlFor:`description`,children:`Description`})}),e[30]=L):L=e[30];let R=!!y.description,z;e[31]===v?z=e[32]:(z=v(`description`),e[31]=v,e[32]=z);let B;e[33]!==R||e[34]!==z?(B=(0,u.jsx)(se,{"aria-invalid":R,id:`description`,placeholder:`My security group description`,...z}),e[33]=R,e[34]=z,e[35]=B):B=e[35];let V;e[36]===y.description?V=e[37]:(V=(0,u.jsx)(c,{errors:[y.description]}),e[36]=y.description,e[37]=V);let H;e[38]!==B||e[39]!==V?(H=(0,u.jsxs)(l,{children:[L,B,V]}),e[38]=B,e[39]=V,e[40]=H):H=e[40];let U;e[41]===Symbol.for(`react.memo_cache_sentinel`)?(U=(0,u.jsx)(s,{children:(0,u.jsx)(`label`,{htmlFor:`vpcId`,children:`VPC`})}),e[41]=U):U=e[41];let W;e[42]!==y.vpcId||e[43]!==f?(W=e=>{let{field:t}=e;return(0,u.jsxs)(ne,{onValueChange:e=>t.onChange(e),value:t.value??``,children:[(0,u.jsx)(te,{"aria-invalid":!!y.vpcId,className:`w-full`,id:`vpcId`,children:(0,u.jsx)(i,{})}),(0,u.jsx)(o,{children:f.map(_e)})]})},e[42]=y.vpcId,e[43]=f,e[44]=W):W=e[44];let G;e[45]!==g||e[46]!==W?(G=(0,u.jsx)(ue,{control:g,name:`vpcId`,render:W}),e[45]=g,e[46]=W,e[47]=G):G=e[47];let K;e[48]===y.vpcId?K=e[49]:(K=(0,u.jsx)(c,{errors:[y.vpcId]}),e[48]=y.vpcId,e[49]=K);let q;e[50]!==G||e[51]!==K?(q=(0,u.jsxs)(l,{children:[U,G,K]}),e[50]=G,e[51]=K,e[52]=q):q=e[52];let J;e[53]===w?J=e[54]:(J=ve(w),e[53]=w,e[54]=J);let Y;e[55]===J?Y=e[56]:(Y=(0,u.jsx)(re,{commands:J}),e[55]=J,e[56]=Y);let X;e[57]===t?X=e[58]:(X=async()=>await t({to:`/ec2/describe-security-groups`}),e[57]=t,e[58]=X);let Z;e[59]!==a.isPending||e[60]!==b||e[61]!==X?(Z=(0,u.jsx)(pe,{isPending:a.isPending,isSubmitting:b,onCancel:X,pendingLabel:`Creating…`,submitLabel:`Create Security Group`}),e[59]=a.isPending,e[60]=b,e[61]=X,e[62]=Z):Z=e[62];let Q;e[63]!==A||e[64]!==I||e[65]!==H||e[66]!==q||e[67]!==Y||e[68]!==Z?(Q=(0,u.jsxs)(`form`,{className:`max-w-4xl space-y-6`,onSubmit:A,children:[I,H,q,Y,Z]}),e[63]=A,e[64]=I,e[65]=H,e[66]=q,e[67]=Y,e[68]=Z,e[69]=Q):Q=e[69];let $;return e[70]!==k||e[71]!==Q?($=(0,u.jsxs)(u.Fragment,{children:[D,O,k,Q]}),e[70]=k,e[71]=Q,e[72]=$):$=e[72],$}function _e(e){let t=r(e.Tags);return(0,u.jsx)(a,{value:e.VpcId??``,children:t?`${e.VpcId} (${t})`:`${e.VpcId} (${e.CidrBlock})`},e.VpcId)}function ve(e){let t=e(`groupName`),n=typeof t==`string`?t:``,r=e(`description`),ee=typeof r==`string`?r:``,i=e(`vpcId`),a=typeof i==`string`?i:``,o=[{type:`bin`,value:`AWS_PROFILE=spinifex aws ec2 create-security-group`},{type:`flag`,value:` \\
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{Ut as r}from"./auth.js";import{t as ee}from"./back-link.js";import{c as i,i as a,n as o,s as te,t as ne}from"./select.js";import{t as re}from"./cli-command-panel.js";import{v as ie}from"./ec2.js";import{Qr as ae,nr as oe,tn as se}from"./index.js";import{a as ce,i as le,n as ue,t as de}from"./zod.js";import{t as fe}from"./error-banner.js";import{t as pe}from"./form-actions.js";import{t as me}from"./page-heading.js";import{a as s,r as c,t as l}from"./field.js";import{d as he}from"./ec22.js";var ge=t(),u=e();function d(){let e=(0,ge.c)(73),t=ae(),{data:r}=n(se),a=ie(),d;e[0]===r.Vpcs?d=e[1]:(d=r.Vpcs??[],e[0]=r.Vpcs,e[1]=d);let f=d,p;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(p=de(he),e[2]=p):p=e[2];let m=f[0]?.VpcId??``,h;e[3]===m?h=e[4]:(h={resolver:p,defaultValues:{groupName:``,description:``,vpcId:m}},e[3]=m,e[4]=h);let{control:g,handleSubmit:_,register:v,formState:ye}=le(h),{errors:y,isSubmitting:b}=ye,x;e[5]===g?x=e[6]:(x={control:g},e[5]=g,e[6]=x);let S=ce(x),C;e[7]===S?C=e[8]:(C=e=>e?S[e]:void 0,e[7]=S,e[8]=C);let w=C,T;e[9]!==a||e[10]!==t?(T=async e=>{let n=(await a.mutateAsync(e)).GroupId;t(n?{to:`/ec2/describe-security-groups/$id`,params:{id:n}}:{to:`/ec2/describe-security-groups`})},e[9]=a,e[10]=t,e[11]=T):T=e[11];let E=T,D,O;e[12]===Symbol.for(`react.memo_cache_sentinel`)?(D=(0,u.jsx)(ee,{to:`/ec2/describe-security-groups`,children:`Back to Security Groups`}),O=(0,u.jsx)(me,{title:`Create Security Group`}),e[12]=D,e[13]=O):(D=e[12],O=e[13]);let k;e[14]===a.error?k=e[15]:(k=a.error&&(0,u.jsx)(fe,{error:a.error,msg:`Failed to create security group`}),e[14]=a.error,e[15]=k);let A;e[16]!==_||e[17]!==E?(A=_(E),e[16]=_,e[17]=E,e[18]=A):A=e[18];let j;e[19]===Symbol.for(`react.memo_cache_sentinel`)?(j=(0,u.jsx)(s,{children:(0,u.jsx)(`label`,{htmlFor:`groupName`,children:`Group Name`})}),e[19]=j):j=e[19];let M=!!y.groupName,N;e[20]===v?N=e[21]:(N=v(`groupName`),e[20]=v,e[21]=N);let P;e[22]!==M||e[23]!==N?(P=(0,u.jsx)(oe,{"aria-invalid":M,id:`groupName`,placeholder:`my-security-group`,...N}),e[22]=M,e[23]=N,e[24]=P):P=e[24];let F;e[25]===y.groupName?F=e[26]:(F=(0,u.jsx)(c,{errors:[y.groupName]}),e[25]=y.groupName,e[26]=F);let I;e[27]!==P||e[28]!==F?(I=(0,u.jsxs)(l,{children:[j,P,F]}),e[27]=P,e[28]=F,e[29]=I):I=e[29];let L;e[30]===Symbol.for(`react.memo_cache_sentinel`)?(L=(0,u.jsx)(s,{children:(0,u.jsx)(`label`,{htmlFor:`description`,children:`Description`})}),e[30]=L):L=e[30];let R=!!y.description,z;e[31]===v?z=e[32]:(z=v(`description`),e[31]=v,e[32]=z);let B;e[33]!==R||e[34]!==z?(B=(0,u.jsx)(oe,{"aria-invalid":R,id:`description`,placeholder:`My security group description`,...z}),e[33]=R,e[34]=z,e[35]=B):B=e[35];let V;e[36]===y.description?V=e[37]:(V=(0,u.jsx)(c,{errors:[y.description]}),e[36]=y.description,e[37]=V);let H;e[38]!==B||e[39]!==V?(H=(0,u.jsxs)(l,{children:[L,B,V]}),e[38]=B,e[39]=V,e[40]=H):H=e[40];let U;e[41]===Symbol.for(`react.memo_cache_sentinel`)?(U=(0,u.jsx)(s,{children:(0,u.jsx)(`label`,{htmlFor:`vpcId`,children:`VPC`})}),e[41]=U):U=e[41];let W;e[42]!==y.vpcId||e[43]!==f?(W=e=>{let{field:t}=e;return(0,u.jsxs)(ne,{onValueChange:e=>t.onChange(e),value:t.value??``,children:[(0,u.jsx)(te,{"aria-invalid":!!y.vpcId,className:`w-full`,id:`vpcId`,children:(0,u.jsx)(i,{})}),(0,u.jsx)(o,{children:f.map(_e)})]})},e[42]=y.vpcId,e[43]=f,e[44]=W):W=e[44];let G;e[45]!==g||e[46]!==W?(G=(0,u.jsx)(ue,{control:g,name:`vpcId`,render:W}),e[45]=g,e[46]=W,e[47]=G):G=e[47];let K;e[48]===y.vpcId?K=e[49]:(K=(0,u.jsx)(c,{errors:[y.vpcId]}),e[48]=y.vpcId,e[49]=K);let q;e[50]!==G||e[51]!==K?(q=(0,u.jsxs)(l,{children:[U,G,K]}),e[50]=G,e[51]=K,e[52]=q):q=e[52];let J;e[53]===w?J=e[54]:(J=ve(w),e[53]=w,e[54]=J);let Y;e[55]===J?Y=e[56]:(Y=(0,u.jsx)(re,{commands:J}),e[55]=J,e[56]=Y);let X;e[57]===t?X=e[58]:(X=async()=>await t({to:`/ec2/describe-security-groups`}),e[57]=t,e[58]=X);let Z;e[59]!==a.isPending||e[60]!==b||e[61]!==X?(Z=(0,u.jsx)(pe,{isPending:a.isPending,isSubmitting:b,onCancel:X,pendingLabel:`Creating…`,submitLabel:`Create Security Group`}),e[59]=a.isPending,e[60]=b,e[61]=X,e[62]=Z):Z=e[62];let Q;e[63]!==A||e[64]!==I||e[65]!==H||e[66]!==q||e[67]!==Y||e[68]!==Z?(Q=(0,u.jsxs)(`form`,{className:`max-w-4xl space-y-6`,onSubmit:A,children:[I,H,q,Y,Z]}),e[63]=A,e[64]=I,e[65]=H,e[66]=q,e[67]=Y,e[68]=Z,e[69]=Q):Q=e[69];let $;return e[70]!==k||e[71]!==Q?($=(0,u.jsxs)(u.Fragment,{children:[D,O,k,Q]}),e[70]=k,e[71]=Q,e[72]=$):$=e[72],$}function _e(e){let t=r(e.Tags);return(0,u.jsx)(a,{value:e.VpcId??``,children:t?`${e.VpcId} (${t})`:`${e.VpcId} (${e.CidrBlock})`},e.VpcId)}function ve(e){let t=e(`groupName`),n=typeof t==`string`?t:``,r=e(`description`),ee=typeof r==`string`?r:``,i=e(`vpcId`),a=typeof i==`string`?i:``,o=[{type:`bin`,value:`AWS_PROFILE=spinifex aws ec2 create-security-group`},{type:`flag`,value:` \\
|
||||
--group-name`},{type:`value`,value:` ${n||`<GroupName>`}`},{type:`flag`,value:` \\
|
||||
--description`},{type:`value`,value:` "${ee||`<Description>`}"`}];return a&&o.push({type:`flag`,value:` \\
|
||||
--vpc-id`},{type:`value`,value:` ${a}`}),[{label:`Create Security Group`,parts:o}]}export{d as component};
|
||||
File diff suppressed because one or more lines are too long
@@ -1,3 +1,3 @@
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{t as r}from"./back-link.js";import{c as i,i as a,n as o,s,t as c}from"./select.js";import{t as l}from"./cli-command-panel.js";import{y as ee}from"./ec2.js";import{V as te,Xr as u,Zt as ne}from"./index.js";import{a as re,i as ie,n as ae,t as oe}from"./zod.js";import{t as se}from"./error-banner.js";import{t as ce}from"./form-actions.js";import{t as le}from"./page-heading.js";import{a as d,r as f,t as p}from"./field.js";import{f as m}from"./ec22.js";import{t as ue}from"./textarea.js";var h=t(),g=e();function _(){let e=(0,h.c)(55),t=u(),{data:a}=n(ne),_=ee(),v;e[0]===a.Volumes?v=e[1]:(v=a.Volumes??[],e[0]=a.Volumes,e[1]=v);let y=v,{volumeId:b}=te.useSearch(),x=b??y[0]?.VolumeId??``,S;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(S=oe(m),e[2]=S):S=e[2];let C;e[3]===x?C=e[4]:(C={resolver:S,defaultValues:{volumeId:x,description:``}},e[3]=x,e[4]=C);let{control:w,handleSubmit:T,register:E,formState:D}=ie(C),{errors:O,isSubmitting:k}=D,A;e[5]===w?A=e[6]:(A={control:w},e[5]=w,e[6]=A);let j=re(A),M;e[7]===j?M=e[8]:(M=e=>e?j[e]:void 0,e[7]=j,e[8]=M);let N=M,P;e[9]!==_||e[10]!==t?(P=async e=>{await _.mutateAsync(e),t({to:`/ec2/describe-snapshots`})},e[9]=_,e[10]=t,e[11]=P):P=e[11];let F=P,I,L;e[12]===Symbol.for(`react.memo_cache_sentinel`)?(I=(0,g.jsx)(r,{to:`/ec2/describe-snapshots`,children:`Back to snapshots`}),L=(0,g.jsx)(le,{title:`Create Snapshot`}),e[12]=I,e[13]=L):(I=e[12],L=e[13]);let R;e[14]===_.error?R=e[15]:(R=_.error&&(0,g.jsx)(se,{error:_.error,msg:`Failed to create snapshot`}),e[14]=_.error,e[15]=R);let z;e[16]!==T||e[17]!==F?(z=T(F),e[16]=T,e[17]=F,e[18]=z):z=e[18];let B;e[19]===Symbol.for(`react.memo_cache_sentinel`)?(B=(0,g.jsx)(d,{children:(0,g.jsx)(`label`,{htmlFor:`volumeId`,children:`Volume`})}),e[19]=B):B=e[19];let V;e[20]!==O.volumeId||e[21]!==y?(V=e=>{let{field:t}=e;return(0,g.jsxs)(c,{onValueChange:e=>t.onChange(e),value:t.value??``,children:[(0,g.jsx)(s,{"aria-invalid":!!O.volumeId,className:`w-full`,id:`volumeId`,children:(0,g.jsx)(i,{})}),(0,g.jsx)(o,{children:y.map(de)})]})},e[20]=O.volumeId,e[21]=y,e[22]=V):V=e[22];let H;e[23]!==w||e[24]!==V?(H=(0,g.jsx)(ae,{control:w,name:`volumeId`,render:V}),e[23]=w,e[24]=V,e[25]=H):H=e[25];let U;e[26]===O.volumeId?U=e[27]:(U=(0,g.jsx)(f,{errors:[O.volumeId]}),e[26]=O.volumeId,e[27]=U);let W;e[28]!==H||e[29]!==U?(W=(0,g.jsxs)(p,{children:[B,H,U]}),e[28]=H,e[29]=U,e[30]=W):W=e[30];let G;e[31]===Symbol.for(`react.memo_cache_sentinel`)?(G=(0,g.jsx)(d,{children:(0,g.jsx)(`label`,{htmlFor:`description`,children:`Description (optional)`})}),e[31]=G):G=e[31];let K;e[32]===E?K=e[33]:(K=E(`description`),e[32]=E,e[33]=K);let q;e[34]===K?q=e[35]:(q=(0,g.jsxs)(p,{children:[G,(0,g.jsx)(ue,{id:`description`,placeholder:`Snapshot description`,...K})]}),e[34]=K,e[35]=q);let J;e[36]===N?J=e[37]:(J=fe(N),e[36]=N,e[37]=J);let Y;e[38]===J?Y=e[39]:(Y=(0,g.jsx)(l,{commands:J}),e[38]=J,e[39]=Y);let X;e[40]===t?X=e[41]:(X=async()=>await t({to:`/ec2/describe-snapshots`}),e[40]=t,e[41]=X);let Z;e[42]!==_.isPending||e[43]!==k||e[44]!==X?(Z=(0,g.jsx)(ce,{isPending:_.isPending,isSubmitting:k,onCancel:X,pendingLabel:`Creating…`,submitLabel:`Create Snapshot`}),e[42]=_.isPending,e[43]=k,e[44]=X,e[45]=Z):Z=e[45];let Q;e[46]!==z||e[47]!==W||e[48]!==q||e[49]!==Y||e[50]!==Z?(Q=(0,g.jsxs)(`form`,{className:`max-w-4xl space-y-6`,onSubmit:z,children:[W,q,Y,Z]}),e[46]=z,e[47]=W,e[48]=q,e[49]=Y,e[50]=Z,e[51]=Q):Q=e[51];let $;return e[52]!==Q||e[53]!==R?($=(0,g.jsxs)(g.Fragment,{children:[I,L,R,Q]}),e[52]=Q,e[53]=R,e[54]=$):$=e[54],$}function de(e){return(0,g.jsxs)(a,{value:e.VolumeId??``,children:[e.VolumeId,` (`,e.Size,` GiB)`]},e.VolumeId)}function fe(e){let t=e(`volumeId`),n=typeof t==`string`?t:``,r=e(`description`),i=typeof r==`string`?r:``,a=[{type:`bin`,value:`AWS_PROFILE=spinifex aws ec2 create-snapshot`},{type:`flag`,value:` \\
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{t as r}from"./back-link.js";import{c as i,i as a,n as o,s,t as c}from"./select.js";import{t as l}from"./cli-command-panel.js";import{y as ee}from"./ec2.js";import{$t as te,Qr as u,U as ne}from"./index.js";import{a as re,i as ie,n as ae,t as oe}from"./zod.js";import{t as se}from"./error-banner.js";import{t as ce}from"./form-actions.js";import{t as le}from"./page-heading.js";import{a as d,r as f,t as p}from"./field.js";import{f as m}from"./ec22.js";import{t as ue}from"./textarea.js";var h=t(),g=e();function _(){let e=(0,h.c)(55),t=u(),{data:a}=n(te),_=ee(),v;e[0]===a.Volumes?v=e[1]:(v=a.Volumes??[],e[0]=a.Volumes,e[1]=v);let y=v,{volumeId:b}=ne.useSearch(),x=b??y[0]?.VolumeId??``,S;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(S=oe(m),e[2]=S):S=e[2];let C;e[3]===x?C=e[4]:(C={resolver:S,defaultValues:{volumeId:x,description:``}},e[3]=x,e[4]=C);let{control:w,handleSubmit:T,register:E,formState:D}=ie(C),{errors:O,isSubmitting:k}=D,A;e[5]===w?A=e[6]:(A={control:w},e[5]=w,e[6]=A);let j=re(A),M;e[7]===j?M=e[8]:(M=e=>e?j[e]:void 0,e[7]=j,e[8]=M);let N=M,P;e[9]!==_||e[10]!==t?(P=async e=>{await _.mutateAsync(e),t({to:`/ec2/describe-snapshots`})},e[9]=_,e[10]=t,e[11]=P):P=e[11];let F=P,I,L;e[12]===Symbol.for(`react.memo_cache_sentinel`)?(I=(0,g.jsx)(r,{to:`/ec2/describe-snapshots`,children:`Back to snapshots`}),L=(0,g.jsx)(le,{title:`Create Snapshot`}),e[12]=I,e[13]=L):(I=e[12],L=e[13]);let R;e[14]===_.error?R=e[15]:(R=_.error&&(0,g.jsx)(se,{error:_.error,msg:`Failed to create snapshot`}),e[14]=_.error,e[15]=R);let z;e[16]!==T||e[17]!==F?(z=T(F),e[16]=T,e[17]=F,e[18]=z):z=e[18];let B;e[19]===Symbol.for(`react.memo_cache_sentinel`)?(B=(0,g.jsx)(d,{children:(0,g.jsx)(`label`,{htmlFor:`volumeId`,children:`Volume`})}),e[19]=B):B=e[19];let V;e[20]!==O.volumeId||e[21]!==y?(V=e=>{let{field:t}=e;return(0,g.jsxs)(c,{onValueChange:e=>t.onChange(e),value:t.value??``,children:[(0,g.jsx)(s,{"aria-invalid":!!O.volumeId,className:`w-full`,id:`volumeId`,children:(0,g.jsx)(i,{})}),(0,g.jsx)(o,{children:y.map(de)})]})},e[20]=O.volumeId,e[21]=y,e[22]=V):V=e[22];let H;e[23]!==w||e[24]!==V?(H=(0,g.jsx)(ae,{control:w,name:`volumeId`,render:V}),e[23]=w,e[24]=V,e[25]=H):H=e[25];let U;e[26]===O.volumeId?U=e[27]:(U=(0,g.jsx)(f,{errors:[O.volumeId]}),e[26]=O.volumeId,e[27]=U);let W;e[28]!==H||e[29]!==U?(W=(0,g.jsxs)(p,{children:[B,H,U]}),e[28]=H,e[29]=U,e[30]=W):W=e[30];let G;e[31]===Symbol.for(`react.memo_cache_sentinel`)?(G=(0,g.jsx)(d,{children:(0,g.jsx)(`label`,{htmlFor:`description`,children:`Description (optional)`})}),e[31]=G):G=e[31];let K;e[32]===E?K=e[33]:(K=E(`description`),e[32]=E,e[33]=K);let q;e[34]===K?q=e[35]:(q=(0,g.jsxs)(p,{children:[G,(0,g.jsx)(ue,{id:`description`,placeholder:`Snapshot description`,...K})]}),e[34]=K,e[35]=q);let J;e[36]===N?J=e[37]:(J=fe(N),e[36]=N,e[37]=J);let Y;e[38]===J?Y=e[39]:(Y=(0,g.jsx)(l,{commands:J}),e[38]=J,e[39]=Y);let X;e[40]===t?X=e[41]:(X=async()=>await t({to:`/ec2/describe-snapshots`}),e[40]=t,e[41]=X);let Z;e[42]!==_.isPending||e[43]!==k||e[44]!==X?(Z=(0,g.jsx)(ce,{isPending:_.isPending,isSubmitting:k,onCancel:X,pendingLabel:`Creating…`,submitLabel:`Create Snapshot`}),e[42]=_.isPending,e[43]=k,e[44]=X,e[45]=Z):Z=e[45];let Q;e[46]!==z||e[47]!==W||e[48]!==q||e[49]!==Y||e[50]!==Z?(Q=(0,g.jsxs)(`form`,{className:`max-w-4xl space-y-6`,onSubmit:z,children:[W,q,Y,Z]}),e[46]=z,e[47]=W,e[48]=q,e[49]=Y,e[50]=Z,e[51]=Q):Q=e[51];let $;return e[52]!==Q||e[53]!==R?($=(0,g.jsxs)(g.Fragment,{children:[I,L,R,Q]}),e[52]=Q,e[53]=R,e[54]=$):$=e[54],$}function de(e){return(0,g.jsxs)(a,{value:e.VolumeId??``,children:[e.VolumeId,` (`,e.Size,` GiB)`]},e.VolumeId)}function fe(e){let t=e(`volumeId`),n=typeof t==`string`?t:``,r=e(`description`),i=typeof r==`string`?r:``,a=[{type:`bin`,value:`AWS_PROFILE=spinifex aws ec2 create-snapshot`},{type:`flag`,value:` \\
|
||||
--volume-id`},{type:`value`,value:` ${n||`<VolumeId>`}`}];return i&&a.push({type:`flag`,value:` \\
|
||||
--description`},{type:`value`,value:` "${i}"`}),[{label:`Create Snapshot`,parts:a}]}export{_ as component};
|
||||
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
|
||||
import{n as e}from"./compiler-runtime.js";import{t}from"./useSuspenseQuery.js";import{t as n}from"./back-link.js";import{t as r}from"./cli-command-panel.js";import{i}from"./elbv2.js";import{$t as a,Xr as o}from"./index.js";import{i as s,t as c}from"./zod.js";import{t as l}from"./error-banner.js";import{t as u}from"./form-actions.js";import{t as d}from"./page-heading.js";import{t as f}from"./target-group-form.js";import{a as p}from"./elbv22.js";var m=e();function h(){let e=o(),{data:h}=t(a),_=i(),v=h.Vpcs??[],y=s({resolver:c(p),defaultValues:{name:``,protocol:`HTTP`,port:80,vpcId:v[0]?.VpcId??``,healthCheck:{protocol:`HTTP`,path:`/`,port:`traffic-port`,intervalSeconds:30,timeoutSeconds:5,healthyThresholdCount:5,unhealthyThresholdCount:2,matcher:`200`},tags:[]}}),{handleSubmit:b,watch:x,formState:{isSubmitting:S}}=y;return(0,m.jsxs)(m.Fragment,{children:[(0,m.jsx)(n,{to:`/ec2/describe-target-groups`,children:`Back to target groups`}),(0,m.jsx)(d,{title:`Create Target Group`}),_.error&&(0,m.jsx)(l,{error:_.error,msg:`Failed to create target group`}),(0,m.jsxs)(`form`,{className:`max-w-4xl space-y-6`,onSubmit:b(async t=>{try{let n=(await _.mutateAsync(t)).TargetGroups?.[0]?.TargetGroupArn;e(n?{to:`/ec2/describe-target-groups/$id`,params:{id:encodeURIComponent(n)}}:{to:`/ec2/describe-target-groups`})}catch{}}),children:[(0,m.jsx)(f,{form:y,vpcs:v}),(0,m.jsx)(r,{commands:g(x)}),(0,m.jsx)(u,{isPending:_.isPending,isSubmitting:S,onCancel:async()=>await e({to:`/ec2/describe-target-groups`}),pendingLabel:`Creating…`,submitLabel:`Create Target Group`})]})]})}function g(e){let t=t=>{let n=e(t);return typeof n==`string`?n:``},n=t=>{let n=e(t);return typeof n==`number`&&Number.isFinite(n)?n:void 0},r=t(`name`),i=t(`protocol`)||`HTTP`,a=n(`port`),o=t(`vpcId`),s=t(`healthCheck.protocol`)||`HTTP`,c=t(`healthCheck.path`)||`/`,l=t(`healthCheck.port`)||`traffic-port`,u=n(`healthCheck.intervalSeconds`),d=n(`healthCheck.timeoutSeconds`),f=n(`healthCheck.healthyThresholdCount`),p=n(`healthCheck.unhealthyThresholdCount`),m=t(`healthCheck.matcher`)||`200`,h=[{type:`bin`,value:`AWS_PROFILE=spinifex aws elbv2 create-target-group`},{type:`flag`,value:` \\
|
||||
import{n as e}from"./compiler-runtime.js";import{t}from"./useSuspenseQuery.js";import{t as n}from"./back-link.js";import{t as r}from"./cli-command-panel.js";import{i}from"./elbv2.js";import{Qr as a,tn as o}from"./index.js";import{i as s,t as c}from"./zod.js";import{t as l}from"./error-banner.js";import{t as u}from"./form-actions.js";import{t as d}from"./page-heading.js";import{t as f}from"./target-group-form.js";import{a as p}from"./elbv22.js";var m=e();function h(){let e=a(),{data:h}=t(o),_=i(),v=h.Vpcs??[],y=s({resolver:c(p),defaultValues:{name:``,protocol:`HTTP`,port:80,vpcId:v[0]?.VpcId??``,healthCheck:{protocol:`HTTP`,path:`/`,port:`traffic-port`,intervalSeconds:30,timeoutSeconds:5,healthyThresholdCount:5,unhealthyThresholdCount:2,matcher:`200`},tags:[]}}),{handleSubmit:b,watch:x,formState:{isSubmitting:S}}=y;return(0,m.jsxs)(m.Fragment,{children:[(0,m.jsx)(n,{to:`/ec2/describe-target-groups`,children:`Back to target groups`}),(0,m.jsx)(d,{title:`Create Target Group`}),_.error&&(0,m.jsx)(l,{error:_.error,msg:`Failed to create target group`}),(0,m.jsxs)(`form`,{className:`max-w-4xl space-y-6`,onSubmit:b(async t=>{try{let n=(await _.mutateAsync(t)).TargetGroups?.[0]?.TargetGroupArn;e(n?{to:`/ec2/describe-target-groups/$id`,params:{id:encodeURIComponent(n)}}:{to:`/ec2/describe-target-groups`})}catch{}}),children:[(0,m.jsx)(f,{form:y,vpcs:v}),(0,m.jsx)(r,{commands:g(x)}),(0,m.jsx)(u,{isPending:_.isPending,isSubmitting:S,onCancel:async()=>await e({to:`/ec2/describe-target-groups`}),pendingLabel:`Creating…`,submitLabel:`Create Target Group`})]})]})}function g(e){let t=t=>{let n=e(t);return typeof n==`string`?n:``},n=t=>{let n=e(t);return typeof n==`number`&&Number.isFinite(n)?n:void 0},r=t(`name`),i=t(`protocol`)||`HTTP`,a=n(`port`),o=t(`vpcId`),s=t(`healthCheck.protocol`)||`HTTP`,c=t(`healthCheck.path`)||`/`,l=t(`healthCheck.port`)||`traffic-port`,u=n(`healthCheck.intervalSeconds`),d=n(`healthCheck.timeoutSeconds`),f=n(`healthCheck.healthyThresholdCount`),p=n(`healthCheck.unhealthyThresholdCount`),m=t(`healthCheck.matcher`)||`200`,h=[{type:`bin`,value:`AWS_PROFILE=spinifex aws elbv2 create-target-group`},{type:`flag`,value:` \\
|
||||
--name`},{type:`value`,value:` ${r||`<Name>`}`},{type:`flag`,value:` \\
|
||||
--protocol`},{type:`value`,value:` ${i}`},{type:`flag`,value:` \\
|
||||
--port`},{type:`value`,value:` ${a??80}`},{type:`flag`,value:` \\
|
||||
|
||||
@@ -1 +1 @@
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./back-link.js";import{t as r}from"./cli-command-panel.js";import{c as i}from"./iam.js";import{Xr as a,er as o}from"./index.js";import{a as s,i as c,t as l}from"./zod.js";import{t as u}from"./error-banner.js";import{t as d}from"./form-actions.js";import{t as f}from"./page-heading.js";import{a as p,r as m,t as h}from"./field.js";import{a as g}from"./iam2.js";var _=t(),v=e();function y(){let e=(0,_.c)(55),t=a(),y=i(),b;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(b={resolver:l(g)},e[0]=b):b=e[0];let{handleSubmit:x,register:S,control:C,formState:w}=c(b),{errors:T,isSubmitting:E}=w,D;e[1]===C?D=e[2]:(D={control:C},e[1]=C,e[2]=D);let O=s(D),k;e[3]===O?k=e[4]:(k=e=>e?O[e]:void 0,e[3]=O,e[4]=k);let A=k,j;e[5]!==y||e[6]!==t?(j=async e=>{await y.mutateAsync(e),t({to:`/iam/list-users`})},e[5]=y,e[6]=t,e[7]=j):j=e[7];let M=j,N,P;e[8]===Symbol.for(`react.memo_cache_sentinel`)?(N=(0,v.jsx)(n,{to:`/iam/list-users`,children:`Back to users`}),P=(0,v.jsx)(f,{title:`Create User`}),e[8]=N,e[9]=P):(N=e[8],P=e[9]);let F;e[10]===y.error?F=e[11]:(F=y.error&&(0,v.jsx)(u,{error:y.error,msg:`Failed to create user`}),e[10]=y.error,e[11]=F);let I;e[12]!==x||e[13]!==M?(I=x(M),e[12]=x,e[13]=M,e[14]=I):I=e[14];let L;e[15]===Symbol.for(`react.memo_cache_sentinel`)?(L=(0,v.jsx)(p,{children:(0,v.jsx)(`label`,{htmlFor:`userName`,children:`User Name`})}),e[15]=L):L=e[15];let R=!!T.userName,z;e[16]===S?z=e[17]:(z=S(`userName`),e[16]=S,e[17]=z);let B;e[18]!==R||e[19]!==z?(B=(0,v.jsx)(o,{"aria-invalid":R,id:`userName`,placeholder:`my-user...`,...z}),e[18]=R,e[19]=z,e[20]=B):B=e[20];let V;e[21]===T.userName?V=e[22]:(V=(0,v.jsx)(m,{errors:[T.userName]}),e[21]=T.userName,e[22]=V);let H;e[23]!==B||e[24]!==V?(H=(0,v.jsxs)(h,{children:[L,B,V]}),e[23]=B,e[24]=V,e[25]=H):H=e[25];let U;e[26]===Symbol.for(`react.memo_cache_sentinel`)?(U=(0,v.jsx)(p,{children:(0,v.jsx)(`label`,{htmlFor:`path`,children:`Path (optional)`})}),e[26]=U):U=e[26];let W;e[27]===S?W=e[28]:(W=S(`path`),e[27]=S,e[28]=W);let G;e[29]===W?G=e[30]:(G=(0,v.jsx)(o,{id:`path`,placeholder:`/`,...W}),e[29]=W,e[30]=G);let K;e[31]===T.path?K=e[32]:(K=(0,v.jsx)(m,{errors:[T.path]}),e[31]=T.path,e[32]=K);let q;e[33]!==G||e[34]!==K?(q=(0,v.jsxs)(h,{children:[U,G,K]}),e[33]=G,e[34]=K,e[35]=q):q=e[35];let J;e[36]===A?J=e[37]:(J=ee(A),e[36]=A,e[37]=J);let Y;e[38]===J?Y=e[39]:(Y=(0,v.jsx)(r,{commands:J}),e[38]=J,e[39]=Y);let X;e[40]===t?X=e[41]:(X=async()=>await t({to:`/iam/list-users`}),e[40]=t,e[41]=X);let Z;e[42]!==y.isPending||e[43]!==E||e[44]!==X?(Z=(0,v.jsx)(d,{isPending:y.isPending,isSubmitting:E,onCancel:X,pendingLabel:`Creating...`,submitLabel:`Create User`}),e[42]=y.isPending,e[43]=E,e[44]=X,e[45]=Z):Z=e[45];let Q;e[46]!==H||e[47]!==q||e[48]!==Y||e[49]!==Z||e[50]!==I?(Q=(0,v.jsxs)(`form`,{className:`max-w-4xl space-y-6`,onSubmit:I,children:[H,q,Y,Z]}),e[46]=H,e[47]=q,e[48]=Y,e[49]=Z,e[50]=I,e[51]=Q):Q=e[51];let $;return e[52]!==Q||e[53]!==F?($=(0,v.jsxs)(v.Fragment,{children:[N,P,F,Q]}),e[52]=Q,e[53]=F,e[54]=$):$=e[54],$}function ee(e){let t=e(`userName`),n=typeof t==`string`?t:``,r=e(`path`),i=typeof r==`string`?r:``,a=[{type:`bin`,value:`AWS_PROFILE=spinifex aws iam create-user`},{type:`flag`,value:` --user-name`},{type:`value`,value:` ${n||`<UserName>`}`}];return i&&i!==`/`&&a.push({type:`flag`,value:` --path`},{type:`value`,value:` ${i}`}),[{label:`Create User`,parts:a}]}export{y as component};
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./back-link.js";import{t as r}from"./cli-command-panel.js";import{c as i}from"./iam.js";import{Qr as a,nr as o}from"./index.js";import{a as s,i as c,t as l}from"./zod.js";import{t as u}from"./error-banner.js";import{t as d}from"./form-actions.js";import{t as f}from"./page-heading.js";import{a as p,r as m,t as h}from"./field.js";import{a as g}from"./iam2.js";var _=t(),v=e();function y(){let e=(0,_.c)(55),t=a(),y=i(),b;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(b={resolver:l(g)},e[0]=b):b=e[0];let{handleSubmit:x,register:S,control:C,formState:w}=c(b),{errors:T,isSubmitting:E}=w,D;e[1]===C?D=e[2]:(D={control:C},e[1]=C,e[2]=D);let O=s(D),k;e[3]===O?k=e[4]:(k=e=>e?O[e]:void 0,e[3]=O,e[4]=k);let A=k,j;e[5]!==y||e[6]!==t?(j=async e=>{await y.mutateAsync(e),t({to:`/iam/list-users`})},e[5]=y,e[6]=t,e[7]=j):j=e[7];let M=j,N,P;e[8]===Symbol.for(`react.memo_cache_sentinel`)?(N=(0,v.jsx)(n,{to:`/iam/list-users`,children:`Back to users`}),P=(0,v.jsx)(f,{title:`Create User`}),e[8]=N,e[9]=P):(N=e[8],P=e[9]);let F;e[10]===y.error?F=e[11]:(F=y.error&&(0,v.jsx)(u,{error:y.error,msg:`Failed to create user`}),e[10]=y.error,e[11]=F);let I;e[12]!==x||e[13]!==M?(I=x(M),e[12]=x,e[13]=M,e[14]=I):I=e[14];let L;e[15]===Symbol.for(`react.memo_cache_sentinel`)?(L=(0,v.jsx)(p,{children:(0,v.jsx)(`label`,{htmlFor:`userName`,children:`User Name`})}),e[15]=L):L=e[15];let R=!!T.userName,z;e[16]===S?z=e[17]:(z=S(`userName`),e[16]=S,e[17]=z);let B;e[18]!==R||e[19]!==z?(B=(0,v.jsx)(o,{"aria-invalid":R,id:`userName`,placeholder:`my-user...`,...z}),e[18]=R,e[19]=z,e[20]=B):B=e[20];let V;e[21]===T.userName?V=e[22]:(V=(0,v.jsx)(m,{errors:[T.userName]}),e[21]=T.userName,e[22]=V);let H;e[23]!==B||e[24]!==V?(H=(0,v.jsxs)(h,{children:[L,B,V]}),e[23]=B,e[24]=V,e[25]=H):H=e[25];let U;e[26]===Symbol.for(`react.memo_cache_sentinel`)?(U=(0,v.jsx)(p,{children:(0,v.jsx)(`label`,{htmlFor:`path`,children:`Path (optional)`})}),e[26]=U):U=e[26];let W;e[27]===S?W=e[28]:(W=S(`path`),e[27]=S,e[28]=W);let G;e[29]===W?G=e[30]:(G=(0,v.jsx)(o,{id:`path`,placeholder:`/`,...W}),e[29]=W,e[30]=G);let K;e[31]===T.path?K=e[32]:(K=(0,v.jsx)(m,{errors:[T.path]}),e[31]=T.path,e[32]=K);let q;e[33]!==G||e[34]!==K?(q=(0,v.jsxs)(h,{children:[U,G,K]}),e[33]=G,e[34]=K,e[35]=q):q=e[35];let J;e[36]===A?J=e[37]:(J=ee(A),e[36]=A,e[37]=J);let Y;e[38]===J?Y=e[39]:(Y=(0,v.jsx)(r,{commands:J}),e[38]=J,e[39]=Y);let X;e[40]===t?X=e[41]:(X=async()=>await t({to:`/iam/list-users`}),e[40]=t,e[41]=X);let Z;e[42]!==y.isPending||e[43]!==E||e[44]!==X?(Z=(0,v.jsx)(d,{isPending:y.isPending,isSubmitting:E,onCancel:X,pendingLabel:`Creating...`,submitLabel:`Create User`}),e[42]=y.isPending,e[43]=E,e[44]=X,e[45]=Z):Z=e[45];let Q;e[46]!==H||e[47]!==q||e[48]!==Y||e[49]!==Z||e[50]!==I?(Q=(0,v.jsxs)(`form`,{className:`max-w-4xl space-y-6`,onSubmit:I,children:[H,q,Y,Z]}),e[46]=H,e[47]=q,e[48]=Y,e[49]=Z,e[50]=I,e[51]=Q):Q=e[51];let $;return e[52]!==Q||e[53]!==F?($=(0,v.jsxs)(v.Fragment,{children:[N,P,F,Q]}),e[52]=Q,e[53]=F,e[54]=$):$=e[54],$}function ee(e){let t=e(`userName`),n=typeof t==`string`?t:``,r=e(`path`),i=typeof r==`string`?r:``,a=[{type:`bin`,value:`AWS_PROFILE=spinifex aws iam create-user`},{type:`flag`,value:` --user-name`},{type:`value`,value:` ${n||`<UserName>`}`}];return i&&i!==`/`&&a.push({type:`flag`,value:` --path`},{type:`value`,value:` ${i}`}),[{label:`Create User`,parts:a}]}export{y as component};
|
||||
@@ -1,3 +1,3 @@
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{t as r}from"./back-link.js";import{c as i,i as a,n as o,s,t as c}from"./select.js";import{t as l}from"./cli-command-panel.js";import{x as u}from"./ec2.js";import{Et as d,Xr as ee,er as te}from"./index.js";import{i as ne,n as re,t as ie}from"./zod.js";import{t as ae}from"./error-banner.js";import{t as oe}from"./form-actions.js";import{t as se}from"./page-heading.js";import{a as f,r as p,t as m}from"./field.js";import{m as h}from"./ec22.js";var g=t(),_=e();function v(){let e=(0,g.c)(57),t=ee(),{data:a}=n(d),v=u(),y;e[0]===a.AvailabilityZones?y=e[1]:(y=a.AvailabilityZones??[],e[0]=a.AvailabilityZones,e[1]=y);let b=y,x=b[0]?.ZoneName??``,S;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(S=ie(h),e[2]=S):S=e[2];let C;e[3]===x?C=e[4]:(C={resolver:S,defaultValues:{size:1,availabilityZone:x}},e[3]=x,e[4]=C);let{control:w,handleSubmit:T,register:E,watch:D,formState:O}=ne(C),{errors:k,isSubmitting:A}=O,j;e[5]!==v||e[6]!==t?(j=async e=>{await v.mutateAsync(e),t({to:`/ec2/describe-volumes`})},e[5]=v,e[6]=t,e[7]=j):j=e[7];let M=j,N,P;e[8]===Symbol.for(`react.memo_cache_sentinel`)?(N=(0,_.jsx)(r,{to:`/ec2/describe-volumes`,children:`Back to volumes`}),P=(0,_.jsx)(se,{title:`Create Volume`}),e[8]=N,e[9]=P):(N=e[8],P=e[9]);let F;e[10]===v.error?F=e[11]:(F=v.error&&(0,_.jsx)(ae,{error:v.error,msg:`Failed to create volume`}),e[10]=v.error,e[11]=F);let I;e[12]!==T||e[13]!==M?(I=T(M),e[12]=T,e[13]=M,e[14]=I):I=e[14];let L;e[15]===Symbol.for(`react.memo_cache_sentinel`)?(L=(0,_.jsx)(f,{children:(0,_.jsx)(`label`,{htmlFor:`size`,children:`Size (GiB)`})}),e[15]=L):L=e[15];let R=!!k.size,z;e[16]===E?z=e[17]:(z=E(`size`,{valueAsNumber:!0}),e[16]=E,e[17]=z);let B;e[18]!==R||e[19]!==z?(B=(0,_.jsx)(te,{"aria-invalid":R,id:`size`,max:16384,min:1,type:`number`,...z}),e[18]=R,e[19]=z,e[20]=B):B=e[20];let V;e[21]===k.size?V=e[22]:(V=(0,_.jsx)(p,{errors:[k.size]}),e[21]=k.size,e[22]=V);let H;e[23]!==B||e[24]!==V?(H=(0,_.jsxs)(m,{children:[L,B,V]}),e[23]=B,e[24]=V,e[25]=H):H=e[25];let U;e[26]===Symbol.for(`react.memo_cache_sentinel`)?(U=(0,_.jsx)(f,{children:(0,_.jsx)(`label`,{htmlFor:`availabilityZone`,children:`Availability Zone`})}),e[26]=U):U=e[26];let W;e[27]!==b||e[28]!==k.availabilityZone?(W=e=>{let{field:t}=e;return(0,_.jsxs)(c,{onValueChange:e=>t.onChange(e),value:t.value??``,children:[(0,_.jsx)(s,{"aria-invalid":!!k.availabilityZone,className:`w-full`,id:`availabilityZone`,children:(0,_.jsx)(i,{})}),(0,_.jsx)(o,{children:b.map(ce)})]})},e[27]=b,e[28]=k.availabilityZone,e[29]=W):W=e[29];let G;e[30]!==w||e[31]!==W?(G=(0,_.jsx)(re,{control:w,name:`availabilityZone`,render:W}),e[30]=w,e[31]=W,e[32]=G):G=e[32];let K;e[33]===k.availabilityZone?K=e[34]:(K=(0,_.jsx)(p,{errors:[k.availabilityZone]}),e[33]=k.availabilityZone,e[34]=K);let q;e[35]!==G||e[36]!==K?(q=(0,_.jsxs)(m,{children:[U,G,K]}),e[35]=G,e[36]=K,e[37]=q):q=e[37];let J;e[38]===D?J=e[39]:(J=le(D),e[38]=D,e[39]=J);let Y;e[40]===J?Y=e[41]:(Y=(0,_.jsx)(l,{commands:J}),e[40]=J,e[41]=Y);let X;e[42]===t?X=e[43]:(X=async()=>await t({to:`/ec2/describe-volumes`}),e[42]=t,e[43]=X);let Z;e[44]!==v.isPending||e[45]!==A||e[46]!==X?(Z=(0,_.jsx)(oe,{isPending:v.isPending,isSubmitting:A,onCancel:X,pendingLabel:`Creating…`,submitLabel:`Create Volume`}),e[44]=v.isPending,e[45]=A,e[46]=X,e[47]=Z):Z=e[47];let Q;e[48]!==H||e[49]!==q||e[50]!==Y||e[51]!==Z||e[52]!==I?(Q=(0,_.jsxs)(`form`,{className:`max-w-4xl space-y-6`,onSubmit:I,children:[H,q,Y,Z]}),e[48]=H,e[49]=q,e[50]=Y,e[51]=Z,e[52]=I,e[53]=Q):Q=e[53];let $;return e[54]!==Q||e[55]!==F?($=(0,_.jsxs)(_.Fragment,{children:[N,P,F,Q]}),e[54]=Q,e[55]=F,e[56]=$):$=e[56],$}function ce(e){return(0,_.jsx)(a,{value:e.ZoneName??``,children:e.ZoneName},e.ZoneName)}function le(e){let t=e(`size`),n=typeof t==`number`?t:0,r=e(`availabilityZone`),i=typeof r==`string`?r:``;return[{label:`Create Volume`,parts:[{type:`bin`,value:`AWS_PROFILE=spinifex aws ec2 create-volume`},{type:`flag`,value:` \\
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{t as r}from"./back-link.js";import{c as i,i as a,n as o,s,t as c}from"./select.js";import{t as l}from"./cli-command-panel.js";import{x as u}from"./ec2.js";import{Ot as d,Qr as ee,nr as te}from"./index.js";import{i as ne,n as re,t as ie}from"./zod.js";import{t as ae}from"./error-banner.js";import{t as oe}from"./form-actions.js";import{t as se}from"./page-heading.js";import{a as f,r as p,t as m}from"./field.js";import{m as h}from"./ec22.js";var g=t(),_=e();function v(){let e=(0,g.c)(57),t=ee(),{data:a}=n(d),v=u(),y;e[0]===a.AvailabilityZones?y=e[1]:(y=a.AvailabilityZones??[],e[0]=a.AvailabilityZones,e[1]=y);let b=y,x=b[0]?.ZoneName??``,S;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(S=ie(h),e[2]=S):S=e[2];let C;e[3]===x?C=e[4]:(C={resolver:S,defaultValues:{size:1,availabilityZone:x}},e[3]=x,e[4]=C);let{control:w,handleSubmit:T,register:E,watch:D,formState:O}=ne(C),{errors:k,isSubmitting:A}=O,j;e[5]!==v||e[6]!==t?(j=async e=>{await v.mutateAsync(e),t({to:`/ec2/describe-volumes`})},e[5]=v,e[6]=t,e[7]=j):j=e[7];let M=j,N,P;e[8]===Symbol.for(`react.memo_cache_sentinel`)?(N=(0,_.jsx)(r,{to:`/ec2/describe-volumes`,children:`Back to volumes`}),P=(0,_.jsx)(se,{title:`Create Volume`}),e[8]=N,e[9]=P):(N=e[8],P=e[9]);let F;e[10]===v.error?F=e[11]:(F=v.error&&(0,_.jsx)(ae,{error:v.error,msg:`Failed to create volume`}),e[10]=v.error,e[11]=F);let I;e[12]!==T||e[13]!==M?(I=T(M),e[12]=T,e[13]=M,e[14]=I):I=e[14];let L;e[15]===Symbol.for(`react.memo_cache_sentinel`)?(L=(0,_.jsx)(f,{children:(0,_.jsx)(`label`,{htmlFor:`size`,children:`Size (GiB)`})}),e[15]=L):L=e[15];let R=!!k.size,z;e[16]===E?z=e[17]:(z=E(`size`,{valueAsNumber:!0}),e[16]=E,e[17]=z);let B;e[18]!==R||e[19]!==z?(B=(0,_.jsx)(te,{"aria-invalid":R,id:`size`,max:16384,min:1,type:`number`,...z}),e[18]=R,e[19]=z,e[20]=B):B=e[20];let V;e[21]===k.size?V=e[22]:(V=(0,_.jsx)(p,{errors:[k.size]}),e[21]=k.size,e[22]=V);let H;e[23]!==B||e[24]!==V?(H=(0,_.jsxs)(m,{children:[L,B,V]}),e[23]=B,e[24]=V,e[25]=H):H=e[25];let U;e[26]===Symbol.for(`react.memo_cache_sentinel`)?(U=(0,_.jsx)(f,{children:(0,_.jsx)(`label`,{htmlFor:`availabilityZone`,children:`Availability Zone`})}),e[26]=U):U=e[26];let W;e[27]!==b||e[28]!==k.availabilityZone?(W=e=>{let{field:t}=e;return(0,_.jsxs)(c,{onValueChange:e=>t.onChange(e),value:t.value??``,children:[(0,_.jsx)(s,{"aria-invalid":!!k.availabilityZone,className:`w-full`,id:`availabilityZone`,children:(0,_.jsx)(i,{})}),(0,_.jsx)(o,{children:b.map(ce)})]})},e[27]=b,e[28]=k.availabilityZone,e[29]=W):W=e[29];let G;e[30]!==w||e[31]!==W?(G=(0,_.jsx)(re,{control:w,name:`availabilityZone`,render:W}),e[30]=w,e[31]=W,e[32]=G):G=e[32];let K;e[33]===k.availabilityZone?K=e[34]:(K=(0,_.jsx)(p,{errors:[k.availabilityZone]}),e[33]=k.availabilityZone,e[34]=K);let q;e[35]!==G||e[36]!==K?(q=(0,_.jsxs)(m,{children:[U,G,K]}),e[35]=G,e[36]=K,e[37]=q):q=e[37];let J;e[38]===D?J=e[39]:(J=le(D),e[38]=D,e[39]=J);let Y;e[40]===J?Y=e[41]:(Y=(0,_.jsx)(l,{commands:J}),e[40]=J,e[41]=Y);let X;e[42]===t?X=e[43]:(X=async()=>await t({to:`/ec2/describe-volumes`}),e[42]=t,e[43]=X);let Z;e[44]!==v.isPending||e[45]!==A||e[46]!==X?(Z=(0,_.jsx)(oe,{isPending:v.isPending,isSubmitting:A,onCancel:X,pendingLabel:`Creating…`,submitLabel:`Create Volume`}),e[44]=v.isPending,e[45]=A,e[46]=X,e[47]=Z):Z=e[47];let Q;e[48]!==H||e[49]!==q||e[50]!==Y||e[51]!==Z||e[52]!==I?(Q=(0,_.jsxs)(`form`,{className:`max-w-4xl space-y-6`,onSubmit:I,children:[H,q,Y,Z]}),e[48]=H,e[49]=q,e[50]=Y,e[51]=Z,e[52]=I,e[53]=Q):Q=e[53];let $;return e[54]!==Q||e[55]!==F?($=(0,_.jsxs)(_.Fragment,{children:[N,P,F,Q]}),e[54]=Q,e[55]=F,e[56]=$):$=e[56],$}function ce(e){return(0,_.jsx)(a,{value:e.ZoneName??``,children:e.ZoneName},e.ZoneName)}function le(e){let t=e(`size`),n=typeof t==`number`?t:0,r=e(`availabilityZone`),i=typeof r==`string`?r:``;return[{label:`Create Volume`,parts:[{type:`bin`,value:`AWS_PROFILE=spinifex aws ec2 create-volume`},{type:`flag`,value:` \\
|
||||
--size`},{type:`value`,value:` ${n||1}`},{type:`flag`,value:` \\
|
||||
--availability-zone`},{type:`value`,value:` ${i||`<AvailabilityZone>`}`}]}]}export{v as component};
|
||||
File diff suppressed because one or more lines are too long
@@ -1 +1 @@
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{ni as r}from"./awsClient.js";import{Ut as i}from"./auth.js";import{t as a}from"./button.js";import{Tt as o}from"./index.js";import{t as s}from"./page-heading.js";import{t as c}from"./list-card.js";var l=t(),u=e();function d(){let e=(0,l.c)(5),{data:t}=n(o),i;e[0]===t.Addresses?i=e[1]:(i=t.Addresses??[],e[0]=t.Addresses,e[1]=i);let c=i,d;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(d=(0,u.jsx)(s,{actions:(0,u.jsx)(r,{to:`/ec2/allocate-address`,children:(0,u.jsx)(a,{children:`Allocate Elastic IP`})}),title:`Elastic IPs`}),e[2]=d):d=e[2];let p;return e[3]===c?p=e[4]:(p=(0,u.jsxs)(u.Fragment,{children:[d,c.length>0?(0,u.jsx)(`div`,{className:`space-y-4`,children:c.map(f)}):(0,u.jsx)(`p`,{className:`text-muted-foreground`,children:`No Elastic IPs found.`})]}),e[3]=c,e[4]=p),p}function f(e){if(!e.AllocationId)return null;let t=i(e.Tags),n=e.AssociationId?`${e.PublicIp} • associated`:`${e.PublicIp} • available`;return(0,u.jsx)(c,{params:{id:e.AllocationId},subtitle:n,title:t?`${e.AllocationId} (${t})`:e.AllocationId??``,to:`/ec2/describe-addresses/$id`},e.AllocationId)}export{d as component};
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{ni as r}from"./awsClient.js";import{Ut as i}from"./auth.js";import{t as a}from"./button.js";import{Dt as o}from"./index.js";import{t as s}from"./page-heading.js";import{t as c}from"./list-card.js";var l=t(),u=e();function d(){let e=(0,l.c)(5),{data:t}=n(o),i;e[0]===t.Addresses?i=e[1]:(i=t.Addresses??[],e[0]=t.Addresses,e[1]=i);let c=i,d;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(d=(0,u.jsx)(s,{actions:(0,u.jsx)(r,{to:`/ec2/allocate-address`,children:(0,u.jsx)(a,{children:`Allocate Elastic IP`})}),title:`Elastic IPs`}),e[2]=d):d=e[2];let p;return e[3]===c?p=e[4]:(p=(0,u.jsxs)(u.Fragment,{children:[d,c.length>0?(0,u.jsx)(`div`,{className:`space-y-4`,children:c.map(f)}):(0,u.jsx)(`p`,{className:`text-muted-foreground`,children:`No Elastic IPs found.`})]}),e[3]=c,e[4]=p),p}function f(e){if(!e.AllocationId)return null;let t=i(e.Tags),n=e.AssociationId?`${e.PublicIp} • associated`:`${e.PublicIp} • available`;return(0,u.jsx)(c,{params:{id:e.AllocationId},subtitle:n,title:t?`${e.AllocationId} (${t})`:e.AllocationId??``,to:`/ec2/describe-addresses/$id`},e.AllocationId)}export{d as component};
|
||||
@@ -1 +1 @@
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{kt as r}from"./index.js";import{t as i}from"./page-heading.js";import{t as a}from"./list-card.js";import{t as o}from"./state-badge.js";import{n as s}from"./system-managed.js";var c=t(),l=e();function u(){let e=(0,c.c)(3),{data:t}=n(r),a;if(e[0]!==t.Images){let n=(t.Images??[]).filter(f),r;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(r=(0,l.jsx)(i,{title:`Images`}),e[2]=r):r=e[2],a=(0,l.jsxs)(l.Fragment,{children:[r,n.length>0?(0,l.jsx)(`div`,{className:`space-y-4`,children:n.map(d)}):(0,l.jsx)(`p`,{className:`text-muted-foreground`,children:`No images found.`})]}),e[0]=t.Images,e[1]=a}else a=e[1];return a}function d(e){return e.ImageId?(0,l.jsx)(a,{badge:(0,l.jsx)(o,{state:e.State}),params:{id:e.ImageId},subtitle:e.ImageId??``,title:e.Name??e.ImageId??``,to:`/ec2/describe-images/$id`},e.ImageId):null}function f(e){return!s(e)}export{u as component};
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{jt as r}from"./index.js";import{t as i}from"./page-heading.js";import{t as a}from"./list-card.js";import{t as o}from"./state-badge.js";import{r as s}from"./system-managed.js";var c=t(),l=e();function u(){let e=(0,c.c)(3),{data:t}=n(r),a;if(e[0]!==t.Images){let n=(t.Images??[]).filter(f),r;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(r=(0,l.jsx)(i,{title:`Images`}),e[2]=r):r=e[2],a=(0,l.jsxs)(l.Fragment,{children:[r,n.length>0?(0,l.jsx)(`div`,{className:`space-y-4`,children:n.map(d)}):(0,l.jsx)(`p`,{className:`text-muted-foreground`,children:`No images found.`})]}),e[0]=t.Images,e[1]=a}else a=e[1];return a}function d(e){return e.ImageId?(0,l.jsx)(a,{badge:(0,l.jsx)(o,{state:e.State}),params:{id:e.ImageId},subtitle:e.ImageId??``,title:e.Name??e.ImageId??``,to:`/ec2/describe-images/$id`},e.ImageId):null}function f(e){return!s(e)}export{u as component};
|
||||
@@ -1 +1 @@
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{ni as r}from"./awsClient.js";import{t as i}from"./button.js";import{Mt as a}from"./index.js";import{t as o}from"./page-heading.js";import{t as s}from"./list-card.js";import{t as c}from"./state-badge.js";var l=t(),u=e(),d={running:0,pending:1,stopping:2,"shutting-down":3,stopped:4,terminated:5};function f(){let e=(0,l.c)(3),{data:t}=n(a),s;if(e[0]!==t.Reservations){let n=(t.Reservations?.flatMap(h)??[]).toSorted(m),a;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(a=(0,u.jsx)(o,{actions:(0,u.jsx)(r,{to:`/ec2/run-instances`,children:(0,u.jsx)(i,{children:`Run Instances`})}),title:`Instances`}),e[2]=a):a=e[2],s=(0,u.jsxs)(u.Fragment,{children:[a,n.length>0?(0,u.jsx)(`div`,{className:`space-y-4`,children:n.map(p)}):(0,u.jsx)(`p`,{className:`text-muted-foreground`,children:`No instances found.`})]}),e[0]=t.Reservations,e[1]=s}else s=e[1];return s}function p(e){return e.InstanceId?(0,u.jsx)(s,{badge:(0,u.jsx)(c,{state:e.State?.Name}),params:{id:e.InstanceId},subtitle:`${e.InstanceType}`,title:e.InstanceId,to:`/ec2/describe-instances/$id`},e.InstanceId):null}function m(e,t){let n=d[e.State?.Name??``]??6,r=d[t.State?.Name??``]??6;return n===r?(e.InstanceId??``).localeCompare(t.InstanceId??``):n-r}function h(e){return e.Instances??[]}export{f as component};
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{ni as r}from"./awsClient.js";import{t as i}from"./button.js";import{Pt as a}from"./index.js";import{t as o}from"./page-heading.js";import{t as s}from"./list-card.js";import{t as c}from"./state-badge.js";var l=t(),u=e(),d={running:0,pending:1,stopping:2,"shutting-down":3,stopped:4,terminated:5};function f(){let e=(0,l.c)(3),{data:t}=n(a),s;if(e[0]!==t.Reservations){let n=(t.Reservations?.flatMap(h)??[]).toSorted(m),a;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(a=(0,u.jsx)(o,{actions:(0,u.jsx)(r,{to:`/ec2/run-instances`,children:(0,u.jsx)(i,{children:`Run Instances`})}),title:`Instances`}),e[2]=a):a=e[2],s=(0,u.jsxs)(u.Fragment,{children:[a,n.length>0?(0,u.jsx)(`div`,{className:`space-y-4`,children:n.map(p)}):(0,u.jsx)(`p`,{className:`text-muted-foreground`,children:`No instances found.`})]}),e[0]=t.Reservations,e[1]=s}else s=e[1];return s}function p(e){return e.InstanceId?(0,u.jsx)(s,{badge:(0,u.jsx)(c,{state:e.State?.Name}),params:{id:e.InstanceId},subtitle:`${e.InstanceType}`,title:e.InstanceId,to:`/ec2/describe-instances/$id`},e.InstanceId):null}function m(e,t){let n=d[e.State?.Name??``]??6,r=d[t.State?.Name??``]??6;return n===r?(e.InstanceId??``).localeCompare(t.InstanceId??``):n-r}function h(e){return e.Instances??[]}export{f as component};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{ni as r}from"./awsClient.js";import{Ut as i}from"./auth.js";import{t as a}from"./button.js";import{Pt as o}from"./index.js";import{t as s}from"./page-heading.js";import{t as c}from"./list-card.js";var l=t(),u=e();function d(){let e=(0,l.c)(5),{data:t}=n(o),i;e[0]===t.InternetGateways?i=e[1]:(i=t.InternetGateways??[],e[0]=t.InternetGateways,e[1]=i);let c=i,d;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(d=(0,u.jsx)(s,{actions:(0,u.jsx)(r,{to:`/ec2/create-internet-gateway`,children:(0,u.jsx)(a,{children:`Create Internet Gateway`})}),title:`Internet Gateways`}),e[2]=d):d=e[2];let p;return e[3]===c?p=e[4]:(p=(0,u.jsxs)(u.Fragment,{children:[d,c.length>0?(0,u.jsx)(`div`,{className:`space-y-4`,children:c.map(f)}):(0,u.jsx)(`p`,{className:`text-muted-foreground`,children:`No Internet Gateways found.`})]}),e[3]=c,e[4]=p),p}function f(e){if(!e.InternetGatewayId)return null;let t=i(e.Tags),n=e.Attachments?.[0]?.VpcId;return(0,u.jsx)(c,{params:{id:e.InternetGatewayId},subtitle:n?`attached to ${n}`:`detached`,title:t?`${e.InternetGatewayId} (${t})`:e.InternetGatewayId,to:`/ec2/describe-internet-gateways/$id`},e.InternetGatewayId)}export{d as component};
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{ni as r}from"./awsClient.js";import{Ut as i}from"./auth.js";import{t as a}from"./button.js";import{It as o}from"./index.js";import{t as s}from"./page-heading.js";import{t as c}from"./list-card.js";var l=t(),u=e();function d(){let e=(0,l.c)(5),{data:t}=n(o),i;e[0]===t.InternetGateways?i=e[1]:(i=t.InternetGateways??[],e[0]=t.InternetGateways,e[1]=i);let c=i,d;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(d=(0,u.jsx)(s,{actions:(0,u.jsx)(r,{to:`/ec2/create-internet-gateway`,children:(0,u.jsx)(a,{children:`Create Internet Gateway`})}),title:`Internet Gateways`}),e[2]=d):d=e[2];let p;return e[3]===c?p=e[4]:(p=(0,u.jsxs)(u.Fragment,{children:[d,c.length>0?(0,u.jsx)(`div`,{className:`space-y-4`,children:c.map(f)}):(0,u.jsx)(`p`,{className:`text-muted-foreground`,children:`No Internet Gateways found.`})]}),e[3]=c,e[4]=p),p}function f(e){if(!e.InternetGatewayId)return null;let t=i(e.Tags),n=e.Attachments?.[0]?.VpcId;return(0,u.jsx)(c,{params:{id:e.InternetGatewayId},subtitle:n?`attached to ${n}`:`detached`,title:t?`${e.InternetGatewayId} (${t})`:e.InternetGatewayId,to:`/ec2/describe-internet-gateways/$id`},e.InternetGatewayId)}export{d as component};
|
||||
@@ -1 +1 @@
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{ni as r}from"./awsClient.js";import{t as i}from"./button.js";import{It as a}from"./index.js";import{t as o}from"./page-heading.js";import{t as s}from"./list-card.js";var c=t(),l=e();function u(){let e=(0,c.c)(4),{data:t}=n(a),s;if(e[0]!==t.KeyPairs){let n=(t.KeyPairs??[]).toSorted(f),a;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(a=(0,l.jsx)(r,{to:`/ec2/import-key-pair`,children:(0,l.jsx)(i,{variant:`outline`,children:`Import Key Pair`})}),e[2]=a):a=e[2];let c;e[3]===Symbol.for(`react.memo_cache_sentinel`)?(c=(0,l.jsx)(o,{actions:(0,l.jsxs)(`div`,{className:`flex gap-2`,children:[a,(0,l.jsx)(r,{to:`/ec2/create-key-pair`,children:(0,l.jsx)(i,{children:`Create Key Pair`})})]}),title:`Key Pairs`}),e[3]=c):c=e[3],s=(0,l.jsxs)(l.Fragment,{children:[c,n.length>0?(0,l.jsx)(`div`,{className:`space-y-4`,children:n.map(d)}):(0,l.jsx)(`p`,{className:`text-muted-foreground`,children:`No key pairs found.`})]}),e[0]=t.KeyPairs,e[1]=s}else s=e[1];return s}function d(e){return e.KeyPairId?(0,l.jsx)(s,{params:{id:e.KeyPairId},subtitle:e.KeyPairId??``,title:e.KeyName??``,to:`/ec2/describe-key-pairs/$id`},e.KeyPairId):null}function f(e,t){let n=e.KeyName?.toLowerCase()??``,r=t.KeyName?.toLowerCase()??``;return n.localeCompare(r)}export{u as component};
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{ni as r}from"./awsClient.js";import{t as i}from"./button.js";import{Rt as a}from"./index.js";import{t as o}from"./page-heading.js";import{t as s}from"./list-card.js";var c=t(),l=e();function u(){let e=(0,c.c)(4),{data:t}=n(a),s;if(e[0]!==t.KeyPairs){let n=(t.KeyPairs??[]).toSorted(f),a;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(a=(0,l.jsx)(r,{to:`/ec2/import-key-pair`,children:(0,l.jsx)(i,{variant:`outline`,children:`Import Key Pair`})}),e[2]=a):a=e[2];let c;e[3]===Symbol.for(`react.memo_cache_sentinel`)?(c=(0,l.jsx)(o,{actions:(0,l.jsxs)(`div`,{className:`flex gap-2`,children:[a,(0,l.jsx)(r,{to:`/ec2/create-key-pair`,children:(0,l.jsx)(i,{children:`Create Key Pair`})})]}),title:`Key Pairs`}),e[3]=c):c=e[3],s=(0,l.jsxs)(l.Fragment,{children:[c,n.length>0?(0,l.jsx)(`div`,{className:`space-y-4`,children:n.map(d)}):(0,l.jsx)(`p`,{className:`text-muted-foreground`,children:`No key pairs found.`})]}),e[0]=t.KeyPairs,e[1]=s}else s=e[1];return s}function d(e){return e.KeyPairId?(0,l.jsx)(s,{params:{id:e.KeyPairId},subtitle:e.KeyPairId??``,title:e.KeyName??``,to:`/ec2/describe-key-pairs/$id`},e.KeyPairId):null}function f(e,t){let n=e.KeyName?.toLowerCase()??``,r=t.KeyName?.toLowerCase()??``;return n.localeCompare(r)}export{u as component};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{ni as r}from"./awsClient.js";import{Bt as i}from"./auth.js";import{t as a}from"./button.js";import{Xr as o,q as s}from"./index.js";import{t as c}from"./page-heading.js";import{t as l}from"./state-badge.js";var u=t(),d=e();function f(){let e=(0,u.c)(10),t=o(),{data:f}=n(s),m;e[0]===f.LoadBalancers?m=e[1]:(m=f.LoadBalancers??[],e[0]=f.LoadBalancers,e[1]=m);let h=m,g;e[2]===t?g=e[3]:(g=(0,d.jsx)(c,{actions:(0,d.jsx)(a,{onClick:async()=>await t({to:`/ec2/create-load-balancer`}),children:`Create Load Balancer`}),title:`Load Balancers`}),e[2]=t,e[3]=g);let _;e[4]!==h||e[5]!==t?(_=h.length>0?(0,d.jsx)(`div`,{className:`overflow-x-auto rounded-lg border bg-card`,children:(0,d.jsxs)(`table`,{className:`w-full text-sm`,children:[(0,d.jsx)(`thead`,{children:(0,d.jsxs)(`tr`,{className:`border-b text-left text-muted-foreground`,children:[(0,d.jsx)(`th`,{className:`px-4 py-2 font-medium`,children:`Name`}),(0,d.jsx)(`th`,{className:`px-4 py-2 font-medium`,children:`DNS Name`}),(0,d.jsx)(`th`,{className:`px-4 py-2 font-medium`,children:`State`}),(0,d.jsx)(`th`,{className:`px-4 py-2 font-medium`,children:`Type`}),(0,d.jsx)(`th`,{className:`px-4 py-2 font-medium`,children:`Scheme`}),(0,d.jsx)(`th`,{className:`px-4 py-2 font-medium`,children:`VPC`}),(0,d.jsx)(`th`,{className:`px-4 py-2 font-medium`,children:`Created`})]})}),(0,d.jsx)(`tbody`,{children:h.map(e=>{if(!e.LoadBalancerArn)return null;let n=e.LoadBalancerArn;return(0,d.jsxs)(`tr`,{className:`cursor-pointer border-b transition-colors last:border-0 hover:bg-accent`,onClick:async()=>await t({to:`/ec2/describe-load-balancers/$id`,params:{id:encodeURIComponent(n)}}),children:[(0,d.jsx)(`td`,{className:`px-4 py-2 font-medium`,children:(0,d.jsx)(r,{className:`text-primary hover:underline`,onClick:p,params:{id:encodeURIComponent(n)},to:`/ec2/describe-load-balancers/$id`,children:e.LoadBalancerName??n})}),(0,d.jsx)(`td`,{className:`px-4 py-2 font-mono text-xs`,children:e.DNSName??``}),(0,d.jsx)(`td`,{className:`px-4 py-2`,children:(0,d.jsx)(l,{state:e.State?.Code})}),(0,d.jsx)(`td`,{className:`px-4 py-2`,children:e.Type??``}),(0,d.jsx)(`td`,{className:`px-4 py-2`,children:e.Scheme??``}),(0,d.jsx)(`td`,{className:`px-4 py-2 font-mono text-xs`,children:e.VpcId??``}),(0,d.jsx)(`td`,{className:`px-4 py-2 text-xs`,children:i(e.CreatedTime)})]},n)})})]})}):(0,d.jsx)(`p`,{className:`text-muted-foreground`,children:`No load balancers found.`}),e[4]=h,e[5]=t,e[6]=_):_=e[6];let v;return e[7]!==g||e[8]!==_?(v=(0,d.jsxs)(d.Fragment,{children:[g,_]}),e[7]=g,e[8]=_,e[9]=v):v=e[9],v}function p(e){return e.stopPropagation()}var m=f;export{m as component};
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{ni as r}from"./awsClient.js";import{Bt as i}from"./auth.js";import{t as a}from"./button.js";import{Qr as o,Y as s}from"./index.js";import{t as c}from"./page-heading.js";import{t as l}from"./state-badge.js";var u=t(),d=e();function f(){let e=(0,u.c)(10),t=o(),{data:f}=n(s),m;e[0]===f.LoadBalancers?m=e[1]:(m=f.LoadBalancers??[],e[0]=f.LoadBalancers,e[1]=m);let h=m,g;e[2]===t?g=e[3]:(g=(0,d.jsx)(c,{actions:(0,d.jsx)(a,{onClick:async()=>await t({to:`/ec2/create-load-balancer`}),children:`Create Load Balancer`}),title:`Load Balancers`}),e[2]=t,e[3]=g);let _;e[4]!==h||e[5]!==t?(_=h.length>0?(0,d.jsx)(`div`,{className:`overflow-x-auto rounded-lg border bg-card`,children:(0,d.jsxs)(`table`,{className:`w-full text-sm`,children:[(0,d.jsx)(`thead`,{children:(0,d.jsxs)(`tr`,{className:`border-b text-left text-muted-foreground`,children:[(0,d.jsx)(`th`,{className:`px-4 py-2 font-medium`,children:`Name`}),(0,d.jsx)(`th`,{className:`px-4 py-2 font-medium`,children:`DNS Name`}),(0,d.jsx)(`th`,{className:`px-4 py-2 font-medium`,children:`State`}),(0,d.jsx)(`th`,{className:`px-4 py-2 font-medium`,children:`Type`}),(0,d.jsx)(`th`,{className:`px-4 py-2 font-medium`,children:`Scheme`}),(0,d.jsx)(`th`,{className:`px-4 py-2 font-medium`,children:`VPC`}),(0,d.jsx)(`th`,{className:`px-4 py-2 font-medium`,children:`Created`})]})}),(0,d.jsx)(`tbody`,{children:h.map(e=>{if(!e.LoadBalancerArn)return null;let n=e.LoadBalancerArn;return(0,d.jsxs)(`tr`,{className:`cursor-pointer border-b transition-colors last:border-0 hover:bg-accent`,onClick:async()=>await t({to:`/ec2/describe-load-balancers/$id`,params:{id:encodeURIComponent(n)}}),children:[(0,d.jsx)(`td`,{className:`px-4 py-2 font-medium`,children:(0,d.jsx)(r,{className:`text-primary hover:underline`,onClick:p,params:{id:encodeURIComponent(n)},to:`/ec2/describe-load-balancers/$id`,children:e.LoadBalancerName??n})}),(0,d.jsx)(`td`,{className:`px-4 py-2 font-mono text-xs`,children:e.DNSName??``}),(0,d.jsx)(`td`,{className:`px-4 py-2`,children:(0,d.jsx)(l,{state:e.State?.Code})}),(0,d.jsx)(`td`,{className:`px-4 py-2`,children:e.Type??``}),(0,d.jsx)(`td`,{className:`px-4 py-2`,children:e.Scheme??``}),(0,d.jsx)(`td`,{className:`px-4 py-2 font-mono text-xs`,children:e.VpcId??``}),(0,d.jsx)(`td`,{className:`px-4 py-2 text-xs`,children:i(e.CreatedTime)})]},n)})})]})}):(0,d.jsx)(`p`,{className:`text-muted-foreground`,children:`No load balancers found.`}),e[4]=h,e[5]=t,e[6]=_):_=e[6];let v;return e[7]!==g||e[8]!==_?(v=(0,d.jsxs)(d.Fragment,{children:[g,_]}),e[7]=g,e[8]=_,e[9]=v):v=e[9],v}function p(e){return e.stopPropagation()}var m=f;export{m as component};
|
||||
@@ -1 +1 @@
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{ni as r}from"./awsClient.js";import{Ut as i}from"./auth.js";import{t as a}from"./button.js";import{Rt as o}from"./index.js";import{t as s}from"./page-heading.js";import{t as c}from"./list-card.js";import{t as l}from"./state-badge.js";var u=t(),d=e();function f(){let e=(0,u.c)(5),{data:t}=n(o),i;e[0]===t.NatGateways?i=e[1]:(i=t.NatGateways??[],e[0]=t.NatGateways,e[1]=i);let c=i,l;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(l=(0,d.jsx)(s,{actions:(0,d.jsx)(r,{to:`/ec2/create-nat-gateway`,children:(0,d.jsx)(a,{children:`Create NAT Gateway`})}),title:`NAT Gateways`}),e[2]=l):l=e[2];let f;return e[3]===c?f=e[4]:(f=(0,d.jsxs)(d.Fragment,{children:[l,c.length>0?(0,d.jsx)(`div`,{className:`space-y-4`,children:c.map(p)}):(0,d.jsx)(`p`,{className:`text-muted-foreground`,children:`No NAT Gateways found.`})]}),e[3]=c,e[4]=f),f}function p(e){if(!e.NatGatewayId)return null;let t=i(e.Tags);return(0,d.jsx)(c,{badge:(0,d.jsx)(l,{state:e.State}),params:{id:e.NatGatewayId},subtitle:e.SubnetId??``,title:t?`${e.NatGatewayId} (${t})`:e.NatGatewayId,to:`/ec2/describe-nat-gateways/$id`},e.NatGatewayId)}export{f as component};
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{ni as r}from"./awsClient.js";import{Ut as i}from"./auth.js";import{t as a}from"./button.js";import{Bt as o}from"./index.js";import{t as s}from"./page-heading.js";import{t as c}from"./list-card.js";import{t as l}from"./state-badge.js";var u=t(),d=e();function f(){let e=(0,u.c)(5),{data:t}=n(o),i;e[0]===t.NatGateways?i=e[1]:(i=t.NatGateways??[],e[0]=t.NatGateways,e[1]=i);let c=i,l;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(l=(0,d.jsx)(s,{actions:(0,d.jsx)(r,{to:`/ec2/create-nat-gateway`,children:(0,d.jsx)(a,{children:`Create NAT Gateway`})}),title:`NAT Gateways`}),e[2]=l):l=e[2];let f;return e[3]===c?f=e[4]:(f=(0,d.jsxs)(d.Fragment,{children:[l,c.length>0?(0,d.jsx)(`div`,{className:`space-y-4`,children:c.map(p)}):(0,d.jsx)(`p`,{className:`text-muted-foreground`,children:`No NAT Gateways found.`})]}),e[3]=c,e[4]=f),f}function p(e){if(!e.NatGatewayId)return null;let t=i(e.Tags);return(0,d.jsx)(c,{badge:(0,d.jsx)(l,{state:e.State}),params:{id:e.NatGatewayId},subtitle:e.SubnetId??``,title:t?`${e.NatGatewayId} (${t})`:e.NatGatewayId,to:`/ec2/describe-nat-gateways/$id`},e.NatGatewayId)}export{f as component};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{ni as r}from"./awsClient.js";import{t as i}from"./button.js";import{Bt as a}from"./index.js";import{t as o}from"./page-heading.js";import{t as s}from"./list-card.js";import{t as c}from"./state-badge.js";var l=t(),u=e();function d(){let e=(0,l.c)(5),{data:t}=n(a),s;e[0]===t.PlacementGroups?s=e[1]:(s=t.PlacementGroups??[],e[0]=t.PlacementGroups,e[1]=s);let c=s,d;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(d=(0,u.jsx)(o,{actions:(0,u.jsx)(r,{to:`/ec2/create-placement-group`,children:(0,u.jsx)(i,{children:`Create Placement Group`})}),title:`Placement Groups`}),e[2]=d):d=e[2];let p;return e[3]===c?p=e[4]:(p=(0,u.jsxs)(u.Fragment,{children:[d,c.length>0?(0,u.jsx)(`div`,{className:`space-y-4`,children:c.map(f)}):(0,u.jsx)(`p`,{className:`text-muted-foreground`,children:`No placement groups found.`})]}),e[3]=c,e[4]=p),p}function f(e){return e.GroupId?(0,u.jsx)(s,{badge:(0,u.jsx)(c,{state:e.State}),params:{id:e.GroupId},subtitle:`${e.Strategy} \u2022 ${e.GroupId}`,title:e.GroupName??e.GroupId,to:`/ec2/describe-placement-groups/$id`},e.GroupId):null}export{d as component};
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{ni as r}from"./awsClient.js";import{t as i}from"./button.js";import{Ht as a}from"./index.js";import{t as o}from"./page-heading.js";import{t as s}from"./list-card.js";import{t as c}from"./state-badge.js";var l=t(),u=e();function d(){let e=(0,l.c)(5),{data:t}=n(a),s;e[0]===t.PlacementGroups?s=e[1]:(s=t.PlacementGroups??[],e[0]=t.PlacementGroups,e[1]=s);let c=s,d;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(d=(0,u.jsx)(o,{actions:(0,u.jsx)(r,{to:`/ec2/create-placement-group`,children:(0,u.jsx)(i,{children:`Create Placement Group`})}),title:`Placement Groups`}),e[2]=d):d=e[2];let p;return e[3]===c?p=e[4]:(p=(0,u.jsxs)(u.Fragment,{children:[d,c.length>0?(0,u.jsx)(`div`,{className:`space-y-4`,children:c.map(f)}):(0,u.jsx)(`p`,{className:`text-muted-foreground`,children:`No placement groups found.`})]}),e[3]=c,e[4]=p),p}function f(e){return e.GroupId?(0,u.jsx)(s,{badge:(0,u.jsx)(c,{state:e.State}),params:{id:e.GroupId},subtitle:`${e.Strategy} \u2022 ${e.GroupId}`,title:e.GroupName??e.GroupId,to:`/ec2/describe-placement-groups/$id`},e.GroupId):null}export{d as component};
|
||||
@@ -1 +1 @@
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{ni as r}from"./awsClient.js";import{Ut as i}from"./auth.js";import{t as a}from"./button.js";import{Ut as o}from"./index.js";import{t as s}from"./page-heading.js";import{t as c}from"./list-card.js";import{t as l}from"./badge.js";var u=t(),d=e();function f(){let e=(0,u.c)(5),{data:t}=n(o),i;e[0]===t.RouteTables?i=e[1]:(i=t.RouteTables??[],e[0]=t.RouteTables,e[1]=i);let c=i,l;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(l=(0,d.jsx)(s,{actions:(0,d.jsx)(r,{to:`/ec2/create-route-table`,children:(0,d.jsx)(a,{children:`Create Route Table`})}),title:`Route Tables`}),e[2]=l):l=e[2];let f;return e[3]===c?f=e[4]:(f=(0,d.jsxs)(d.Fragment,{children:[l,c.length>0?(0,d.jsx)(`div`,{className:`space-y-4`,children:c.map(p)}):(0,d.jsx)(`p`,{className:`text-muted-foreground`,children:`No Route Tables found.`})]}),e[3]=c,e[4]=f),f}function p(e){if(!e.RouteTableId)return null;let t=i(e.Tags),n=e.Associations?.some(h)??!1,r=e.Associations?.filter(m).length??0;return(0,d.jsx)(c,{badge:n?(0,d.jsx)(l,{variant:`secondary`,children:`Main`}):null,params:{id:e.RouteTableId},subtitle:`${e.VpcId??``} · ${r} subnet${r===1?``:`s`}`,title:t?`${e.RouteTableId} (${t})`:e.RouteTableId,to:`/ec2/describe-route-tables/$id`},e.RouteTableId)}function m(e){return e.SubnetId}function h(e){return e.Main}export{f as component};
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{ni as r}from"./awsClient.js";import{Ut as i}from"./auth.js";import{t as a}from"./button.js";import{Gt as o}from"./index.js";import{t as s}from"./page-heading.js";import{t as c}from"./list-card.js";import{t as l}from"./badge.js";var u=t(),d=e();function f(){let e=(0,u.c)(5),{data:t}=n(o),i;e[0]===t.RouteTables?i=e[1]:(i=t.RouteTables??[],e[0]=t.RouteTables,e[1]=i);let c=i,l;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(l=(0,d.jsx)(s,{actions:(0,d.jsx)(r,{to:`/ec2/create-route-table`,children:(0,d.jsx)(a,{children:`Create Route Table`})}),title:`Route Tables`}),e[2]=l):l=e[2];let f;return e[3]===c?f=e[4]:(f=(0,d.jsxs)(d.Fragment,{children:[l,c.length>0?(0,d.jsx)(`div`,{className:`space-y-4`,children:c.map(p)}):(0,d.jsx)(`p`,{className:`text-muted-foreground`,children:`No Route Tables found.`})]}),e[3]=c,e[4]=f),f}function p(e){if(!e.RouteTableId)return null;let t=i(e.Tags),n=e.Associations?.some(h)??!1,r=e.Associations?.filter(m).length??0;return(0,d.jsx)(c,{badge:n?(0,d.jsx)(l,{variant:`secondary`,children:`Main`}):null,params:{id:e.RouteTableId},subtitle:`${e.VpcId??``} · ${r} subnet${r===1?``:`s`}`,title:t?`${e.RouteTableId} (${t})`:e.RouteTableId,to:`/ec2/describe-route-tables/$id`},e.RouteTableId)}function m(e){return e.SubnetId}function h(e){return e.Main}export{f as component};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{ni as r}from"./awsClient.js";import{t as i}from"./button.js";import{Gt as a}from"./index.js";import{t as o}from"./page-heading.js";import{t as s}from"./list-card.js";var c=t(),l=e();function u(){let e=(0,c.c)(5),{data:t}=n(a),s;e[0]===t.SecurityGroups?s=e[1]:(s=t.SecurityGroups??[],e[0]=t.SecurityGroups,e[1]=s);let u=s,f;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(f=(0,l.jsx)(o,{actions:(0,l.jsx)(r,{to:`/ec2/create-security-group`,children:(0,l.jsx)(i,{children:`Create Security Group`})}),title:`Security Groups`}),e[2]=f):f=e[2];let p;return e[3]===u?p=e[4]:(p=(0,l.jsxs)(l.Fragment,{children:[f,u.length>0?(0,l.jsx)(`div`,{className:`space-y-4`,children:u.map(d)}):(0,l.jsx)(`p`,{className:`text-muted-foreground`,children:`No security groups found.`})]}),e[3]=u,e[4]=p),p}function d(e){return e.GroupId?(0,l.jsx)(s,{params:{id:e.GroupId},subtitle:e.VpcId??``,title:e.GroupName?`${e.GroupId} (${e.GroupName})`:e.GroupId,to:`/ec2/describe-security-groups/$id`},e.GroupId):null}export{u as component};
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{ni as r}from"./awsClient.js";import{t as i}from"./button.js";import{qt as a}from"./index.js";import{t as o}from"./page-heading.js";import{t as s}from"./list-card.js";var c=t(),l=e();function u(){let e=(0,c.c)(5),{data:t}=n(a),s;e[0]===t.SecurityGroups?s=e[1]:(s=t.SecurityGroups??[],e[0]=t.SecurityGroups,e[1]=s);let u=s,f;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(f=(0,l.jsx)(o,{actions:(0,l.jsx)(r,{to:`/ec2/create-security-group`,children:(0,l.jsx)(i,{children:`Create Security Group`})}),title:`Security Groups`}),e[2]=f):f=e[2];let p;return e[3]===u?p=e[4]:(p=(0,l.jsxs)(l.Fragment,{children:[f,u.length>0?(0,l.jsx)(`div`,{className:`space-y-4`,children:u.map(d)}):(0,l.jsx)(`p`,{className:`text-muted-foreground`,children:`No security groups found.`})]}),e[3]=u,e[4]=p),p}function d(e){return e.GroupId?(0,l.jsx)(s,{params:{id:e.GroupId},subtitle:e.VpcId??``,title:e.GroupName?`${e.GroupId} (${e.GroupName})`:e.GroupId,to:`/ec2/describe-security-groups/$id`},e.GroupId):null}export{u as component};
|
||||
@@ -1 +1 @@
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{ni as r}from"./awsClient.js";import{t as i}from"./button.js";import{qt as a}from"./index.js";import{t as o}from"./page-heading.js";import{t as s}from"./list-card.js";import{t as c}from"./state-badge.js";var l=t(),u=e();function d(){let e=(0,l.c)(5),{data:t}=n(a),s;e[0]===t.Snapshots?s=e[1]:(s=t.Snapshots??[],e[0]=t.Snapshots,e[1]=s);let c=s,d;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(d=(0,u.jsx)(o,{actions:(0,u.jsx)(r,{to:`/ec2/create-snapshot`,children:(0,u.jsx)(i,{children:`Create Snapshot`})}),title:`Snapshots`}),e[2]=d):d=e[2];let p;return e[3]===c?p=e[4]:(p=(0,u.jsxs)(u.Fragment,{children:[d,c.length>0?(0,u.jsx)(`div`,{className:`space-y-4`,children:c.map(f)}):(0,u.jsx)(`p`,{className:`text-muted-foreground`,children:`No snapshots found.`})]}),e[3]=c,e[4]=p),p}function f(e){return e.SnapshotId?(0,u.jsx)(s,{badge:(0,u.jsx)(c,{state:e.State}),params:{id:e.SnapshotId},subtitle:`${e.VolumeSize} GiB \u2022 ${e.VolumeId}`,title:e.SnapshotId,to:`/ec2/describe-snapshots/$id`},e.SnapshotId):null}export{d as component};
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{ni as r}from"./awsClient.js";import{t as i}from"./button.js";import{Yt as a}from"./index.js";import{t as o}from"./page-heading.js";import{t as s}from"./list-card.js";import{t as c}from"./state-badge.js";var l=t(),u=e();function d(){let e=(0,l.c)(5),{data:t}=n(a),s;e[0]===t.Snapshots?s=e[1]:(s=t.Snapshots??[],e[0]=t.Snapshots,e[1]=s);let c=s,d;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(d=(0,u.jsx)(o,{actions:(0,u.jsx)(r,{to:`/ec2/create-snapshot`,children:(0,u.jsx)(i,{children:`Create Snapshot`})}),title:`Snapshots`}),e[2]=d):d=e[2];let p;return e[3]===c?p=e[4]:(p=(0,u.jsxs)(u.Fragment,{children:[d,c.length>0?(0,u.jsx)(`div`,{className:`space-y-4`,children:c.map(f)}):(0,u.jsx)(`p`,{className:`text-muted-foreground`,children:`No snapshots found.`})]}),e[3]=c,e[4]=p),p}function f(e){return e.SnapshotId?(0,u.jsx)(s,{badge:(0,u.jsx)(c,{state:e.State}),params:{id:e.SnapshotId},subtitle:`${e.VolumeSize} GiB \u2022 ${e.VolumeId}`,title:e.SnapshotId,to:`/ec2/describe-snapshots/$id`},e.SnapshotId):null}export{d as component};
|
||||
@@ -1 +1 @@
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{ni as r}from"./awsClient.js";import{Ut as i}from"./auth.js";import{t as a}from"./button.js";import{Yt as o}from"./index.js";import{t as s}from"./page-heading.js";import{t as c}from"./list-card.js";import{t as l}from"./state-badge.js";var u=t(),d=e();function f(){let e=(0,u.c)(5),{data:t}=n(o),i;e[0]===t.Subnets?i=e[1]:(i=t.Subnets??[],e[0]=t.Subnets,e[1]=i);let c=i,l;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(l=(0,d.jsx)(s,{actions:(0,d.jsx)(r,{to:`/ec2/create-subnet`,children:(0,d.jsx)(a,{children:`Create Subnet`})}),title:`Subnets`}),e[2]=l):l=e[2];let f;return e[3]===c?f=e[4]:(f=(0,d.jsxs)(d.Fragment,{children:[l,c.length>0?(0,d.jsx)(`div`,{className:`space-y-4`,children:c.map(p)}):(0,d.jsx)(`p`,{className:`text-muted-foreground`,children:`No subnets found.`})]}),e[3]=c,e[4]=f),f}function p(e){if(!e.SubnetId)return null;let t=i(e.Tags);return(0,d.jsx)(c,{badge:(0,d.jsx)(l,{state:e.State}),params:{id:e.SubnetId},subtitle:`${e.CidrBlock??``} \u2022 ${e.AvailabilityZone??``}`,title:t?`${e.SubnetId} (${t})`:e.SubnetId,to:`/ec2/describe-subnets/$id`},e.SubnetId)}export{f as component};
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{ni as r}from"./awsClient.js";import{Ut as i}from"./auth.js";import{t as a}from"./button.js";import{Zt as o}from"./index.js";import{t as s}from"./page-heading.js";import{t as c}from"./list-card.js";import{t as l}from"./state-badge.js";var u=t(),d=e();function f(){let e=(0,u.c)(5),{data:t}=n(o),i;e[0]===t.Subnets?i=e[1]:(i=t.Subnets??[],e[0]=t.Subnets,e[1]=i);let c=i,l;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(l=(0,d.jsx)(s,{actions:(0,d.jsx)(r,{to:`/ec2/create-subnet`,children:(0,d.jsx)(a,{children:`Create Subnet`})}),title:`Subnets`}),e[2]=l):l=e[2];let f;return e[3]===c?f=e[4]:(f=(0,d.jsxs)(d.Fragment,{children:[l,c.length>0?(0,d.jsx)(`div`,{className:`space-y-4`,children:c.map(p)}):(0,d.jsx)(`p`,{className:`text-muted-foreground`,children:`No subnets found.`})]}),e[3]=c,e[4]=f),f}function p(e){if(!e.SubnetId)return null;let t=i(e.Tags);return(0,d.jsx)(c,{badge:(0,d.jsx)(l,{state:e.State}),params:{id:e.SubnetId},subtitle:`${e.CidrBlock??``} \u2022 ${e.AvailabilityZone??``}`,title:t?`${e.SubnetId} (${t})`:e.SubnetId,to:`/ec2/describe-subnets/$id`},e.SubnetId)}export{f as component};
|
||||
+1
-1
@@ -1 +1 @@
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useQuery.js";import{t as r}from"./useSuspenseQuery.js";import{ni as i}from"./awsClient.js";import{t as a}from"./button.js";import{$ as o,Q as s,Xr as c}from"./index.js";import{t as l}from"./page-heading.js";var u=t(),d=e();function f(){let e=(0,u.c)(6),t=c(),{data:n}=r(s),o;e[0]===n.TargetGroups?o=e[1]:(o=n.TargetGroups??[],e[0]=n.TargetGroups,e[1]=o);let f=o,h;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(h=(0,d.jsx)(l,{actions:(0,d.jsx)(i,{to:`/ec2/create-target-group`,children:(0,d.jsx)(a,{children:`Create Target Group`})}),title:`Target Groups`}),e[2]=h):h=e[2];let g;return e[3]!==t||e[4]!==f?(g=(0,d.jsxs)(d.Fragment,{children:[h,f.length>0?(0,d.jsx)(`div`,{className:`overflow-x-auto rounded-lg border bg-card`,children:(0,d.jsxs)(`table`,{className:`w-full text-sm`,children:[(0,d.jsx)(`thead`,{children:(0,d.jsxs)(`tr`,{className:`border-b text-left text-muted-foreground`,children:[(0,d.jsx)(`th`,{className:`px-4 py-2 font-medium`,children:`Name`}),(0,d.jsx)(`th`,{className:`px-4 py-2 font-medium`,children:`Protocol`}),(0,d.jsx)(`th`,{className:`px-4 py-2 font-medium`,children:`Port`}),(0,d.jsx)(`th`,{className:`px-4 py-2 font-medium`,children:`VPC`}),(0,d.jsx)(`th`,{className:`px-4 py-2 font-medium`,children:`Target Type`}),(0,d.jsx)(`th`,{className:`px-4 py-2 font-medium`,children:`Targets`}),(0,d.jsx)(`th`,{className:`px-4 py-2 font-medium`,children:`Health`})]})}),(0,d.jsx)(`tbody`,{children:f.map(e=>{if(!e.TargetGroupArn)return null;let n=e.TargetGroupArn;return(0,d.jsxs)(`tr`,{className:`cursor-pointer border-b transition-colors last:border-0 hover:bg-accent`,onClick:async()=>await t({to:`/ec2/describe-target-groups/$id`,params:{id:encodeURIComponent(n)}}),children:[(0,d.jsx)(`td`,{className:`px-4 py-2 font-medium`,children:(0,d.jsx)(i,{className:`text-primary hover:underline`,onClick:p,params:{id:encodeURIComponent(n)},to:`/ec2/describe-target-groups/$id`,children:e.TargetGroupName??n})}),(0,d.jsx)(`td`,{className:`px-4 py-2`,children:e.Protocol??``}),(0,d.jsx)(`td`,{className:`px-4 py-2`,children:e.Port??``}),(0,d.jsx)(`td`,{className:`px-4 py-2 font-mono text-xs`,children:e.VpcId??``}),(0,d.jsx)(`td`,{className:`px-4 py-2`,children:e.TargetType??``}),(0,d.jsx)(m,{arn:n})]},n)})})]})}):(0,d.jsx)(`p`,{className:`text-muted-foreground`,children:`No target groups found.`})]}),e[3]=t,e[4]=f,e[5]=g):g=e[5],g}function p(e){return e.stopPropagation()}function m(e){let t=(0,u.c)(13),{arn:r}=e,i;t[0]===r?i=t[1]:(i=o(r),t[0]=r,t[1]=i);let{data:a,isLoading:s}=n(i);if(s){let e;return t[2]===Symbol.for(`react.memo_cache_sentinel`)?(e=(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(`td`,{className:`px-4 py-2 text-muted-foreground`,children:`…`}),(0,d.jsx)(`td`,{className:`px-4 py-2 text-muted-foreground`,children:`…`})]}),t[2]=e):e=t[2],e}let c,l;if(t[3]!==a?.TargetHealthDescriptions){c=a?.TargetHealthDescriptions??[];let e={};for(let t of c){let n=t.TargetHealth?.State??`unknown`;e[n]=(e[n]??0)+1}l=Object.entries(e).map(h).join(`, `)||`—`,t[3]=a?.TargetHealthDescriptions,t[4]=c,t[5]=l}else c=t[4],l=t[5];let f=l,p;t[6]===c.length?p=t[7]:(p=(0,d.jsx)(`td`,{className:`px-4 py-2`,children:c.length}),t[6]=c.length,t[7]=p);let m;t[8]===f?m=t[9]:(m=(0,d.jsx)(`td`,{className:`px-4 py-2 text-xs`,children:f}),t[8]=f,t[9]=m);let g;return t[10]!==p||t[11]!==m?(g=(0,d.jsxs)(d.Fragment,{children:[p,m]}),t[10]=p,t[11]=m,t[12]=g):g=t[12],g}function h(e){let[t,n]=e;return`${n} ${t}`}var g=f;export{g as component};
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useQuery.js";import{t as r}from"./useSuspenseQuery.js";import{ni as i}from"./awsClient.js";import{t as a}from"./button.js";import{Qr as o,et as s,tt as c}from"./index.js";import{t as l}from"./page-heading.js";var u=t(),d=e();function f(){let e=(0,u.c)(6),t=o(),{data:n}=r(s),c;e[0]===n.TargetGroups?c=e[1]:(c=n.TargetGroups??[],e[0]=n.TargetGroups,e[1]=c);let f=c,h;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(h=(0,d.jsx)(l,{actions:(0,d.jsx)(i,{to:`/ec2/create-target-group`,children:(0,d.jsx)(a,{children:`Create Target Group`})}),title:`Target Groups`}),e[2]=h):h=e[2];let g;return e[3]!==t||e[4]!==f?(g=(0,d.jsxs)(d.Fragment,{children:[h,f.length>0?(0,d.jsx)(`div`,{className:`overflow-x-auto rounded-lg border bg-card`,children:(0,d.jsxs)(`table`,{className:`w-full text-sm`,children:[(0,d.jsx)(`thead`,{children:(0,d.jsxs)(`tr`,{className:`border-b text-left text-muted-foreground`,children:[(0,d.jsx)(`th`,{className:`px-4 py-2 font-medium`,children:`Name`}),(0,d.jsx)(`th`,{className:`px-4 py-2 font-medium`,children:`Protocol`}),(0,d.jsx)(`th`,{className:`px-4 py-2 font-medium`,children:`Port`}),(0,d.jsx)(`th`,{className:`px-4 py-2 font-medium`,children:`VPC`}),(0,d.jsx)(`th`,{className:`px-4 py-2 font-medium`,children:`Target Type`}),(0,d.jsx)(`th`,{className:`px-4 py-2 font-medium`,children:`Targets`}),(0,d.jsx)(`th`,{className:`px-4 py-2 font-medium`,children:`Health`})]})}),(0,d.jsx)(`tbody`,{children:f.map(e=>{if(!e.TargetGroupArn)return null;let n=e.TargetGroupArn;return(0,d.jsxs)(`tr`,{className:`cursor-pointer border-b transition-colors last:border-0 hover:bg-accent`,onClick:async()=>await t({to:`/ec2/describe-target-groups/$id`,params:{id:encodeURIComponent(n)}}),children:[(0,d.jsx)(`td`,{className:`px-4 py-2 font-medium`,children:(0,d.jsx)(i,{className:`text-primary hover:underline`,onClick:p,params:{id:encodeURIComponent(n)},to:`/ec2/describe-target-groups/$id`,children:e.TargetGroupName??n})}),(0,d.jsx)(`td`,{className:`px-4 py-2`,children:e.Protocol??``}),(0,d.jsx)(`td`,{className:`px-4 py-2`,children:e.Port??``}),(0,d.jsx)(`td`,{className:`px-4 py-2 font-mono text-xs`,children:e.VpcId??``}),(0,d.jsx)(`td`,{className:`px-4 py-2`,children:e.TargetType??``}),(0,d.jsx)(m,{arn:n})]},n)})})]})}):(0,d.jsx)(`p`,{className:`text-muted-foreground`,children:`No target groups found.`})]}),e[3]=t,e[4]=f,e[5]=g):g=e[5],g}function p(e){return e.stopPropagation()}function m(e){let t=(0,u.c)(13),{arn:r}=e,i;t[0]===r?i=t[1]:(i=c(r),t[0]=r,t[1]=i);let{data:a,isLoading:o}=n(i);if(o){let e;return t[2]===Symbol.for(`react.memo_cache_sentinel`)?(e=(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(`td`,{className:`px-4 py-2 text-muted-foreground`,children:`…`}),(0,d.jsx)(`td`,{className:`px-4 py-2 text-muted-foreground`,children:`…`})]}),t[2]=e):e=t[2],e}let s,l;if(t[3]!==a?.TargetHealthDescriptions){s=a?.TargetHealthDescriptions??[];let e={};for(let t of s){let n=t.TargetHealth?.State??`unknown`;e[n]=(e[n]??0)+1}l=Object.entries(e).map(h).join(`, `)||`—`,t[3]=a?.TargetHealthDescriptions,t[4]=s,t[5]=l}else s=t[4],l=t[5];let f=l,p;t[6]===s.length?p=t[7]:(p=(0,d.jsx)(`td`,{className:`px-4 py-2`,children:s.length}),t[6]=s.length,t[7]=p);let m;t[8]===f?m=t[9]:(m=(0,d.jsx)(`td`,{className:`px-4 py-2 text-xs`,children:f}),t[8]=f,t[9]=m);let g;return t[10]!==p||t[11]!==m?(g=(0,d.jsxs)(d.Fragment,{children:[p,m]}),t[10]=p,t[11]=m,t[12]=g):g=t[12],g}function h(e){let[t,n]=e;return`${n} ${t}`}var g=f;export{g as component};
|
||||
@@ -1 +1 @@
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{ni as r}from"./awsClient.js";import{t as i}from"./button.js";import{Zt as a}from"./index.js";import{t as o}from"./page-heading.js";import{t as s}from"./list-card.js";import{t as c}from"./state-badge.js";var l=t(),u=e();function d(){let e=(0,l.c)(5),{data:t}=n(a),s;e[0]===t.Volumes?s=e[1]:(s=t.Volumes??[],e[0]=t.Volumes,e[1]=s);let c=s,d;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(d=(0,u.jsx)(o,{actions:(0,u.jsx)(r,{to:`/ec2/create-volume`,children:(0,u.jsx)(i,{children:`Create Volume`})}),title:`Volumes`}),e[2]=d):d=e[2];let p;return e[3]===c?p=e[4]:(p=(0,u.jsxs)(u.Fragment,{children:[d,c.length>0?(0,u.jsx)(`div`,{className:`space-y-4`,children:c.map(f)}):(0,u.jsx)(`p`,{className:`text-muted-foreground`,children:`No volumes found.`})]}),e[3]=c,e[4]=p),p}function f(e){return e.VolumeId?(0,u.jsx)(s,{badge:(0,u.jsx)(c,{state:e.State}),params:{id:e.VolumeId},subtitle:`${e.Size} GiB`,title:e.VolumeId,to:`/ec2/describe-volumes/$id`},e.VolumeId):null}export{d as component};
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{ni as r}from"./awsClient.js";import{t as i}from"./button.js";import{$t as a}from"./index.js";import{t as o}from"./page-heading.js";import{t as s}from"./list-card.js";import{t as c}from"./state-badge.js";var l=t(),u=e();function d(){let e=(0,l.c)(5),{data:t}=n(a),s;e[0]===t.Volumes?s=e[1]:(s=t.Volumes??[],e[0]=t.Volumes,e[1]=s);let c=s,d;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(d=(0,u.jsx)(o,{actions:(0,u.jsx)(r,{to:`/ec2/create-volume`,children:(0,u.jsx)(i,{children:`Create Volume`})}),title:`Volumes`}),e[2]=d):d=e[2];let p;return e[3]===c?p=e[4]:(p=(0,u.jsxs)(u.Fragment,{children:[d,c.length>0?(0,u.jsx)(`div`,{className:`space-y-4`,children:c.map(f)}):(0,u.jsx)(`p`,{className:`text-muted-foreground`,children:`No volumes found.`})]}),e[3]=c,e[4]=p),p}function f(e){return e.VolumeId?(0,u.jsx)(s,{badge:(0,u.jsx)(c,{state:e.State}),params:{id:e.VolumeId},subtitle:`${e.Size} GiB`,title:e.VolumeId,to:`/ec2/describe-volumes/$id`},e.VolumeId):null}export{d as component};
|
||||
@@ -1 +1 @@
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{ni as r}from"./awsClient.js";import{Ut as i}from"./auth.js";import{t as a}from"./button.js";import{$t as o}from"./index.js";import{t as s}from"./page-heading.js";import{t as c}from"./list-card.js";import{t as l}from"./state-badge.js";var u=t(),d=e();function f(){let e=(0,u.c)(5),{data:t}=n(o),i;e[0]===t.Vpcs?i=e[1]:(i=t.Vpcs??[],e[0]=t.Vpcs,e[1]=i);let c=i,l;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(l=(0,d.jsx)(s,{actions:(0,d.jsx)(r,{to:`/ec2/create-vpc`,children:(0,d.jsx)(a,{children:`Create VPC`})}),title:`VPCs`}),e[2]=l):l=e[2];let f;return e[3]===c?f=e[4]:(f=(0,d.jsxs)(d.Fragment,{children:[l,c.length>0?(0,d.jsx)(`div`,{className:`space-y-4`,children:c.map(p)}):(0,d.jsx)(`p`,{className:`text-muted-foreground`,children:`No VPCs found.`})]}),e[3]=c,e[4]=f),f}function p(e){if(!e.VpcId)return null;let t=i(e.Tags);return(0,d.jsx)(c,{badge:(0,d.jsx)(l,{state:e.State}),params:{id:e.VpcId},subtitle:e.CidrBlock??``,title:t?`${e.VpcId} (${t})`:e.VpcId,to:`/ec2/describe-vpcs/$id`},e.VpcId)}export{f as component};
|
||||
import{n as e,t}from"./compiler-runtime.js";import{t as n}from"./useSuspenseQuery.js";import{ni as r}from"./awsClient.js";import{Ut as i}from"./auth.js";import{t as a}from"./button.js";import{tn as o}from"./index.js";import{t as s}from"./page-heading.js";import{t as c}from"./list-card.js";import{t as l}from"./state-badge.js";var u=t(),d=e();function f(){let e=(0,u.c)(5),{data:t}=n(o),i;e[0]===t.Vpcs?i=e[1]:(i=t.Vpcs??[],e[0]=t.Vpcs,e[1]=i);let c=i,l;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(l=(0,d.jsx)(s,{actions:(0,d.jsx)(r,{to:`/ec2/create-vpc`,children:(0,d.jsx)(a,{children:`Create VPC`})}),title:`VPCs`}),e[2]=l):l=e[2];let f;return e[3]===c?f=e[4]:(f=(0,d.jsxs)(d.Fragment,{children:[l,c.length>0?(0,d.jsx)(`div`,{className:`space-y-4`,children:c.map(p)}):(0,d.jsx)(`p`,{className:`text-muted-foreground`,children:`No VPCs found.`})]}),e[3]=c,e[4]=f),f}function p(e){if(!e.VpcId)return null;let t=i(e.Tags);return(0,d.jsx)(c,{badge:(0,d.jsx)(l,{state:e.State}),params:{id:e.VpcId},subtitle:e.CidrBlock??``,title:t?`${e.VpcId} (${t})`:e.VpcId,to:`/ec2/describe-vpcs/$id`},e.VpcId)}export{f as component};
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user