Skip to content

Commit 5182487

Browse files
authored
feat: user can set envvars
1 parent 89b9b73 commit 5182487

File tree

8 files changed

+97
-36
lines changed

8 files changed

+97
-36
lines changed

cmd/create.go

+4-3
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ project configuration file faas.yaml.
6060
}
6161

6262
func runCreate(cmd *cobra.Command, args []string) (err error) {
63-
config := newCreateConfig(args).Prompt()
63+
config := newCreateConfig(cmd, args).Prompt()
6464

6565
function := faas.Function{
6666
Name: config.initConfig.Name,
@@ -114,10 +114,11 @@ type createConfig struct {
114114
// Note that ambiguous references set to assume .initConfig
115115
}
116116

117-
func newCreateConfig(args []string) createConfig {
117+
func newCreateConfig(cmd *cobra.Command, args []string) createConfig {
118+
118119
return createConfig{
119120
initConfig: newInitConfig(args),
120-
deployConfig: newDeployConfig(),
121+
deployConfig: newDeployConfig(cmd),
121122
}
122123
}
123124

cmd/deploy.go

+8-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package cmd
22

33
import (
44
"fmt"
5-
65
"github.com/ory/viper"
76
"github.com/spf13/cobra"
87

@@ -17,6 +16,7 @@ import (
1716
func init() {
1817
root.AddCommand(deployCmd)
1918
deployCmd.Flags().BoolP("confirm", "c", false, "Prompt to confirm all configuration options - $FAAS_CONFIRM")
19+
deployCmd.Flags().StringArrayP("env", "e", []string{}, "Sets environment variables for the Function.")
2020
deployCmd.Flags().StringP("image", "i", "", "Optional full image name, in form [registry]/[namespace]/[name]:[tag] for example quay.io/myrepo/project.name:latest (overrides --registry) - $FAAS_IMAGE")
2121
deployCmd.Flags().StringP("namespace", "n", "", "Override namespace into which the Function is deployed (on supported platforms). Default is to use currently active underlying platform setting - $FAAS_NAMESPACE")
2222
deployCmd.Flags().StringP("path", "p", cwd(), "Path to the function project directory - $FAAS_PATH")
@@ -52,13 +52,15 @@ or -n flag, and if so this will overwrite the value in the faas.yaml file.
5252

5353
func runDeploy(cmd *cobra.Command, _ []string) (err error) {
5454

55-
config := newDeployConfig().Prompt()
55+
config := newDeployConfig(cmd).Prompt()
5656

5757
function, err := functionWithOverrides(config.Path, functionOverrides{Namespace: config.Namespace, Image: config.Image})
5858
if err != nil {
5959
return
6060
}
6161

62+
function.EnvVars = mergeEnvVarsMaps(function.EnvVars, config.EnvVars)
63+
6264
// Check if the Function has been initialized
6365
if !function.Initialized() {
6466
return fmt.Errorf("the given path '%v' does not contain an initialized Function. Please create one at this path before deploying.", config.Path)
@@ -138,17 +140,20 @@ type deployConfig struct {
138140
// Confirm: confirm values arrived upon from environment plus flags plus defaults,
139141
// with interactive prompting (only applicable when attached to a TTY).
140142
Confirm bool
143+
144+
EnvVars map[string]string
141145
}
142146

143147
// newDeployConfig creates a buildConfig populated from command flags and
144148
// environment variables; in that precedence.
145-
func newDeployConfig() deployConfig {
149+
func newDeployConfig(cmd *cobra.Command) deployConfig {
146150
return deployConfig{
147151
buildConfig: newBuildConfig(),
148152
Namespace: viper.GetString("namespace"),
149153
Path: viper.GetString("path"),
150154
Verbose: viper.GetBool("verbose"), // defined on root
151155
Confirm: viper.GetBool("confirm"),
156+
EnvVars: envVarsFromCmd(cmd),
152157
}
153158
}
154159

cmd/root.go

+40
Original file line numberDiff line numberDiff line change
@@ -235,3 +235,43 @@ func deriveImage(explicitImage, defaultRegistry, path string) string {
235235
derivedValue, _ := faas.DerivedImage(path, defaultRegistry)
236236
return derivedValue // Use the faas system's derivation logic.
237237
}
238+
239+
func envVarsFromCmd(cmd *cobra.Command) map[string]string {
240+
envVarsM := make(map[string]string)
241+
if cmd.Flags().Changed("env") {
242+
envVarsA, err := cmd.Flags().GetStringArray("env")
243+
if err == nil {
244+
for _, s := range envVarsA {
245+
kvp := strings.Split(s, "=")
246+
if len(kvp) == 2 && kvp[0] != "" {
247+
envVarsM[kvp[0]] = kvp[1]
248+
} else if len(kvp) == 1 && kvp[0] != "" {
249+
envVarsM[kvp[0]] = ""
250+
}
251+
}
252+
}
253+
}
254+
return envVarsM
255+
}
256+
257+
func mergeEnvVarsMaps(dest, src map[string]string) map[string]string {
258+
result := make(map[string]string, len(dest) +len(src))
259+
260+
for name, value := range dest {
261+
if strings.HasSuffix(name, "-") {
262+
if _, ok := src[strings.TrimSuffix(name, "-")]; !ok {
263+
result[name] = value
264+
}
265+
} else {
266+
if _, ok := src[name+"-"]; !ok {
267+
result[name] = value
268+
}
269+
}
270+
}
271+
272+
for name, value := range src {
273+
result[name] = value
274+
}
275+
276+
return result
277+
}

cmd/run.go

+13-2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
func init() {
1414
// Add the run command as a subcommand of root.
1515
root.AddCommand(runCmd)
16+
runCmd.Flags().StringArrayP("env", "e", []string{}, "Sets environment variables for the Function.")
1617
runCmd.Flags().StringP("path", "p", cwd(), "Path to the Function project directory - $FAAS_PATH")
1718
}
1819

@@ -31,13 +32,20 @@ already have been built as an OCI container image using the 'build' command.
3132
}
3233

3334
func runRun(cmd *cobra.Command, args []string) (err error) {
34-
config := newRunConfig()
35+
config := newRunConfig(cmd)
3536

3637
function, err := faas.NewFunction(config.Path)
3738
if err != nil {
3839
return
3940
}
4041

42+
function.EnvVars = mergeEnvVarsMaps(function.EnvVars, config.EnvVars)
43+
44+
err = function.WriteConfig()
45+
if err != nil {
46+
return
47+
}
48+
4149
// Check if the Function has been initialized
4250
if !function.Initialized() {
4351
return fmt.Errorf("the given path '%v' does not contain an initialized Function.", config.Path)
@@ -60,11 +68,14 @@ type runConfig struct {
6068

6169
// Verbose logging.
6270
Verbose bool
71+
72+
EnvVars map[string]string
6373
}
6474

65-
func newRunConfig() runConfig {
75+
func newRunConfig(cmd *cobra.Command) runConfig {
6676
return runConfig{
6777
Path: viper.GetString("path"),
6878
Verbose: viper.GetBool("verbose"), // defined on root
79+
EnvVars: envVarsFromCmd(cmd),
6980
}
7081
}

config.go

+3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ type config struct {
2121
Trigger string `yaml:"trigger"`
2222
Builder string `yaml:"builder"`
2323
BuilderMap map[string]string `yaml:"builderMap"`
24+
EnvVars map[string]string `yaml:"envVars"`
2425
// Add new values to the toConfig/fromConfig functions.
2526
}
2627

@@ -57,6 +58,7 @@ func fromConfig(c config) (f Function) {
5758
Trigger: c.Trigger,
5859
Builder: c.Builder,
5960
BuilderMap: c.BuilderMap,
61+
EnvVars: c.EnvVars,
6062
}
6163
}
6264

@@ -70,6 +72,7 @@ func toConfig(f Function) config {
7072
Trigger: f.Trigger,
7173
Builder: f.Builder,
7274
BuilderMap: f.BuilderMap,
75+
EnvVars: f.EnvVars,
7376
}
7477
}
7578

docker/runner.go

+8-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66
"os"
77
"os/exec"
8+
"strings"
89

910
"github.com/boson-project/faas"
1011
)
@@ -36,9 +37,15 @@ func (n *Runner) Run(f faas.Function) error {
3637
// Extra arguments to docker
3738
args := []string{"run", "--rm", "-t", "-p=8080:8080"}
3839

40+
for name, value := range f.EnvVars {
41+
if !strings.HasSuffix(name,"-") {
42+
args = append(args, fmt.Sprintf("-e%s=%s", name, value))
43+
}
44+
}
45+
3946
// If verbosity is enabled, pass along as an environment variable to the Function.
4047
if n.Verbose {
41-
args = append(args, []string{"-e VERBOSE=true"}...)
48+
args = append(args, "-e VERBOSE=true")
4249
}
4350
args = append(args, f.Image)
4451

function.go

+2
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ type Function struct {
4848
// Map containing known builders.
4949
// e.g. { "jvm": "docker.io/example/quarkus-jvm-builder" }
5050
BuilderMap map[string]string
51+
52+
EnvVars map[string]string
5153
}
5254

5355
// NewFunction loads a Function from a path on disk. use .Initialized() to determine if

knative/deployer.go

+19-27
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,13 @@ package knative
33
import (
44
"bytes"
55
"fmt"
6-
"sort"
6+
"strings"
77
"time"
88

99
corev1 "k8s.io/api/core/v1"
1010
"k8s.io/apimachinery/pkg/api/errors"
1111
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
12+
servinglib "knative.dev/client/pkg/serving"
1213
"knative.dev/client/pkg/wait"
1314
servingv1 "knative.dev/serving/pkg/apis/serving/v1"
1415
v1 "knative.dev/serving/pkg/apis/serving/v1"
@@ -97,7 +98,7 @@ func (d *Deployer) Deploy(f faas.Function) (err error) {
9798
}
9899
} else {
99100
// Update the existing Service
100-
err = client.UpdateServiceWithRetry(encodedName, updateBuiltTimeStampEnvVar, 3)
101+
err = client.UpdateServiceWithRetry(encodedName, updateEnvVars(f.EnvVars), 3)
101102
if err != nil {
102103
if !d.Verbose {
103104
err = fmt.Errorf("deployer failed to update the service: %v.\nStdOut: %s", err, output.(*bytes.Buffer).String())
@@ -142,34 +143,25 @@ func generateNewService(name, image string) *servingv1.Service {
142143
}
143144
}
144145

145-
func updateBuiltTimeStampEnvVar(service *servingv1.Service) (*servingv1.Service, error) {
146-
envs := service.Spec.Template.Spec.Containers[0].Env
146+
func updateEnvVars(envVars map[string]string) func(service *servingv1.Service) (*servingv1.Service, error) {
147+
return func(service *servingv1.Service) (*servingv1.Service, error) {
148+
builtEnvVarName := "BUILT"
149+
builtEnvVarValue := time.Now().Format("20060102T150405")
147150

148-
builtEnvVarName := "BUILT"
151+
toUpdate := make(map[string]string, len(envVars)+1)
152+
toRemove := make([]string, 0)
149153

150-
builtEnvVar := findEnvVar(builtEnvVarName, envs)
151-
if builtEnvVar == nil {
152-
envs = append(envs, corev1.EnvVar{Name: "VERBOSE", Value: "true"})
153-
builtEnvVar = &envs[len(envs)-1]
154-
}
155-
156-
builtEnvVar.Value = time.Now().Format("20060102T150405")
157-
158-
sort.SliceStable(envs, func(i, j int) bool {
159-
return envs[i].Name <= envs[j].Name
160-
})
161-
service.Spec.Template.Spec.Containers[0].Env = envs
154+
for name, value := range envVars {
155+
if strings.HasSuffix(name, "-") {
156+
toRemove = append(toRemove, strings.TrimSuffix(name, "-"))
157+
} else {
158+
toUpdate[name] = value
159+
}
160+
}
162161

163-
return service, nil
164-
}
162+
toUpdate[builtEnvVarName] = builtEnvVarValue
165163

166-
func findEnvVar(name string, envs []corev1.EnvVar) *corev1.EnvVar {
167-
var result *corev1.EnvVar = nil
168-
for i, envVar := range envs {
169-
if envVar.Name == name {
170-
result = &envs[i]
171-
break
172-
}
164+
return service, servinglib.UpdateEnvVars(&service.Spec.Template, toUpdate, toRemove)
173165
}
174-
return result
166+
175167
}

0 commit comments

Comments
 (0)