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.
|
||||
type Describer interface {
|
||||
// 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"`
|
||||
Image string `json:"image" yaml:"image"`
|
||||
Namespace string `json:"namespace" yaml:"namespace"`
|
||||
|
@ -549,9 +549,9 @@ func (c *Client) List(ctx context.Context) ([]ListItem, error) {
|
|||
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.
|
||||
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() {
|
||||
<-ctx.Done()
|
||||
c.progressListener.Stopping()
|
||||
|
|
|
@ -124,7 +124,7 @@ func endpoint(ctx context.Context, cfg emitConfig) (url string, err error) {
|
|||
var (
|
||||
f fn.Function
|
||||
d fn.Describer
|
||||
desc fn.Description
|
||||
i fn.Info
|
||||
)
|
||||
|
||||
// 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.
|
||||
if desc, err = d.Describe(ctx, f.Name); err != nil {
|
||||
if i, err = d.Describe(ctx, f.Name); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Probably wise to be defensive here:
|
||||
if len(desc.Routes) == 0 {
|
||||
if len(i.Routes) == 0 {
|
||||
err = errors.New("function has no active routes")
|
||||
return
|
||||
}
|
||||
|
||||
// The first route should be the destination.
|
||||
return desc.Routes[0], nil
|
||||
return i.Routes[0], nil
|
||||
}
|
||||
|
||||
type emitConfig struct {
|
||||
|
|
|
@ -16,10 +16,10 @@ import (
|
|||
)
|
||||
|
||||
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)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -33,11 +33,11 @@ func newDescribeClient(cfg describeConfig) (*fn.Client, error) {
|
|||
), 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{
|
||||
Use: "describe <name>",
|
||||
Use: "info <name>",
|
||||
Short: "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: `
|
||||
# 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
|
||||
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,
|
||||
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 {
|
||||
return runDescribe(cmd, args, clientFn)
|
||||
return runInfo(cmd, args, clientFn)
|
||||
}
|
||||
|
||||
return cmd
|
||||
}
|
||||
|
||||
func runDescribe(cmd *cobra.Command, args []string, clientFn describeClientFn) (err error) {
|
||||
config := newDescribeConfig(args)
|
||||
func runInfo(cmd *cobra.Command, args []string, clientFn infoClientFn) (err error) {
|
||||
config := newInfoConfig(args)
|
||||
|
||||
function, err := fn.NewFunction(config.Path)
|
||||
if err != nil {
|
||||
|
@ -91,20 +91,20 @@ func runDescribe(cmd *cobra.Command, args []string, clientFn describeClientFn) (
|
|||
}
|
||||
|
||||
// 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 {
|
||||
return
|
||||
}
|
||||
d.Image = function.Image
|
||||
|
||||
write(os.Stdout, description(d), config.Output)
|
||||
write(os.Stdout, info(d), config.Output)
|
||||
return
|
||||
}
|
||||
|
||||
// CLI Configuration (parameters)
|
||||
// ------------------------------
|
||||
|
||||
type describeConfig struct {
|
||||
type infoConfig struct {
|
||||
Name string
|
||||
Namespace string
|
||||
Output string
|
||||
|
@ -112,12 +112,12 @@ type describeConfig struct {
|
|||
Verbose bool
|
||||
}
|
||||
|
||||
func newDescribeConfig(args []string) describeConfig {
|
||||
func newInfoConfig(args []string) infoConfig {
|
||||
var name string
|
||||
if len(args) > 0 {
|
||||
name = args[0]
|
||||
}
|
||||
return describeConfig{
|
||||
return infoConfig{
|
||||
Name: deriveName(name, viper.GetString("path")),
|
||||
Namespace: viper.GetString("namespace"),
|
||||
Output: viper.GetString("output"),
|
||||
|
@ -129,62 +129,62 @@ func newDescribeConfig(args []string) describeConfig {
|
|||
// 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.Fprintf(w, " %v\n", d.Name)
|
||||
fmt.Fprintf(w, " %v\n", i.Name)
|
||||
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.Fprintf(w, " %v\n", d.Namespace)
|
||||
fmt.Fprintf(w, " %v\n", i.Namespace)
|
||||
fmt.Fprintln(w, "Routes:")
|
||||
|
||||
for _, route := range d.Routes {
|
||||
for _, route := range i.Routes {
|
||||
fmt.Fprintf(w, " %v\n", route)
|
||||
}
|
||||
|
||||
if len(d.Subscriptions) > 0 {
|
||||
if len(i.Subscriptions) > 0 {
|
||||
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)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d description) Plain(w io.Writer) error {
|
||||
fmt.Fprintf(w, "Name %v\n", d.Name)
|
||||
fmt.Fprintf(w, "Image %v\n", d.Image)
|
||||
fmt.Fprintf(w, "Namespace %v\n", d.Namespace)
|
||||
func (i info) Plain(w io.Writer) error {
|
||||
fmt.Fprintf(w, "Name %v\n", i.Name)
|
||||
fmt.Fprintf(w, "Image %v\n", i.Image)
|
||||
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)
|
||||
}
|
||||
|
||||
if len(d.Subscriptions) > 0 {
|
||||
for _, s := range d.Subscriptions {
|
||||
if len(i.Subscriptions) > 0 {
|
||||
for _, s := range i.Subscriptions {
|
||||
fmt.Fprintf(w, "Subscription %v %v %v\n", s.Source, s.Type, s.Broker)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d description) JSON(w io.Writer) error {
|
||||
return json.NewEncoder(w).Encode(d)
|
||||
func (i info) JSON(w io.Writer) error {
|
||||
return json.NewEncoder(w).Encode(i)
|
||||
}
|
||||
|
||||
func (d description) XML(w io.Writer) error {
|
||||
return xml.NewEncoder(w).Encode(d)
|
||||
func (i info) XML(w io.Writer) error {
|
||||
return xml.NewEncoder(w).Encode(i)
|
||||
}
|
||||
|
||||
func (d description) YAML(w io.Writer) error {
|
||||
return yaml.NewEncoder(w).Encode(d)
|
||||
func (i info) YAML(w io.Writer) error {
|
||||
return yaml.NewEncoder(w).Encode(i)
|
||||
}
|
||||
|
||||
func (d description) URL(w io.Writer) error {
|
||||
if len(d.Routes) > 0 {
|
||||
fmt.Fprintf(w, "%s\n", d.Routes[0])
|
||||
func (i info) URL(w io.Writer) error {
|
||||
if len(i.Routes) > 0 {
|
||||
fmt.Fprintf(w, "%s\n", i.Routes[0])
|
||||
}
|
||||
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]
|
||||
```
|
||||
|
||||
## `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`.
|
||||
|
||||
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
|
||||
func describe [-o <output> -n <namespace> -p <path>]
|
||||
func info [-o <output> -n <namespace> -p <path>]
|
||||
```
|
||||
|
||||
When run as a `kn` plugin.
|
||||
|
||||
```console
|
||||
kn func describe [-o <output> -n <namespace> -p <path>]
|
||||
kn func info [-o <output> -n <namespace> -p <path>]
|
||||
```
|
||||
|
||||
## `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
|
||||
// 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
|
||||
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)
|
||||
if err != nil {
|
||||
|
|
|
@ -5,10 +5,10 @@ import (
|
|||
"testing"
|
||||
)
|
||||
|
||||
// Describe runs `func describe' command basic test.
|
||||
func Describe(t *testing.T, knFunc *TestShellCmdRunner, project *FunctionTestProject) {
|
||||
// Info runs `func info' command basic test.
|
||||
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 {
|
||||
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)
|
||||
// we compare just to verify they match
|
||||
// otherwise we take advantage and capture the route from the output
|
||||
routeFromDescribe := ""
|
||||
routeFromInfo := ""
|
||||
|
||||
matches := regexp.MustCompile("Route (http.*)").FindStringSubmatch(result.Stdout)
|
||||
if len(matches) > 1 {
|
||||
routeFromDescribe = matches[1]
|
||||
routeFromInfo = matches[1]
|
||||
}
|
||||
if routeFromDescribe == "" {
|
||||
if routeFromInfo == "" {
|
||||
t.Fatal("Function Route not present on output")
|
||||
}
|
||||
if project.FunctionURL != "" && project.FunctionURL != routeFromDescribe {
|
||||
t.Fatalf("Expected Route %v but found %v", project.FunctionURL, routeFromDescribe)
|
||||
if project.FunctionURL != "" && project.FunctionURL != routeFromInfo {
|
||||
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)
|
||||
defer Delete(t, knFunc, &project)
|
||||
ReadyCheck(t, knFunc, project)
|
||||
Describe(t, knFunc, &project)
|
||||
Info(t, knFunc, &project)
|
||||
DefaultFunctionHttpTest(t, knFunc, project)
|
||||
Update(t, knFunc, &project)
|
||||
NewRevisionFunctionHttpTest(t, knFunc, project)
|
||||
|
@ -40,8 +40,7 @@ func TestCloudEventsFunction(t *testing.T) {
|
|||
Deploy(t, knFunc, &project)
|
||||
defer Delete(t, knFunc, &project)
|
||||
ReadyCheck(t, knFunc, project)
|
||||
Describe(t, knFunc, &project)
|
||||
Info(t, knFunc, &project)
|
||||
DefaultFunctionEventsTest(t, knFunc, project)
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue