feat: adds a `func environment` command (#1761)

* feat: adds a `func environment` command

Adds `func environment` to print the current function execution
environment as JSON.

See: https://github.com/knative/func/discussions/1676

Signed-off-by: Lance Ball <lball@redhat.com>

* fixup

Signed-off-by: Lance Ball <lball@redhat.com>

* fixup: add environment variables

Signed-off-by: Lance Ball <lball@redhat.com>

* fixup: add cluster host

Signed-off-by: Lance Ball <lball@redhat.com>

* fixup: review feedback

Signed-off-by: Lance Ball <lball@redhat.com>

---------

Signed-off-by: Lance Ball <lball@redhat.com>
This commit is contained in:
Lance Ball 2023-05-31 08:36:35 -04:00 committed by GitHub
parent 4dad8aaf7a
commit fea4a72734
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 199 additions and 0 deletions

163
cmd/environment.go Normal file
View File

@ -0,0 +1,163 @@
package cmd
import (
"encoding/json"
"fmt"
"os"
"strings"
"github.com/ory/viper"
"github.com/spf13/cobra"
"knative.dev/func/pkg/config"
"knative.dev/func/pkg/functions"
"knative.dev/func/pkg/k8s"
)
func NewEnvironmentCmd(newClient ClientFactory, version *Version) *cobra.Command {
cmd := &cobra.Command{
Use: "environment",
Short: "Display function execution environment information",
Long: `
NAME
{{rootCmdUse}} environment
SYNOPSIS
{{rootCmdUse}} environment - display function execution environment information
DESCRIPTION
Display information about the function execution environment, including
the version of func, the version of the function spec, the default builder,
available runtimes, and available templates.
`,
SuggestFor: []string{"env", "environemtn", "enviroment", "enviornment", "enviroment"},
RunE: func(cmd *cobra.Command, args []string) error {
return runEnvironment(cmd, newClient, version)
},
}
cfg, err := config.NewDefault()
if err != nil {
fmt.Fprintf(cmd.OutOrStdout(), "error loading config at '%v'. %v\n", config.File(), err)
}
addVerboseFlag(cmd, cfg.Verbose)
return cmd
}
type Environment struct {
Version string
GitRevision string
BuildDate string
SpecVersion string
SocatImage string
TarImage string
Languages []string
Templates map[string][]string
Environment []string
Cluster string
Defaults config.Global
}
func runEnvironment(cmd *cobra.Command, newClient ClientFactory, v *Version) (err error) {
cfg, err := newEnvironmentConfig()
if err != nil {
return
}
// Create a client to get runtimes and templates
client := functions.New(functions.WithVerbose(cfg.Verbose))
r, err := getRuntimes(client)
if err != nil {
return
}
t, err := getTemplates(client, r)
if err != nil {
return
}
// Get all environment variables that start with FUNC_
var envs []string
for _, e := range os.Environ() {
if strings.HasPrefix(e, "FUNC_") {
envs = append(envs, e)
}
}
// If no environment variables are set, make sure we return an empty array
// otherwise the output is "null" instead of "[]"
if len(envs) == 0 {
envs = make([]string, 0)
}
// Get global defaults
defaults, err := config.NewDefault()
if err != nil {
return
}
// Gets the cluster host
var host string
cc, err := k8s.GetClientConfig().ClientConfig()
if err != nil {
fmt.Printf("error getting client config %v\n", err)
} else {
host = cc.Host
}
environment := Environment{
Version: v.String(),
GitRevision: v.Hash,
BuildDate: v.Date,
SpecVersion: functions.LastSpecVersion(),
SocatImage: k8s.SocatImage,
TarImage: k8s.TarImage,
Languages: r,
Templates: t,
Environment: envs,
Cluster: host,
Defaults: defaults,
}
if s, err := json.MarshalIndent(environment, "", " "); err != nil {
return err
} else {
fmt.Fprintln(cmd.OutOrStdout(), string(s))
}
return nil
}
func getRuntimes(client *functions.Client) ([]string, error) {
runtimes, err := client.Runtimes()
if err != nil {
return nil, err
}
return runtimes, nil
}
func getTemplates(client *functions.Client, runtimes []string) (map[string][]string, error) {
templateMap := make(map[string][]string)
for _, runtime := range runtimes {
templates, err := client.Templates().List(runtime)
if err != nil {
return nil, err
}
templateMap[runtime] = templates
}
return templateMap, nil
}
type environmentConfig struct {
Verbose bool
// TODO: add format (e.g. JSON/YAML)
}
func newEnvironmentConfig() (cfg environmentConfig, err error) {
cfg = environmentConfig{
Verbose: viper.GetBool("verbose"),
}
return
}

View File

@ -90,6 +90,7 @@ Learn more about Knative at: https://knative.dev`, cfg.Name),
NewLanguagesCmd(newClient),
NewTemplatesCmd(newClient),
NewRepositoryCmd(newClient),
NewEnvironmentCmd(newClient, &cfg.Version),
},
},
{

View File

@ -30,6 +30,7 @@ Learn more about Knative at: https://knative.dev
* [func delete](func_delete.md) - Undeploy a function
* [func deploy](func_deploy.md) - Deploy a function
* [func describe](func_describe.md) - Describe a function
* [func environment](func_environment.md) - Display function execution environment information
* [func invoke](func_invoke.md) - Invoke a local or remote function
* [func languages](func_languages.md) - List available function language runtimes
* [func list](func_list.md) - List deployed functions

View File

@ -0,0 +1,34 @@
## func environment
Display function execution environment information
### Synopsis
NAME
func environment
SYNOPSIS
func environment - display function execution environment information
DESCRIPTION
Display information about the function execution environment, including
the version of func, the version of the function spec, the default builder,
available runtimes, and available templates.
```
func environment
```
### Options
```
-h, --help help for environment
-v, --verbose Print verbose logs ($FUNC_VERBOSE)
```
### SEE ALSO
* [func](func.md) - func manages Knative Functions