From 523226767558c463ceba14ba6fbbbf63de9c4951 Mon Sep 17 00:00:00 2001 From: Swanny Date: Thu, 15 May 2025 13:38:11 -0400 Subject: [PATCH 1/9] feat: builder --- builder/builder.go | 245 +++++++++++++++++++++++++++++++++++++ builder/helpers.go | 96 +++++++++++++++ builder/types.go | 114 +++++++++++++++++ builder/validation.go | 94 +++++++++++++++ go.mod | 91 ++++++++++++++ go.sum | 275 ++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 915 insertions(+) create mode 100644 builder/builder.go create mode 100644 builder/helpers.go create mode 100644 builder/types.go create mode 100644 builder/validation.go create mode 100644 go.mod create mode 100644 go.sum diff --git a/builder/builder.go b/builder/builder.go new file mode 100644 index 0000000..587b56b --- /dev/null +++ b/builder/builder.go @@ -0,0 +1,245 @@ +// Package builder provides a Pulumi component for deploying a builder service to Kubernetes. +package builder + +import ( + "encoding/json" + "fmt" + + "github.com/pulumi/pulumi-aws/sdk/v6/go/aws/iam" + crd "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/apiextensions" + appsv1 "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/apps/v1" + corev1 "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/core/v1" + metav1 "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/meta/v1" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" +) + +// NewBuilder creates a new builder component with the given configuration. +func NewBuilder(ctx *pulumi.Context, args BuilderComponentArgs, opts ...pulumi.ResourceOption) (*BuilderComponent, error) { + if err := args.Validate(); err != nil { + return nil, fmt.Errorf("invalid builder component args: %w", err) + } + + component := &BuilderComponent{ + BuilderComponentArgs: args, + } + err := ctx.RegisterComponentResource("the-builder:index:Builder", args.Name, component) + if err != nil { + return nil, fmt.Errorf("failed to register component resource: %w", err) + } + + // Create service account + sa, err := corev1.NewServiceAccount(ctx, "builder-sa", &corev1.ServiceAccountArgs{ + Metadata: &metav1.ObjectMetaArgs{ + Name: pulumi.String("builder-sa"), + Namespace: pulumi.String(args.Namespace), + }, + }, pulumi.Parent(component)) + if err != nil { + return nil, fmt.Errorf("failed to create service account: %w", err) + } + component.ServiceAccount = sa + + // Create IAM role + assumeRolePolicy := IAMPolicy{ + Version: "2012-10-17", + Statement: []IAMStatement{ + { + Sid: "AllowEksAuthToAssumeRoleForPodIdentity", + Effect: "Allow", + Principal: struct { + Service []string `json:"Service"` + }{ + Service: []string{ + "pods.eks.amazonaws.com", + "ec2.amazonaws.com", + }, + }, + Action: []string{ + "sts:AssumeRole", + "sts:TagSession", + }, + }, + }, + } + + assumeRolePolicyJSON, err := json.Marshal(assumeRolePolicy) + if err != nil { + return nil, fmt.Errorf("failed to marshal assume role policy: %w", err) + } + + role, err := iam.NewRole(ctx, "builder-role", &iam.RoleArgs{ + AssumeRolePolicy: pulumi.String(assumeRolePolicyJSON), + Description: pulumi.String("Role for builder pod to assume"), + Tags: pulumi.StringMap{ + "Name": pulumi.String("builder-role"), + }, + }, pulumi.Parent(component)) + if err != nil { + return nil, fmt.Errorf("failed to create IAM role: %w", err) + } + component.IAMRole = role + + // Create KMS policy + policyJSON := createKMSPolicy(args.BuilderEnv.BuilderKey) + + policy, err := iam.NewPolicy(ctx, "quinceyAppPolicy", &iam.PolicyArgs{ + Policy: policyJSON, + }, pulumi.Parent(component)) + if err != nil { + return nil, fmt.Errorf("failed to create IAM policy: %w", err) + } + component.IAMPolicy = policy + + // Attach policy to role + _, err = iam.NewRolePolicyAttachment(ctx, "builder-role-policy-attachment", &iam.RolePolicyAttachmentArgs{ + Role: role.Name, + PolicyArn: policy.Arn, + }, pulumi.Parent(component)) + if err != nil { + return nil, fmt.Errorf("failed to attach policy to role: %w", err) + } + + // Create deployment + deployment, err := appsv1.NewDeployment(ctx, "builder-deployment", &appsv1.DeploymentArgs{ + Metadata: &metav1.ObjectMetaArgs{ + Name: pulumi.String("builder-deployment"), + Namespace: pulumi.String(args.Namespace), + }, + Spec: &appsv1.DeploymentSpecArgs{ + Replicas: pulumi.Int(DefaultReplicas), + Selector: &metav1.LabelSelectorArgs{ + MatchLabels: args.AppLabels.Labels, + }, + Template: &corev1.PodTemplateSpecArgs{ + Metadata: &metav1.ObjectMetaArgs{ + Labels: args.AppLabels.Labels, + }, + Spec: &corev1.PodSpecArgs{ + ServiceAccountName: pulumi.String("builder-sa"), + Containers: corev1.ContainerArray{ + &corev1.ContainerArgs{ + Name: pulumi.String("builder"), + Image: pulumi.String(args.Image), + Env: createEnvVars(args.BuilderEnv), + Ports: corev1.ContainerPortArray{ + &corev1.ContainerPortArgs{ + ContainerPort: args.BuilderEnv.BuilderPort, + }, + &corev1.ContainerPortArgs{ + ContainerPort: pulumi.Int(MetricsPort), + }, + }, + Resources: &corev1.ResourceRequirementsArgs{ + Limits: pulumi.StringMap{ + "cpu": pulumi.String("2"), + "memory": pulumi.String("2Gi"), + }, + Requests: pulumi.StringMap{ + "cpu": pulumi.String("1"), + "memory": pulumi.String("1Gi"), + }, + }, + LivenessProbe: &corev1.ProbeArgs{ + HttpGet: &corev1.HTTPGetActionArgs{ + Path: pulumi.String("/healthcheck"), + Port: args.BuilderEnv.BuilderPort, + }, + InitialDelaySeconds: pulumi.Int(5), + PeriodSeconds: pulumi.Int(1), + TimeoutSeconds: pulumi.Int(1), + FailureThreshold: pulumi.Int(3), + }, + ReadinessProbe: &corev1.ProbeArgs{ + HttpGet: &corev1.HTTPGetActionArgs{ + Path: pulumi.String("/healthcheck"), + Port: args.BuilderEnv.BuilderPort, + }, + InitialDelaySeconds: pulumi.Int(5), + PeriodSeconds: pulumi.Int(10), + }, + }, + }, + }, + }, + }, + }, pulumi.DependsOn([]pulumi.Resource{role, policy}), pulumi.DeleteBeforeReplace(true), pulumi.Parent(component)) + if err != nil { + return nil, fmt.Errorf("failed to create deployment: %w", err) + } + component.Deployment = deployment + + // Create service + service, err := corev1.NewService(ctx, "builder-service", &corev1.ServiceArgs{ + Metadata: &metav1.ObjectMetaArgs{ + Name: pulumi.String("builder-service"), + Namespace: pulumi.String(args.Namespace), + Annotations: pulumi.StringMap{ + "prometheus.io/scrape": pulumi.String("true"), + "prometheus.io/port": pulumi.Sprintf("%d", MetricsPort), + "prometheus.io/path": pulumi.String("/metrics"), + }, + }, + Spec: &corev1.ServiceSpecArgs{ + Selector: args.AppLabels.Labels, + Ports: corev1.ServicePortArray{ + &corev1.ServicePortArgs{ + Port: args.BuilderEnv.BuilderPort, + TargetPort: args.BuilderEnv.BuilderPort, + Name: pulumi.String("http"), + }, + &corev1.ServicePortArgs{ + Port: pulumi.Int(MetricsPort), + TargetPort: pulumi.Int(MetricsPort), + Name: pulumi.String("metrics"), + }, + }, + }, + }, pulumi.DependsOn([]pulumi.Resource{deployment}), pulumi.DeleteBeforeReplace(true), pulumi.Parent(component)) + if err != nil { + return nil, fmt.Errorf("failed to create service: %w", err) + } + component.Service = service + + // Create pod monitor + _, err = crd.NewCustomResource(ctx, "builder-svcmon", &crd.CustomResourceArgs{ + ApiVersion: pulumi.String("monitoring.coreos.com/v1"), + Kind: pulumi.String("PodMonitor"), + Metadata: &metav1.ObjectMetaArgs{ + Name: pulumi.String("builder-pod-monitor"), + Namespace: pulumi.String(args.Namespace), + }, + OtherFields: map[string]interface{}{ + "spec": map[string]interface{}{ + "selector": map[string]interface{}{ + "matchLabels": args.AppLabels.Labels, + }, + "namespaceSelector": map[string]interface{}{ + "any": true, + }, + "podMetricsEndpoints": []map[string]interface{}{ + { + "port": "metrics", + }, + }, + }, + }, + }, pulumi.Parent(component)) + if err != nil { + return nil, fmt.Errorf("failed to create pod monitor: %w", err) + } + + return component, nil +} + +// GetServiceURL returns the URL of the builder service +func (c *BuilderComponent) GetServiceURL() pulumi.StringOutput { + return pulumi.Sprintf("http://%s.%s.svc.cluster.local", c.Service.Metadata.Name(), c.Service.Metadata.Namespace()) +} + +// GetMetricsURL returns the URL of the builder metrics endpoint +func (c *BuilderComponent) GetMetricsURL() pulumi.StringOutput { + return pulumi.Sprintf("http://%s.%s.svc.cluster.local:%d/metrics", + c.Service.Metadata.Name(), + c.Service.Metadata.Namespace(), + MetricsPort) +} diff --git a/builder/helpers.go b/builder/helpers.go new file mode 100644 index 0000000..a3ac305 --- /dev/null +++ b/builder/helpers.go @@ -0,0 +1,96 @@ +package builder + +import ( + "reflect" + "strings" + "unicode" + + corev1 "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/core/v1" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" +) + +// createKMSPolicy creates a KMS policy for the builder service. +func createKMSPolicy(key pulumi.StringInput) pulumi.StringOutput { + return pulumi.Sprintf(`{ + "Version": "2012-10-17", + "Statement": [ + { + "Effect": "Allow", + "Action": [ + "kms:Sign", + "kms:GetPublicKey" + ], + "Resource": %s + } + ] + }`, key) +} + +// createEnvVars creates environment variables by automatically mapping +// struct field names to environment variable names. +func createEnvVars(env BuilderEnv) corev1.EnvVarArray { + result := corev1.EnvVarArray{} + + // Special case for BuilderPort as it needs string conversion + result = append(result, &corev1.EnvVarArgs{ + Name: pulumi.String("BUILDER_PORT"), + Value: pulumi.Sprintf("%d", env.BuilderPort), + }) + + // Process all string inputs from the struct's tags + envVarMap := getEnvironmentVarsFromStruct(env) + for name, value := range envVarMap { + if name != "BUILDER_PORT" { // Skip the one we already handled + result = append(result, &corev1.EnvVarArgs{ + Name: pulumi.String(name), + Value: value.(pulumi.StringInput), + }) + } + } + + return result +} + +// getEnvironmentVarsFromStruct uses reflection to extract environment variables from struct tags +func getEnvironmentVarsFromStruct(env BuilderEnv) map[string]pulumi.Input { + result := make(map[string]pulumi.Input) + + t := reflect.TypeOf(env) + v := reflect.ValueOf(env) + + for i := 0; i < t.NumField(); i++ { + field := t.Field(i) + + // Get the field value + fieldValue := v.Field(i).Interface() + + // Skip nil values and BuilderPort (handled specially) + if fieldValue == nil || field.Name == "BuilderPort" { + continue + } + + // Convert camelCase to SNAKE_CASE for env var name + envName := camelToSnake(field.Name) + + // Add to map + result[envName] = fieldValue.(pulumi.Input) + } + + return result +} + +// camelToSnake converts a camelCase string to SNAKE_CASE +func camelToSnake(s string) string { + var result strings.Builder + for i, r := range s { + if unicode.IsUpper(r) { + if i > 0 { + result.WriteRune('_') + } + result.WriteRune(unicode.ToUpper(r)) + } else { + result.WriteRune(unicode.ToUpper(r)) + } + } + return result.String() +} diff --git a/builder/types.go b/builder/types.go new file mode 100644 index 0000000..bb791f9 --- /dev/null +++ b/builder/types.go @@ -0,0 +1,114 @@ +package builder + +import ( + "github.com/pulumi/pulumi-aws/sdk/v6/go/aws/iam" + appsv1 "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/apps/v1" + corev1 "github.com/pulumi/pulumi-kubernetes/sdk/v4/go/kubernetes/core/v1" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" +) + +const ( + // Service ports + MetricsPort = 9000 + + // Deployment settings + DefaultReplicas = 1 +) + +// AppLabels represents the Kubernetes labels to be applied to the builder resources. +type AppLabels struct { + Labels pulumi.StringMap +} + +// BuilderComponent represents a Pulumi component that deploys a builder service. +type BuilderComponent struct { + pulumi.ResourceState + BuilderComponentArgs BuilderComponentArgs + Deployment *appsv1.Deployment + Service *corev1.Service + ServiceAccount *corev1.ServiceAccount + IAMRole *iam.Role + IAMPolicy *iam.Policy +} + +// BuilderComponentArgs contains the configuration for deploying a builder service. +type BuilderComponentArgs struct { + Namespace string // k8s namespace to deploy the builder to + AppLabels AppLabels // Labels to apply to the builder pod + Name string // Builder name identifier + Image string // Builder docker image + BuilderEnv BuilderEnv // Builder environment variables +} + +// BuilderEnv contains all environment variables required by the builder service. +type BuilderEnv struct { + AuthTokenRefreshInterval pulumi.StringInput `pulumi:"authTokenRefreshInterval"` + AWSAccountId pulumi.StringInput `pulumi:"awsAccountId"` + AWSAccessKeyId pulumi.StringInput `pulumi:"awsAccessKeyId"` + AWSRegion pulumi.StringInput `pulumi:"awsRegion"` + AWSSecretAccessKey pulumi.StringInput `pulumi:"awsSecretAccessKey"` + BlockConfirmationBuffer pulumi.StringInput `pulumi:"blockConfirmationBuffer"` + BlockQueryCutoff pulumi.StringInput `pulumi:"blockQueryCutoff"` + BlockQueryStart pulumi.StringInput `pulumi:"blockQueryStart"` + BuilderHelperAddress pulumi.StringInput `pulumi:"builderHelperAddress"` + BuilderKey pulumi.StringInput `pulumi:"builderKey"` + BuilderPort pulumi.IntInput `pulumi:"builderPort"` + BuilderRewardsAddress pulumi.StringInput `pulumi:"builderRewardsAddress"` + ChainOffset pulumi.StringInput `pulumi:"chainOffset"` + ConcurrentLimit pulumi.StringInput `pulumi:"concurrentLimit"` + HostChainId pulumi.StringInput `pulumi:"hostChainId"` + HostRpcUrl pulumi.StringInput `pulumi:"hostRpcUrl"` + OauthAudience pulumi.StringInput `pulumi:"oauthAudience"` + OauthAuthenticateUrl pulumi.StringInput `pulumi:"oauthAuthenticateUrl"` + OAuthClientId pulumi.StringInput `pulumi:"oauthClientId"` + OauthClientSecret pulumi.StringInput `pulumi:"oauthClientSecret"` + OauthIssuer pulumi.StringInput `pulumi:"oauthIssuer"` + OauthTokenUrl pulumi.StringInput `pulumi:"oauthTokenUrl"` + OtelExporterOtlpEndpoint pulumi.StringInput `pulumi:"otelExporterOtlpEndpoint"` + QuinceyUrl pulumi.StringInput `pulumi:"quinceyUrl"` + RollupBlockGasLimit pulumi.StringInput `pulumi:"rollupBlockGasLimit"` + RollupChainId pulumi.StringInput `pulumi:"rollupChainId"` + RollupRpcUrl pulumi.StringInput `pulumi:"rollupRpcUrl"` + RustLog pulumi.StringInput `pulumi:"rustLog"` + SlotOffset pulumi.StringInput `pulumi:"slotOffset"` + StartTimestamp pulumi.StringInput `pulumi:"startTimestamp"` + SubmitViaCallData pulumi.StringInput `pulumi:"submitViaCallData"` + TargetSlotTime pulumi.StringInput `pulumi:"targetSlotTime"` + TxBroadcastUrls pulumi.StringInput `pulumi:"txBroadcastUrls"` + TxPoolCacheDuration pulumi.StringInput `pulumi:"txPoolCacheDuration"` + TxPoolUrl pulumi.StringInput `pulumi:"txPoolUrl"` + ZenithAddress pulumi.StringInput `pulumi:"zenithAddress"` +} + +type IAMStatement struct { + Sid string `json:"sid,omitempty"` + Effect string `json:"effect"` + Principal struct { + Service []string `json:"Service"` + } `json:"Principal"` + Action []string `json:"Action"` +} + +type IAMPolicy struct { + Version string `json:"Version"` + Statement []IAMStatement `json:"Statement"` +} + +type KMSStatement struct { + Effect string `json:"Effect"` + Action []string `json:"Action"` + Resource pulumi.StringInput `json:"Resource"` +} + +type KMSPolicy struct { + Version string `json:"Version"` + Statement []KMSStatement `json:"Statement"` +} + +type Builder interface { + GetServiceURL() pulumi.StringOutput + GetMetricsURL() pulumi.StringOutput +} + +// Ensure BuilderComponent implements Builder +var _ Builder = &BuilderComponent{} diff --git a/builder/validation.go b/builder/validation.go new file mode 100644 index 0000000..1a51437 --- /dev/null +++ b/builder/validation.go @@ -0,0 +1,94 @@ +package builder + +import ( + "fmt" +) + +// Validate validates the BuilderComponentArgs +func (args *BuilderComponentArgs) Validate() error { + if args.Namespace == "" { + return fmt.Errorf("namespace is required") + } + if args.Name == "" { + return fmt.Errorf("name is required") + } + if args.Image == "" { + return fmt.Errorf("image is required") + } + if args.AppLabels.Labels == nil { + return fmt.Errorf("app labels are required") + } + return args.BuilderEnv.Validate() +} + +// Validate validates the BuilderEnv +func (env *BuilderEnv) Validate() error { + if env.BuilderPort == nil { + return fmt.Errorf("builder port is required") + } + if env.BuilderKey == nil { + return fmt.Errorf("builder key is required") + } + if env.HostRpcUrl == nil { + return fmt.Errorf("host RPC URL is required") + } + if env.RollupRpcUrl == nil { + return fmt.Errorf("rollup RPC URL is required") + } + if env.ZenithAddress == nil { + return fmt.Errorf("zenith address is required") + } + if env.QuinceyUrl == nil { + return fmt.Errorf("quincey URL is required") + } + if env.OtelExporterOtlpEndpoint == nil { + return fmt.Errorf("otel exporter otlp endpoint is required") + } + if env.OauthAudience == nil { + return fmt.Errorf("oauth audience is required") + } + if env.OauthAuthenticateUrl == nil { + return fmt.Errorf("oauth authenticate URL is required") + } + if env.OAuthClientId == nil { + return fmt.Errorf("oauth client ID is required") + } + if env.OauthClientSecret == nil { + return fmt.Errorf("oauth client secret is required") + } + if env.OauthIssuer == nil { + return fmt.Errorf("oauth issuer is required") + } + if env.OauthTokenUrl == nil { + return fmt.Errorf("oauth token URL is required") + } + if env.RustLog == nil { + return fmt.Errorf("rust log is required") + } + if env.SlotOffset == nil { + return fmt.Errorf("slot offset is required") + } + if env.StartTimestamp == nil { + return fmt.Errorf("start timestamp is required") + } + if env.SubmitViaCallData == nil { + return fmt.Errorf("submit via call data is required") + } + if env.TargetSlotTime == nil { + return fmt.Errorf("target slot time is required") + } + if env.TxBroadcastUrls == nil { + return fmt.Errorf("tx broadcast URLs is required") + } + if env.TxPoolCacheDuration == nil { + return fmt.Errorf("tx pool cache duration is required") + } + if env.TxPoolUrl == nil { + return fmt.Errorf("tx pool URL is required") + } + if env.ZenithAddress == nil { + return fmt.Errorf("zenith address is required") + } + + return nil +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..220dd87 --- /dev/null +++ b/go.mod @@ -0,0 +1,91 @@ +module github.com/init4tech/signet-infra-components + +go 1.24.3 + +require ( + dario.cat/mergo v1.0.0 // indirect + github.com/BurntSushi/toml v1.2.1 // indirect + github.com/Microsoft/go-winio v0.6.1 // indirect + github.com/ProtonMail/go-crypto v1.1.3 // indirect + github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da // indirect + github.com/agext/levenshtein v1.2.3 // indirect + github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect + github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect + github.com/atotto/clipboard v0.1.4 // indirect + github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect + github.com/blang/semver v3.5.1+incompatible // indirect + github.com/charmbracelet/bubbles v0.16.1 // indirect + github.com/charmbracelet/bubbletea v0.25.0 // indirect + github.com/charmbracelet/lipgloss v0.7.1 // indirect + github.com/cheggaaa/pb v1.0.29 // indirect + github.com/cloudflare/circl v1.3.7 // indirect + github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect + github.com/cyphar/filepath-securejoin v0.3.6 // indirect + github.com/djherbis/times v1.5.0 // indirect + github.com/emirpasic/gods v1.18.1 // indirect + github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect + github.com/go-git/go-billy/v5 v5.6.1 // indirect + github.com/go-git/go-git/v5 v5.13.1 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/glog v1.2.4 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/hcl/v2 v2.22.0 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect + github.com/kevinburke/ssh_config v1.2.0 // indirect + github.com/lucasb-eyer/go-colorful v1.2.0 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-localereader v0.0.1 // indirect + github.com/mattn/go-runewidth v0.0.15 // indirect + github.com/mitchellh/go-ps v1.0.0 // indirect + github.com/mitchellh/go-wordwrap v1.0.1 // indirect + github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect + github.com/muesli/cancelreader v0.2.2 // indirect + github.com/muesli/reflow v0.3.0 // indirect + github.com/muesli/termenv v0.15.2 // indirect + github.com/opentracing/basictracer-go v1.1.0 // indirect + github.com/opentracing/opentracing-go v1.2.0 // indirect + github.com/pgavlin/fx v0.1.6 // indirect + github.com/pjbgf/sha1cd v0.3.0 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pkg/term v1.1.0 // indirect + github.com/pulumi/appdash v0.0.0-20231130102222-75f619a67231 // indirect + github.com/pulumi/esc v0.13.0 // indirect + github.com/pulumi/pulumi-aws/sdk/v6 v6.80.0 // indirect + github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.23.0 // indirect + github.com/pulumi/pulumi/sdk/v3 v3.170.0 // indirect + github.com/rivo/uniseg v0.4.4 // indirect + github.com/rogpeppe/go-internal v1.12.0 // indirect + github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 // indirect + github.com/santhosh-tekuri/jsonschema/v5 v5.0.0 // indirect + github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect + github.com/skeema/knownhosts v1.3.0 // indirect + github.com/spf13/cast v1.4.1 // indirect + github.com/spf13/cobra v1.8.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/texttheater/golang-levenshtein v1.0.1 // indirect + github.com/uber/jaeger-client-go v2.30.0+incompatible // indirect + github.com/uber/jaeger-lib v2.4.1+incompatible // indirect + github.com/xanzy/ssh-agent v0.3.3 // indirect + github.com/zclconf/go-cty v1.13.2 // indirect + go.uber.org/atomic v1.9.0 // indirect + golang.org/x/crypto v0.37.0 // indirect + golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect + golang.org/x/mod v0.19.0 // indirect + golang.org/x/net v0.39.0 // indirect + golang.org/x/sync v0.13.0 // indirect + golang.org/x/sys v0.32.0 // indirect + golang.org/x/term v0.31.0 // indirect + golang.org/x/text v0.24.0 // indirect + golang.org/x/tools v0.23.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 // indirect + google.golang.org/grpc v1.67.1 // indirect + google.golang.org/protobuf v1.35.1 // indirect + gopkg.in/warnings.v0 v0.1.2 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + lukechampine.com/frand v1.4.2 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..a0b0841 --- /dev/null +++ b/go.sum @@ -0,0 +1,275 @@ +dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= +dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= +github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= +github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= +github.com/ProtonMail/go-crypto v1.1.3 h1:nRBOetoydLeUb4nHajyO2bKqMLfWQ/ZPwkXqXxPxCFk= +github.com/ProtonMail/go-crypto v1.1.3/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= +github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da h1:KjTM2ks9d14ZYCvmHS9iAKVt9AyzRSqNU1qabPih5BY= +github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da/go.mod h1:eHEWzANqSiWQsof+nXEI9bUVUyV6F53Fp89EuCh2EAA= +github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= +github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= +github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw= +github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= +github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= +github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= +github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4= +github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= +github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= +github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= +github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ= +github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/charmbracelet/bubbles v0.16.1 h1:6uzpAAaT9ZqKssntbvZMlksWHruQLNxg49H5WdeuYSY= +github.com/charmbracelet/bubbles v0.16.1/go.mod h1:2QCp9LFlEsBQMvIYERr7Ww2H2bA7xen1idUDIzm/+Xc= +github.com/charmbracelet/bubbletea v0.25.0 h1:bAfwk7jRz7FKFl9RzlIULPkStffg5k6pNt5dywy4TcM= +github.com/charmbracelet/bubbletea v0.25.0/go.mod h1:EN3QDR1T5ZdWmdfDzYcqOCAps45+QIJbLOBxmVNWNNg= +github.com/charmbracelet/lipgloss v0.7.1 h1:17WMwi7N1b1rVWOjMT+rCh7sQkvDU75B2hbZpc5Kc1E= +github.com/charmbracelet/lipgloss v0.7.1/go.mod h1:yG0k3giv8Qj8edTCbbg6AlQ5e8KNWpFujkNawKNhE2c= +github.com/cheggaaa/pb v1.0.29 h1:FckUN5ngEk2LpvuG0fw1GEFx6LtyY2pWI/Z2QgCnEYo= +github.com/cheggaaa/pb v1.0.29/go.mod h1:W40334L7FMC5JKWldsTWbdGjLo0RxUKK73K+TuPxX30= +github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= +github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= +github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY= +github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= +github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cyphar/filepath-securejoin v0.3.6 h1:4d9N5ykBnSp5Xn2JkhocYDkOpURL/18CYMpo6xB9uWM= +github.com/cyphar/filepath-securejoin v0.3.6/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/djherbis/times v1.5.0 h1:79myA211VwPhFTqUk8xehWrsEO+zcIZj0zT8mXPVARU= +github.com/djherbis/times v1.5.0/go.mod h1:5q7FDLvbNg1L/KaBmPcWlVR9NmoKo3+ucqUA3ijQhA0= +github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= +github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= +github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= +github.com/go-git/go-billy/v5 v5.6.1 h1:u+dcrgaguSSkbjzHwelEjc0Yj300NUevrrPphk/SoRA= +github.com/go-git/go-billy/v5 v5.6.1/go.mod h1:0AsLr1z2+Uksi4NlElmMblP5rPcDZNRCD8ujZCRR2BE= +github.com/go-git/go-git/v5 v5.13.1 h1:DAQ9APonnlvSWpvolXWIuV6Q6zXy2wHbN4cVlNR5Q+M= +github.com/go-git/go-git/v5 v5.13.1/go.mod h1:qryJB4cSBoq3FRoBRf5A77joojuBcmPJ0qu3XXXVixc= +github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/glog v1.2.4 h1:CNNw5U8lSiiBk7druxtSHHTsRWcxKoac6kZKm2peBBc= +github.com/golang/glog v1.2.4/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 h1:MJG/KsmcqMwFAkh8mTnAwhyKoB+sTAnY4CACC110tbU= +github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/hcl/v2 v2.17.0 h1:z1XvSUyXd1HP10U4lrLg5e0JMVz6CPaJvAgxM0KNZVY= +github.com/hashicorp/hcl/v2 v2.17.0/go.mod h1:gJyW2PTShkJqQBKpAmPO3yxMxIuoXkOF2TpqXzrQyx4= +github.com/hashicorp/hcl/v2 v2.22.0 h1:hkZ3nCtqeJsDhPRFz5EA9iwcG1hNWGePOTw6oyul12M= +github.com/hashicorp/hcl/v2 v2.22.0/go.mod h1:62ZYHrXgPoX8xBnzl8QzbWq4dyDsDtfCRgIq1rbJEvA= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= +github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= +github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= +github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4= +github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88= +github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= +github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= +github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc= +github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg= +github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= +github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= +github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI= +github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo= +github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= +github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= +github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= +github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8= +github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo= +github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8= +github.com/opentracing/basictracer-go v1.1.0 h1:Oa1fTSBvAl8pa3U+IJYqrKm0NALwH9OsgwOqDv4xJW0= +github.com/opentracing/basictracer-go v1.1.0/go.mod h1:V2HZueSJEp879yv285Aap1BS69fQMD+MNP1mRs6mBQc= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= +github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= +github.com/pgavlin/fx v0.1.6 h1:r9jEg69DhNoCd3Xh0+5mIbdbS3PqWrVWujkY76MFRTU= +github.com/pgavlin/fx v0.1.6/go.mod h1:KWZJ6fqBBSh8GxHYqwYCf3rYE7Gp2p0N8tJp8xv9u9M= +github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= +github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/term v1.1.0 h1:xIAAdCMh3QIAy+5FrE8Ad8XoDhEU4ufwbaSozViP9kk= +github.com/pkg/term v1.1.0/go.mod h1:E25nymQcrSllhX42Ok8MRm1+hyBdHY0dCeiKZ9jpNGw= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pulumi/appdash v0.0.0-20231130102222-75f619a67231 h1:vkHw5I/plNdTr435cARxCW6q9gc0S/Yxz7Mkd38pOb0= +github.com/pulumi/appdash v0.0.0-20231130102222-75f619a67231/go.mod h1:murToZ2N9hNJzewjHBgfFdXhZKjY3z5cYC1VXk+lbFE= +github.com/pulumi/esc v0.13.0 h1:O2MPR2koScaQ2fXwyer8Q3Dd7z+DCnaDfsgNl5mVNMk= +github.com/pulumi/esc v0.13.0/go.mod h1:IIQo6W6Uzajt6f1RW4QvNxIRDlbK3TNQysnrwBHNo3U= +github.com/pulumi/pulumi-aws/sdk/v6 v6.80.0 h1:7DF4YPMqF9HPJQ5HZuLmyhr7X2nHH1M+0IRRDG6f2Io= +github.com/pulumi/pulumi-aws/sdk/v6 v6.80.0/go.mod h1:UeRQp0Sl5xTti7scMrMfQie1xs1nnChkMSTS/HfmIUQ= +github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.23.0 h1:TZ/XhzF+3/jRiGsjlJHCWhXcU5E5tbXU8O0DKnPmFic= +github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.23.0/go.mod h1:jOdpeNeRvY4iN+W8aDP5+HyqrM7hXsxa9paPsmjQFfY= +github.com/pulumi/pulumi/sdk/v3 v3.163.0 h1:yiT1nPelxXILVrN0yRn0I3NO8Yybba2IvWArYBstZJ8= +github.com/pulumi/pulumi/sdk/v3 v3.163.0/go.mod h1:GAaHrdv3kWJHbzkFFFflGbTBQXUYu6SF1ZCo+O9jo44= +github.com/pulumi/pulumi/sdk/v3 v3.170.0 h1:jwouot8dwuGngG6br6M9sP1NwwC4e6OBtkeJp0h4bSQ= +github.com/pulumi/pulumi/sdk/v3 v3.170.0/go.mod h1:Qhe4dOjqedyLr47kGGnG6ULIbzaPTlmjAvPqNQ1Ollo= +github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= +github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 h1:OkMGxebDjyw0ULyrTYWeN0UNCCkmCWfjPnIA2W6oviI= +github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06/go.mod h1:+ePHsJ1keEjQtpvf9HHw0f4ZeJ0TLRsxhunSI2hYJSs= +github.com/santhosh-tekuri/jsonschema/v5 v5.0.0 h1:TToq11gyfNlrMFZiYujSekIsPd9AmsA2Bj/iv+s4JHE= +github.com/santhosh-tekuri/jsonschema/v5 v5.0.0/go.mod h1:FKdcjfQW6rpZSnxxUvEA5H/cDPdvJ/SZJQLWWXWGrZ0= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= +github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/skeema/knownhosts v1.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0LY= +github.com/skeema/knownhosts v1.3.0/go.mod h1:sPINvnADmT/qYH1kfv+ePMmOBTH6Tbl7b5LvTDjFK7M= +github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA= +github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= +github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/texttheater/golang-levenshtein v1.0.1 h1:+cRNoVrfiwufQPhoMzB6N0Yf/Mqajr6t1lOv8GyGE2U= +github.com/texttheater/golang-levenshtein v1.0.1/go.mod h1:PYAKrbF5sAiq9wd+H82hs7gNaen0CplQ9uvm6+enD/8= +github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o= +github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= +github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVKhn2Um6rjCsSsg= +github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= +github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= +github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/zclconf/go-cty v1.13.2 h1:4GvrUxe/QUDYuJKAav4EYqdM47/kZa672LwmXFmEKT0= +github.com/zclconf/go-cty v1.13.2/go.mod h1:YKQzy/7pZ7iq2jNFzy5go57xdxdWoLLpaEp4u238AE0= +go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= +go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus= +golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= +golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= +golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= +golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56/go.mod h1:M4RDyNAINzryxdtnbRXRL/OHtkFuWGRjvuhBJpk2IlY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= +golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= +golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= +golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY= +golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= +golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610= +golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= +golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= +golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= +golang.org/x/term v0.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o= +golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= +golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= +golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240311173647-c811ad7063a7 h1:8EeVk1VKMD+GD/neyEHGmz7pFblqPjHoi+PGQIlLx2s= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240311173647-c811ad7063a7/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= +google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= +google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= +google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= +google.golang.org/protobuf v1.34.0 h1:Qo/qEd2RZPCf2nKuorzksSknv0d3ERwp1vFG38gSmH4= +google.golang.org/protobuf v1.34.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= +google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +lukechampine.com/frand v1.4.2 h1:RzFIpOvkMXuPMBb9maa4ND4wjBn71E1Jpf8BzJHMaVw= +lukechampine.com/frand v1.4.2/go.mod h1:4S/TM2ZgrKejMcKMbeLjISpJMO+/eZ1zu3vYX9dtj3s= From f522737e6892278cdc54b949d856cdd1be1e93be Mon Sep 17 00:00:00 2001 From: Swanny Date: Thu, 15 May 2025 13:44:41 -0400 Subject: [PATCH 2/9] chore: readme --- README.md | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 97 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 231a794..6faaa47 100644 --- a/README.md +++ b/README.md @@ -1 +1,97 @@ -# signet-infra-components \ No newline at end of file +# Signet Infrastructure Components + +A collection of Pulumi infrastructure components for Signet blockchain services deployed to Kubernetes. + +## Overview + +This repository contains reusable Pulumi components for deploying and managing Signet blockchain infrastructure. Each component is packaged as a separate Go module that can be imported into your Pulumi projects. + +## Components + +### Builder + +The `builder` component deploys a Signet builder service to Kubernetes. It creates the necessary resources: + +- Kubernetes Deployment +- Kubernetes Service +- Service Account +- IAM Role and Policies +- Prometheus monitoring + +#### Usage + +```go +import ( + "github.com/your-org/signet-infra-components/builder" +) + +func main() { + // Create a new builder component + builderComponent, err := builder.NewBuilder(ctx, builder.BuilderComponentArgs{ + Namespace: "signet", + Name: "signet-builder", + Image: "your-registry/builder:latest", + AppLabels: builder.AppLabels{ + Labels: pulumi.StringMap{ + "app": pulumi.String("builder"), + }, + }, + BuilderEnv: builder.BuilderEnv{ + BuilderPort: pulumi.Int(8080), + BuilderKey: pulumi.String("arn:aws:kms:region:account:key/keyid"), + HostRpcUrl: pulumi.String("https://ethereum-rpc.example.com"), + RollupRpcUrl: pulumi.String("https://rollup-rpc.example.com"), + // Add other required environment variables + }, + }) + if err != nil { + // Handle error + } + + // Export the service URL + ctx.Export("builderServiceUrl", builderComponent.GetServiceURL()) +} +``` + +## Adding New Components + +To add a new component: + +1. Create a new directory with the component name +2. Implement the component following the same structure as the `builder` component: + - `types.go` - Define component types and interfaces + - `[component].go` - Implement the main component logic + - `validation.go` - Implement input validation + - `helpers.go` - Add helper functions + +## Development + +### Prerequisites + +- Go 1.20+ +- Pulumi CLI +- Access to a Kubernetes cluster + +### Testing Components + +You can test components by creating a simple Pulumi program that uses them: + +```go +package main + +import ( + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" + "github.com/your-org/signet-infra-components/builder" +) + +func main() { + pulumi.Run(func(ctx *pulumi.Context) error { + // Test your component here + return nil + }) +} +``` + +## License + +MIT License see [LICENSE](LICENSE) \ No newline at end of file From b6a5a39c4575e552a0f816190e7000e10a673b5f Mon Sep 17 00:00:00 2001 From: Swanny Date: Thu, 15 May 2025 13:50:10 -0400 Subject: [PATCH 3/9] fix: copilot review comments --- builder/builder.go | 30 +++++++++++++++--------------- builder/validation.go | 3 --- 2 files changed, 15 insertions(+), 18 deletions(-) diff --git a/builder/builder.go b/builder/builder.go index 587b56b..973360d 100644 --- a/builder/builder.go +++ b/builder/builder.go @@ -28,9 +28,9 @@ func NewBuilder(ctx *pulumi.Context, args BuilderComponentArgs, opts ...pulumi.R } // Create service account - sa, err := corev1.NewServiceAccount(ctx, "builder-sa", &corev1.ServiceAccountArgs{ + sa, err := corev1.NewServiceAccount(ctx, fmt.Sprintf("%s-sa", args.Name), &corev1.ServiceAccountArgs{ Metadata: &metav1.ObjectMetaArgs{ - Name: pulumi.String("builder-sa"), + Name: pulumi.String(fmt.Sprintf("%s-sa", args.Name)), Namespace: pulumi.String(args.Namespace), }, }, pulumi.Parent(component)) @@ -67,11 +67,11 @@ func NewBuilder(ctx *pulumi.Context, args BuilderComponentArgs, opts ...pulumi.R return nil, fmt.Errorf("failed to marshal assume role policy: %w", err) } - role, err := iam.NewRole(ctx, "builder-role", &iam.RoleArgs{ + role, err := iam.NewRole(ctx, fmt.Sprintf("%s-role", args.Name), &iam.RoleArgs{ AssumeRolePolicy: pulumi.String(assumeRolePolicyJSON), - Description: pulumi.String("Role for builder pod to assume"), + Description: pulumi.String(fmt.Sprintf("Role for %s pod to assume", args.Name)), Tags: pulumi.StringMap{ - "Name": pulumi.String("builder-role"), + "Name": pulumi.String(fmt.Sprintf("%s-role", args.Name)), }, }, pulumi.Parent(component)) if err != nil { @@ -82,7 +82,7 @@ func NewBuilder(ctx *pulumi.Context, args BuilderComponentArgs, opts ...pulumi.R // Create KMS policy policyJSON := createKMSPolicy(args.BuilderEnv.BuilderKey) - policy, err := iam.NewPolicy(ctx, "quinceyAppPolicy", &iam.PolicyArgs{ + policy, err := iam.NewPolicy(ctx, fmt.Sprintf("%s-policy", args.Name), &iam.PolicyArgs{ Policy: policyJSON, }, pulumi.Parent(component)) if err != nil { @@ -91,7 +91,7 @@ func NewBuilder(ctx *pulumi.Context, args BuilderComponentArgs, opts ...pulumi.R component.IAMPolicy = policy // Attach policy to role - _, err = iam.NewRolePolicyAttachment(ctx, "builder-role-policy-attachment", &iam.RolePolicyAttachmentArgs{ + _, err = iam.NewRolePolicyAttachment(ctx, fmt.Sprintf("%s-role-policy-attachment", args.Name), &iam.RolePolicyAttachmentArgs{ Role: role.Name, PolicyArn: policy.Arn, }, pulumi.Parent(component)) @@ -100,9 +100,9 @@ func NewBuilder(ctx *pulumi.Context, args BuilderComponentArgs, opts ...pulumi.R } // Create deployment - deployment, err := appsv1.NewDeployment(ctx, "builder-deployment", &appsv1.DeploymentArgs{ + deployment, err := appsv1.NewDeployment(ctx, fmt.Sprintf("%s-deployment", args.Name), &appsv1.DeploymentArgs{ Metadata: &metav1.ObjectMetaArgs{ - Name: pulumi.String("builder-deployment"), + Name: pulumi.String(fmt.Sprintf("%s-deployment", args.Name)), Namespace: pulumi.String(args.Namespace), }, Spec: &appsv1.DeploymentSpecArgs{ @@ -115,10 +115,10 @@ func NewBuilder(ctx *pulumi.Context, args BuilderComponentArgs, opts ...pulumi.R Labels: args.AppLabels.Labels, }, Spec: &corev1.PodSpecArgs{ - ServiceAccountName: pulumi.String("builder-sa"), + ServiceAccountName: pulumi.String(fmt.Sprintf("%s-sa", args.Name)), Containers: corev1.ContainerArray{ &corev1.ContainerArgs{ - Name: pulumi.String("builder"), + Name: pulumi.String(args.Name), Image: pulumi.String(args.Image), Env: createEnvVars(args.BuilderEnv), Ports: corev1.ContainerPortArray{ @@ -169,9 +169,9 @@ func NewBuilder(ctx *pulumi.Context, args BuilderComponentArgs, opts ...pulumi.R component.Deployment = deployment // Create service - service, err := corev1.NewService(ctx, "builder-service", &corev1.ServiceArgs{ + service, err := corev1.NewService(ctx, fmt.Sprintf("%s-service", args.Name), &corev1.ServiceArgs{ Metadata: &metav1.ObjectMetaArgs{ - Name: pulumi.String("builder-service"), + Name: pulumi.String(fmt.Sprintf("%s-service", args.Name)), Namespace: pulumi.String(args.Namespace), Annotations: pulumi.StringMap{ "prometheus.io/scrape": pulumi.String("true"), @@ -201,11 +201,11 @@ func NewBuilder(ctx *pulumi.Context, args BuilderComponentArgs, opts ...pulumi.R component.Service = service // Create pod monitor - _, err = crd.NewCustomResource(ctx, "builder-svcmon", &crd.CustomResourceArgs{ + _, err = crd.NewCustomResource(ctx, fmt.Sprintf("%s-svcmon", args.Name), &crd.CustomResourceArgs{ ApiVersion: pulumi.String("monitoring.coreos.com/v1"), Kind: pulumi.String("PodMonitor"), Metadata: &metav1.ObjectMetaArgs{ - Name: pulumi.String("builder-pod-monitor"), + Name: pulumi.String(fmt.Sprintf("%s-pod-monitor", args.Name)), Namespace: pulumi.String(args.Namespace), }, OtherFields: map[string]interface{}{ diff --git a/builder/validation.go b/builder/validation.go index 1a51437..f0d1228 100644 --- a/builder/validation.go +++ b/builder/validation.go @@ -86,9 +86,6 @@ func (env *BuilderEnv) Validate() error { if env.TxPoolUrl == nil { return fmt.Errorf("tx pool URL is required") } - if env.ZenithAddress == nil { - return fmt.Errorf("zenith address is required") - } return nil } From d36376ad5ebfcc248f8b391fcedaea465e19c3e0 Mon Sep 17 00:00:00 2001 From: Swanny Date: Thu, 15 May 2025 13:50:34 -0400 Subject: [PATCH 4/9] chore: go mod tidy --- go.mod | 10 ++++++---- go.sum | 58 ++++++++++++++++++++++++++++++++++------------------------ 2 files changed, 40 insertions(+), 28 deletions(-) diff --git a/go.mod b/go.mod index 220dd87..16f9727 100644 --- a/go.mod +++ b/go.mod @@ -2,6 +2,12 @@ module github.com/init4tech/signet-infra-components go 1.24.3 +require ( + github.com/pulumi/pulumi-aws/sdk/v6 v6.80.0 + github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.23.0 + github.com/pulumi/pulumi/sdk/v3 v3.170.0 +) + require ( dario.cat/mergo v1.0.0 // indirect github.com/BurntSushi/toml v1.2.1 // indirect @@ -55,16 +61,12 @@ require ( github.com/pkg/term v1.1.0 // indirect github.com/pulumi/appdash v0.0.0-20231130102222-75f619a67231 // indirect github.com/pulumi/esc v0.13.0 // indirect - github.com/pulumi/pulumi-aws/sdk/v6 v6.80.0 // indirect - github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.23.0 // indirect - github.com/pulumi/pulumi/sdk/v3 v3.170.0 // indirect github.com/rivo/uniseg v0.4.4 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/sabhiram/go-gitignore v0.0.0-20210923224102-525f6e181f06 // indirect github.com/santhosh-tekuri/jsonschema/v5 v5.0.0 // indirect github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect github.com/skeema/knownhosts v1.3.0 // indirect - github.com/spf13/cast v1.4.1 // indirect github.com/spf13/cobra v1.8.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/texttheater/golang-levenshtein v1.0.1 // indirect diff --git a/go.sum b/go.sum index a0b0841..6ffef60 100644 --- a/go.sum +++ b/go.sum @@ -2,6 +2,8 @@ dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob0t8PQPMybUNFM= +github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= @@ -11,10 +13,14 @@ github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da h1:KjTM2ks9d14ZYCvmH github.com/aead/chacha20 v0.0.0-20180709150244-8b13a72661da/go.mod h1:eHEWzANqSiWQsof+nXEI9bUVUyV6F53Fp89EuCh2EAA= github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw= github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4= github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= @@ -37,16 +43,25 @@ github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t github.com/cyphar/filepath-securejoin v0.3.6 h1:4d9N5ykBnSp5Xn2JkhocYDkOpURL/18CYMpo6xB9uWM= github.com/cyphar/filepath-securejoin v0.3.6/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/djherbis/times v1.5.0 h1:79myA211VwPhFTqUk8xehWrsEO+zcIZj0zT8mXPVARU= github.com/djherbis/times v1.5.0/go.mod h1:5q7FDLvbNg1L/KaBmPcWlVR9NmoKo3+ucqUA3ijQhA0= +github.com/elazarl/goproxy v1.2.3 h1:xwIyKHbaP5yfT6O9KIeYJR5549MXRQkoQMRXGztz8YQ= +github.com/elazarl/goproxy v1.2.3/go.mod h1:YfEbZtqP4AetfO6d40vWchF3znWX7C7Vd6ZMfdL8z64= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c= +github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= github.com/go-git/go-billy/v5 v5.6.1 h1:u+dcrgaguSSkbjzHwelEjc0Yj300NUevrrPphk/SoRA= github.com/go-git/go-billy/v5 v5.6.1/go.mod h1:0AsLr1z2+Uksi4NlElmMblP5rPcDZNRCD8ujZCRR2BE= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= github.com/go-git/go-git/v5 v5.13.1 h1:DAQ9APonnlvSWpvolXWIuV6Q6zXy2wHbN4cVlNR5Q+M= github.com/go-git/go-git/v5 v5.13.1/go.mod h1:qryJB4cSBoq3FRoBRf5A77joojuBcmPJ0qu3XXXVixc= github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= @@ -56,6 +71,8 @@ github.com/golang/glog v1.2.4 h1:CNNw5U8lSiiBk7druxtSHHTsRWcxKoac6kZKm2peBBc= github.com/golang/glog v1.2.4/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645 h1:MJG/KsmcqMwFAkh8mTnAwhyKoB+sTAnY4CACC110tbU= @@ -65,8 +82,6 @@ github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/hcl/v2 v2.17.0 h1:z1XvSUyXd1HP10U4lrLg5e0JMVz6CPaJvAgxM0KNZVY= -github.com/hashicorp/hcl/v2 v2.17.0/go.mod h1:gJyW2PTShkJqQBKpAmPO3yxMxIuoXkOF2TpqXzrQyx4= github.com/hashicorp/hcl/v2 v2.22.0 h1:hkZ3nCtqeJsDhPRFz5EA9iwcG1hNWGePOTw6oyul12M= github.com/hashicorp/hcl/v2 v2.22.0/go.mod h1:62ZYHrXgPoX8xBnzl8QzbWq4dyDsDtfCRgIq1rbJEvA= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= @@ -79,11 +94,17 @@ github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQL github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= @@ -106,6 +127,8 @@ github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8= github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo= github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8= +github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= +github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= github.com/opentracing/basictracer-go v1.1.0 h1:Oa1fTSBvAl8pa3U+IJYqrKm0NALwH9OsgwOqDv4xJW0= github.com/opentracing/basictracer-go v1.1.0/go.mod h1:V2HZueSJEp879yv285Aap1BS69fQMD+MNP1mRs6mBQc= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= @@ -119,6 +142,7 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/term v1.1.0 h1:xIAAdCMh3QIAy+5FrE8Ad8XoDhEU4ufwbaSozViP9kk= github.com/pkg/term v1.1.0/go.mod h1:E25nymQcrSllhX42Ok8MRm1+hyBdHY0dCeiKZ9jpNGw= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pulumi/appdash v0.0.0-20231130102222-75f619a67231 h1:vkHw5I/plNdTr435cARxCW6q9gc0S/Yxz7Mkd38pOb0= github.com/pulumi/appdash v0.0.0-20231130102222-75f619a67231/go.mod h1:murToZ2N9hNJzewjHBgfFdXhZKjY3z5cYC1VXk+lbFE= @@ -128,8 +152,6 @@ github.com/pulumi/pulumi-aws/sdk/v6 v6.80.0 h1:7DF4YPMqF9HPJQ5HZuLmyhr7X2nHH1M+0 github.com/pulumi/pulumi-aws/sdk/v6 v6.80.0/go.mod h1:UeRQp0Sl5xTti7scMrMfQie1xs1nnChkMSTS/HfmIUQ= github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.23.0 h1:TZ/XhzF+3/jRiGsjlJHCWhXcU5E5tbXU8O0DKnPmFic= github.com/pulumi/pulumi-kubernetes/sdk/v4 v4.23.0/go.mod h1:jOdpeNeRvY4iN+W8aDP5+HyqrM7hXsxa9paPsmjQFfY= -github.com/pulumi/pulumi/sdk/v3 v3.163.0 h1:yiT1nPelxXILVrN0yRn0I3NO8Yybba2IvWArYBstZJ8= -github.com/pulumi/pulumi/sdk/v3 v3.163.0/go.mod h1:GAaHrdv3kWJHbzkFFFflGbTBQXUYu6SF1ZCo+O9jo44= github.com/pulumi/pulumi/sdk/v3 v3.170.0 h1:jwouot8dwuGngG6br6M9sP1NwwC4e6OBtkeJp0h4bSQ= github.com/pulumi/pulumi/sdk/v3 v3.170.0/go.mod h1:Qhe4dOjqedyLr47kGGnG6ULIbzaPTlmjAvPqNQ1Ollo= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= @@ -148,18 +170,19 @@ github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/skeema/knownhosts v1.3.0 h1:AM+y0rI04VksttfwjkSTNQorvGqmwATnvnAHpSgc0LY= github.com/skeema/knownhosts v1.3.0/go.mod h1:sPINvnADmT/qYH1kfv+ePMmOBTH6Tbl7b5LvTDjFK7M= -github.com/spf13/cast v1.4.1 h1:s0hze+J0196ZfEMTs80N7UlFt0BDuQ7Q+JDnHiMWKdA= -github.com/spf13/cast v1.4.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/texttheater/golang-levenshtein v1.0.1 h1:+cRNoVrfiwufQPhoMzB6N0Yf/Mqajr6t1lOv8GyGE2U= github.com/texttheater/golang-levenshtein v1.0.1/go.mod h1:PYAKrbF5sAiq9wd+H82hs7gNaen0CplQ9uvm6+enD/8= github.com/uber/jaeger-client-go v2.30.0+incompatible h1:D6wyKGCecFaSRUpo8lCVbaOOb6ThwMmTEbhRwtKR97o= @@ -178,8 +201,6 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.33.0 h1:IOBPskki6Lysi0lo9qQvbxiQ+FvsCC/YWOecCHAixus= -golang.org/x/crypto v0.33.0/go.mod h1:bVdXmD7IV/4GdElGPozy6U7lWdRXA4qyRVGJV57uQ5M= golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 h1:2dVuKD2vS7b0QIHQbpyTISPd0LeHDbnYEryqj5Q1ug8= @@ -196,15 +217,11 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= -golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY= golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= -golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610= golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -222,20 +239,14 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= -golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.29.0 h1:L6pJp37ocefwRRtYPKSWOWzOtWSxVajvz2ldH/xi3iU= -golang.org/x/term v0.29.0/go.mod h1:6bl4lRlvVuDgSf3179VpIxBF0o10JUpXWOnI7nErv7s= golang.org/x/term v0.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o= golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= -golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -250,26 +261,25 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240311173647-c811ad7063a7 h1:8EeVk1VKMD+GD/neyEHGmz7pFblqPjHoi+PGQIlLx2s= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240311173647-c811ad7063a7/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142 h1:e7S5W7MGGLaSu8j3YjdezkZ+m1/Nm0uRVRMEMGk26Xs= google.golang.org/genproto/googleapis/rpc v0.0.0-20240814211410-ddb44dafa142/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU= -google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= -google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= -google.golang.org/protobuf v1.34.0 h1:Qo/qEd2RZPCf2nKuorzksSknv0d3ERwp1vFG38gSmH4= -google.golang.org/protobuf v1.34.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= lukechampine.com/frand v1.4.2 h1:RzFIpOvkMXuPMBb9maa4ND4wjBn71E1Jpf8BzJHMaVw= lukechampine.com/frand v1.4.2/go.mod h1:4S/TM2ZgrKejMcKMbeLjISpJMO+/eZ1zu3vYX9dtj3s= +pgregory.net/rapid v0.6.1 h1:4eyrDxyht86tT4Ztm+kvlyNBLIk071gR+ZQdhphc9dQ= +pgregory.net/rapid v0.6.1/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= From 4e2aa22cad851a6d815f4e550382ceb4358abed5 Mon Sep 17 00:00:00 2001 From: Swanny Date: Thu, 15 May 2025 14:05:07 -0400 Subject: [PATCH 5/9] chore: .github dir contents --- .github/CODEOWNERS | 1 + .github/dependabot.yml | 6 ++++++ .github/workflows/go.yml | 25 +++++++++++++++++++++++++ 3 files changed, 32 insertions(+) create mode 100644 .github/CODEOWNERS create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/go.yml diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..46d0ded --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1 @@ +* @rswanson \ No newline at end of file diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..a5f3c6c --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: +- package-ecosystem: gomod + directory: / + schedule: + interval: weekly \ No newline at end of file diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml new file mode 100644 index 0000000..5d8130e --- /dev/null +++ b/.github/workflows/go.yml @@ -0,0 +1,25 @@ +# This workflow will build a golang project +# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-go + +name: Go + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + +jobs: + + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Set up Go + uses: actions/setup-go@v4 + with: + go-version: '1.22' + + - name: Build + run: go build -v ./... From b4cbc16641adb03ecc26be27d96c842f51cbb6f3 Mon Sep 17 00:00:00 2001 From: Swanny Date: Thu, 15 May 2025 14:47:02 -0400 Subject: [PATCH 6/9] feat: tests --- go.mod | 4 + go.sum | 2 + {builder => pkg/builder}/builder.go | 0 {builder => pkg/builder}/helpers.go | 49 +++++++--- pkg/builder/helpers_test.go | 130 +++++++++++++++++++++++++ {builder => pkg/builder}/types.go | 8 +- {builder => pkg/builder}/validation.go | 0 pkg/builder/validation_test.go | 123 +++++++++++++++++++++++ 8 files changed, 301 insertions(+), 15 deletions(-) rename {builder => pkg/builder}/builder.go (100%) rename {builder => pkg/builder}/helpers.go (57%) create mode 100644 pkg/builder/helpers_test.go rename {builder => pkg/builder}/types.go (94%) rename {builder => pkg/builder}/validation.go (100%) create mode 100644 pkg/builder/validation_test.go diff --git a/go.mod b/go.mod index 16f9727..cca963b 100644 --- a/go.mod +++ b/go.mod @@ -27,6 +27,7 @@ require ( github.com/cloudflare/circl v1.3.7 // indirect github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect github.com/cyphar/filepath-securejoin v0.3.6 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect github.com/djherbis/times v1.5.0 // indirect github.com/emirpasic/gods v1.18.1 // indirect github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect @@ -59,6 +60,7 @@ require ( github.com/pjbgf/sha1cd v0.3.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pkg/term v1.1.0 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect github.com/pulumi/appdash v0.0.0-20231130102222-75f619a67231 // indirect github.com/pulumi/esc v0.13.0 // indirect github.com/rivo/uniseg v0.4.4 // indirect @@ -69,6 +71,8 @@ require ( github.com/skeema/knownhosts v1.3.0 // indirect github.com/spf13/cobra v1.8.0 // indirect github.com/spf13/pflag v1.0.5 // indirect + github.com/stretchr/objx v0.5.2 // indirect + github.com/stretchr/testify v1.10.0 // indirect github.com/texttheater/golang-levenshtein v1.0.1 // indirect github.com/uber/jaeger-client-go v2.30.0+incompatible // indirect github.com/uber/jaeger-lib v2.4.1+incompatible // indirect diff --git a/go.sum b/go.sum index 6ffef60..70f49e2 100644 --- a/go.sum +++ b/go.sum @@ -176,6 +176,8 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= diff --git a/builder/builder.go b/pkg/builder/builder.go similarity index 100% rename from builder/builder.go rename to pkg/builder/builder.go diff --git a/builder/helpers.go b/pkg/builder/helpers.go similarity index 57% rename from builder/helpers.go rename to pkg/builder/helpers.go index a3ac305..2f6768d 100644 --- a/builder/helpers.go +++ b/pkg/builder/helpers.go @@ -9,8 +9,9 @@ import ( "github.com/pulumi/pulumi/sdk/v3/go/pulumi" ) -// createKMSPolicy creates a KMS policy for the builder service. -func createKMSPolicy(key pulumi.StringInput) pulumi.StringOutput { +// CreateKMSPolicy creates a KMS policy for the builder service. +// Exported for testing. +func CreateKMSPolicy(key pulumi.StringInput) pulumi.StringOutput { return pulumi.Sprintf(`{ "Version": "2012-10-17", "Statement": [ @@ -26,9 +27,15 @@ func createKMSPolicy(key pulumi.StringInput) pulumi.StringOutput { }`, key) } -// createEnvVars creates environment variables by automatically mapping +// createKMSPolicy is the internal version kept for backward compatibility +func createKMSPolicy(key pulumi.StringInput) pulumi.StringOutput { + return CreateKMSPolicy(key) +} + +// CreateEnvVars creates environment variables by automatically mapping // struct field names to environment variable names. -func createEnvVars(env BuilderEnv) corev1.EnvVarArray { +// Exported for testing. +func CreateEnvVars(env BuilderEnv) corev1.EnvVarArray { result := corev1.EnvVarArray{} // Special case for BuilderPort as it needs string conversion @@ -38,7 +45,7 @@ func createEnvVars(env BuilderEnv) corev1.EnvVarArray { }) // Process all string inputs from the struct's tags - envVarMap := getEnvironmentVarsFromStruct(env) + envVarMap := GetEnvironmentVarsFromStruct(env) for name, value := range envVarMap { if name != "BUILDER_PORT" { // Skip the one we already handled result = append(result, &corev1.EnvVarArgs{ @@ -51,8 +58,14 @@ func createEnvVars(env BuilderEnv) corev1.EnvVarArray { return result } -// getEnvironmentVarsFromStruct uses reflection to extract environment variables from struct tags -func getEnvironmentVarsFromStruct(env BuilderEnv) map[string]pulumi.Input { +// createEnvVars is kept for backward compatibility +func createEnvVars(env BuilderEnv) corev1.EnvVarArray { + return CreateEnvVars(env) +} + +// GetEnvironmentVarsFromStruct uses reflection to extract environment variables from struct tags +// Exported for testing. +func GetEnvironmentVarsFromStruct(env BuilderEnv) map[string]pulumi.Input { result := make(map[string]pulumi.Input) t := reflect.TypeOf(env) @@ -70,7 +83,7 @@ func getEnvironmentVarsFromStruct(env BuilderEnv) map[string]pulumi.Input { } // Convert camelCase to SNAKE_CASE for env var name - envName := camelToSnake(field.Name) + envName := CamelToSnake(field.Name) // Add to map result[envName] = fieldValue.(pulumi.Input) @@ -79,12 +92,26 @@ func getEnvironmentVarsFromStruct(env BuilderEnv) map[string]pulumi.Input { return result } -// camelToSnake converts a camelCase string to SNAKE_CASE -func camelToSnake(s string) string { +// getEnvironmentVarsFromStruct is kept for backward compatibility +func getEnvironmentVarsFromStruct(env BuilderEnv) map[string]pulumi.Input { + return GetEnvironmentVarsFromStruct(env) +} + +// CamelToSnake converts a camelCase string to SNAKE_CASE +// Exported for testing purposes +func CamelToSnake(s string) string { var result strings.Builder + + // Handle consecutive uppercase characters (acronyms) for i, r := range s { if unicode.IsUpper(r) { - if i > 0 { + // Add underscore if not the first character and either: + // 1. Previous character is lowercase, or + // 2. Not the last character and next character is lowercase (end of acronym) + needsUnderscore := i > 0 && (unicode.IsLower(rune(s[i-1])) || + (i < len(s)-1 && unicode.IsLower(rune(s[i+1])) && i > 1 && unicode.IsUpper(rune(s[i-1])))) + + if needsUnderscore { result.WriteRune('_') } result.WriteRune(unicode.ToUpper(r)) diff --git a/pkg/builder/helpers_test.go b/pkg/builder/helpers_test.go new file mode 100644 index 0000000..bcfea30 --- /dev/null +++ b/pkg/builder/helpers_test.go @@ -0,0 +1,130 @@ +package builder + +import ( + "testing" + + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" + "github.com/stretchr/testify/assert" +) + +func TestCamelToSnake(t *testing.T) { + testCases := []struct { + input string + output string + }{ + { + input: "BuilderPort", + output: "BUILDER_PORT", + }, + { + input: "HostRpcUrl", + output: "HOST_RPC_URL", + }, + { + input: "AWSRegion", + output: "AWS_REGION", + }, + { + input: "OtelExporterOtlpEndpoint", + output: "OTEL_EXPORTER_OTLP_ENDPOINT", + }, + { + input: "simpleText", + output: "SIMPLE_TEXT", + }, + } + + for _, tc := range testCases { + t.Run(tc.input, func(t *testing.T) { + result := CamelToSnake(tc.input) + assert.Equal(t, tc.output, result) + }) + } +} + +func TestCreateKMSPolicy(t *testing.T) { + // Test with a simple key ARN + keyArn := "arn:aws:kms:us-west-2:123456789012:key/1234abcd-12ab-34cd-56ef-1234567890ab" + key := pulumi.String(keyArn) + + // Get the policy string + // Note: We can't directly access the string value from StringOutput in a unit test + // So we'll just verify the function returns a non-nil value and the structure will + // be tested separately when used in the actual builder component. + policy := CreateKMSPolicy(key) + + // We can only indirectly test this by asserting the output is not nil + assert.NotNil(t, policy) + + // Test with another key to ensure the function uses the provided key + anotherKey := pulumi.String("another-key-arn") + anotherPolicy := CreateKMSPolicy(anotherKey) + assert.NotNil(t, anotherPolicy) +} + +func TestCreateEnvVars(t *testing.T) { + // Create a test BuilderEnv with some values + env := BuilderEnv{ + BuilderPort: pulumi.Int(8080), + BuilderKey: pulumi.String("test-key"), + HostRpcUrl: pulumi.String("http://host-rpc"), + RollupRpcUrl: pulumi.String("http://rollup-rpc"), + ZenithAddress: pulumi.String("0x123456"), + AwsRegion: pulumi.String("us-west-2"), + AwsAccountId: pulumi.String("123456789012"), + } + + // Get the environment variables + envVars := CreateEnvVars(env) + + // Test that the array is not nil and has the correct length + // We expect one env var for BuilderPort plus one for each of the other fields + assert.NotNil(t, envVars) + + // Count the non-nil fields in env to determine expected size + // We need to do this because BuilderEnv has many fields and we're only setting a few + expectedSize := 0 + if env.BuilderPort != nil { + expectedSize++ + } + envVarMap := GetEnvironmentVarsFromStruct(env) + expectedSize += len(envVarMap) + + // Check if the array is the expected size + assert.Len(t, envVars, expectedSize) + + // Test that specific environment variables are set correctly + // Due to the nature of Pulumi outputs, we can only test basics here + // Just check that we have a non-empty array + assert.Greater(t, len(envVars), 0, "Should have at least one environment variable") +} + +func TestGetEnvironmentVarsFromStruct(t *testing.T) { + // Create a test BuilderEnv with some values + env := BuilderEnv{ + BuilderPort: pulumi.Int(8080), + BuilderKey: pulumi.String("test-key"), + HostRpcUrl: pulumi.String("http://host-rpc"), + AwsRegion: pulumi.String("us-west-2"), + } + + // Get the environment variables map + envVars := GetEnvironmentVarsFromStruct(env) + + // Test that the map is not nil and has the expected keys + assert.NotNil(t, envVars) + + // BuilderPort should be excluded (handled specially) + _, hasBuilderPort := envVars["BUILDER_PORT"] + assert.False(t, hasBuilderPort, "BUILDER_PORT should not be in the map") + + // Other fields should be included + _, hasBuilderKey := envVars["BUILDER_KEY"] + assert.True(t, hasBuilderKey, "BUILDER_KEY should be in the map") + + _, hasHostRpcUrl := envVars["HOST_RPC_URL"] + assert.True(t, hasHostRpcUrl, "HOST_RPC_URL should be in the map") + + _, hasAwsRegion := envVars["AWS_REGION"] + assert.True(t, hasAwsRegion, "AWS_REGION should be in the map") +} diff --git a/builder/types.go b/pkg/builder/types.go similarity index 94% rename from builder/types.go rename to pkg/builder/types.go index bb791f9..3b6785d 100644 --- a/builder/types.go +++ b/pkg/builder/types.go @@ -43,10 +43,10 @@ type BuilderComponentArgs struct { // BuilderEnv contains all environment variables required by the builder service. type BuilderEnv struct { AuthTokenRefreshInterval pulumi.StringInput `pulumi:"authTokenRefreshInterval"` - AWSAccountId pulumi.StringInput `pulumi:"awsAccountId"` - AWSAccessKeyId pulumi.StringInput `pulumi:"awsAccessKeyId"` - AWSRegion pulumi.StringInput `pulumi:"awsRegion"` - AWSSecretAccessKey pulumi.StringInput `pulumi:"awsSecretAccessKey"` + AwsAccountId pulumi.StringInput `pulumi:"awsAccountId"` + AwsAccessKeyId pulumi.StringInput `pulumi:"awsAccessKeyId"` + AwsRegion pulumi.StringInput `pulumi:"awsRegion"` + AwsSecretAccessKey pulumi.StringInput `pulumi:"awsSecretAccessKey"` BlockConfirmationBuffer pulumi.StringInput `pulumi:"blockConfirmationBuffer"` BlockQueryCutoff pulumi.StringInput `pulumi:"blockQueryCutoff"` BlockQueryStart pulumi.StringInput `pulumi:"blockQueryStart"` diff --git a/builder/validation.go b/pkg/builder/validation.go similarity index 100% rename from builder/validation.go rename to pkg/builder/validation.go diff --git a/pkg/builder/validation_test.go b/pkg/builder/validation_test.go new file mode 100644 index 0000000..2546ea4 --- /dev/null +++ b/pkg/builder/validation_test.go @@ -0,0 +1,123 @@ +package builder + +import ( + "testing" + + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" + "github.com/stretchr/testify/assert" +) + +func TestBuilderComponentArgsValidate(t *testing.T) { + // Test validation with missing fields + testCases := []struct { + name string + args BuilderComponentArgs + wantErr string + }{ + { + name: "missing namespace", + args: BuilderComponentArgs{}, + wantErr: "namespace is required", + }, + { + name: "missing name", + args: BuilderComponentArgs{ + Namespace: "test-namespace", + }, + wantErr: "name is required", + }, + { + name: "missing image", + args: BuilderComponentArgs{ + Namespace: "test-namespace", + Name: "test-builder", + }, + wantErr: "image is required", + }, + { + name: "missing app labels", + args: BuilderComponentArgs{ + Namespace: "test-namespace", + Name: "test-builder", + Image: "test-image:latest", + }, + wantErr: "app labels are required", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + err := tc.args.Validate() + assert.Error(t, err) + assert.Equal(t, tc.wantErr, err.Error()) + }) + } + + // Test with valid args but empty BuilderEnv + t.Run("valid args but empty BuilderEnv", func(t *testing.T) { + args := BuilderComponentArgs{ + Namespace: "test-namespace", + Name: "test-builder", + Image: "test-image:latest", + AppLabels: AppLabels{Labels: pulumi.StringMap{"app": pulumi.String("test")}}, + } + err := args.Validate() + assert.Error(t, err) + assert.Equal(t, "builder port is required", err.Error()) + }) + + // Test with valid args and minimal valid BuilderEnv + t.Run("valid args with minimal BuilderEnv", func(t *testing.T) { + args := BuilderComponentArgs{ + Namespace: "test-namespace", + Name: "test-builder", + Image: "test-image:latest", + AppLabels: AppLabels{Labels: pulumi.StringMap{"app": pulumi.String("test")}}, + BuilderEnv: BuilderEnv{ + BuilderPort: pulumi.Int(8080), + BuilderKey: pulumi.String("test-key"), + HostRpcUrl: pulumi.String("http://host-rpc"), + RollupRpcUrl: pulumi.String("http://rollup-rpc"), + ZenithAddress: pulumi.String("0x123456"), + QuinceyUrl: pulumi.String("http://quincey"), + OtelExporterOtlpEndpoint: pulumi.String("http://otel"), + OauthAudience: pulumi.String("audience"), + OauthAuthenticateUrl: pulumi.String("http://auth"), + OAuthClientId: pulumi.String("client-id"), + OauthClientSecret: pulumi.String("secret"), + OauthIssuer: pulumi.String("issuer"), + OauthTokenUrl: pulumi.String("http://token"), + RustLog: pulumi.String("info"), + SlotOffset: pulumi.String("10"), + StartTimestamp: pulumi.String("123456789"), + SubmitViaCallData: pulumi.String("true"), + TargetSlotTime: pulumi.String("20"), + TxBroadcastUrls: pulumi.String("http://broadcast"), + TxPoolCacheDuration: pulumi.String("60"), + TxPoolUrl: pulumi.String("http://txpool"), + }, + } + err := args.Validate() + assert.NoError(t, err) + }) +} + +func TestBuilderEnvValidate(t *testing.T) { + // Test just one case for BuilderEnv validation + t.Run("missing builder port", func(t *testing.T) { + env := BuilderEnv{} + err := env.Validate() + assert.Error(t, err) + assert.Equal(t, "builder port is required", err.Error()) + }) + + // Test with just BuilderPort set + t.Run("missing builder key", func(t *testing.T) { + env := BuilderEnv{ + BuilderPort: pulumi.Int(8080), + } + err := env.Validate() + assert.Error(t, err) + assert.Equal(t, "builder key is required", err.Error()) + }) +} From 796fcf10ee04adbc745653f0a6d70c22b05caf74 Mon Sep 17 00:00:00 2001 From: Swanny Date: Thu, 15 May 2025 14:48:18 -0400 Subject: [PATCH 7/9] fix: run tests in ci --- .github/workflows/go.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 5d8130e..1edc215 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -23,3 +23,6 @@ jobs: - name: Build run: go build -v ./... + + - name: Run tests + run: go test -v ./... \ No newline at end of file From 5d6403388854dc343bbdf0417e0405c7289161ef Mon Sep 17 00:00:00 2001 From: Swanny Date: Thu, 15 May 2025 14:50:30 -0400 Subject: [PATCH 8/9] fix: action workflow name --- .github/workflows/go.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 1edc215..f307c58 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -11,7 +11,7 @@ on: jobs: - build: + tests: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 From 1af8e9977d0fd60f76e599941c030b90c6a1c28c Mon Sep 17 00:00:00 2001 From: Swanny Date: Fri, 16 May 2025 08:27:04 -0400 Subject: [PATCH 9/9] fix: construct json better --- pkg/builder/builder.go | 2 +- pkg/builder/helpers.go | 35 ++++++++++++++++++++--------------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/pkg/builder/builder.go b/pkg/builder/builder.go index 973360d..1df2034 100644 --- a/pkg/builder/builder.go +++ b/pkg/builder/builder.go @@ -80,7 +80,7 @@ func NewBuilder(ctx *pulumi.Context, args BuilderComponentArgs, opts ...pulumi.R component.IAMRole = role // Create KMS policy - policyJSON := createKMSPolicy(args.BuilderEnv.BuilderKey) + policyJSON := CreateKMSPolicy(args.BuilderEnv.BuilderKey) policy, err := iam.NewPolicy(ctx, fmt.Sprintf("%s-policy", args.Name), &iam.PolicyArgs{ Policy: policyJSON, diff --git a/pkg/builder/helpers.go b/pkg/builder/helpers.go index 2f6768d..a4d8e89 100644 --- a/pkg/builder/helpers.go +++ b/pkg/builder/helpers.go @@ -1,6 +1,7 @@ package builder import ( + "encoding/json" "reflect" "strings" "unicode" @@ -12,24 +13,28 @@ import ( // CreateKMSPolicy creates a KMS policy for the builder service. // Exported for testing. func CreateKMSPolicy(key pulumi.StringInput) pulumi.StringOutput { - return pulumi.Sprintf(`{ - "Version": "2012-10-17", - "Statement": [ + policy := KMSPolicy{ + Version: "2012-10-17", + Statement: []KMSStatement{ { - "Effect": "Allow", - "Action": [ + Effect: "Allow", + Action: []string{ "kms:Sign", - "kms:GetPublicKey" - ], - "Resource": %s - } - ] - }`, key) -} + "kms:GetPublicKey", + }, + Resource: key, + }, + }, + } -// createKMSPolicy is the internal version kept for backward compatibility -func createKMSPolicy(key pulumi.StringInput) pulumi.StringOutput { - return CreateKMSPolicy(key) + // Convert to JSON string output + return pulumi.All(key).ApplyT(func(_ []interface{}) (string, error) { + jsonBytes, err := json.Marshal(policy) + if err != nil { + return "", err + } + return string(jsonBytes), nil + }).(pulumi.StringOutput) } // CreateEnvVars creates environment variables by automatically mapping