diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 52faa87..65a29a9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -5,7 +5,7 @@ on: jobs: lint: name: Lint - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 env: TOKEN: ${{ secrets.RIDECELL_PUBLIC_REPO_TOKEN }} steps: @@ -25,7 +25,7 @@ jobs: build: name: Build - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 needs: lint env: TOKEN: ${{ secrets.RIDECELL_PUBLIC_REPO_TOKEN }} diff --git a/go.sum b/go.sum index 673d811..aa2edca 100644 --- a/go.sum +++ b/go.sum @@ -20,8 +20,6 @@ github.com/Ridecell/ridecell-controllers v0.0.0-20240404104926-a7f0de0ec6ca/go.m github.com/Ridecell/summon-operator v0.0.0-20240812144338-f38221eb2924 h1:CYGiiD/L7cmM8qS8hD/S61JbKmuki4ZOr0pzDb80MWw= github.com/Ridecell/summon-operator v0.0.0-20240812144338-f38221eb2924/go.mod h1:itkR/RkrWXNslZ5VcbgpwM/zzLYHoxzuQZs0CxvHIz4= github.com/atomicgo/cursor v0.0.1/go.mod h1:cBON2QmmrysudxNBFthvMtN32r3jxVRIvzkUiF/RuIk= -github.com/aws/aws-sdk-go-v2 v1.32.2 h1:AkNLZEyYMLnx/Q/mSKkcMqwNFXMAvFto9bNsHqcTduI= -github.com/aws/aws-sdk-go-v2 v1.32.2/go.mod h1:2SK5n0a2karNTv5tbP1SjsX0uhttou00v/HpXKM1ZUo= github.com/aws/aws-sdk-go-v2 v1.32.7 h1:ky5o35oENWi0JYWUZkB7WYvVPP+bcRF5/Iq7JWSb5Rw= github.com/aws/aws-sdk-go-v2 v1.32.7/go.mod h1:P5WJBrYqqbWVaOxgH0X/FYYD47/nooaPOZPlQdmiN2U= github.com/aws/aws-sdk-go-v2/config v1.27.11 h1:f47rANd2LQEYHda2ddSCKYId18/8BhSRM4BULGmfgNA= @@ -30,12 +28,8 @@ github.com/aws/aws-sdk-go-v2/credentials v1.17.11 h1:YuIB1dJNf1Re822rriUOTxopaHH github.com/aws/aws-sdk-go-v2/credentials v1.17.11/go.mod h1:AQtFPsDH9bI2O+71anW6EKL+NcD7LG3dpKGMV4SShgo= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.1 h1:FVJ0r5XTHSmIHJV6KuDmdYhEpvlHpiSd38RQWhut5J4= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.1/go.mod h1:zusuAeqezXzAB24LGuzuekqMAEgWkVYukBec3kr3jUg= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.21 h1:UAsR3xA31QGf79WzpG/ixT9FZvQlh5HY1NRqSHBNOCk= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.21/go.mod h1:JNr43NFf5L9YaG3eKTm7HQzls9J+A9YYcGI5Quh1r2Y= github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.26 h1:I/5wmGMffY4happ8NOCuIUEWGUvvFp5NSeQcXl9RHcI= github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.26/go.mod h1:FR8f4turZtNy6baO0KJ5FJUmXH/cSkI9fOngs0yl6mA= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.21 h1:6jZVETqmYCadGFvrYEQfC5fAQmlo80CeL5psbno6r0s= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.21/go.mod h1:1SR0GbLlnN3QUmYaflZNiH1ql+1qrSiB2vwcJ+4UM60= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.26 h1:zXFLuEuMMUOvEARXFUVJdfqZ4bvvSgdGRq/ATcrQxzM= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.26/go.mod h1:3o2Wpy0bogG1kyOPrgkXA8pgIfEEv0+m19O9D5+W8y8= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU= @@ -46,22 +40,14 @@ github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2 h1:Ji0DY1x github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.2/go.mod h1:5CsjAbs3NlGQyZNFACh+zztPDI7fU6eW9QsxjfnuBKg= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.7 h1:ogRAwT1/gxJBcSWDMZlgyFUM962F51A5CRhDLbxLdmo= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.11.7/go.mod h1:YCsIZhXfRPLFFCl5xxY+1T9RKzOKjCut+28JSX2DnAk= -github.com/aws/aws-sdk-go-v2/service/kms v1.30.1 h1:SBn4I0fJXF9FYOVRSVMWuhvEKoAHDikjGpS3wlmw5DE= -github.com/aws/aws-sdk-go-v2/service/kms v1.30.1/go.mod h1:2snWQJQUKsbN66vAawJuOGX7dr37pfOq9hb0tZDGIqQ= github.com/aws/aws-sdk-go-v2/service/kms v1.37.8 h1:KbLZjYqhQ9hyB4HwXiheiflTlYQa0+Fz0Ms/rh5f3mk= github.com/aws/aws-sdk-go-v2/service/kms v1.37.8/go.mod h1:ANs9kBhK4Ghj9z1W+bsr3WsNaPF71qkgd6eE6Ekol/Y= -github.com/aws/aws-sdk-go-v2/service/sso v1.20.5 h1:vN8hEbpRnL7+Hopy9dzmRle1xmDc7o8tmY0klsr175w= -github.com/aws/aws-sdk-go-v2/service/sso v1.20.5/go.mod h1:qGzynb/msuZIE8I75DVRCUXw3o3ZyBmUvMwQ2t/BrGM= github.com/aws/aws-sdk-go-v2/service/sso v1.24.8 h1:CvuUmnXI7ebaUAhbJcDy9YQx8wHR69eZ9I7q5hszt/g= github.com/aws/aws-sdk-go-v2/service/sso v1.24.8/go.mod h1:XDeGv1opzwm8ubxddF0cgqkZWsyOtw4lr6dxwmb6YQg= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.4 h1:Jux+gDDyi1Lruk+KHF91tK2KCuY61kzoCpvtvJJBtOE= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.23.4/go.mod h1:mUYPBhaF2lGiukDEjJX2BLRRKTmoUSitGDUgM4tRxak= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.7 h1:F2rBfNAL5UyswqoeWv9zs74N/NanhK16ydHW1pahX6E= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.7/go.mod h1:JfyQ0g2JG8+Krq0EuZNnRwX0mU0HrwY/tG6JNfcqh4k= github.com/aws/aws-sdk-go-v2/service/sts v1.28.6 h1:cwIxeBttqPN3qkaAjcEcsh8NYr8n2HZPkcKgPAi1phU= github.com/aws/aws-sdk-go-v2/service/sts v1.28.6/go.mod h1:FZf1/nKNEkHdGGJP/cI2MoIMquumuRK6ol3QQJNDxmw= -github.com/aws/smithy-go v1.22.0 h1:uunKnWlcoL3zO7q+gG2Pk53joueEOsnNB28QdMsmiMM= -github.com/aws/smithy-go v1.22.0/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= github.com/aws/smithy-go v1.22.1 h1:/HPHZQ0g7f4eUeK6HKglFz8uwVfZKgoI25rb/J+dnro= github.com/aws/smithy-go v1.22.1/go.mod h1:irrKGvNn1InZwb2d7fkIRNucdfwR8R+Ts3wxYa/cJHg= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= diff --git a/pkg/cmd/proxy.go b/pkg/cmd/proxy.go new file mode 100644 index 0000000..89bf6b5 --- /dev/null +++ b/pkg/cmd/proxy.go @@ -0,0 +1,64 @@ +/* +Copyright 2025 Ridecell, Inc. +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cmd + +import ( + "fmt" + + "github.com/Ridecell/ridectl/pkg/exec" + "github.com/pterm/pterm" + "github.com/spf13/cobra" + + utils "github.com/Ridecell/ridectl/pkg/utils" +) + +func init() { + rootCmd.AddCommand(proxyCmd) +} + +var proxyCmd = &cobra.Command{ + Use: "proxy ", + Short: "Creates a proxy to Teleport's TCP application to access it localy.", + Long: "Example:\n" + + "ridectl proxy -- e.g. ridectl proxy data-lab-superset-db\n", + Args: func(_ *cobra.Command, args []string) error { + if len(args) == 0 { + return fmt.Errorf("teleport application name argument is required") + } + if len(args) > 1 { + return fmt.Errorf("too many arguments") + } + return nil + }, + PreRunE: func(cmd *cobra.Command, args []string) error { + utils.CheckTshLogin() + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + + pterm.Info.Println("Checking teleport application") + err := exec.ExecuteShellCommand("tsh apps ls app_name="+args[0]+" | grep ridectl || exit 1", false) + if err != nil { + return fmt.Errorf("the teleport application with ridectl label does not exists or you do not have access to it, %s", err) + } + + pterm.Info.Println("Logging into application") + err = exec.ExecuteShellCommand("tsh apps login "+args[0], false) + if err != nil { + return fmt.Errorf("could not login to teleport application, %s", err) + } + pterm.Info.Println("Starting proxy to application") + return exec.ExecuteShellCommand("tsh proxy app "+args[0], true) + }, +} diff --git a/pkg/exec/exec.go b/pkg/exec/exec.go index 6c83afe..508e74e 100644 --- a/pkg/exec/exec.go +++ b/pkg/exec/exec.go @@ -107,6 +107,40 @@ func CheckBinary(binary string) (string, bool) { return binaryPath, err == nil } +// ExecuteShellCommand uses os/exec Command function to execute shell command, +// which returns the process output/error to parent process, +// If detachProcess flag set to true, then ridectl will exit with +// no error irrespective of given command's exit code. +func ExecuteShellCommand(cmd string, detachProcess bool) error { + + c := exec.Command("sh", "-c", cmd) + c.Stdin = os.Stdin + + // Execute a process by seperating it's Stderr and Stdout streams from ridectl code + // Here we will just execute the command, and complete ridectl command with no error + // Mainly used by "kubectl exec" and "psql" commands + if detachProcess { + c.Stdout = os.Stdout + c.Stderr = os.Stderr + _ = c.Run() + return nil + } + + // Here we will capture Stderr from given command output + // Mainly used by "tsh status" and "tsh db login" commands + var stderr bytes.Buffer + c.Stderr = &stderr + err := c.Run() + if err != nil { + if stderr.String() != "" { + + return fmt.Errorf("%s", stderr.String()) + } + return fmt.Errorf("error while executing command: %s", err.Error()) + } + return nil +} + // ExecuteCommand uses os/exec Command fucntion to execute command, // which returns the process output/error to parent process, // If detachProcess flag set to true, then ridectl will exit with @@ -137,10 +171,9 @@ func ExecuteCommand(binary string, args []string, detachProcess bool) error { err = c.Run() if err != nil { if stderr.String() != "" { - return fmt.Errorf("%s", stderr.String()) } - return fmt.Errorf("Error while executing command: %s", err.Error()) + return fmt.Errorf("error while executing command: %s", err.Error()) } return nil }