mirror of https://github.com/knative/func.git
feat: `func config volumes` - interactive prompt (#391)
Signed-off-by: Zbynek Roubalik <zroubali@redhat.com>
This commit is contained in:
parent
6e8517c023
commit
4ba95b69a8
|
@ -0,0 +1,124 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/AlecAivazis/survey/v2/terminal"
|
||||
"github.com/ory/viper"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
bosonFunc "github.com/boson-project/func"
|
||||
)
|
||||
|
||||
func init() {
|
||||
root.AddCommand(configCmd)
|
||||
configCmd.Flags().StringP("path", "p", cwd(), "Path to the project directory (Env: $FUNC_PATH)")
|
||||
}
|
||||
|
||||
var configCmd = &cobra.Command{
|
||||
Use: "config",
|
||||
Short: "Configure a function",
|
||||
Long: `Configure a function
|
||||
|
||||
Interactive propmt that allows configuration of Volume mounts and Environment variables for a function
|
||||
project present in the current directory or from the directory specified with --path.
|
||||
`,
|
||||
SuggestFor: []string{"cfg", "cofnig"},
|
||||
PreRunE: bindEnv("path"),
|
||||
RunE: runConfigCmd,
|
||||
}
|
||||
|
||||
func runConfigCmd(cmd *cobra.Command, args []string) (err error) {
|
||||
|
||||
function, err := initConfigCommand(args)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var qs = []*survey.Question{
|
||||
{
|
||||
Name: "selectedConfig",
|
||||
Prompt: &survey.Select{
|
||||
Message: "What do you want to configure?",
|
||||
Options: []string{"Environment values", "Volumes"},
|
||||
Default: "Environment values",
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "selectedOperation",
|
||||
Prompt: &survey.Select{
|
||||
Message: "What operation do you want to perform?",
|
||||
Options: []string{"Add", "Remove", "List"},
|
||||
Default: "List",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
answers := struct {
|
||||
SelectedConfig string
|
||||
SelectedOperation string
|
||||
}{}
|
||||
|
||||
err = survey.Ask(qs, &answers)
|
||||
if err != nil {
|
||||
if err == terminal.InterruptErr {
|
||||
return nil
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
switch answers.SelectedOperation {
|
||||
case "Add":
|
||||
if answers.SelectedConfig == "Volumes" {
|
||||
err = runAddVolumesPrompt(cmd.Context(), function)
|
||||
}
|
||||
case "Remove":
|
||||
if answers.SelectedConfig == "Volumes" {
|
||||
err = runRemoveVolumesPrompt(function)
|
||||
}
|
||||
case "List":
|
||||
if answers.SelectedConfig == "Volumes" {
|
||||
listVolumes(function)
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// CLI Configuration (parameters)
|
||||
// ------------------------------
|
||||
|
||||
type configCmdConfig struct {
|
||||
Name string
|
||||
Path string
|
||||
Verbose bool
|
||||
}
|
||||
|
||||
func newConfigCmdConfig(args []string) configCmdConfig {
|
||||
var name string
|
||||
if len(args) > 0 {
|
||||
name = args[0]
|
||||
}
|
||||
return configCmdConfig{
|
||||
Name: deriveName(name, viper.GetString("path")),
|
||||
Path: viper.GetString("path"),
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func initConfigCommand(args []string) (bosonFunc.Function, error) {
|
||||
config := newConfigCmdConfig(args)
|
||||
|
||||
function, err := bosonFunc.NewFunction(config.Path)
|
||||
if err != nil {
|
||||
return bosonFunc.Function{}, err
|
||||
}
|
||||
|
||||
// Check if the Function has been initialized
|
||||
if !function.Initialized() {
|
||||
return bosonFunc.Function{}, fmt.Errorf("the given path '%v' does not contain an initialized function", config.Path)
|
||||
}
|
||||
|
||||
return function, nil
|
||||
}
|
|
@ -0,0 +1,247 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/AlecAivazis/survey/v2/terminal"
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
bosonFunc "github.com/boson-project/func"
|
||||
"github.com/boson-project/func/k8s"
|
||||
)
|
||||
|
||||
func init() {
|
||||
configCmd.AddCommand(configVolumesCmd)
|
||||
configVolumesCmd.Flags().StringP("path", "p", cwd(), "Path to the project directory (Env: $FUNC_PATH)")
|
||||
configVolumesCmd.AddCommand(configVolumesAddCmd)
|
||||
configVolumesAddCmd.Flags().StringP("path", "p", cwd(), "Path to the project directory (Env: $FUNC_PATH)")
|
||||
configVolumesCmd.AddCommand(configVolumesRemoveCmd)
|
||||
configVolumesRemoveCmd.Flags().StringP("path", "p", cwd(), "Path to the project directory (Env: $FUNC_PATH)")
|
||||
}
|
||||
|
||||
var configVolumesCmd = &cobra.Command{
|
||||
Use: "volumes",
|
||||
Short: "List and manage configured volumes for a function",
|
||||
Long: `List and manage configured volumes for a function
|
||||
|
||||
Prints configured Volume mounts for a function project present in
|
||||
the current directory or from the directory specified with --path.
|
||||
`,
|
||||
SuggestFor: []string{"volums", "volume", "vols"},
|
||||
PreRunE: bindEnv("path"),
|
||||
RunE: func(cmd *cobra.Command, args []string) (err error) {
|
||||
function, err := initConfigCommand(args)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
listVolumes(function)
|
||||
|
||||
return
|
||||
},
|
||||
}
|
||||
|
||||
var configVolumesAddCmd = &cobra.Command{
|
||||
Use: "add",
|
||||
Short: "Add volume to the function configuration",
|
||||
Long: `Add volume to the function configuration
|
||||
|
||||
Interactive prompt to add Secrets and ConfigMaps as Volume mounts to the function project
|
||||
in the current directory or from the directory specified with --path.
|
||||
`,
|
||||
SuggestFor: []string{"ad", "create", "insert", "append"},
|
||||
//ValidArgsFunction: CompleteFunctionList,
|
||||
PreRunE: bindEnv("path"),
|
||||
RunE: func(cmd *cobra.Command, args []string) (err error) {
|
||||
function, err := initConfigCommand(args)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return runAddVolumesPrompt(cmd.Context(), function)
|
||||
},
|
||||
}
|
||||
|
||||
var configVolumesRemoveCmd = &cobra.Command{
|
||||
Use: "remove",
|
||||
Short: "Remove volume from the function configuration",
|
||||
Long: `Remove volume from the function configuration
|
||||
|
||||
Interactive prompt to remove Volume mounts from the function project
|
||||
in the current directory or from the directory specified with --path.
|
||||
`,
|
||||
SuggestFor: []string{"del", "delete", "rmeove"},
|
||||
PreRunE: bindEnv("path"),
|
||||
RunE: func(cmd *cobra.Command, args []string) (err error) {
|
||||
function, err := initConfigCommand(args)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return runRemoveVolumesPrompt(function)
|
||||
},
|
||||
}
|
||||
|
||||
func listVolumes(f bosonFunc.Function) {
|
||||
if len(f.Volumes) == 0 {
|
||||
fmt.Println("There aren't any configured Volume mounts")
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("Configured Volumes mounts:")
|
||||
for _, v := range f.Volumes {
|
||||
fmt.Println(" - ", v.String())
|
||||
}
|
||||
}
|
||||
|
||||
func runAddVolumesPrompt(ctx context.Context, f bosonFunc.Function) (err error) {
|
||||
|
||||
secrets, err := k8s.ListSecretsNames(ctx, f.Namespace)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
configMaps, err := k8s.ListConfigMapsNames(ctx, f.Namespace)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// SECTION - select resource type to be mounted
|
||||
options := []string{}
|
||||
selectedOption := ""
|
||||
const optionConfigMap = "ConfigMap"
|
||||
const optionSecret = "Secret"
|
||||
|
||||
if len(configMaps) > 0 {
|
||||
options = append(options, optionConfigMap)
|
||||
}
|
||||
if len(secrets) > 0 {
|
||||
options = append(options, optionSecret)
|
||||
}
|
||||
|
||||
switch len(options) {
|
||||
case 0:
|
||||
fmt.Printf("There aren't any Secrets or ConfiMaps in the namespace \"%s\"\n", f.Namespace)
|
||||
return
|
||||
case 1:
|
||||
selectedOption = options[0]
|
||||
case 2:
|
||||
err = survey.AskOne(&survey.Select{
|
||||
Message: "What do you want to mount as a Volume?",
|
||||
Options: options,
|
||||
}, &selectedOption)
|
||||
if err != nil {
|
||||
if err == terminal.InterruptErr {
|
||||
return nil
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// SECTION - select the specific resource to be mounted
|
||||
optionsResoures := []string{}
|
||||
resourceType := ""
|
||||
switch selectedOption {
|
||||
case optionConfigMap:
|
||||
resourceType = optionConfigMap
|
||||
optionsResoures = configMaps
|
||||
case optionSecret:
|
||||
resourceType = optionSecret
|
||||
optionsResoures = secrets
|
||||
}
|
||||
|
||||
selectedResource := ""
|
||||
err = survey.AskOne(&survey.Select{
|
||||
Message: fmt.Sprintf("Which \"%s\" do you want to mount?", resourceType),
|
||||
Options: optionsResoures,
|
||||
}, &selectedResource)
|
||||
if err != nil {
|
||||
if err == terminal.InterruptErr {
|
||||
return nil
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// SECTION - specify mount Path of the Volume
|
||||
|
||||
path := ""
|
||||
err = survey.AskOne(&survey.Input{
|
||||
Message: fmt.Sprintf("Please specify the path where the %s should be mounted:", resourceType),
|
||||
}, &path, survey.WithValidator(func(val interface{}) error {
|
||||
if str, ok := val.(string); !ok || len(str) <= 0 || !strings.HasPrefix(str, "/") {
|
||||
return fmt.Errorf("The input must be non-empty absolute path.")
|
||||
}
|
||||
return nil
|
||||
}))
|
||||
if err != nil {
|
||||
if err == terminal.InterruptErr {
|
||||
return nil
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// we have all necessary information -> let's store the new Volume
|
||||
newVolume := bosonFunc.Volume{Path: &path}
|
||||
switch selectedOption {
|
||||
case optionConfigMap:
|
||||
newVolume.ConfigMap = &selectedResource
|
||||
case optionSecret:
|
||||
newVolume.Secret = &selectedResource
|
||||
}
|
||||
|
||||
f.Volumes = append(f.Volumes, newVolume)
|
||||
|
||||
err = f.WriteConfig()
|
||||
if err == nil {
|
||||
fmt.Println("Volume was added to the function configuration")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func runRemoveVolumesPrompt(f bosonFunc.Function) (err error) {
|
||||
if len(f.Volumes) == 0 {
|
||||
fmt.Println("There aren't any configured Volume mounts")
|
||||
return
|
||||
}
|
||||
|
||||
options := []string{}
|
||||
for _, v := range f.Volumes {
|
||||
options = append(options, v.String())
|
||||
}
|
||||
|
||||
selectedVolume := ""
|
||||
prompt := &survey.Select{
|
||||
Message: "Which Volume do you want to remove?",
|
||||
Options: options,
|
||||
}
|
||||
err = survey.AskOne(prompt, &selectedVolume)
|
||||
if err != nil {
|
||||
if err == terminal.InterruptErr {
|
||||
return nil
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var newVolumes bosonFunc.Volumes
|
||||
removed := false
|
||||
for i, v := range f.Volumes {
|
||||
if v.String() == selectedVolume {
|
||||
newVolumes = append(f.Volumes[:i], f.Volumes[i+1:]...)
|
||||
removed = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if removed {
|
||||
f.Volumes = newVolumes
|
||||
err = f.WriteConfig()
|
||||
if err == nil {
|
||||
fmt.Println("Volume was removed from the function configuration")
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
10
config.go
10
config.go
|
@ -22,6 +22,16 @@ type Volume struct {
|
|||
Path *string `yaml:"path"`
|
||||
}
|
||||
|
||||
func (v Volume) String() string {
|
||||
if v.ConfigMap != nil {
|
||||
return fmt.Sprintf("ConfigMap \"%s\" mounted at path: \"%s\"", *v.ConfigMap, *v.Path)
|
||||
} else if v.Secret != nil {
|
||||
return fmt.Sprintf("Secret \"%s\" mounted at path: \"%s\"", *v.Secret, *v.Path)
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
type Envs []Env
|
||||
type Env struct {
|
||||
Name *string `yaml:"name,omitempty"`
|
||||
|
|
|
@ -159,3 +159,43 @@ kn func emit --path /path/to/fn -i fn.test
|
|||
# Send a CloudEvent to an arbitrary endpoint
|
||||
kn func emit --sink "http://my.event.broker.com"
|
||||
```
|
||||
|
||||
## `config`
|
||||
|
||||
Invokes interactive prompt that manages configuration of the Function project in the current directory.
|
||||
The user may specify a path to the project directory using the `--path` or `-p` flag. This command operates on configuration
|
||||
specified in `func.yaml` configuration file.
|
||||
Users need to deploy or update the function with `func deploy` in order to apply the updated configuration to the deployed function.
|
||||
|
||||
This command has subcommands `envs` and `volumes` to manage directly the specific resouces: Environment variables and Volumes.
|
||||
These subcommands has commands `add` and `remove` to add and remove specified resouces.
|
||||
|
||||
Invokes top level interactive prompt that allows choosing the resouce and operation:
|
||||
```console
|
||||
func config [-p <path>]
|
||||
```
|
||||
|
||||
Example:
|
||||
```console
|
||||
func config
|
||||
? What do you want to configure? Volumes
|
||||
? What operation do you want to perform? List
|
||||
Configured Volumes mounts:
|
||||
- Secret "mysecret" mounted at path: "/workspace/secret"
|
||||
- ConfigMap "mycm" mounted at path: "/workspace/configmap"
|
||||
```
|
||||
|
||||
This command lists configured Volumes:
|
||||
```console
|
||||
func config volumes [-p <path>]
|
||||
```
|
||||
|
||||
Invokes interactive prompt that allows addind Volumes to the function configuration
|
||||
```console
|
||||
func config volumes add [-p <path>]
|
||||
```
|
||||
|
||||
Invokes interactive prompt that allows removing Volumes from the function configuration
|
||||
```console
|
||||
func config volumes remove [-p <path>]
|
||||
```
|
1
go.mod
1
go.mod
|
@ -3,6 +3,7 @@ module github.com/boson-project/func
|
|||
go 1.15
|
||||
|
||||
require (
|
||||
github.com/AlecAivazis/survey/v2 v2.2.12
|
||||
github.com/buildpacks/pack v0.18.0
|
||||
github.com/cloudevents/sdk-go/v2 v2.2.0
|
||||
github.com/containers/image/v5 v5.10.5
|
||||
|
|
10
go.sum
10
go.sum
|
@ -44,6 +44,8 @@ contrib.go.opencensus.io/exporter/stackdriver v0.13.5/go.mod h1:aXENhDJ1Y4lIg4EU
|
|||
contrib.go.opencensus.io/exporter/zipkin v0.1.2/go.mod h1:mP5xM3rrgOjpn79MM8fZbj3gsxcuytSqtH0dxSWW1RE=
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/14rcole/gopopulate v0.0.0-20180821133914-b175b219e774/go.mod h1:6/0dYRLLXyJjbkIPeeGyoJ/eKOSI0eU6eTlCBYibgd0=
|
||||
github.com/AlecAivazis/survey/v2 v2.2.12 h1:5a07y93zA6SZ09gOa9wLVLznF5zTJMQ+pJ3cZK4IuO8=
|
||||
github.com/AlecAivazis/survey/v2 v2.2.12/go.mod h1:6d4saEvBsfSHXeN1a5OA5m2+HJ2LuVokllnC77pAIKI=
|
||||
github.com/Azure/azure-sdk-for-go v35.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-sdk-for-go v38.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-sdk-for-go v42.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
|
@ -96,6 +98,7 @@ github.com/Microsoft/hcsshim v0.8.10/go.mod h1:g5uw8EV2mAlzqe94tfNBNdr89fnbD/n3H
|
|||
github.com/Microsoft/hcsshim v0.8.14 h1:lbPVK25c1cu5xTLITwpUcxoA9vKrKErASPYygvouJns=
|
||||
github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg=
|
||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||
github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc=
|
||||
github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE=
|
||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
|
@ -544,6 +547,7 @@ github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2p
|
|||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
||||
github.com/heroku/color v0.0.6 h1:UTFFMrmMLFcL3OweqP1lAdp8i1y/9oHqkeHjQ/b/Ny0=
|
||||
github.com/heroku/color v0.0.6/go.mod h1:ZBvOcx7cTF2QKOv4LbmoBtNl5uB17qWxGuzZrsi1wLU=
|
||||
github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
|
@ -585,6 +589,7 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV
|
|||
github.com/juju/ansiterm v0.0.0-20180109212912-720a0952cc2a/go.mod h1:UJSiEoRfvx3hP73CvoARgeLjaIOjybY9vj8PUPPFGeU=
|
||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||
github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8=
|
||||
github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg=
|
||||
|
@ -604,6 +609,7 @@ github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFB
|
|||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.4/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
|
@ -649,6 +655,7 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5
|
|||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||
github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY=
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/miekg/dns v1.1.17/go.mod h1:WgzbA6oji13JREwiNsRDNfl7jYdPnmz+VEuLrA+/48M=
|
||||
|
@ -912,6 +919,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
|
|||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
|
@ -1018,6 +1026,7 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
|
|||
golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190617133340-57b3e21c3d56/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
|
@ -1160,6 +1169,7 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
|
|||
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190530182044-ad28b68e88f1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
package k8s
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
)
|
||||
|
||||
|
||||
func NewKubernetesClientset(namespace string) (*kubernetes.Clientset, error) {
|
||||
|
||||
restConfig, err := GetClientConfig().ClientConfig()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create new kubernetes client: %v", err)
|
||||
}
|
||||
|
||||
return kubernetes.NewForConfig(restConfig)
|
||||
}
|
||||
|
||||
func GetNamespace(defaultNamespace string) (namespace string, err error) {
|
||||
namespace = defaultNamespace
|
||||
|
||||
if defaultNamespace == "" {
|
||||
namespace, _, err = GetClientConfig().Namespace()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func GetClientConfig() clientcmd.ClientConfig {
|
||||
return clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
|
||||
clientcmd.NewDefaultClientConfigLoadingRules(),
|
||||
&clientcmd.ConfigOverrides{})
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package k8s
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
func GetConfigMap(ctx context.Context, name, namespaceOverride string) (*corev1.ConfigMap, error) {
|
||||
|
||||
namespace, err := GetNamespace(namespaceOverride)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
client, err := NewKubernetesClientset(namespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return client.CoreV1().ConfigMaps(namespace).Get(ctx, name, metav1.GetOptions{})
|
||||
}
|
||||
|
||||
func ListConfigMapsNames(ctx context.Context, namespaceOverride string) (names []string, err error) {
|
||||
|
||||
namespace, err := GetNamespace(namespaceOverride)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
client, err := NewKubernetesClientset(namespace)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
cms, err := client.CoreV1().ConfigMaps(namespace).List(ctx, metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, cm := range cms.Items {
|
||||
names = append(names, cm.Name)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
package k8s
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
func GetSecret(ctx context.Context, name, namespaceOverride string) (*corev1.Secret, error) {
|
||||
|
||||
namespace, err := GetNamespace(namespaceOverride)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
client, err := NewKubernetesClientset(namespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return client.CoreV1().Secrets(namespace).Get(ctx, name, metav1.GetOptions{})
|
||||
}
|
||||
|
||||
func ListSecretsNames(ctx context.Context, namespaceOverride string) (names []string, err error) {
|
||||
|
||||
namespace, err := GetNamespace(namespaceOverride)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
client, err := NewKubernetesClientset(namespace)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
secrets, err := client.CoreV1().Secrets(namespace).List(ctx, metav1.ListOptions{})
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, s := range secrets.Items {
|
||||
names = append(names, s.Name)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
|
@ -4,12 +4,12 @@ import (
|
|||
"fmt"
|
||||
"time"
|
||||
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/tools/clientcmd"
|
||||
clienteventingv1beta1 "knative.dev/client/pkg/eventing/v1beta1"
|
||||
clientservingv1 "knative.dev/client/pkg/serving/v1"
|
||||
eventingv1beta1 "knative.dev/eventing/pkg/client/clientset/versioned/typed/eventing/v1beta1"
|
||||
servingv1 "knative.dev/serving/pkg/client/clientset/versioned/typed/serving/v1"
|
||||
|
||||
"github.com/boson-project/func/k8s"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -18,7 +18,7 @@ const (
|
|||
|
||||
func NewServingClient(namespace string) (clientservingv1.KnServingClient, error) {
|
||||
|
||||
restConfig, err := getClientConfig().ClientConfig()
|
||||
restConfig, err := k8s.GetClientConfig().ClientConfig()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create new serving client: %v", err)
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ func NewServingClient(namespace string) (clientservingv1.KnServingClient, error)
|
|||
|
||||
func NewEventingClient(namespace string) (clienteventingv1beta1.KnEventingClient, error) {
|
||||
|
||||
restConfig, err := getClientConfig().ClientConfig()
|
||||
restConfig, err := k8s.GetClientConfig().ClientConfig()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create new serving client: %v", err)
|
||||
}
|
||||
|
@ -49,31 +49,3 @@ func NewEventingClient(namespace string) (clienteventingv1beta1.KnEventingClient
|
|||
|
||||
return client, nil
|
||||
}
|
||||
|
||||
func NewKubernetesClientset(namespace string) (*kubernetes.Clientset, error) {
|
||||
|
||||
restConfig, err := getClientConfig().ClientConfig()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to create new kubernetes client: %v", err)
|
||||
}
|
||||
|
||||
return kubernetes.NewForConfig(restConfig)
|
||||
}
|
||||
|
||||
func GetNamespace(defaultNamespace string) (namespace string, err error) {
|
||||
namespace = defaultNamespace
|
||||
|
||||
if defaultNamespace == "" {
|
||||
namespace, _, err = getClientConfig().Namespace()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func getClientConfig() clientcmd.ClientConfig {
|
||||
return clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
|
||||
clientcmd.NewDefaultClientConfigLoadingRules(),
|
||||
&clientcmd.ConfigOverrides{})
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ import (
|
|||
v1 "knative.dev/serving/pkg/apis/serving/v1"
|
||||
|
||||
fn "github.com/boson-project/func"
|
||||
"github.com/boson-project/func/k8s"
|
||||
)
|
||||
|
||||
type Deployer struct {
|
||||
|
@ -32,7 +33,7 @@ type Deployer struct {
|
|||
|
||||
func NewDeployer(namespaceOverride string) (deployer *Deployer, err error) {
|
||||
deployer = &Deployer{}
|
||||
namespace, err := GetNamespace(namespaceOverride)
|
||||
namespace, err := k8s.GetNamespace(namespaceOverride)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -495,21 +496,17 @@ func processVolumes(volumes fn.Volumes, referencedSecrets, referencedConfigMaps
|
|||
// checkSecretsConfigMapsArePresent returns error if Secrets or ConfigMaps
|
||||
// referenced in input sets are not deployed on the cluster in the specified namespace
|
||||
func checkSecretsConfigMapsArePresent(ctx context.Context, namespace string, referencedSecrets, referencedConfigMaps *sets.String) error {
|
||||
client, err := NewKubernetesClientset(namespace)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
errMsg := ""
|
||||
for s := range *referencedSecrets {
|
||||
_, err := client.CoreV1().Secrets(namespace).Get(ctx, s, metav1.GetOptions{})
|
||||
_, err := k8s.GetSecret(ctx, s, namespace)
|
||||
if err != nil {
|
||||
errMsg += fmt.Sprintf(" referenced Secret \"%s\" is not present in namespace \"%s\"\n", s, namespace)
|
||||
}
|
||||
}
|
||||
|
||||
for cm := range *referencedConfigMaps {
|
||||
_, err := client.CoreV1().ConfigMaps(namespace).Get(ctx, cm, metav1.GetOptions{})
|
||||
_, err := k8s.GetConfigMap(ctx, cm, namespace)
|
||||
if err != nil {
|
||||
errMsg += fmt.Sprintf(" referenced ConfigMap \"%s\" is not present in namespace \"%s\"\n", cm, namespace)
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"knative.dev/eventing/pkg/apis/eventing/v1beta1"
|
||||
|
||||
bosonFunc "github.com/boson-project/func"
|
||||
"github.com/boson-project/func/k8s"
|
||||
)
|
||||
|
||||
type Describer struct {
|
||||
|
@ -17,7 +18,7 @@ type Describer struct {
|
|||
|
||||
func NewDescriber(namespaceOverride string) (describer *Describer, err error) {
|
||||
describer = &Describer{}
|
||||
namespace, err := GetNamespace(namespaceOverride)
|
||||
namespace, err := k8s.GetNamespace(namespaceOverride)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"knative.dev/pkg/apis"
|
||||
|
||||
bosonFunc "github.com/boson-project/func"
|
||||
"github.com/boson-project/func/k8s"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -22,7 +23,7 @@ type Lister struct {
|
|||
func NewLister(namespaceOverride string) (l *Lister, err error) {
|
||||
l = &Lister{}
|
||||
|
||||
namespace, err := GetNamespace(namespaceOverride)
|
||||
namespace, err := k8s.GetNamespace(namespaceOverride)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -4,13 +4,15 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/boson-project/func/k8s"
|
||||
)
|
||||
|
||||
const RemoveTimeout = 120 * time.Second
|
||||
|
||||
func NewRemover(namespaceOverride string) (remover *Remover, err error) {
|
||||
remover = &Remover{}
|
||||
namespace, err := GetNamespace(namespaceOverride)
|
||||
namespace, err := k8s.GetNamespace(namespaceOverride)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue