diff --git a/cmd/cli/connect/cli.go b/cmd/cli/connect/cli.go index 98425ac..bbb7e13 100644 --- a/cmd/cli/connect/cli.go +++ b/cmd/cli/connect/cli.go @@ -3,6 +3,7 @@ package connect import ( "github.com/jaxxstorm/connecti/cmd/cli/connect/aws" "github.com/jaxxstorm/connecti/cmd/cli/connect/azure" + "github.com/jaxxstorm/connecti/cmd/cli/connect/kubernetes" "github.com/spf13/cobra" ) @@ -15,6 +16,7 @@ func Command() *cobra.Command { command.AddCommand(aws.Command()) command.AddCommand(azure.Command()) + command.AddCommand(kubernetes.Command()) return command } diff --git a/cmd/cli/connect/kubernetes/cli.go b/cmd/cli/connect/kubernetes/cli.go new file mode 100644 index 0000000..c43ecf9 --- /dev/null +++ b/cmd/cli/connect/kubernetes/cli.go @@ -0,0 +1,115 @@ +package kubernetes + +import ( + "context" + "fmt" + + "github.com/jaxxstorm/connecti/pkg/kubernetes" + randomname "github.com/jaxxstorm/connecti/pkg/name" + tui "github.com/jaxxstorm/connecti/pkg/terminal" + "github.com/pulumi/pulumi/sdk/v3/go/auto/optup" + "github.com/spf13/cobra" + "github.com/spf13/viper" +) + +var ( + name string + tailnet string + apiKey string + routes []string +) + +func Command() *cobra.Command { + command := &cobra.Command{ + Use: "kubernetes", + Short: "Connect to Kubernetes infrastructure.", + Long: `Create a tailscale bastion in a Kubernetes cluster via a deployment.`, + RunE: tui.WrapCobraCommand(func(cmd *cobra.Command, args []string, view tui.View) error { + // Grab all the configuration variables + tailnet = viper.GetString("tailnet") + apiKey = viper.GetString("apiKey") + name = viper.GetString("name") + routes = viper.GetStringSlice("routes") + + view.Ready() + + // apparently you can't specify if a flag is required + // and set in configuration, so manual validation is the only way + // see: https://github.com/spf13/viper/issues/397 + if tailnet == "" { + return fmt.Errorf("must specify a tailnet. See --help") + } + + if apiKey == "" { + return fmt.Errorf("must specify a tailscale api key. See --help") + } + + if name == "" { + name = randomname.Generate() + } + + if len(routes) == 0 { + return fmt.Errorf("must specify at least one route. See --help") + } + + ctx := context.Background() + program, err := kubernetes.Program(name, ctx, kubernetes.BastionArgs{ + Name: name, + Routes: routes, + Tailnet: tailnet, + ApiKey: apiKey, + CreateNamespace: true, // FIXME: should we allow usage of an existing namespace? + }) + if err != nil { + return err + } + + view.SetPulumiProgramCancelFn(func() error { + return program.Cancel(ctx) + }) + + outputHandler := view.NewPulumiOutputHandler("update") + stdoutStreamer := optup.ProgressStreams(outputHandler) + _, err = program.Refresh(ctx) + if err != nil { + return fmt.Errorf("error refreshing stack: %v", err) + } + _, err = program.Up(ctx, stdoutStreamer) + if err != nil { + view.SendPulumiProgressOutput(outputHandler.CurrentProgress, "Failed to create resources. Cleaning up.", "") + // If the update errors, we should clean up the stack for the user. + _, dErr := program.Destroy(ctx) + if dErr != nil { + return fmt.Errorf("failed update: %v\n\n\tfailed clean up: %v", err, dErr) + } + rmErr := program.Workspace().RemoveStack(ctx, name) + if rmErr != nil { + return fmt.Errorf("failed update: %v\n\n\tfailed stack removal: %v", err, rmErr) + } + + return fmt.Errorf("failed update: %v", err) + } + + return nil + + }), + } + + command.Flags().StringVar(&name, "name", "", "Unique name to use for your bastion.") + command.Flags().StringVar(&tailnet, "tailnet", "", "The name of the tailnet to connect to. See: https://login.tailscale.com/admin/settings/general") + command.Flags().StringVar(&apiKey, "api-key", "", "The tailnet api key to use. See: https://login.tailscale.com/admin/settings/keys") + command.Flags().StringSliceVar(&routes, "routes", nil, "The routes to advertise. This is likely the cluster Pod CIDR and Service CIDR.") + + viper.BindPFlag("name", command.Flags().Lookup("name")) + viper.BindPFlag("tailnet", command.Flags().Lookup("tailnet")) + viper.BindPFlag("apiKey", command.Flags().Lookup("api-key")) + viper.BindPFlag("routes", command.Flags().Lookup("routes")) + + // Bind the env vars to the provider env vars + viper.BindEnv("tailnet", "TAILSCALE_TAILNET") + viper.BindEnv("apiKey", "TAILSCALE_API_KEY") + + command.MarkFlagRequired("routes") + + return command +} diff --git a/cmd/cli/disconnect/cli.go b/cmd/cli/disconnect/cli.go index c5a5c71..98ed3a2 100644 --- a/cmd/cli/disconnect/cli.go +++ b/cmd/cli/disconnect/cli.go @@ -3,6 +3,7 @@ package disconnect import ( "github.com/jaxxstorm/connecti/cmd/cli/disconnect/aws" "github.com/jaxxstorm/connecti/cmd/cli/disconnect/azure" + "github.com/jaxxstorm/connecti/cmd/cli/disconnect/kubernetes" "github.com/spf13/cobra" ) @@ -15,6 +16,7 @@ func Command() *cobra.Command { command.AddCommand(aws.Command()) command.AddCommand(azure.Command()) + command.AddCommand(kubernetes.Command()) return command } diff --git a/cmd/cli/disconnect/kubernetes/cli.go b/cmd/cli/disconnect/kubernetes/cli.go new file mode 100644 index 0000000..5532525 --- /dev/null +++ b/cmd/cli/disconnect/kubernetes/cli.go @@ -0,0 +1,64 @@ +package kubernetes + +import ( + "context" + "fmt" + + "github.com/jaxxstorm/connecti/pkg/kubernetes" + tui "github.com/jaxxstorm/connecti/pkg/terminal" + "github.com/pulumi/pulumi/sdk/v3/go/auto/optdestroy" + "github.com/spf13/cobra" +) + +var ( + name string +) + +func Command() *cobra.Command { + command := &cobra.Command{ + Use: "kubernetes", + Short: "Disconnect from Kubernetes infrastructure", + Long: `Tear down a tailscale bastion in an Kubernetes cluster via a deployment`, + RunE: tui.WrapCobraCommand(func(cmd *cobra.Command, args []string, view tui.View) error { + + view.Ready() + ctx := context.Background() + // FIXME: do we need to specify credentials here? + // I suspect not because I believe they're hardcoded into the provider + // but we should check + program, err := kubernetes.Program(name, ctx, kubernetes.BastionArgs{ + Name: name, + }) + if err != nil { + return err + } + + view.SetPulumiProgramCancelFn(func() error { + return program.Cancel(ctx) + }) + + pulumiOutputHandler := view.NewPulumiOutputHandler("destroy") + stdoutStreamer := optdestroy.ProgressStreams(pulumiOutputHandler) + _, err = program.Refresh(ctx) + if err != nil { + return fmt.Errorf("error refreshing stack: %v", err) + } + _, err = program.Destroy(ctx, stdoutStreamer) + if err != nil { + return fmt.Errorf("failed destroy: %v", err) + } + + err = program.Workspace().RemoveStack(ctx, name) + if err != nil { + return fmt.Errorf("failed to remove stack: %v", err) + } + + return nil + }), + } + + command.Flags().StringVar(&name, "name", "", "The name of the bastion to tear down") + command.MarkFlagRequired("name") + + return command +} diff --git a/go.mod b/go.mod index cc99b14..3a32958 100644 --- a/go.mod +++ b/go.mod @@ -9,11 +9,11 @@ require ( github.com/charmbracelet/bubbletea v0.22.1 github.com/cip8/autoname v1.0.1 github.com/gobeam/stringy v0.0.5 - github.com/lbrlabs/pulumi-tailscale-bastion/sdk v0.0.10 + github.com/lbrlabs/pulumi-tailscale-bastion/sdk v0.0.11 github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de github.com/pulumi/pulumi-aws/sdk/v5 v5.19.0 github.com/pulumi/pulumi-azure/sdk/v5 v5.23.0 - github.com/pulumi/pulumi/sdk/v3 v3.44.2 + github.com/pulumi/pulumi/sdk/v3 v3.44.3 github.com/spf13/cobra v1.5.0 github.com/spf13/viper v1.13.0 golang.org/x/text v0.3.7 @@ -77,6 +77,7 @@ require ( github.com/pelletier/go-toml/v2 v2.0.5 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pkg/term v1.1.0 // indirect + github.com/pulumi/pulumi-kubernetes/sdk/v3 v3.22.1 // indirect github.com/rivo/uniseg v0.2.0 // indirect github.com/rogpeppe/go-internal v1.8.1 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect diff --git a/go.sum b/go.sum index 1300a8e..d5df9bc 100644 --- a/go.sum +++ b/go.sum @@ -107,8 +107,10 @@ github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd h1:qMd81Ts1T2OTKmB4acZcyKaMtRnY5Y44NuXGX2GFJ1w= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw= github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= +github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -126,6 +128,7 @@ github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5y github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= @@ -211,6 +214,7 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= @@ -222,6 +226,7 @@ github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/U github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-version v1.4.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= @@ -248,13 +253,14 @@ github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= 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/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= -github.com/lbrlabs/pulumi-tailscale-bastion/sdk v0.0.10 h1:5ohOpxfmgUcT7w4faiUj18CjpeTCd7zQrjaNHUX4BR8= -github.com/lbrlabs/pulumi-tailscale-bastion/sdk v0.0.10/go.mod h1:fcA8byByL2xyQvjih/l/eEciR1Urey9FXe8oqYij7YE= +github.com/lbrlabs/pulumi-tailscale-bastion/sdk v0.0.11 h1:wEhWDjZTsMbtKoQG9Pel8+i41gHdVgdGWxZADd77ngU= +github.com/lbrlabs/pulumi-tailscale-bastion/sdk v0.0.11/go.mod h1:PHPJq/SWG5sjYo1WJucGSu6j8DoDDnFX8aIp+b7mk1w= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0= github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= @@ -263,12 +269,18 @@ github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamh github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A= github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= +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.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= 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.8/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= @@ -315,13 +327,17 @@ github.com/pulumi/pulumi-aws/sdk/v5 v5.19.0 h1:XgTU+K7lyq425S0t3S7I81ilzBhD4ErcT github.com/pulumi/pulumi-aws/sdk/v5 v5.19.0/go.mod h1:Ro2eNbpP/uGWMMvtBDrVph+jdL/G6+IiGB6kj+kDRYM= github.com/pulumi/pulumi-azure/sdk/v5 v5.23.0 h1:8S3owMkMrlV4cFW7GSAsBDpj1UXavIAhWpBBfgvnZTM= github.com/pulumi/pulumi-azure/sdk/v5 v5.23.0/go.mod h1:izER0SHHulmql/9sR/+bknW2xWcR+9cVJWNdnVK/jKE= -github.com/pulumi/pulumi/sdk/v3 v3.44.2 h1:hBHR4J6kBLJSXFBEa41OPGkyOkJKiMGxewjsaESwnlg= -github.com/pulumi/pulumi/sdk/v3 v3.44.2/go.mod h1:N5jL+cw5KiOeMn9bwvRuPQEAhbE3KPq2wSb/Kw+6HuY= +github.com/pulumi/pulumi-kubernetes/sdk/v3 v3.22.1 h1:jr3g7EAeknKpp7s754DaGyvTqsvuwkdIxw/3PPsz1TQ= +github.com/pulumi/pulumi-kubernetes/sdk/v3 v3.22.1/go.mod h1:0ez2D9IZhmXuyZ85jBVyqvHn6IKW7gTfoQTgJo8xTEk= +github.com/pulumi/pulumi/sdk/v3 v3.43.1/go.mod h1:N5jL+cw5KiOeMn9bwvRuPQEAhbE3KPq2wSb/Kw+6HuY= +github.com/pulumi/pulumi/sdk/v3 v3.44.3 h1:S1AJsZvzbuHPc5DTo/G86HiTKwJNQI8fuIroeXFR0o4= +github.com/pulumi/pulumi/sdk/v3 v3.44.3/go.mod h1:n5EPRVFDh+EFwYZ+oaZmEtwgVN1A6NnI82B7ks/bmTU= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg= github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= @@ -337,8 +353,10 @@ github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMB github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo= github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= +github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= @@ -382,6 +400,7 @@ go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -487,6 +506,7 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 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-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -502,6 +522,7 @@ golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -570,6 +591,7 @@ golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -660,6 +682,7 @@ google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200608115520-7c474a2e3482/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= @@ -716,6 +739,7 @@ gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8 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/cheggaaa/pb.v1 v1.0.28 h1:n1tBJnnK2r7g9OW2btFH91V92STTUevLXYFb8gy9EMk= +gopkg.in/cheggaaa/pb.v1 v1.0.28/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= @@ -743,6 +767,7 @@ honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 lukechampine.com/frand v1.4.2 h1:RzFIpOvkMXuPMBb9maa4ND4wjBn71E1Jpf8BzJHMaVw= lukechampine.com/frand v1.4.2/go.mod h1:4S/TM2ZgrKejMcKMbeLjISpJMO+/eZ1zu3vYX9dtj3s= pgregory.net/rapid v0.4.7 h1:MTNRktPuv5FNqOO151TM9mDTa+XHcX6ypYeISDVD14g= +pgregory.net/rapid v0.4.7/go.mod h1:UYpPVyjFHzYBGHIxLFoupi8vwk6rXNzRY9OMvVxFIOU= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/pkg/aws/program.go b/pkg/aws/program.go index 055ef47..b7a73ef 100644 --- a/pkg/aws/program.go +++ b/pkg/aws/program.go @@ -24,7 +24,7 @@ func Program(name string, ctx context.Context, args BastionArgs) (auto.Stack, er return s, fmt.Errorf("error installing AWS resource plugin: %v", err) } - err = w.InstallPluginFromServer(ctx, "tailscale-bastion", "v0.0.9", "github://api.github.com/lbrlabs") + err = w.InstallPluginFromServer(ctx, "tailscale-bastion", "v0.0.11", "github://api.github.com/lbrlabs") if err != nil { return s, fmt.Errorf("error installing tailscale plugin: %v", err) } diff --git a/pkg/azure/program.go b/pkg/azure/program.go index 93dbbb9..2c7b30b 100644 --- a/pkg/azure/program.go +++ b/pkg/azure/program.go @@ -24,7 +24,7 @@ func Program(name string, ctx context.Context, args BastionArgs) (auto.Stack, er return s, fmt.Errorf("error installing Azure resource plugin: %v", err) } - err = w.InstallPluginFromServer(ctx, "tailscale-bastion", "v0.0.10", "github://api.github.com/lbrlabs") + err = w.InstallPluginFromServer(ctx, "tailscale-bastion", "v0.0.11", "github://api.github.com/lbrlabs") if err != nil { return s, fmt.Errorf("error installing tailscale plugin: %v", err) } diff --git a/pkg/kubernetes/bastion.go b/pkg/kubernetes/bastion.go new file mode 100644 index 0000000..8eb45bc --- /dev/null +++ b/pkg/kubernetes/bastion.go @@ -0,0 +1,32 @@ +package kubernetes + +import ( + "fmt" + + k8stailscale "github.com/lbrlabs/pulumi-tailscale-bastion/sdk/go/bastion/kubernetes" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" +) + +func Bastion(args BastionArgs) pulumi.RunFunc { + return func(ctx *pulumi.Context) error { + + // convert the routes to a pulumi string array + routes := pulumi.StringArray{} + for _, route := range args.Routes { + routes = append(routes, pulumi.String(route)) + } + + bastion, err := k8stailscale.NewBastion(ctx, args.Name, &k8stailscale.BastionArgs{ + Routes: pulumi.StringArray(routes), + CreateNamespace: args.CreateNamespace, + }) + if err != nil { + return fmt.Errorf("error creating bastion: %v", err) + } + + ctx.Export("deploymentName", bastion.DeploymentName) + ctx.Export("connectiType", pulumi.String("k8s")) + + return nil + } +} diff --git a/pkg/kubernetes/program.go b/pkg/kubernetes/program.go new file mode 100644 index 0000000..60313de --- /dev/null +++ b/pkg/kubernetes/program.go @@ -0,0 +1,38 @@ +package kubernetes + +import ( + "context" + "fmt" + + "github.com/pulumi/pulumi/sdk/v3/go/auto" +) + +func Program(name string, ctx context.Context, args BastionArgs) (auto.Stack, error) { + projectName := "connecti" + stackName := name + + s, err := auto.UpsertStackInlineSource(ctx, stackName, projectName, Bastion(args)) + if err != nil { + return s, err + } + + w := s.Workspace() + + // FIXME: + err = w.InstallPlugin(ctx, "kubernetes", "v3.22.1") + if err != nil { + return s, fmt.Errorf("error installing Kubernetes resource plugin: %v", err) + } + + err = w.InstallPluginFromServer(ctx, "tailscale-bastion", "v0.0.11", "github://api.github.com/lbrlabs") + if err != nil { + return s, fmt.Errorf("error installing tailscale plugin: %v", err) + } + + s.SetConfig(ctx, "connecti:type", auto.ConfigValue{Value: "kubernetes"}) + s.SetConfig(ctx, "tailscale:tailnet", auto.ConfigValue{Value: args.Tailnet}) + s.SetConfig(ctx, "tailscale:apiKey", auto.ConfigValue{Value: args.ApiKey, Secret: true}) + + return s, nil + +} diff --git a/pkg/kubernetes/types.go b/pkg/kubernetes/types.go new file mode 100644 index 0000000..9bfddf5 --- /dev/null +++ b/pkg/kubernetes/types.go @@ -0,0 +1,9 @@ +package kubernetes + +type BastionArgs struct { + Name string + Tailnet string + ApiKey string + Routes []string + CreateNamespace bool +}