mirror of https://github.com/knative/func.git
feat!: change `describe` command to `info` (#474)
The describe command conflicts sematically with kubectl describe. This commit changes the command name to `info`. Fixes: https://github.com/knative-sandbox/kn-plugin-func/issues/337 Signed-off-by: Lance Ball <lball@redhat.com>
This commit is contained in:
parent
c8875938d7
commit
10a07578e9
|
@ -126,10 +126,10 @@ type ProgressListener interface {
|
||||||
// Describer of Functions' remote deployed aspect.
|
// Describer of Functions' remote deployed aspect.
|
||||||
type Describer interface {
|
type Describer interface {
|
||||||
// Describe the running state of the service as reported by the underlyng platform.
|
// Describe the running state of the service as reported by the underlyng platform.
|
||||||
Describe(ctx context.Context, name string) (description Description, err error)
|
Describe(ctx context.Context, name string) (description Info, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Description struct {
|
type Info struct {
|
||||||
Name string `json:"name" yaml:"name"`
|
Name string `json:"name" yaml:"name"`
|
||||||
Image string `json:"image" yaml:"image"`
|
Image string `json:"image" yaml:"image"`
|
||||||
Namespace string `json:"namespace" yaml:"namespace"`
|
Namespace string `json:"namespace" yaml:"namespace"`
|
||||||
|
@ -549,9 +549,9 @@ func (c *Client) List(ctx context.Context) ([]ListItem, error) {
|
||||||
return c.lister.List(ctx)
|
return c.lister.List(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Describe a Function. Name takes precidence. If no name is provided,
|
// Info for a Function. Name takes precidence. If no name is provided,
|
||||||
// the Function defined at root is used.
|
// the Function defined at root is used.
|
||||||
func (c *Client) Describe(ctx context.Context, name, root string) (d Description, err error) {
|
func (c *Client) Info(ctx context.Context, name, root string) (d Info, err error) {
|
||||||
go func() {
|
go func() {
|
||||||
<-ctx.Done()
|
<-ctx.Done()
|
||||||
c.progressListener.Stopping()
|
c.progressListener.Stopping()
|
||||||
|
|
12
cmd/emit.go
12
cmd/emit.go
|
@ -122,9 +122,9 @@ func runEmit(cmd *cobra.Command, _ []string, clientFn emitClientFn) (err error)
|
||||||
// Otherwise the value of Sink is used verbatim if defined.
|
// Otherwise the value of Sink is used verbatim if defined.
|
||||||
func endpoint(ctx context.Context, cfg emitConfig) (url string, err error) {
|
func endpoint(ctx context.Context, cfg emitConfig) (url string, err error) {
|
||||||
var (
|
var (
|
||||||
f fn.Function
|
f fn.Function
|
||||||
d fn.Describer
|
d fn.Describer
|
||||||
desc fn.Description
|
i fn.Info
|
||||||
)
|
)
|
||||||
|
|
||||||
// If the special value "local" was requested,
|
// If the special value "local" was requested,
|
||||||
|
@ -151,18 +151,18 @@ func endpoint(ctx context.Context, cfg emitConfig) (url string, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the current state of the function.
|
// Get the current state of the function.
|
||||||
if desc, err = d.Describe(ctx, f.Name); err != nil {
|
if i, err = d.Describe(ctx, f.Name); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Probably wise to be defensive here:
|
// Probably wise to be defensive here:
|
||||||
if len(desc.Routes) == 0 {
|
if len(i.Routes) == 0 {
|
||||||
err = errors.New("function has no active routes")
|
err = errors.New("function has no active routes")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// The first route should be the destination.
|
// The first route should be the destination.
|
||||||
return desc.Routes[0], nil
|
return i.Routes[0], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type emitConfig struct {
|
type emitConfig struct {
|
||||||
|
|
|
@ -16,10 +16,10 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
root.AddCommand(NewDescribeCmd(newDescribeClient))
|
root.AddCommand(NewInfoCmd(newInfoClient))
|
||||||
}
|
}
|
||||||
|
|
||||||
func newDescribeClient(cfg describeConfig) (*fn.Client, error) {
|
func newInfoClient(cfg infoConfig) (*fn.Client, error) {
|
||||||
describer, err := knative.NewDescriber(cfg.Namespace)
|
describer, err := knative.NewDescriber(cfg.Namespace)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -33,11 +33,11 @@ func newDescribeClient(cfg describeConfig) (*fn.Client, error) {
|
||||||
), nil
|
), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type describeClientFn func(describeConfig) (*fn.Client, error)
|
type infoClientFn func(infoConfig) (*fn.Client, error)
|
||||||
|
|
||||||
func NewDescribeCmd(clientFn describeClientFn) *cobra.Command {
|
func NewInfoCmd(clientFn infoClientFn) *cobra.Command {
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "describe <name>",
|
Use: "info <name>",
|
||||||
Short: "Show details of a function",
|
Short: "Show details of a function",
|
||||||
Long: `Show details of a function
|
Long: `Show details of a function
|
||||||
|
|
||||||
|
@ -46,12 +46,12 @@ the current directory or from the directory specified with --path.
|
||||||
`,
|
`,
|
||||||
Example: `
|
Example: `
|
||||||
# Show the details of a function as declared in the local func.yaml
|
# Show the details of a function as declared in the local func.yaml
|
||||||
kn func describe
|
kn func info
|
||||||
|
|
||||||
# Show the details of the function in the myotherfunc directory with yaml output
|
# Show the details of the function in the myotherfunc directory with yaml output
|
||||||
kn func describe --output yaml --path myotherfunc
|
kn func info --output yaml --path myotherfunc
|
||||||
`,
|
`,
|
||||||
SuggestFor: []string{"desc", "get"},
|
SuggestFor: []string{"ifno", "describe", "fino", "get"},
|
||||||
ValidArgsFunction: CompleteFunctionList,
|
ValidArgsFunction: CompleteFunctionList,
|
||||||
PreRunE: bindEnv("namespace", "output", "path"),
|
PreRunE: bindEnv("namespace", "output", "path"),
|
||||||
}
|
}
|
||||||
|
@ -65,14 +65,14 @@ kn func describe --output yaml --path myotherfunc
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.RunE = func(cmd *cobra.Command, args []string) error {
|
cmd.RunE = func(cmd *cobra.Command, args []string) error {
|
||||||
return runDescribe(cmd, args, clientFn)
|
return runInfo(cmd, args, clientFn)
|
||||||
}
|
}
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func runDescribe(cmd *cobra.Command, args []string, clientFn describeClientFn) (err error) {
|
func runInfo(cmd *cobra.Command, args []string, clientFn infoClientFn) (err error) {
|
||||||
config := newDescribeConfig(args)
|
config := newInfoConfig(args)
|
||||||
|
|
||||||
function, err := fn.NewFunction(config.Path)
|
function, err := fn.NewFunction(config.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -91,20 +91,20 @@ func runDescribe(cmd *cobra.Command, args []string, clientFn describeClientFn) (
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the description
|
// Get the description
|
||||||
d, err := client.Describe(cmd.Context(), config.Name, config.Path)
|
d, err := client.Info(cmd.Context(), config.Name, config.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
d.Image = function.Image
|
d.Image = function.Image
|
||||||
|
|
||||||
write(os.Stdout, description(d), config.Output)
|
write(os.Stdout, info(d), config.Output)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// CLI Configuration (parameters)
|
// CLI Configuration (parameters)
|
||||||
// ------------------------------
|
// ------------------------------
|
||||||
|
|
||||||
type describeConfig struct {
|
type infoConfig struct {
|
||||||
Name string
|
Name string
|
||||||
Namespace string
|
Namespace string
|
||||||
Output string
|
Output string
|
||||||
|
@ -112,12 +112,12 @@ type describeConfig struct {
|
||||||
Verbose bool
|
Verbose bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func newDescribeConfig(args []string) describeConfig {
|
func newInfoConfig(args []string) infoConfig {
|
||||||
var name string
|
var name string
|
||||||
if len(args) > 0 {
|
if len(args) > 0 {
|
||||||
name = args[0]
|
name = args[0]
|
||||||
}
|
}
|
||||||
return describeConfig{
|
return infoConfig{
|
||||||
Name: deriveName(name, viper.GetString("path")),
|
Name: deriveName(name, viper.GetString("path")),
|
||||||
Namespace: viper.GetString("namespace"),
|
Namespace: viper.GetString("namespace"),
|
||||||
Output: viper.GetString("output"),
|
Output: viper.GetString("output"),
|
||||||
|
@ -129,62 +129,62 @@ func newDescribeConfig(args []string) describeConfig {
|
||||||
// Output Formatting (serializers)
|
// Output Formatting (serializers)
|
||||||
// -------------------------------
|
// -------------------------------
|
||||||
|
|
||||||
type description fn.Description
|
type info fn.Info
|
||||||
|
|
||||||
func (d description) Human(w io.Writer) error {
|
func (i info) Human(w io.Writer) error {
|
||||||
fmt.Fprintln(w, "Function name:")
|
fmt.Fprintln(w, "Function name:")
|
||||||
fmt.Fprintf(w, " %v\n", d.Name)
|
fmt.Fprintf(w, " %v\n", i.Name)
|
||||||
fmt.Fprintln(w, "Function is built in image:")
|
fmt.Fprintln(w, "Function is built in image:")
|
||||||
fmt.Fprintf(w, " %v\n", d.Image)
|
fmt.Fprintf(w, " %v\n", i.Image)
|
||||||
fmt.Fprintln(w, "Function is deployed in namespace:")
|
fmt.Fprintln(w, "Function is deployed in namespace:")
|
||||||
fmt.Fprintf(w, " %v\n", d.Namespace)
|
fmt.Fprintf(w, " %v\n", i.Namespace)
|
||||||
fmt.Fprintln(w, "Routes:")
|
fmt.Fprintln(w, "Routes:")
|
||||||
|
|
||||||
for _, route := range d.Routes {
|
for _, route := range i.Routes {
|
||||||
fmt.Fprintf(w, " %v\n", route)
|
fmt.Fprintf(w, " %v\n", route)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(d.Subscriptions) > 0 {
|
if len(i.Subscriptions) > 0 {
|
||||||
fmt.Fprintln(w, "Subscriptions (Source, Type, Broker):")
|
fmt.Fprintln(w, "Subscriptions (Source, Type, Broker):")
|
||||||
for _, s := range d.Subscriptions {
|
for _, s := range i.Subscriptions {
|
||||||
fmt.Fprintf(w, " %v %v %v\n", s.Source, s.Type, s.Broker)
|
fmt.Fprintf(w, " %v %v %v\n", s.Source, s.Type, s.Broker)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d description) Plain(w io.Writer) error {
|
func (i info) Plain(w io.Writer) error {
|
||||||
fmt.Fprintf(w, "Name %v\n", d.Name)
|
fmt.Fprintf(w, "Name %v\n", i.Name)
|
||||||
fmt.Fprintf(w, "Image %v\n", d.Image)
|
fmt.Fprintf(w, "Image %v\n", i.Image)
|
||||||
fmt.Fprintf(w, "Namespace %v\n", d.Namespace)
|
fmt.Fprintf(w, "Namespace %v\n", i.Namespace)
|
||||||
|
|
||||||
for _, route := range d.Routes {
|
for _, route := range i.Routes {
|
||||||
fmt.Fprintf(w, "Route %v\n", route)
|
fmt.Fprintf(w, "Route %v\n", route)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(d.Subscriptions) > 0 {
|
if len(i.Subscriptions) > 0 {
|
||||||
for _, s := range d.Subscriptions {
|
for _, s := range i.Subscriptions {
|
||||||
fmt.Fprintf(w, "Subscription %v %v %v\n", s.Source, s.Type, s.Broker)
|
fmt.Fprintf(w, "Subscription %v %v %v\n", s.Source, s.Type, s.Broker)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d description) JSON(w io.Writer) error {
|
func (i info) JSON(w io.Writer) error {
|
||||||
return json.NewEncoder(w).Encode(d)
|
return json.NewEncoder(w).Encode(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d description) XML(w io.Writer) error {
|
func (i info) XML(w io.Writer) error {
|
||||||
return xml.NewEncoder(w).Encode(d)
|
return xml.NewEncoder(w).Encode(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d description) YAML(w io.Writer) error {
|
func (i info) YAML(w io.Writer) error {
|
||||||
return yaml.NewEncoder(w).Encode(d)
|
return yaml.NewEncoder(w).Encode(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d description) URL(w io.Writer) error {
|
func (i info) URL(w io.Writer) error {
|
||||||
if len(d.Routes) > 0 {
|
if len(i.Routes) > 0 {
|
||||||
fmt.Fprintf(w, "%s\n", d.Routes[0])
|
fmt.Fprintf(w, "%s\n", i.Routes[0])
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
|
@ -79,20 +79,20 @@ When run as a `kn` plugin.
|
||||||
kn func deploy [-n <namespace> -p <path> -i <image> -r <registry> -b=true|false]
|
kn func deploy [-n <namespace> -p <path> -i <image> -r <registry> -b=true|false]
|
||||||
```
|
```
|
||||||
|
|
||||||
## `describe`
|
## `info`
|
||||||
|
|
||||||
Prints the name, route and any event subscriptions for a deployed Function. The user may also specify the name of the function to describe. The namespace defaults to the value in `func.yaml` or the namespace currently active in the user's Kubernetes configuration. The namespace may be specified on the command line, and if so this will overwrite the value in `func.yaml`.
|
Prints the name, route and any event subscriptions for a deployed Function. The user may also specify the name of the function to describe. The namespace defaults to the value in `func.yaml` or the namespace currently active in the user's Kubernetes configuration. The namespace may be specified on the command line, and if so this will overwrite the value in `func.yaml`.
|
||||||
|
|
||||||
Similar `kn` command: `kn service describe NAME [flags]`. This flag provides a lot of nice information not available in `func describe`, such as revisions, age, annotations and labels. This command should be renamed to make it distinct from `kn` - e.g. `func status`.
|
Similar `kn` command: `kn service describe NAME [flags]`. This flag provides a lot of nice information not available in `func info`, such as revisions, age, annotations and labels.
|
||||||
|
|
||||||
```console
|
```console
|
||||||
func describe [-o <output> -n <namespace> -p <path>]
|
func info [-o <output> -n <namespace> -p <path>]
|
||||||
```
|
```
|
||||||
|
|
||||||
When run as a `kn` plugin.
|
When run as a `kn` plugin.
|
||||||
|
|
||||||
```console
|
```console
|
||||||
kn func describe [-o <output> -n <namespace> -p <path>]
|
kn func info [-o <output> -n <namespace> -p <path>]
|
||||||
```
|
```
|
||||||
|
|
||||||
## `list`
|
## `list`
|
||||||
|
|
|
@ -31,7 +31,7 @@ func NewDescriber(namespaceOverride string) (describer *Describer, err error) {
|
||||||
// restricts to label-syntax, which is thus escaped. Therefore as a knative (kube) implementation
|
// restricts to label-syntax, which is thus escaped. Therefore as a knative (kube) implementation
|
||||||
// detal proper full names have to be escaped on the way in and unescaped on the way out. ex:
|
// detal proper full names have to be escaped on the way in and unescaped on the way out. ex:
|
||||||
// www.example-site.com -> www-example--site-com
|
// www.example-site.com -> www-example--site-com
|
||||||
func (d *Describer) Describe(ctx context.Context, name string) (description fn.Description, err error) {
|
func (d *Describer) Describe(ctx context.Context, name string) (description fn.Info, err error) {
|
||||||
|
|
||||||
servingClient, err := NewServingClient(d.namespace)
|
servingClient, err := NewServingClient(d.namespace)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -5,10 +5,10 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Describe runs `func describe' command basic test.
|
// Info runs `func info' command basic test.
|
||||||
func Describe(t *testing.T, knFunc *TestShellCmdRunner, project *FunctionTestProject) {
|
func Info(t *testing.T, knFunc *TestShellCmdRunner, project *FunctionTestProject) {
|
||||||
|
|
||||||
result := knFunc.Exec("describe", "--path", project.ProjectPath, "--output", "plain")
|
result := knFunc.Exec("info", "--path", project.ProjectPath, "--output", "plain")
|
||||||
if result.Error != nil {
|
if result.Error != nil {
|
||||||
t.Fail()
|
t.Fail()
|
||||||
}
|
}
|
||||||
|
@ -17,18 +17,18 @@ func Describe(t *testing.T, knFunc *TestShellCmdRunner, project *FunctionTestPro
|
||||||
// In case we have the route stored (i.e. by deploy command tested earlier)
|
// In case we have the route stored (i.e. by deploy command tested earlier)
|
||||||
// we compare just to verify they match
|
// we compare just to verify they match
|
||||||
// otherwise we take advantage and capture the route from the output
|
// otherwise we take advantage and capture the route from the output
|
||||||
routeFromDescribe := ""
|
routeFromInfo := ""
|
||||||
|
|
||||||
matches := regexp.MustCompile("Route (http.*)").FindStringSubmatch(result.Stdout)
|
matches := regexp.MustCompile("Route (http.*)").FindStringSubmatch(result.Stdout)
|
||||||
if len(matches) > 1 {
|
if len(matches) > 1 {
|
||||||
routeFromDescribe = matches[1]
|
routeFromInfo = matches[1]
|
||||||
}
|
}
|
||||||
if routeFromDescribe == "" {
|
if routeFromInfo == "" {
|
||||||
t.Fatal("Function Route not present on output")
|
t.Fatal("Function Route not present on output")
|
||||||
}
|
}
|
||||||
if project.FunctionURL != "" && project.FunctionURL != routeFromDescribe {
|
if project.FunctionURL != "" && project.FunctionURL != routeFromInfo {
|
||||||
t.Fatalf("Expected Route %v but found %v", project.FunctionURL, routeFromDescribe)
|
t.Fatalf("Expected Route %v but found %v", project.FunctionURL, routeFromInfo)
|
||||||
}
|
}
|
||||||
project.FunctionURL = routeFromDescribe
|
project.FunctionURL = routeFromInfo
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ func TestHttpFunction(t *testing.T) {
|
||||||
Deploy(t, knFunc, &project)
|
Deploy(t, knFunc, &project)
|
||||||
defer Delete(t, knFunc, &project)
|
defer Delete(t, knFunc, &project)
|
||||||
ReadyCheck(t, knFunc, project)
|
ReadyCheck(t, knFunc, project)
|
||||||
Describe(t, knFunc, &project)
|
Info(t, knFunc, &project)
|
||||||
DefaultFunctionHttpTest(t, knFunc, project)
|
DefaultFunctionHttpTest(t, knFunc, project)
|
||||||
Update(t, knFunc, &project)
|
Update(t, knFunc, &project)
|
||||||
NewRevisionFunctionHttpTest(t, knFunc, project)
|
NewRevisionFunctionHttpTest(t, knFunc, project)
|
||||||
|
@ -40,8 +40,7 @@ func TestCloudEventsFunction(t *testing.T) {
|
||||||
Deploy(t, knFunc, &project)
|
Deploy(t, knFunc, &project)
|
||||||
defer Delete(t, knFunc, &project)
|
defer Delete(t, knFunc, &project)
|
||||||
ReadyCheck(t, knFunc, project)
|
ReadyCheck(t, knFunc, project)
|
||||||
Describe(t, knFunc, &project)
|
Info(t, knFunc, &project)
|
||||||
DefaultFunctionEventsTest(t, knFunc, project)
|
DefaultFunctionEventsTest(t, knFunc, project)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue