mirror of https://github.com/knative/client.git
Add cronjob and apiserver source list commands (#559)
* Add kn source cronjob list command * Add kn source apiserver list command
This commit is contained in:
parent
8b1434b789
commit
6380fc5eaf
|
|
@ -30,5 +30,6 @@ kn source apiserver [flags]
|
|||
* [kn source apiserver create](kn_source_apiserver_create.md) - Create an ApiServer source.
|
||||
* [kn source apiserver delete](kn_source_apiserver_delete.md) - Delete an ApiServer source.
|
||||
* [kn source apiserver describe](kn_source_apiserver_describe.md) - Describe an ApiServer source.
|
||||
* [kn source apiserver list](kn_source_apiserver_list.md) - List ApiServer sources.
|
||||
* [kn source apiserver update](kn_source_apiserver_update.md) - Update an ApiServer source.
|
||||
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ kn source apiserver create NAME --resource RESOURCE --service-account ACCOUNTNAM
|
|||
|
||||
```
|
||||
-h, --help help for create
|
||||
--mode string The mode the receive adapter controller runs under:,
|
||||
"Ref" sends only the reference to the resource,
|
||||
--mode string The mode the receive adapter controller runs under:,
|
||||
"Ref" sends only the reference to the resource,
|
||||
"Resource" send the full resource. (default "Ref")
|
||||
-n, --namespace string Specify the namespace to operate in.
|
||||
--resource strings Comma seperate Kind:APIVersion:isController list, e.g. Event:v1:true.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
## kn source apiserver list
|
||||
|
||||
List ApiServer sources.
|
||||
|
||||
### Synopsis
|
||||
|
||||
List ApiServer sources.
|
||||
|
||||
```
|
||||
kn source apiserver list [flags]
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
```
|
||||
|
||||
# List all ApiServer sources in YAML format
|
||||
kn source apiserver list -o yaml
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-A, --all-namespaces If present, list the requested object(s) across all namespaces. Namespace in current context is ignored even if specified with --namespace.
|
||||
--allow-missing-template-keys If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. (default true)
|
||||
-h, --help help for list
|
||||
-n, --namespace string Specify the namespace to operate in.
|
||||
--no-headers When using the default output format, don't print headers (default: print headers).
|
||||
-o, --output string Output format. One of: json|yaml|name|go-template|go-template-file|template|templatefile|jsonpath|jsonpath-file.
|
||||
--template string Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--config string kn config file (default is $HOME/.kn/config.yaml)
|
||||
--kubeconfig string kubectl config file (default is $HOME/.kube/config)
|
||||
--log-http log http traffic
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [kn source apiserver](kn_source_apiserver.md) - Kubernetes API Server Event Source command group
|
||||
|
||||
|
|
@ -22,8 +22,8 @@ kn source apiserver update NAME --resource RESOURCE --service-account ACCOUNTNAM
|
|||
|
||||
```
|
||||
-h, --help help for update
|
||||
--mode string The mode the receive adapter controller runs under:,
|
||||
"Ref" sends only the reference to the resource,
|
||||
--mode string The mode the receive adapter controller runs under:,
|
||||
"Ref" sends only the reference to the resource,
|
||||
"Resource" send the full resource. (default "Ref")
|
||||
-n, --namespace string Specify the namespace to operate in.
|
||||
--resource strings Comma seperate Kind:APIVersion:isController list, e.g. Event:v1:true.
|
||||
|
|
|
|||
|
|
@ -30,5 +30,6 @@ kn source cronjob [flags]
|
|||
* [kn source cronjob create](kn_source_cronjob_create.md) - Create a CronJob source.
|
||||
* [kn source cronjob delete](kn_source_cronjob_delete.md) - Delete a CronJob source.
|
||||
* [kn source cronjob describe](kn_source_cronjob_describe.md) - Describe a CronJob source.
|
||||
* [kn source cronjob list](kn_source_cronjob_list.md) - List CronJob sources.
|
||||
* [kn source cronjob update](kn_source_cronjob_update.md) - Update a CronJob source.
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,44 @@
|
|||
## kn source cronjob list
|
||||
|
||||
List CronJob sources.
|
||||
|
||||
### Synopsis
|
||||
|
||||
List CronJob sources.
|
||||
|
||||
```
|
||||
kn source cronjob list [flags]
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
```
|
||||
|
||||
# List all CronJob sources in YAML format
|
||||
kn source cronjob list -o yaml
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
```
|
||||
-A, --all-namespaces If present, list the requested object(s) across all namespaces. Namespace in current context is ignored even if specified with --namespace.
|
||||
--allow-missing-template-keys If true, ignore any errors in templates when a field or map key is missing in the template. Only applies to golang and jsonpath output formats. (default true)
|
||||
-h, --help help for list
|
||||
-n, --namespace string Specify the namespace to operate in.
|
||||
--no-headers When using the default output format, don't print headers (default: print headers).
|
||||
-o, --output string Output format. One of: json|yaml|name|go-template|go-template-file|template|templatefile|jsonpath|jsonpath-file.
|
||||
--template string Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
|
||||
```
|
||||
|
||||
### Options inherited from parent commands
|
||||
|
||||
```
|
||||
--config string kn config file (default is $HOME/.kn/config.yaml)
|
||||
--kubeconfig string kubectl config file (default is $HOME/.kube/config)
|
||||
--log-http log http traffic
|
||||
```
|
||||
|
||||
### SEE ALSO
|
||||
|
||||
* [kn source cronjob](kn_source_cronjob.md) - CronJob source command group
|
||||
|
||||
|
|
@ -37,6 +37,10 @@ type KnAPIServerSourcesClient interface {
|
|||
// Delete an ApiServerSource by name
|
||||
DeleteAPIServerSource(name string) error
|
||||
|
||||
// List ApiServerSource
|
||||
// TODO: Support list configs like in service list
|
||||
ListAPIServerSource() (*v1alpha1.ApiServerSourceList, error)
|
||||
|
||||
// Get namespace for this client
|
||||
Namespace() string
|
||||
}
|
||||
|
|
@ -98,6 +102,35 @@ func (c *apiServerSourcesClient) Namespace() string {
|
|||
return c.namespace
|
||||
}
|
||||
|
||||
// ListAPIServerSource returns the available ApiServer type sources
|
||||
func (c *apiServerSourcesClient) ListAPIServerSource() (*v1alpha1.ApiServerSourceList, error) {
|
||||
sourceList, err := c.client.List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return updateAPIServerSourceListGVK(sourceList)
|
||||
}
|
||||
|
||||
func updateAPIServerSourceListGVK(sourceList *v1alpha1.ApiServerSourceList) (*v1alpha1.ApiServerSourceList, error) {
|
||||
sourceListNew := sourceList.DeepCopy()
|
||||
err := updateSourceGVK(sourceListNew)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sourceListNew.Items = make([]v1alpha1.ApiServerSource, len(sourceList.Items))
|
||||
for idx, source := range sourceList.Items {
|
||||
sourceClone := source.DeepCopy()
|
||||
err := updateSourceGVK(sourceClone)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sourceListNew.Items[idx] = *sourceClone
|
||||
}
|
||||
return sourceListNew, nil
|
||||
}
|
||||
|
||||
// APIServerSourceBuilder is for building the source
|
||||
type APIServerSourceBuilder struct {
|
||||
apiServerSource *v1alpha1.ApiServerSource
|
||||
|
|
|
|||
|
|
@ -103,6 +103,17 @@ func (c *MockKnAPIServerSourceClient) DeleteAPIServerSource(name string) error {
|
|||
return mock.ErrorOrNil(call.Result[0])
|
||||
}
|
||||
|
||||
// ListAPIServerSource records a call for ListAPIServerSource with the expected error (nil if none)
|
||||
func (sr *APIServerSourcesRecorder) ListAPIServerSource(apiJobSourceList *v1alpha1.ApiServerSourceList, err error) {
|
||||
sr.r.Add("ListAPIServerSource", []interface{}{}, []interface{}{apiJobSourceList, err})
|
||||
}
|
||||
|
||||
// ListAPIServerSource performs a previously recorded action, failing if non has been registered
|
||||
func (c *MockKnAPIServerSourceClient) ListAPIServerSource() (*v1alpha1.ApiServerSourceList, error) {
|
||||
call := c.recorder.r.VerifyCall("ListAPIServerSource")
|
||||
return call.Result[0].(*v1alpha1.ApiServerSourceList), mock.ErrorOrNil(call.Result[1])
|
||||
}
|
||||
|
||||
// Validate validates whether every recorded action has been called
|
||||
func (sr *APIServerSourcesRecorder) Validate() {
|
||||
sr.r.CheckThatAllRecordedMethodsHaveBeenCalled()
|
||||
|
|
|
|||
|
|
@ -116,6 +116,20 @@ func TestUpdateApiServerSource(t *testing.T) {
|
|||
assert.ErrorContains(t, err, "errorSource")
|
||||
}
|
||||
|
||||
func TestListAPIServerSource(t *testing.T) {
|
||||
sourcesServer, client := setupAPIServerSourcesClient(t)
|
||||
|
||||
sourcesServer.AddReactor("list", "apiserversources",
|
||||
func(a client_testing.Action) (bool, runtime.Object, error) {
|
||||
cJSource := newAPIServerSource("testsource", "Event")
|
||||
return true, &v1alpha1.ApiServerSourceList{Items: []v1alpha1.ApiServerSource{*cJSource}}, nil
|
||||
})
|
||||
|
||||
sourceList, err := client.ListAPIServerSource()
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, len(sourceList.Items), 1)
|
||||
}
|
||||
|
||||
func newAPIServerSource(name, resource string) *v1alpha1.ApiServerSource {
|
||||
b := NewAPIServerSourceBuilder(name).ServiceAccount("testsa").Mode("Ref")
|
||||
b.Sink(&v1beta1.Destination{
|
||||
|
|
|
|||
|
|
@ -17,8 +17,12 @@ package v1alpha1
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"knative.dev/eventing/pkg/apis/sources/v1alpha1"
|
||||
|
||||
"knative.dev/client/pkg/util"
|
||||
"knative.dev/eventing/pkg/client/clientset/versioned/scheme"
|
||||
client_v1alpha1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/sources/v1alpha1"
|
||||
duckv1beta1 "knative.dev/pkg/apis/duck/v1beta1"
|
||||
)
|
||||
|
|
@ -38,6 +42,10 @@ type KnCronJobSourcesClient interface {
|
|||
// Delete a cronjob source by name
|
||||
DeleteCronJobSource(name string) error
|
||||
|
||||
// List CronJob sources
|
||||
// TODO: Support list configs like in service list
|
||||
ListCronJobSource() (*v1alpha1.CronJobSourceList, error)
|
||||
|
||||
// Get namespace for this source
|
||||
Namespace() string
|
||||
}
|
||||
|
|
@ -77,11 +85,44 @@ func (c *cronJobSourcesClient) UpdateCronJobSource(cronjobSource *v1alpha1.CronJ
|
|||
}
|
||||
|
||||
func (c *cronJobSourcesClient) DeleteCronJobSource(name string) error {
|
||||
return c.client.Delete(name, &meta_v1.DeleteOptions{})
|
||||
return c.client.Delete(name, &metav1.DeleteOptions{})
|
||||
}
|
||||
|
||||
func (c *cronJobSourcesClient) GetCronJobSource(name string) (*v1alpha1.CronJobSource, error) {
|
||||
return c.client.Get(name, meta_v1.GetOptions{})
|
||||
return c.client.Get(name, metav1.GetOptions{})
|
||||
}
|
||||
|
||||
// ListCronJobSource returns the available CronJob type sources
|
||||
func (c *cronJobSourcesClient) ListCronJobSource() (*v1alpha1.CronJobSourceList, error) {
|
||||
sourceList, err := c.client.List(metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return updateCronJobSourceListGVK(sourceList)
|
||||
}
|
||||
|
||||
func updateCronJobSourceListGVK(sourceList *v1alpha1.CronJobSourceList) (*v1alpha1.CronJobSourceList, error) {
|
||||
sourceListNew := sourceList.DeepCopy()
|
||||
err := updateSourceGVK(sourceListNew)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sourceListNew.Items = make([]v1alpha1.CronJobSource, len(sourceList.Items))
|
||||
for idx, source := range sourceList.Items {
|
||||
sourceClone := source.DeepCopy()
|
||||
err := updateSourceGVK(sourceClone)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
sourceListNew.Items[idx] = *sourceClone
|
||||
}
|
||||
return sourceListNew, nil
|
||||
}
|
||||
|
||||
func updateSourceGVK(obj runtime.Object) error {
|
||||
return util.UpdateGroupVersionKindWithScheme(obj, v1alpha1.SchemeGroupVersion, scheme.Scheme)
|
||||
}
|
||||
|
||||
// Builder for building up cronjob sources
|
||||
|
|
@ -92,7 +133,7 @@ type CronJobSourceBuilder struct {
|
|||
|
||||
func NewCronJobSourceBuilder(name string) *CronJobSourceBuilder {
|
||||
return &CronJobSourceBuilder{cronjobSource: &v1alpha1.CronJobSource{
|
||||
ObjectMeta: meta_v1.ObjectMeta{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
},
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -102,6 +102,17 @@ func (c *MockKnCronJobSourceClient) DeleteCronJobSource(name string) error {
|
|||
return mock.ErrorOrNil(call.Result[0])
|
||||
}
|
||||
|
||||
// ListCronJobSource records a call for ListCronJobSource with the expected error (nil if none)
|
||||
func (sr *CronJobSourcesRecorder) ListCronJobSource(cronJobSourceList *v1alpha1.CronJobSourceList, err error) {
|
||||
sr.r.Add("ListCronJobSource", []interface{}{}, []interface{}{cronJobSourceList, err})
|
||||
}
|
||||
|
||||
// ListCronJobSource performs a previously recorded action, failing if non has been registered
|
||||
func (c *MockKnCronJobSourceClient) ListCronJobSource() (*v1alpha1.CronJobSourceList, error) {
|
||||
call := c.recorder.r.VerifyCall("ListCronJobSource")
|
||||
return call.Result[0].(*v1alpha1.CronJobSourceList), mock.ErrorOrNil(call.Result[1])
|
||||
}
|
||||
|
||||
// Validates validates whether every recorded action has been called
|
||||
func (sr *CronJobSourcesRecorder) Validate() {
|
||||
sr.r.CheckThatAllRecordedMethodsHaveBeenCalled()
|
||||
|
|
|
|||
|
|
@ -119,6 +119,20 @@ func TestGetCronJobSource(t *testing.T) {
|
|||
assert.ErrorContains(t, err, "errorSource")
|
||||
}
|
||||
|
||||
func TestListCronJobSource(t *testing.T) {
|
||||
sourcesServer, client := setupCronJobSourcesClient(t)
|
||||
|
||||
sourcesServer.AddReactor("list", "cronjobsources",
|
||||
func(a client_testing.Action) (bool, runtime.Object, error) {
|
||||
cJSource := newCronJobSource("testsource", "mysvc")
|
||||
return true, &v1alpha1.CronJobSourceList{Items: []v1alpha1.CronJobSource{*cJSource}}, nil
|
||||
})
|
||||
|
||||
sourceList, err := client.ListCronJobSource()
|
||||
assert.NilError(t, err)
|
||||
assert.Equal(t, len(sourceList.Items), 1)
|
||||
}
|
||||
|
||||
func newCronJobSource(name string, sink string) *v1alpha1.CronJobSource {
|
||||
b := NewCronJobSourceBuilder(name).
|
||||
Schedule("* * * * *").
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ func NewAPIServerCommand(p *commands.KnParams) *cobra.Command {
|
|||
apiServerSourceCmd.AddCommand(NewAPIServerUpdateCommand(p))
|
||||
apiServerSourceCmd.AddCommand(NewAPIServerDescribeCommand(p))
|
||||
apiServerSourceCmd.AddCommand(NewAPIServerDeleteCommand(p))
|
||||
apiServerSourceCmd.AddCommand(NewAPIServerListCommand(p))
|
||||
return apiServerSourceCmd
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,11 +15,18 @@
|
|||
package apiserver
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"knative.dev/client/pkg/kn/commands"
|
||||
"knative.dev/eventing/pkg/apis/sources/v1alpha1"
|
||||
|
||||
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
|
||||
hprinters "knative.dev/client/pkg/printers"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
@ -77,8 +84,8 @@ func (f *APIServerSourceUpdateFlags) Add(cmd *cobra.Command) {
|
|||
cmd.Flags().StringVar(&f.Mode,
|
||||
"mode",
|
||||
"Ref",
|
||||
`The mode the receive adapter controller runs under:,
|
||||
"Ref" sends only the reference to the resource,
|
||||
`The mode the receive adapter controller runs under:,
|
||||
"Ref" sends only the reference to the resource,
|
||||
"Resource" send the full resource.`)
|
||||
cmd.Flags().StringSliceVar(&f.Resources,
|
||||
"resource",
|
||||
|
|
@ -87,3 +94,108 @@ func (f *APIServerSourceUpdateFlags) Add(cmd *cobra.Command) {
|
|||
"APIVersion" and "isControler" can be omitted.
|
||||
"APIVersion" is "v1" by default, "isController" is "false" by default.`)
|
||||
}
|
||||
|
||||
// APIServerSourceListHandlers handles printing human readable table for `kn source apiserver list` command's output
|
||||
func APIServerSourceListHandlers(h hprinters.PrintHandler) {
|
||||
sourceColumnDefinitions := []metav1beta1.TableColumnDefinition{
|
||||
{Name: "Namespace", Type: "string", Description: "Namespace of the ApiServer source", Priority: 0},
|
||||
{Name: "Name", Type: "string", Description: "Name of the ApiServer source", Priority: 1},
|
||||
{Name: "Resources", Type: "string", Description: "Event resources configured for the ApiServer source", Priority: 1},
|
||||
{Name: "Sink", Type: "string", Description: "Sink of the ApiServer source", Priority: 1},
|
||||
{Name: "Conditions", Type: "string", Description: "Ready state conditions", Priority: 1},
|
||||
{Name: "Ready", Type: "string", Description: "Ready state of the ApiServer source", Priority: 1},
|
||||
{Name: "Reason", Type: "string", Description: "Reason if state is not Ready", Priority: 1},
|
||||
}
|
||||
h.TableHandler(sourceColumnDefinitions, printSource)
|
||||
h.TableHandler(sourceColumnDefinitions, printSourceList)
|
||||
}
|
||||
|
||||
// printSource populates a single row of source apiserver list table
|
||||
func printSource(source *v1alpha1.ApiServerSource, options hprinters.PrintOptions) ([]metav1beta1.TableRow, error) {
|
||||
row := metav1beta1.TableRow{
|
||||
Object: runtime.RawExtension{Object: source},
|
||||
}
|
||||
|
||||
name := source.Name
|
||||
conditions := commands.ConditionsValue(source.Status.Conditions)
|
||||
ready := commands.ReadyCondition(source.Status.Conditions)
|
||||
reason := strings.TrimSpace(commands.NonReadyConditionReason(source.Status.Conditions))
|
||||
var resources []string
|
||||
for _, resource := range source.Spec.Resources {
|
||||
resources = append(resources, fmt.Sprintf("%s:%s:%s", resource.Kind, resource.APIVersion, strconv.FormatBool(resource.Controller)))
|
||||
}
|
||||
|
||||
var sink string
|
||||
if source.Spec.Sink != nil {
|
||||
if source.Spec.Sink.Ref != nil {
|
||||
if source.Spec.Sink.Ref.Kind == "Service" {
|
||||
sink = fmt.Sprintf("svc:%s", source.Spec.Sink.Ref.Name)
|
||||
} else {
|
||||
sink = fmt.Sprintf("%s:%s", source.Spec.Sink.Ref.Kind, source.Spec.Sink.Ref.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if options.AllNamespaces {
|
||||
row.Cells = append(row.Cells, source.Namespace)
|
||||
}
|
||||
|
||||
row.Cells = append(row.Cells, name, strings.Join(resources[:], ","), sink, conditions, ready, reason)
|
||||
return []metav1beta1.TableRow{row}, nil
|
||||
}
|
||||
|
||||
// printSourceList populates the source apiserver list table rows
|
||||
func printSourceList(sourceList *v1alpha1.ApiServerSourceList, options hprinters.PrintOptions) ([]metav1beta1.TableRow, error) {
|
||||
if options.AllNamespaces {
|
||||
return printSourceListWithNamespace(sourceList, options)
|
||||
}
|
||||
|
||||
rows := make([]metav1beta1.TableRow, 0, len(sourceList.Items))
|
||||
|
||||
sort.SliceStable(sourceList.Items, func(i, j int) bool {
|
||||
return sourceList.Items[i].GetName() < sourceList.Items[j].GetName()
|
||||
})
|
||||
|
||||
for _, item := range sourceList.Items {
|
||||
row, err := printSource(&item, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rows = append(rows, row...)
|
||||
}
|
||||
return rows, nil
|
||||
}
|
||||
|
||||
// printSourceListWithNamespace populates the knative service table rows with namespace column
|
||||
func printSourceListWithNamespace(sourceList *v1alpha1.ApiServerSourceList, options hprinters.PrintOptions) ([]metav1beta1.TableRow, error) {
|
||||
rows := make([]metav1beta1.TableRow, 0, len(sourceList.Items))
|
||||
|
||||
// temporary slice for sorting services in non-default namespace
|
||||
others := []metav1beta1.TableRow{}
|
||||
|
||||
for _, source := range sourceList.Items {
|
||||
// Fill in with services in `default` namespace at first
|
||||
if source.Namespace == "default" {
|
||||
r, err := printSource(&source, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rows = append(rows, r...)
|
||||
continue
|
||||
}
|
||||
// put other services in temporary slice
|
||||
r, err := printSource(&source, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
others = append(others, r...)
|
||||
}
|
||||
|
||||
// sort other services list alphabetically by namespace
|
||||
sort.SliceStable(others, func(i, j int) bool {
|
||||
return others[i].Cells[0].(string) < others[j].Cells[0].(string)
|
||||
})
|
||||
|
||||
return append(rows, others...), nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,74 @@
|
|||
// 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 apiserver
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"knative.dev/client/pkg/kn/commands"
|
||||
"knative.dev/client/pkg/kn/commands/flags"
|
||||
)
|
||||
|
||||
// NewAPIServerListCommand is for listing ApiServer source COs
|
||||
func NewAPIServerListCommand(p *commands.KnParams) *cobra.Command {
|
||||
listFlags := flags.NewListFlags(APIServerSourceListHandlers)
|
||||
|
||||
listCommand := &cobra.Command{
|
||||
Use: "list",
|
||||
Short: "List ApiServer sources.",
|
||||
Example: `
|
||||
# List all ApiServer sources in YAML format
|
||||
kn source apiserver list -o yaml`,
|
||||
|
||||
RunE: func(cmd *cobra.Command, args []string) (err error) {
|
||||
// TODO: filter list by given source name
|
||||
|
||||
apiSourceClient, err := newAPIServerSourceClient(p, cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sourceList, err := apiSourceClient.ListAPIServerSource()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(sourceList.Items) == 0 {
|
||||
fmt.Fprintf(cmd.OutOrStdout(), "No ApiServer source found.\n")
|
||||
return nil
|
||||
}
|
||||
|
||||
if apiSourceClient.Namespace() == "" {
|
||||
listFlags.EnsureWithNamespace()
|
||||
}
|
||||
|
||||
printer, err := listFlags.ToPrinter()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
err = printer.PrintObj(sourceList, cmd.OutOrStdout())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
commands.AddNamespaceFlags(listCommand.Flags(), true)
|
||||
listFlags.AddFlags(listCommand)
|
||||
return listCommand
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
// 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 apiserver
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"gotest.tools/assert"
|
||||
|
||||
knsource_v1alpha1 "knative.dev/client/pkg/eventing/sources/v1alpha1"
|
||||
"knative.dev/client/pkg/util"
|
||||
"knative.dev/eventing/pkg/apis/sources/v1alpha1"
|
||||
)
|
||||
|
||||
func TestListAPIServerSource(t *testing.T) {
|
||||
apiServerClient := knsource_v1alpha1.NewMockKnAPIServerSourceClient(t)
|
||||
|
||||
apiServerRecorder := apiServerClient.Recorder()
|
||||
sampleSource := createAPIServerSource("testsource", "Event", "v1", "testsa", "Ref", "testsvc", false)
|
||||
sampleSourceList := v1alpha1.ApiServerSourceList{}
|
||||
sampleSourceList.Items = []v1alpha1.ApiServerSource{*sampleSource}
|
||||
|
||||
apiServerRecorder.ListAPIServerSource(&sampleSourceList, nil)
|
||||
|
||||
out, err := executeAPIServerSourceCommand(apiServerClient, nil, "list")
|
||||
assert.NilError(t, err, "sources should be listed")
|
||||
util.ContainsAll(out, "NAME", "RESOURCES", "SINK", "CONDITIONS", "READY", "REASON")
|
||||
util.ContainsAll(out, "testsource", "Eventing:v1:false", "mysvc")
|
||||
|
||||
apiServerRecorder.Validate()
|
||||
}
|
||||
|
||||
func TestListAPIServerSourceEmpty(t *testing.T) {
|
||||
apiServerClient := knsource_v1alpha1.NewMockKnAPIServerSourceClient(t)
|
||||
|
||||
apiServerRecorder := apiServerClient.Recorder()
|
||||
sampleSourceList := v1alpha1.ApiServerSourceList{}
|
||||
|
||||
apiServerRecorder.ListAPIServerSource(&sampleSourceList, nil)
|
||||
|
||||
out, err := executeAPIServerSourceCommand(apiServerClient, nil, "list")
|
||||
assert.NilError(t, err, "Sources should be listed")
|
||||
util.ContainsNone(out, "NAME", "RESOURCES", "SINK", "CONDITIONS", "READY", "REASON")
|
||||
util.ContainsAll(out, "No", "ApiServer", "source", "found")
|
||||
|
||||
apiServerRecorder.Validate()
|
||||
}
|
||||
|
|
@ -33,6 +33,7 @@ func NewCronJobCommand(p *commands.KnParams) *cobra.Command {
|
|||
cronImporterCmd.AddCommand(NewCronJobDeleteCommand(p))
|
||||
cronImporterCmd.AddCommand(NewCronJobDescribeCommand(p))
|
||||
cronImporterCmd.AddCommand(NewCronJobUpdateCommand(p))
|
||||
cronImporterCmd.AddCommand(NewCronJobListCommand(p))
|
||||
return cronImporterCmd
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,19 @@
|
|||
|
||||
package cronjob
|
||||
|
||||
import "github.com/spf13/cobra"
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
|
||||
"knative.dev/client/pkg/kn/commands"
|
||||
hprinters "knative.dev/client/pkg/printers"
|
||||
|
||||
"knative.dev/eventing/pkg/apis/sources/v1alpha1"
|
||||
)
|
||||
|
||||
type cronJobUpdateFlags struct {
|
||||
schedule string
|
||||
|
|
@ -25,3 +37,105 @@ func (c *cronJobUpdateFlags) addCronJobFlags(cmd *cobra.Command) {
|
|||
cmd.Flags().StringVar(&c.schedule, "schedule", "", "Schedule specification in crontab format (e.g. '* * * * */2' for every two minutes")
|
||||
cmd.Flags().StringVarP(&c.data, "data", "d", "", "String data to send")
|
||||
}
|
||||
|
||||
// CronJobListHandlers handles printing human readable table for `kn source cronjob list` command's output
|
||||
func CronJobSourceListHandlers(h hprinters.PrintHandler) {
|
||||
sourceColumnDefinitions := []metav1beta1.TableColumnDefinition{
|
||||
{Name: "Namespace", Type: "string", Description: "Namespace of the CronJob source", Priority: 0},
|
||||
{Name: "Name", Type: "string", Description: "Name of the CronJob source", Priority: 1},
|
||||
{Name: "Schedule", Type: "string", Description: "Schedule of the CronJob source", Priority: 1},
|
||||
{Name: "Sink", Type: "string", Description: "Sink of the CronJob source", Priority: 1},
|
||||
{Name: "Conditions", Type: "string", Description: "Ready state conditions", Priority: 1},
|
||||
{Name: "Ready", Type: "string", Description: "Ready state of the CronJob source", Priority: 1},
|
||||
{Name: "Reason", Type: "string", Description: "Reason if state is not Ready", Priority: 1},
|
||||
}
|
||||
h.TableHandler(sourceColumnDefinitions, printSource)
|
||||
h.TableHandler(sourceColumnDefinitions, printSourceList)
|
||||
}
|
||||
|
||||
// printSource populates a single row of source cronjob list table
|
||||
func printSource(source *v1alpha1.CronJobSource, options hprinters.PrintOptions) ([]metav1beta1.TableRow, error) {
|
||||
row := metav1beta1.TableRow{
|
||||
Object: runtime.RawExtension{Object: source},
|
||||
}
|
||||
|
||||
name := source.Name
|
||||
schedule := source.Spec.Schedule
|
||||
conditions := commands.ConditionsValue(source.Status.Conditions)
|
||||
ready := commands.ReadyCondition(source.Status.Conditions)
|
||||
reason := commands.NonReadyConditionReason(source.Status.Conditions)
|
||||
|
||||
var sink string
|
||||
if source.Spec.Sink != nil {
|
||||
if source.Spec.Sink.Ref != nil {
|
||||
if source.Spec.Sink.Ref.Kind == "Service" {
|
||||
sink = fmt.Sprintf("svc:%s", source.Spec.Sink.Ref.Name)
|
||||
} else {
|
||||
sink = fmt.Sprintf("%s:%s", source.Spec.Sink.Ref.Kind, source.Spec.Sink.Ref.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if options.AllNamespaces {
|
||||
row.Cells = append(row.Cells, source.Namespace)
|
||||
}
|
||||
|
||||
row.Cells = append(row.Cells, name, schedule, sink, conditions, ready, reason)
|
||||
return []metav1beta1.TableRow{row}, nil
|
||||
}
|
||||
|
||||
// printSourceList populates the source cronjob list table rows
|
||||
func printSourceList(sourceList *v1alpha1.CronJobSourceList, options hprinters.PrintOptions) ([]metav1beta1.TableRow, error) {
|
||||
if options.AllNamespaces {
|
||||
return printSourceListWithNamespace(sourceList, options)
|
||||
}
|
||||
|
||||
rows := make([]metav1beta1.TableRow, 0, len(sourceList.Items))
|
||||
|
||||
sort.SliceStable(sourceList.Items, func(i, j int) bool {
|
||||
return sourceList.Items[i].GetName() < sourceList.Items[j].GetName()
|
||||
})
|
||||
|
||||
for _, item := range sourceList.Items {
|
||||
row, err := printSource(&item, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rows = append(rows, row...)
|
||||
}
|
||||
return rows, nil
|
||||
}
|
||||
|
||||
// printSourceListWithNamespace populates the knative service table rows with namespace column
|
||||
func printSourceListWithNamespace(sourceList *v1alpha1.CronJobSourceList, options hprinters.PrintOptions) ([]metav1beta1.TableRow, error) {
|
||||
rows := make([]metav1beta1.TableRow, 0, len(sourceList.Items))
|
||||
|
||||
// temporary slice for sorting services in non-default namespace
|
||||
others := []metav1beta1.TableRow{}
|
||||
|
||||
for _, source := range sourceList.Items {
|
||||
// Fill in with services in `default` namespace at first
|
||||
if source.Namespace == "default" {
|
||||
r, err := printSource(&source, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rows = append(rows, r...)
|
||||
continue
|
||||
}
|
||||
// put other services in temporary slice
|
||||
r, err := printSource(&source, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
others = append(others, r...)
|
||||
}
|
||||
|
||||
// sort other services list alphabetically by namespace
|
||||
sort.SliceStable(others, func(i, j int) bool {
|
||||
return others[i].Cells[0].(string) < others[j].Cells[0].(string)
|
||||
})
|
||||
|
||||
return append(rows, others...), nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,74 @@
|
|||
// 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 cronjob
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"knative.dev/client/pkg/kn/commands"
|
||||
"knative.dev/client/pkg/kn/commands/flags"
|
||||
)
|
||||
|
||||
// NewCronJobListCommand is for listing CronJob source COs
|
||||
func NewCronJobListCommand(p *commands.KnParams) *cobra.Command {
|
||||
listFlags := flags.NewListFlags(CronJobSourceListHandlers)
|
||||
|
||||
listCommand := &cobra.Command{
|
||||
Use: "list",
|
||||
Short: "List CronJob sources.",
|
||||
Example: `
|
||||
# List all CronJob sources in YAML format
|
||||
kn source cronjob list -o yaml`,
|
||||
|
||||
RunE: func(cmd *cobra.Command, args []string) (err error) {
|
||||
// TODO: filter list by given source name
|
||||
|
||||
cronSourceClient, err := newCronJobSourceClient(p, cmd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sourceList, err := cronSourceClient.ListCronJobSource()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(sourceList.Items) == 0 {
|
||||
fmt.Fprintf(cmd.OutOrStdout(), "No CronJob source found.\n")
|
||||
return nil
|
||||
}
|
||||
|
||||
if cronSourceClient.Namespace() == "" {
|
||||
listFlags.EnsureWithNamespace()
|
||||
}
|
||||
|
||||
printer, err := listFlags.ToPrinter()
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
err = printer.PrintObj(sourceList, cmd.OutOrStdout())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
}
|
||||
commands.AddNamespaceFlags(listCommand.Flags(), true)
|
||||
listFlags.AddFlags(listCommand)
|
||||
return listCommand
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
// 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 cronjob
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"gotest.tools/assert"
|
||||
|
||||
knsource_v1alpha1 "knative.dev/client/pkg/eventing/sources/v1alpha1"
|
||||
"knative.dev/client/pkg/util"
|
||||
"knative.dev/eventing/pkg/apis/sources/v1alpha1"
|
||||
)
|
||||
|
||||
func TestListCronJobSource(t *testing.T) {
|
||||
cronjobClient := knsource_v1alpha1.NewMockKnCronJobSourceClient(t)
|
||||
|
||||
cronJobRecorder := cronjobClient.Recorder()
|
||||
cJSource := createCronJobSource("testsource", "* * * * */2", "maxwell", "mysvc")
|
||||
cJSourceList := v1alpha1.CronJobSourceList{}
|
||||
cJSourceList.Items = []v1alpha1.CronJobSource{*cJSource}
|
||||
|
||||
cronJobRecorder.ListCronJobSource(&cJSourceList, nil)
|
||||
|
||||
out, err := executeCronJobSourceCommand(cronjobClient, nil, "list")
|
||||
assert.NilError(t, err, "Sources should be listed")
|
||||
util.ContainsAll(out, "NAME", "SCHEDULE", "SINK", "CONDITIONS", "READY", "REASON")
|
||||
util.ContainsAll(out, "testsource", "* * * * */2", "mysvc")
|
||||
|
||||
cronJobRecorder.Validate()
|
||||
}
|
||||
|
||||
func TestListCronJobSourceEmpty(t *testing.T) {
|
||||
cronjobClient := knsource_v1alpha1.NewMockKnCronJobSourceClient(t)
|
||||
|
||||
cronJobRecorder := cronjobClient.Recorder()
|
||||
cJSourceList := v1alpha1.CronJobSourceList{}
|
||||
|
||||
cronJobRecorder.ListCronJobSource(&cJSourceList, nil)
|
||||
|
||||
out, err := executeCronJobSourceCommand(cronjobClient, nil, "list")
|
||||
assert.NilError(t, err, "Sources should be listed")
|
||||
util.ContainsNone(out, "NAME", "SCHEDULE", "SINK", "CONDITIONS", "READY", "REASON")
|
||||
util.ContainsAll(out, "No", "CronJob", "source", "found")
|
||||
|
||||
cronJobRecorder.Validate()
|
||||
}
|
||||
Loading…
Reference in New Issue