From a4ca3355e0649c191f7a1f806788434768102d05 Mon Sep 17 00:00:00 2001 From: "Alex Ellis (OpenFaaS Ltd)" Date: Thu, 31 Aug 2023 18:19:50 +0100 Subject: [PATCH] Enable letsencrypt mode for EC2 provisioner Signed-off-by: Alex Ellis (OpenFaaS Ltd) --- cmd/common.go | 6 ++-- cmd/create.go | 80 ++++++++++++++++++++++++---------------------- cmd/create_test.go | 21 ++++++------ cmd/delete.go | 2 +- cmd/download.go | 2 +- cmd/inletsctl.go | 2 +- cmd/kfwd.go | 8 ++--- go.mod | 2 +- go.sum | 4 +++ main.go | 2 +- pkg/env/env.go | 6 ++-- 11 files changed, 72 insertions(+), 63 deletions(-) diff --git a/cmd/common.go b/cmd/common.go index dfcc30ab..5d160e58 100644 --- a/cmd/common.go +++ b/cmd/common.go @@ -1,11 +1,11 @@ -// Copyright (c) Inlets Author(s) 2019. All rights reserved. +// Copyright (c) Inlets Author(s) 2023. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. package cmd import ( "fmt" - "io/ioutil" + "os" "strings" "github.com/pkg/errors" @@ -16,7 +16,7 @@ func getFileOrString(flags *pflag.FlagSet, file, value string, required bool) (s var val string fileVal, _ := flags.GetString(file) if len(fileVal) > 0 { - res, err := ioutil.ReadFile(fileVal) + res, err := os.ReadFile(fileVal) if err != nil { return "", err } diff --git a/cmd/create.go b/cmd/create.go index df02483b..facc9d7b 100644 --- a/cmd/create.go +++ b/cmd/create.go @@ -1,4 +1,4 @@ -// Copyright (c) Inlets Author(s) 2019. All rights reserved. +// Copyright (c) Inlets Author(s) 2023. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. package cmd @@ -50,6 +50,7 @@ func init() { createCmd.Flags().String("consumer-key", "", "The Consumer Key for using the OVH API") createCmd.Flags().Bool("tcp", true, `Provision an exit-server with inlets running as a TCP server`) + createCmd.Flags().String("aws-key-name", "", "The name of an existing SSH key on AWS to be used to access the EC2 instance for maintenance (optional)") createCmd.Flags().StringArray("letsencrypt-domain", []string{}, `Domains you want to get a Let's Encrypt certificate for`) createCmd.Flags().String("letsencrypt-issuer", "prod", `The issuer endpoint to use with Let's Encrypt - \"prod\" or \"staging\"`) @@ -98,9 +99,14 @@ const EquinixMetalProvider = "equinix-metal" func runCreate(cmd *cobra.Command, _ []string) error { + awsKeyName, err := cmd.Flags().GetString("aws-key-name") + if err != nil { + return err + } + provider, err := cmd.Flags().GetString("provider") if err != nil { - return errors.Wrap(err, "failed to get 'provider' value.") + return err } // Migrate to new name @@ -112,8 +118,9 @@ func runCreate(cmd *cobra.Command, _ []string) error { inletsToken, err := cmd.Flags().GetString("inlets-token") if err != nil { - return errors.Wrap(err, "failed to get 'inlets-token' value.") + return err } + if len(inletsToken) == 0 { var passwordErr error inletsToken, passwordErr = generateAuth() @@ -250,18 +257,18 @@ func runCreate(cmd *cobra.Command, _ []string) error { } provisioner, err := getProvisioner(provider, accessToken, secretKey, organisationID, region, subscriptionID, sessionToken, endpoint, consumerKey, projectID) - if err != nil { return err } - pro := true + tcp := true + if cmd.Flags().Changed("pro") { fmt.Printf("WARN: --pro is deprecated, use --tcp instead.") - pro, _ = cmd.Flags().GetBool("pro") + tcp, _ = cmd.Flags().GetBool("pro") } if cmd.Flags().Changed("tcp") { - pro, _ = cmd.Flags().GetBool("tcp") + tcp, _ = cmd.Flags().GetBool("tcp") } letsencryptDomains, _ := cmd.Flags().GetStringArray("letsencrypt-domain") @@ -275,6 +282,7 @@ func runCreate(cmd *cobra.Command, _ []string) error { if len(letsencryptIssuer) == 0 { return fmt.Errorf("--letsencrypt-issuer is required when --letsencrypt-domain is given") } + tcp = false } inletsProVersion, err := cmd.Flags().GetString("inlets-version") @@ -305,11 +313,13 @@ func runCreate(cmd *cobra.Command, _ []string) error { zone, projectID, userData, - "0", + fmt.Sprintf("%d", inletsProControlPort), vpcID, subnetID, - pro) - + awsKeyName, + tcp, + letsencryptDomains, + ) if err != nil { return err } @@ -357,15 +367,9 @@ func runCreate(cmd *cobra.Command, _ []string) error { Command: -# Obtain a license at https://inlets.dev/pricing -# Store it at $HOME/.inlets/LICENSE or use --help for more options - -# Where to route traffic from the inlets server -export UPSTREAM="http://127.0.0.1:8000" - inlets-pro http client --url "wss://%s:%d" \ ---token "%s" \ ---upstream $UPSTREAM + --token "%s" \ + --upstream http://127.0.0.1:8080 To delete: inletsctl delete --provider %s --id "%s" @@ -388,19 +392,10 @@ To delete: Command: -# Obtain a license at https://inlets.dev/pricing -# Store it at $HOME/.inlets/LICENSE or use --help for more options - -# Give a single value or comma-separated -export PORTS="8000" - -# Where to route traffic from the inlets server -export UPSTREAM="localhost" - inlets-pro tcp client --url "wss://%s:%d" \ --token "%s" \ - --upstream $UPSTREAM \ - --ports $PORTS + --upstream 127.0.0.1 \ + --ports 2222 To delete: inletsctl delete --provider %s --id "%s" @@ -458,7 +453,7 @@ func generateAuth() (string, error) { return pwdRes, pwdErr } -func createHost(provider, name, region, zone, projectID, userData, inletsPort string, vpcID string, subnetID string, pro bool) (*provision.BasicHost, error) { +func createHost(provider, name, region, zone, projectID, userData, inletsProControlPort, vpcID, subnetID, awsKeyName string, tcp bool, letsencryptDomains []string) (*provision.BasicHost, error) { if provider == "digitalocean" { return &provision.BasicHost{ Name: name, @@ -518,8 +513,8 @@ func createHost(provider, name, region, zone, projectID, userData, inletsPort st "projectid": projectID, "zone": zone, "firewall-name": "inlets", - "firewall-port": inletsPort, - "pro": fmt.Sprint(pro), + "firewall-port": inletsProControlPort, + "pro": fmt.Sprint(tcp), }, }, nil } else if provider == "ec2" { @@ -527,8 +522,16 @@ func createHost(provider, name, region, zone, projectID, userData, inletsPort st // Name is used in the OS field so the ami can be lookup up in the region specified var additional = map[string]string{ - "inlets-port": inletsPort, - "pro": fmt.Sprint(pro), + "inlets-port": inletsProControlPort, + "pro": fmt.Sprint(tcp), + } + + if len(letsencryptDomains) > 0 { + additional["ports"] = "80,443" + } + + if len(awsKeyName) > 0 { + additional["key-name"] = awsKeyName } if len(vpcID) > 0 { @@ -547,6 +550,7 @@ func createHost(provider, name, region, zone, projectID, userData, inletsPort st UserData: base64.StdEncoding.EncodeToString([]byte(userData)), Additional: additional, }, nil + } else if provider == "azure" { // Ubuntu images can be found here https://docs.microsoft.com/en-us/azure/virtual-machines/linux/cli-ps-findimage#list-popular-images // An image includes more than one property, it has publisher, offer, sku and version. @@ -558,8 +562,8 @@ func createHost(provider, name, region, zone, projectID, userData, inletsPort st Region: region, UserData: userData, Additional: map[string]string{ - "inlets-port": inletsPort, - "pro": fmt.Sprint(pro), + "inlets-port": inletsProControlPort, + "pro": fmt.Sprint(tcp), "imagePublisher": "Canonical", "imageOffer": "0001-com-ubuntu-server-focal", "imageSku": "20_04-lts", @@ -596,8 +600,8 @@ func createHost(provider, name, region, zone, projectID, userData, inletsPort st Region: region, UserData: userData, Additional: map[string]string{ - "inlets-port": inletsPort, - "pro": fmt.Sprint(pro), + "inlets-port": inletsProControlPort, + "pro": fmt.Sprint(tcp), }, }, nil } else if provider == "hetzner" { diff --git a/cmd/create_test.go b/cmd/create_test.go index ced010a0..fd880f5f 100644 --- a/cmd/create_test.go +++ b/cmd/create_test.go @@ -1,25 +1,26 @@ -// Copyright (c) Inlets Author(s) 2019. All rights reserved. +// Copyright (c) Inlets Author(s) 2023. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. package cmd import ( - "io/ioutil" + "os" "testing" ) func Test_MakeHTTPSUserdata_OneDomain(t *testing.T) { - got := MakeHTTPSUserdata("token", "0.8.4", "contact@example.com", "prod", []string{"example.com"}) - ioutil.WriteFile("/tmp/t.txt", []byte(got), 0600) + got := MakeHTTPSUserdata("token", "0.9.21", "contact@example.com", "prod", []string{"example.com"}) + + os.WriteFile("/tmp/t.txt", []byte(got), 0600) want := `#!/bin/bash export AUTHTOKEN="token" export IP=$(curl -sfSL https://checkip.amazonaws.com) -curl -SLsf https://github.com/inlets/inlets-pro/releases/download/0.8.4/inlets-pro -o /tmp/inlets-pro && \ +curl -SLsf https://github.com/inlets/inlets-pro/releases/download/0.9.21/inlets-pro -o /tmp/inlets-pro && \ chmod +x /tmp/inlets-pro && \ mv /tmp/inlets-pro /usr/local/bin/inlets-pro -curl -SLsf https://github.com/inlets/inlets-pro/releases/download/0.8.4/inlets-pro-http.service -o inlets-pro.service && \ +curl -SLsf https://github.com/inlets/inlets-pro/releases/download/0.9.21/inlets-pro-http.service -o inlets-pro.service && \ mv inlets-pro.service /etc/systemd/system/inlets-pro.service && \ echo "AUTHTOKEN=$AUTHTOKEN" >> /etc/default/inlets-pro && \ echo "IP=$IP" >> /etc/default/inlets-pro && \ @@ -36,19 +37,19 @@ curl -SLsf https://github.com/inlets/inlets-pro/releases/download/0.8.4/inlets-p } func Test_MakeHTTPSUserdata_TwoDomains(t *testing.T) { - got := MakeHTTPSUserdata("token", "0.8.4", "contact@example.com", "prod", + got := MakeHTTPSUserdata("token", "0.9.21", "contact@example.com", "prod", []string{"a.example.com", "b.example.com"}) - ioutil.WriteFile("/tmp/t.txt", []byte(got), 0600) + os.WriteFile("/tmp/t.txt", []byte(got), 0600) want := `#!/bin/bash export AUTHTOKEN="token" export IP=$(curl -sfSL https://checkip.amazonaws.com) -curl -SLsf https://github.com/inlets/inlets-pro/releases/download/0.8.4/inlets-pro -o /tmp/inlets-pro && \ +curl -SLsf https://github.com/inlets/inlets-pro/releases/download/0.9.21/inlets-pro -o /tmp/inlets-pro && \ chmod +x /tmp/inlets-pro && \ mv /tmp/inlets-pro /usr/local/bin/inlets-pro -curl -SLsf https://github.com/inlets/inlets-pro/releases/download/0.8.4/inlets-pro-http.service -o inlets-pro.service && \ +curl -SLsf https://github.com/inlets/inlets-pro/releases/download/0.9.21/inlets-pro-http.service -o inlets-pro.service && \ mv inlets-pro.service /etc/systemd/system/inlets-pro.service && \ echo "AUTHTOKEN=$AUTHTOKEN" >> /etc/default/inlets-pro && \ echo "IP=$IP" >> /etc/default/inlets-pro && \ diff --git a/cmd/delete.go b/cmd/delete.go index 843fcd4d..5c18e58c 100644 --- a/cmd/delete.go +++ b/cmd/delete.go @@ -1,4 +1,4 @@ -// Copyright (c) Inlets Author(s) 2019. All rights reserved. +// Copyright (c) Inlets Author(s) 2023. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. package cmd diff --git a/cmd/download.go b/cmd/download.go index 06aaa469..e23e7349 100644 --- a/cmd/download.go +++ b/cmd/download.go @@ -154,7 +154,7 @@ func downloadBinary(client *http.Client, url, name string) (string, error) { outputPath := path.Join(tempDir, name) if res.Body != nil { defer res.Body.Close() - res, _ := ioutil.ReadAll(res.Body) + res, _ := io.ReadAll(res.Body) err := ioutil.WriteFile(outputPath, res, 0777) if err != nil { diff --git a/cmd/inletsctl.go b/cmd/inletsctl.go index 5da239be..ee892600 100644 --- a/cmd/inletsctl.go +++ b/cmd/inletsctl.go @@ -1,4 +1,4 @@ -// Copyright (c) Inlets Author(s) 2019. All rights reserved. +// Copyright (c) Inlets Author(s) 2023. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. package cmd diff --git a/cmd/kfwd.go b/cmd/kfwd.go index 50524e5d..5b3c490a 100644 --- a/cmd/kfwd.go +++ b/cmd/kfwd.go @@ -1,4 +1,4 @@ -// Copyright (c) Inlets Author(s) 2019. All rights reserved. +// Copyright (c) Inlets Author(s) 2023. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. package cmd @@ -98,12 +98,12 @@ func fwdTCP(cmd *cobra.Command, eth, port, upstream, ns, inletsToken, license st res, err := task.Execute() if err != nil { - fmt.Fprintf(os.Stderr, err.Error()) + fmt.Fprintf(os.Stderr, "%s", err.Error()) return } if res.ExitCode != 0 { - fmt.Fprintf(os.Stderr, fmt.Errorf("exit code unexpected from kubectl delete: %d, stderr: %s", res.ExitCode, res.Stderr).Error()) + fmt.Fprintf(os.Stderr, "%s", fmt.Errorf("exit code unexpected from kubectl delete: %d, stderr: %s", res.ExitCode, res.Stderr).Error()) return } }() @@ -330,7 +330,7 @@ spec: spec: containers: - name: inlets - image: ghcr.io/inlets/inlets-pro:0.9.9 + image: ghcr.io/inlets/inlets-pro:0.9.21 imagePullPolicy: IfNotPresent command: ["inlets-pro"] args: diff --git a/go.mod b/go.mod index 7d2b7571..a476a4a1 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.20 require ( github.com/alexellis/go-execute v0.5.0 github.com/golang/mock v1.6.0 - github.com/inlets/cloud-provision v0.6.5 + github.com/inlets/cloud-provision v0.6.7 github.com/linode/linodego v1.12.0 github.com/morikuni/aec v1.0.0 github.com/pkg/errors v0.9.1 diff --git a/go.sum b/go.sum index a23a1f32..bfedeaad 100644 --- a/go.sum +++ b/go.sum @@ -209,6 +209,10 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/inlets/cloud-provision v0.6.5 h1:IOzdBguO+QkqO3uEwyv1bNBHyI7EhyEJr5B3br7Q4eA= github.com/inlets/cloud-provision v0.6.5/go.mod h1:zK0cG+FIZuKHyxx0PwBim5qM1AApAxmZfCExZa3VVqc= +github.com/inlets/cloud-provision v0.6.6 h1:7xqSQ7RCZPpiFXegBGWP4dEebSUgtfCnMRMUbal6eSs= +github.com/inlets/cloud-provision v0.6.6/go.mod h1:zK0cG+FIZuKHyxx0PwBim5qM1AApAxmZfCExZa3VVqc= +github.com/inlets/cloud-provision v0.6.7 h1:gBr1knWRdhdR8uAPX1ljyf2VyNTiYs2Gl/Fa1snVwdQ= +github.com/inlets/cloud-provision v0.6.7/go.mod h1:zK0cG+FIZuKHyxx0PwBim5qM1AApAxmZfCExZa3VVqc= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= diff --git a/main.go b/main.go index 79d93454..c08a9a4b 100644 --- a/main.go +++ b/main.go @@ -1,4 +1,4 @@ -// Copyright (c) Inlets Author(s) 2019. All rights reserved. +// Copyright (c) Inlets Author(s) 2023. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. package main diff --git a/pkg/env/env.go b/pkg/env/env.go index acdbcb86..923fd25b 100644 --- a/pkg/env/env.go +++ b/pkg/env/env.go @@ -2,10 +2,10 @@ package env import ( "fmt" - "github.com/spf13/pflag" - "io/ioutil" "os" "strings" + + "github.com/spf13/pflag" ) func GetRequiredFileOrString(flags *pflag.FlagSet, file, value, envVarName string) (string, error) { @@ -21,7 +21,7 @@ func getFileOrString(flags *pflag.FlagSet, file, value, envVarName string, requi if len(authFile) > 0 { // Fallback to the File Flag, then the Env Var - res, err := ioutil.ReadFile(authFile) + res, err := os.ReadFile(authFile) if err != nil { return "", err }