Skip to content

Commit

Permalink
Adds service get command (#90)
Browse files Browse the repository at this point in the history
* Adds service get command

 replaces service list command

* Updates go.mod and vendors/*

* Adds message if no services found in requested namespace

* Adds tests for service get
  • Loading branch information
navidshaikh authored and knative-prow-robot committed May 13, 2019
1 parent 6582e82 commit bd7d57f
Show file tree
Hide file tree
Showing 8 changed files with 402 additions and 62 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ require (
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/json-iterator/go v1.1.6 // indirect
github.com/knative/build v0.5.0 // indirect
github.com/knative/pkg v0.0.0-20190329155329-916205998db9 // indirect
github.com/knative/pkg v0.0.0-20190329155329-916205998db9
github.com/knative/serving v0.5.2
github.com/knative/test-infra v0.0.0-20190509163238-a721698dbe49
github.com/mattbaird/jsonpatch v0.0.0-20171005235357-81af80346b1a // indirect
Expand Down
54 changes: 54 additions & 0 deletions pkg/kn/commands/human_readable_flags.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// Copyright © 2019 The Knative Authors
//
// 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 commands

import (
hprinters "github.com/knative/client/pkg/printers"
"github.com/spf13/cobra"
)

// HumanPrintFlags provides default flags necessary for printing.
// Given the following flag values, a printer can be requested that knows
// how to handle printing based on these values.
type HumanPrintFlags struct {
//TODO: Add more flags as required
}

// AllowedFormats returns more customized formating options
func (f *HumanPrintFlags) AllowedFormats() []string {
// TODO: Add more formats eg: wide
return []string{""}
}

// ToPrinter receives returns a printer capable of
// handling human-readable output.
func (f *HumanPrintFlags) ToPrinter() (hprinters.ResourcePrinter, error) {
p := hprinters.NewTablePrinter(hprinters.PrintOptions{})
// Add the column definitions and respective functions
ServiceGetHandlers(p)
return p, nil
}

// AddFlags receives a *cobra.Command reference and binds
// flags related to human-readable printing to it
func (f *HumanPrintFlags) AddFlags(c *cobra.Command) {
//TODO: Add more flags as required
}

// NewHumanPrintFlags returns flags associated with
// human-readable printing, with default values set.
func NewHumanPrintFlags() *HumanPrintFlags {
return &HumanPrintFlags{}
}
2 changes: 1 addition & 1 deletion pkg/kn/commands/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func NewServiceCommand(p *KnParams) *cobra.Command {
Use: "service",
Short: "Service command group",
}
serviceCmd.AddCommand(NewServiceListCommand(p))
serviceCmd.AddCommand(NewServiceGetCommand(p))
serviceCmd.AddCommand(NewServiceDescribeCommand(p))
serviceCmd.AddCommand(NewServiceCreateCommand(p))
serviceCmd.AddCommand(NewServiceDeleteCommand(p))
Expand Down
38 changes: 21 additions & 17 deletions pkg/kn/commands/service_list.go → pkg/kn/commands/service_get.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright © 2018 The Knative Authors
// Copyright © 2019 The Knative Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -15,21 +15,20 @@
package commands

import (
"fmt"

"github.com/spf13/cobra"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/cli-runtime/pkg/genericclioptions"
)

var serviceListPrintFlags *genericclioptions.PrintFlags
// NewServiceGetCommand represents 'kn service get' command
func NewServiceGetCommand(p *KnParams) *cobra.Command {
serviceGetFlags := NewServiceGetFlags()

// listCmd represents the list command
func NewServiceListCommand(p *KnParams) *cobra.Command {
serviceListPrintFlags := genericclioptions.NewPrintFlags("").WithDefaultOutput(
"jsonpath={range .items[*]}{.metadata.name}{\"\\n\"}{end}")
serviceListCommand := &cobra.Command{
Use: "list",
Short: "List available services.",
serviceGetCommand := &cobra.Command{
Use: "get",
Short: "Get available services.",
RunE: func(cmd *cobra.Command, args []string) error {
client, err := p.ServingFactory()
if err != nil {
Expand All @@ -43,23 +42,28 @@ func NewServiceListCommand(p *KnParams) *cobra.Command {
if err != nil {
return err
}

printer, err := serviceListPrintFlags.ToPrinter()
if err != nil {
return err
if len(service.Items) == 0 {
fmt.Fprintf(cmd.OutOrStdout(), "No resources found.\n")
return nil
}
service.GetObjectKind().SetGroupVersionKind(schema.GroupVersionKind{
Group: "knative.dev",
Version: "v1alpha1",
Kind: "Service"})

printer, err := serviceGetFlags.ToPrinter()
if err != nil {
return err
}

err = printer.PrintObj(service, cmd.OutOrStdout())
if err != nil {
return err
}
return nil
},
}
AddNamespaceFlags(serviceListCommand.Flags(), true)
serviceListPrintFlags.AddFlags(serviceListCommand)
return serviceListCommand
AddNamespaceFlags(serviceGetCommand.Flags(), true)
serviceGetFlags.AddFlags(serviceGetCommand)
return serviceGetCommand
}
181 changes: 181 additions & 0 deletions pkg/kn/commands/service_get_flags.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,181 @@
// Copyright © 2019 The Knative Authors
//
// 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 im
// See the License for the specific language governing permissions and
// limitations under the License.

package commands

import (
"fmt"
hprinters "github.com/knative/client/pkg/printers"
duckv1alpha1 "github.com/knative/pkg/apis/duck/v1alpha1"
servingv1alpha1 "github.com/knative/serving/pkg/apis/serving/v1alpha1"
"github.com/spf13/cobra"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/util/duration"
"k8s.io/cli-runtime/pkg/genericclioptions"
"time"
)

// ServiceGetFlags composes common printer flag structs
// used in the Get command.
type ServiceGetFlags struct {
GenericPrintFlags *genericclioptions.PrintFlags
HumanReadableFlags *HumanPrintFlags
}

// AllowedFormats is the list of formats in which data can be displayed
func (f *ServiceGetFlags) AllowedFormats() []string {
formats := f.GenericPrintFlags.AllowedFormats()
formats = append(formats, f.HumanReadableFlags.AllowedFormats()...)
return formats
}

// ToPrinter attempts to find a composed set of ServiceGetFlags suitable for
// returning a printer based on current flag values.
func (f *ServiceGetFlags) ToPrinter() (hprinters.ResourcePrinter, error) {
// if there are flags specified for generic printing
if f.GenericPrintFlags.OutputFlagSpecified() {
p, err := f.GenericPrintFlags.ToPrinter()
if err != nil {
return nil, err
}
return p, nil
}
// if no flags specified, use the table printing
p, err := f.HumanReadableFlags.ToPrinter()
if err != nil {
return nil, err
}
return p, nil
}

// AddFlags receives a *cobra.Command reference and binds
// flags related to humanreadable and template printing.
func (f *ServiceGetFlags) AddFlags(cmd *cobra.Command) {
f.GenericPrintFlags.AddFlags(cmd)
f.HumanReadableFlags.AddFlags(cmd)
}

// NewGetPrintFlags returns flags associated with humanreadable,
// template, and "name" printing, with default values set.
func NewServiceGetFlags() *ServiceGetFlags {
return &ServiceGetFlags{
GenericPrintFlags: genericclioptions.NewPrintFlags(""),
HumanReadableFlags: NewHumanPrintFlags(),
}
}

// ServiceGetHandlers adds print handlers for service get command
func ServiceGetHandlers(h hprinters.PrintHandler) {
kServiceColumnDefinitions := []metav1beta1.TableColumnDefinition{
{Name: "Name", Type: "string", Description: "Name of the knative service."},
{Name: "Domain", Type: "string", Description: "Domain name of the knative service."},
//{Name: "LastCreatedRevision", Type: "string", Description: "Name of last revision created."},
//{Name: "LastReadyRevision", Type: "string", Description: "Name of last ready revision."},
{Name: "Generation", Type: "integer", Description: "Sequence number of 'Generation' of the service that was last processed by the controller."},
{Name: "Age", Type: "string", Description: "Age of the service."},
{Name: "Conditions", Type: "string", Description: "Conditions describing statuses of service components."},
{Name: "Ready", Type: "string", Description: "Ready condition status of the service."},
{Name: "Reason", Type: "string", Description: "Reason for non-ready condition of the service."},
}
h.TableHandler(kServiceColumnDefinitions, printKService)
h.TableHandler(kServiceColumnDefinitions, printKServiceList)
}

// conditionsValue returns the True conditions count among total conditions
func conditionsValue(conditions duckv1alpha1.Conditions) string {
var ok int
for _, condition := range conditions {
if condition.Status == "True" {
ok++
}
}
return fmt.Sprintf("%d OK / %d", ok, len(conditions))
}

// readyCondition returns status of resource's Ready type condition
func readyCondition(conditions duckv1alpha1.Conditions) string {
for _, condition := range conditions {
if condition.Type == duckv1alpha1.ConditionReady {
return string(condition.Status)
}
}
return "<unknown>"
}

func nonReadyConditionReason(conditions duckv1alpha1.Conditions) string {
for _, condition := range conditions {
if condition.Type == duckv1alpha1.ConditionReady {
if string(condition.Status) == "True" {
return ""
}
if condition.Message != "" {
return fmt.Sprintf("%s : %s", condition.Reason, condition.Message)
}
return string(condition.Reason)
}
}
return "<unknown>"
}

// translateTimestampSince returns the elapsed time since timestamp in
// human-readable approximation.
func translateTimestampSince(timestamp metav1.Time) string {
if timestamp.IsZero() {
return "<unknown>"
}
return duration.HumanDuration(time.Since(timestamp.Time))
}

// printKServiceList populates the knative service list table rows
func printKServiceList(kServiceList *servingv1alpha1.ServiceList, options hprinters.PrintOptions) ([]metav1beta1.TableRow, error) {
rows := make([]metav1beta1.TableRow, 0, len(kServiceList.Items))
for _, ksvc := range kServiceList.Items {
r, err := printKService(&ksvc, options)
if err != nil {
return nil, err
}
rows = append(rows, r...)
}
return rows, nil
}

// printKService populates the knative service table rows
func printKService(kService *servingv1alpha1.Service, options hprinters.PrintOptions) ([]metav1beta1.TableRow, error) {
name := kService.Name
domain := kService.Status.Domain
//lastCreatedRevision := kService.Status.LatestCreatedRevisionName
//lastReadyRevision := kService.Status.LatestReadyRevisionName
generation := kService.Status.ObservedGeneration
age := translateTimestampSince(kService.CreationTimestamp)
conditions := conditionsValue(kService.Status.Conditions)
ready := readyCondition(kService.Status.Conditions)
reason := nonReadyConditionReason(kService.Status.Conditions)

row := metav1beta1.TableRow{
Object: runtime.RawExtension{Object: kService},
}
row.Cells = append(row.Cells,
name,
domain,
//lastCreatedRevision,
//lastReadyRevision,
generation,
age,
conditions,
ready,
reason)
return []metav1beta1.TableRow{row}, nil
}
Loading

0 comments on commit bd7d57f

Please sign in to comment.