Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds service get command #90

Merged
merged 4 commits into from
May 13, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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) {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rhuss : There is one thing that I have updated, changed the reference for ResourcePrinter from printers.ResourcePrinter defined here to hprinters.ResourcePrinter defined in client here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that was it. As long as you don't have a reference into 'cli-runtime/pkg/printers' anymore, there is no need for 'go modules' to add a newer version of cli-runtime (i.e. 1.14) which conflicts with serving 0.5.2 (and k8s 1.12).

So this is actually the important change and of course a better fix then copying over stuff.

// 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
navidshaikh marked this conversation as resolved.
Show resolved Hide resolved
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