Skip to content

Commit

Permalink
rollouts: added skeleton CLI (#3724)
Browse files Browse the repository at this point in the history
* rollouts: added skeleton CLI

* added table display
  • Loading branch information
droot authored Jan 11, 2023
1 parent afc2da4 commit 87b40f7
Show file tree
Hide file tree
Showing 7 changed files with 313 additions and 0 deletions.
5 changes: 5 additions & 0 deletions rollouts/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ build: manifests generate fmt vet ## Build manager binary.
run: manifests generate fmt vet ## Run a controller from your host.
go run ./main.go


.PHONY: cli
cli:
go build -o ./bin/rollouts ./cli

# If you wish built the manager image targeting other platforms you can use the --platform flag.
# (i.e. docker build --platform linux/arm64 ). However, you must enable docker buildKit for it.
# More info: https://docs.docker.com/develop/develop-images/build_enhancements/
Expand Down
66 changes: 66 additions & 0 deletions rollouts/cli/get/get.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright 2023 Google LLC
//
// 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 get

import (
"context"
"fmt"

"github.com/GoogleContainerTools/kpt/rollouts/rolloutsclient"
"github.com/spf13/cobra"
)

func NewCommand(ctx context.Context) *cobra.Command {
return newRunner(ctx).Command
}

func newRunner(ctx context.Context) *runner {
r := &runner{
ctx: ctx,
}
c := &cobra.Command{
Use: "get",
Short: "lists rollouts",
Long: "lists rollouts",
Example: "lists rollouts",
RunE: r.runE,
}
r.Command = c
return r
}

type runner struct {
ctx context.Context
Command *cobra.Command
}

func (r *runner) runE(cmd *cobra.Command, args []string) error {
rlc, err := rolloutsclient.New()
if err != nil {
fmt.Printf("%s\n", err)
return err
}

rollouts, err := rlc.List(r.ctx, "")
if err != nil {
fmt.Printf("%s\n", err)
return err
}
for _, rollout := range rollouts.Items {
fmt.Printf("%s\n", rollout.Name)
}

return nil
}
53 changes: 53 additions & 0 deletions rollouts/cli/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright 2022 Google LLC
//
// 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 main

import (
"context"
"os"

"github.com/GoogleContainerTools/kpt/rollouts/cli/get"
"github.com/GoogleContainerTools/kpt/rollouts/cli/status"
"github.com/spf13/cobra"
_ "k8s.io/client-go/plugin/pkg/client/auth"
)

func main() {
ctx := context.Background()

rolloutsCmd := &cobra.Command{
Use: "cli",
Short: "cli ",
Long: "cli",
RunE: func(cmd *cobra.Command, args []string) error {
h, err := cmd.Flags().GetBool("help")
if err != nil {
return err
}
if h {
return cmd.Help()
}
return cmd.Usage()
},
}

rolloutsCmd.AddCommand(
get.NewCommand(ctx),
status.NewCommand(ctx),
)
if err := rolloutsCmd.Execute(); err != nil {
os.Exit(-1)
}
}
86 changes: 86 additions & 0 deletions rollouts/cli/status/status.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// Copyright 2023 Google LLC
//
// 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 status

import (
"context"
"fmt"

rolloutsapi "github.com/GoogleContainerTools/kpt/rollouts/api/v1alpha1"
"github.com/GoogleContainerTools/kpt/rollouts/rolloutsclient"
"github.com/spf13/cobra"

"github.com/jedib0t/go-pretty/v6/table"
)

func newRunner(ctx context.Context) *runner {
r := &runner{
ctx: ctx,
}
c := &cobra.Command{
Use: "status",
Short: "displays status of a rollout",
Long: "displays status of a rollout",
Example: "displays status of a rollout",
RunE: r.runE,
}
r.Command = c
return r
}

func NewCommand(ctx context.Context) *cobra.Command {
return newRunner(ctx).Command
}

type runner struct {
ctx context.Context
Command *cobra.Command
}

func (r *runner) runE(cmd *cobra.Command, args []string) error {
rlc, err := rolloutsclient.New()
if err != nil {
fmt.Printf("%s\n", err)
return err
}

if len(args) == 0 {
fmt.Printf("must provide rollout name")
return nil
}

rollout, err := rlc.Get(r.ctx, args[0])
if err != nil {
fmt.Printf("%s\n", err)
return err
}

renderStatusAsTable(cmd, rollout)
return nil
}

func renderStatusAsTable(cmd *cobra.Command, rollout *rolloutsapi.Rollout) {
t := table.NewWriter()
t.SetOutputMirror(cmd.OutOrStdout())
t.AppendHeader(table.Row{"CLUSTER", "PACKAGE ID", "PACKAGE STATUS", "SYNC STATUS"})
for _, cluster := range rollout.Status.ClusterStatuses {
pkgStatus := cluster.PackageStatus
t.AppendRow([]interface{}{cluster.Name, pkgStatus.PackageID, pkgStatus.Status, pkgStatus.SyncStatus})
}
t.AppendSeparator()
// t.AppendRow([]interface{}{300, "Tyrion", "Lannister", 5000})
// t.AppendFooter(table.Row{"", "", "Total", 10000})
t.Render()
}
3 changes: 3 additions & 0 deletions rollouts/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,11 @@ require (
github.com/googleapis/enterprise-certificate-proxy v0.2.0 // indirect
github.com/googleapis/gax-go/v2 v2.7.0 // indirect
github.com/imdario/mergo v0.3.12 // indirect
github.com/jedib0t/go-pretty/v6 v6.4.4 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-runewidth v0.0.13 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
Expand All @@ -65,6 +67,7 @@ require (
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.32.1 // indirect
github.com/prometheus/procfs v0.7.3 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/stoewer/go-strcase v1.2.0 // indirect
go.opencensus.io v0.24.0 // indirect
Expand Down
8 changes: 8 additions & 0 deletions rollouts/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,8 @@ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/jedib0t/go-pretty/v6 v6.4.4 h1:N+gz6UngBPF4M288kiMURPHELDMIhF/Em35aYuKrsSc=
github.com/jedib0t/go-pretty/v6 v6.4.4/go.mod h1:MgmISkTWDSFu0xOqiZ0mKNntMQ2mDgOcwOkwBEkMDJI=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
Expand Down Expand Up @@ -249,6 +251,8 @@ github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU=
github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
Expand All @@ -275,6 +279,7 @@ github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/profile v1.6.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18=
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/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
Expand All @@ -299,6 +304,8 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU=
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
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/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
Expand All @@ -320,6 +327,7 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.4/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
Expand Down
92 changes: 92 additions & 0 deletions rollouts/rolloutsclient/client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
// Copyright 2023 Google LLC
//
// 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 rolloutsclient

import (
"context"
"fmt"

rolloutsapi "github.com/GoogleContainerTools/kpt/rollouts/api/v1alpha1"
coreapi "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/client/config"
)

// Client implments client for the rollouts API.
type Client struct {
client client.Client
}

func New() (*Client, error) {
scheme, err := createScheme()
if err != nil {
return nil, err
}
cl, err := client.New(config.GetConfigOrDie(), client.Options{
Scheme: scheme,
})
if err != nil {
return nil, err
}
return &Client{client: cl}, nil
}

func createScheme() (*runtime.Scheme, error) {
scheme := runtime.NewScheme()

for _, api := range (runtime.SchemeBuilder{
rolloutsapi.AddToScheme,
coreapi.AddToScheme,
metav1.AddMetaToScheme,
}) {
if err := api(scheme); err != nil {
return nil, err
}
}
return scheme, nil
}

func (rlc *Client) List(ctx context.Context, ns string) (*rolloutsapi.RolloutList, error) {
if ns == "" {
ns = "default"
}

rollouts := &rolloutsapi.RolloutList{}
if err := rlc.client.List(context.Background(), rollouts, client.InNamespace(ns)); err != nil {
return nil, err
}

return rollouts, nil
}

func (rlc *Client) Get(ctx context.Context, name string) (*rolloutsapi.Rollout, error) {
if name == "" {
return nil, fmt.Errorf("must provide rollout name")
}

key := types.NamespacedName{
Namespace: "default",
Name: name,
}
rollout := &rolloutsapi.Rollout{}
if err := rlc.client.Get(context.Background(), key, rollout); err != nil {
return nil, err
}

return rollout, nil
}

0 comments on commit 87b40f7

Please sign in to comment.