Skip to content

Commit

Permalink
Check if service exists and look up pod by service's unsanitized name
Browse files Browse the repository at this point in the history
  • Loading branch information
maxsokolovsky committed Apr 19, 2023
1 parent aa911a5 commit b67e40a
Show file tree
Hide file tree
Showing 8 changed files with 127 additions and 23 deletions.
11 changes: 6 additions & 5 deletions cmd/k8s/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"os"
"path/filepath"

"github.com/shipyard/shipyard-cli/types"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
Expand Down Expand Up @@ -59,19 +60,19 @@ func getRESTConfig() (*rest.Config, string, error) {
return restClientConfig, namespace, nil
}

// getPodName tries to fetch the name of the first pod given a deployment name and a clientset.
func getPodName(clientset *kubernetes.Clientset, namespace, deployment string) (string, error) {
// getPodName uses the service's sanitized name to find the pod in a given namespace.
func getPodName(clientSet *kubernetes.Clientset, namespace string, svc *types.Service) (string, error) {
options := metav1.ListOptions{
LabelSelector: "component=" + deployment,
LabelSelector: "component=" + svc.SanitizedName,
}

pods, err := clientset.CoreV1().Pods(namespace).List(context.TODO(), options)
pods, err := clientSet.CoreV1().Pods(namespace).List(context.TODO(), options)
if err != nil {
return "", err
}

if len(pods.Items) == 0 {
return "", fmt.Errorf("no pod found for service %s", deployment)
return "", fmt.Errorf("no pod found for service %s", svc.Name)
}

return pods.Items[0].Name, nil
Expand Down
13 changes: 10 additions & 3 deletions cmd/k8s/exec.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"os"

"github.com/docker/cli/cli/streams"
"github.com/shipyard/shipyard-cli/cmd/services"
"github.com/spf13/cobra"
"github.com/spf13/viper"
v1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -51,7 +52,14 @@ func handleExecCmd(args []string) error {
return errors.New("no command arguments provided")
}

if err := SetKubeconfig(viper.GetString("env")); err != nil {
id := viper.GetString("env")
serviceName := viper.GetString("service")
s, err := services.GetByName(serviceName)
if err != nil {
return err
}

if err := SetKubeconfig(id); err != nil {
return err
}

Expand All @@ -65,8 +73,7 @@ func handleExecCmd(args []string) error {
return err
}

serviceName := viper.GetString("service")
podName, err := getPodName(clientSet, namespace, serviceName)
podName, err := getPodName(clientSet, namespace, s)
if err != nil {
return err
}
Expand Down
17 changes: 12 additions & 5 deletions cmd/k8s/logs.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"context"
"io"

"github.com/shipyard/shipyard-cli/cmd/services"
"github.com/spf13/cobra"
"github.com/spf13/viper"
corev1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -53,7 +54,14 @@ func NewLogsCmd() *cobra.Command {
}

func handleLogsCmd() error {
if err := SetKubeconfig(viper.GetString("env")); err != nil {
id := viper.GetString("env")
serviceName := viper.GetString("service")
s, err := services.GetByName(serviceName)
if err != nil {
return err
}

if err := SetKubeconfig(id); err != nil {
return err
}

Expand All @@ -62,13 +70,12 @@ func handleLogsCmd() error {
return err
}

clientset, err := kubernetes.NewForConfig(config)
clientSet, err := kubernetes.NewForConfig(config)
if err != nil {
return err
}

serviceName := viper.GetString("service")
podName, err := getPodName(clientset, namespace, serviceName)
podName, err := getPodName(clientSet, namespace, s)
if err != nil {
return err
}
Expand All @@ -80,7 +87,7 @@ func handleLogsCmd() error {
Follow: follow,
TailLines: &tail,
}
req := clientset.CoreV1().Pods(namespace).GetLogs(podName, &podLogOpts)
req := clientSet.CoreV1().Pods(namespace).GetLogs(podName, &podLogOpts)
podLogs, err := req.Stream(context.TODO())
if err != nil {
return err
Expand Down
13 changes: 10 additions & 3 deletions cmd/k8s/port_forward.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"net/url"
"strings"

"github.com/shipyard/shipyard-cli/cmd/services"
"github.com/spf13/cobra"
"github.com/spf13/viper"
"k8s.io/client-go/kubernetes"
Expand Down Expand Up @@ -53,7 +54,14 @@ func NewPortForwardCmd() *cobra.Command {
}

func handlePortForwardCmd() error {
if err := SetKubeconfig(viper.GetString("env")); err != nil {
id := viper.GetString("env")
serviceName := viper.GetString("service")
s, err := services.GetByName(serviceName)
if err != nil {
return err
}

if err := SetKubeconfig(id); err != nil {
return err
}

Expand All @@ -67,8 +75,7 @@ func handlePortForwardCmd() error {
return err
}

serviceName := viper.GetString("service")
podName, err := getPodName(clientset, namespace, serviceName)
podName, err := getPodName(clientset, namespace, s)
if err != nil {
return err
}
Expand Down
62 changes: 62 additions & 0 deletions cmd/services/check.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package services

import (
"fmt"
"sort"

"github.com/agnivade/levenshtein"
"github.com/spf13/viper"

"github.com/shipyard/shipyard-cli/types"
)

func GetByName(serviceName string) (*types.Service, error) {
if serviceName == "" {
return nil, fmt.Errorf("service name not provided")
}
envID := viper.GetString("env")
if envID == "" {
return nil, fmt.Errorf("environment ID not provided")
}

svcs, err := GetAllByEnvironment(envID)
if err != nil {
return nil, err
}
s := findService(svcs, serviceName)
if s == nil {
return nil, fmt.Errorf("service %s is not found, but there is a service named %s",
serviceName, similarServiceName(svcs, serviceName))
}
return s, nil
}

func findService(coll []types.Service, unsanitizedName string) *types.Service {
for i := range coll {
if coll[i].Name == unsanitizedName {
return &coll[i]
}
}
return nil
}

func similarServiceName(coll []types.Service, unsanitizedName string) string {
if len(coll) == 0 || unsanitizedName == "" {
return ""
}

type entry struct {
name string
distance int
}

entries := make([]entry, len(coll))
for i := range coll {
entries[i].name = coll[i].Name
entries[i].distance = levenshtein.ComputeDistance(unsanitizedName, entries[i].name)
}
sort.Slice(entries, func(i, j int) bool {
return entries[i].distance < entries[j].distance
})
return entries[0].name
}
27 changes: 20 additions & 7 deletions cmd/services/services.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package services

import (
"errors"
"fmt"
"io"
"os"

"github.com/spf13/cobra"
Expand All @@ -11,6 +11,7 @@ import (
"github.com/shipyard/shipyard-cli/cmd/env"
"github.com/shipyard/shipyard-cli/display"
"github.com/shipyard/shipyard-cli/requests"
"github.com/shipyard/shipyard-cli/types"
)

func NewGetServicesCmd() *cobra.Command {
Expand All @@ -34,20 +35,32 @@ func NewGetServicesCmd() *cobra.Command {
return cmd
}

func handleGetServicesCmd() error {
client, err := requests.NewClient(os.Stdout)
func GetAllByEnvironment(id string) ([]types.Service, error) {
if id == "" {
return nil, fmt.Errorf("environment ID is missing")
}
client, err := requests.NewClient(io.Discard)
if err != nil {
return err
return nil, err
}

environment, err := env.GetEnvironmentByID(client, viper.GetString("env"))
environment, err := env.GetEnvironmentByID(client, id)
if err != nil {
return err
return nil, err
}

services := environment.Data.Attributes.Services
if len(services) == 0 {
return errors.New("no services found, check if the environment is running")
return nil, fmt.Errorf("no services found for environment, check if it's running")
}
return services, nil
}

func handleGetServicesCmd() error {
id := viper.GetString("env")
services, err := GetAllByEnvironment(id)
if err != nil {
return fmt.Errorf("failed to get services for environment %s: %w", id, err)
}

var data [][]string
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/shipyard/shipyard-cli
go 1.20

require (
github.com/agnivade/levenshtein v1.1.1
github.com/docker/cli v20.10.23+incompatible
github.com/fatih/color v1.15.0
github.com/olekukonko/tablewriter v0.0.5
Expand Down
6 changes: 6 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8=
github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo=
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q=
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE=
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
Expand All @@ -65,6 +69,8 @@ github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
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/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g=
github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA=
github.com/docker/cli v20.10.23+incompatible h1:qwyha/T3rXk9lfuVcn533cKFc7n/6IzL5GXVAgMVPBg=
github.com/docker/cli v20.10.23+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
Expand Down

0 comments on commit b67e40a

Please sign in to comment.