Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OPENFAAS_URL env-var for gateway and IPv4 defaults #351

Merged
merged 3 commits into from Mar 12, 2018
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Next Next commit
Move from localhost to 127.0.0.1 as a default for IPv6 clashes, add e…
…nv-var OPENFAAS_URL as override for gateway URL for Kubernetes users

Signed-off-by: Alex Ellis (VMware) <alexellis2@gmail.com>
  • Loading branch information
alexellis committed Mar 12, 2018
commit e25d64f0a6e320fc7ccdbade8f55a3110b0454ce
2 changes: 1 addition & 1 deletion MANUAL_CLI.md
Expand Up @@ -51,7 +51,7 @@ $ faas-cli deploy \

200 OK

URL: http://localhost:8080/function/node_info
URL: http://127.0.0.1:8080/function/node_info
```

> This tool can be used to deploy any Docker image as a FaaS function, as long as it includes the watchdog binary as the `CMD` or `ENTRYPOINT` of the image.
Expand Down
39 changes: 33 additions & 6 deletions README.md
Expand Up @@ -91,6 +91,18 @@ The main commands supported by the CLI are:
* `faas-cli logout` - removes basic auth credentials for a given gateway
* `faas-cli store` - allows browsing and deploying OpenFaaS store functions

The default gateway URL of `127.0.0.1:8080` can be overriden in three places including an environmental variable.

* 1st priority `--gateway` flag
* 2nd priority `--yaml` / `-f` flag or `stack.yml` if in current directory
* 3rd priority `OPENFAAS_URL` environmental variable

For Kubernetes users you may want to set this in your `.bash_rc` file:

```
export OPENFAAS_URL=127.0.0.1:31112
```

Advanced commands:

* `faas-cli template pull` - pull in templates from a remote GitHub repository [Detailed Documentation](guide/TEMPLATE.md)
Expand Down Expand Up @@ -141,6 +153,9 @@ Specify `lang: Dockerfile` if you want the faas-cli to execute a build or `skip_
* If you are using a stack file add the `skip_build: true` attribute
* Use one of the [samples as a basis](https://github.com/openfaas/faas/tree/master/sample-functions)

Read the blog post/tutorial: [Turn Any CLI into a Function with OpenFaaS](https://blog.alexellis.io/cli-functions-with-openfaas/)


### Use a YAML stack file

A YAML stack file groups functions together and also saves on typing.
Expand All @@ -152,7 +167,7 @@ Here is an example file using the `stack.yml` file included in the repository.
```yaml
provider:
name: faas
gateway: http://localhost:8080
gateway: http://127.0.0.1:8080

functions:
url-ping:
Expand Down Expand Up @@ -187,9 +202,21 @@ Now you can use the following command to deploy your function(s):
$ faas-cli deploy -f ./stack.yml
```

#### Managing secrets
#### Secure secret management

Secrets can be used with OpenFaaS when using Docker Swarm or Kubernetes, this means your data is encrypted at rest and is less likely to be leaked during logging / stack traces than with environmental variables.

```yaml
secrets:
- secret-name-1
- secret-name-2
```

Secrets should be defined in the cluster ahead of time using `docker secret create` or `kubectl`.

#### Managing environment/configuration

You can deploy secrets and configuration via environmental variables in-line or via external files.
You can deploy non-encrypted secrets and configuration via environmental variables set either in-line or via external (environment) files.

> Note: external files take priority over in-line environmental variables. This allows you to specify a default and then have overrides within an external file.

Expand Down Expand Up @@ -289,12 +316,12 @@ You can initiate a HTTP POST via `curl`:
* if you want to pass input from STDIN then use `--data-binary @-`

```
$ curl -d '{"hello": "world"}' http://localhost:8080/function/nodejs-echo
$ curl -d '{"hello": "world"}' http://127.0.0.1:8080/function/nodejs-echo
{ nodeVersion: 'v6.9.1', input: '{"hello": "world"}' }

$ curl --data-binary @README.md http://localhost:8080/function/nodejs-echo
$ curl --data-binary @README.md http://127.0.0.1:8080/function/nodejs-echo

$ uname -a | curl http://localhost:8080/function/nodejs-echo--data-binary @-
$ uname -a | curl http://127.0.0.1:8080/function/nodejs-echo--data-binary @-
```

> For further instructions on the manual CLI flags (without using a YAML file) read [manual_cli.md](https://github.com/openfaas/faas-cli/blob/master/MANUAL_CLI.md)
Expand Down
78 changes: 78 additions & 0 deletions commands/config_priority_test.go
@@ -0,0 +1,78 @@
// Copyright (c) Alex Ellis 2017. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

package commands

import (
"testing"
)

// Test_getGatewayURL tests for priority of URL for gateway over several sources
func Test_getGatewayURL(t *testing.T) {
defaultValue := "http://127.0.0.1:8080"
testCases := []struct {
name string
defaultURL string

yamlURL string
argumentURL string
environmentURL string
expectedURL string
}{
{
name: "Nothing provided",
defaultURL: defaultValue,
yamlURL: "",
argumentURL: "",
expectedURL: "http://127.0.0.1:8080",
},
{
name: "Only YAML provided",
defaultURL: defaultValue,
yamlURL: "http://remote1:8080",
argumentURL: "",
expectedURL: "http://remote1:8080",
},
{
name: "Only argument override",
defaultURL: defaultValue,
yamlURL: "",
argumentURL: "http://remote2:8080",
expectedURL: "http://remote2:8080",
},
{
name: "Prioritize argument over YAML when argument is not default",
defaultURL: defaultValue,
yamlURL: "http://remote-yml:8080",
argumentURL: "http://remote-arg:8080",
expectedURL: "http://remote-arg:8080",
},
{
name: "When argument is default use YAML",
defaultURL: defaultValue,
yamlURL: "http://remote-yml:8080",
argumentURL: defaultValue,
expectedURL: "http://remote-yml:8080",
},
{
name: "YAML provided (with defaults) and env-var override",
defaultURL: defaultValue,
yamlURL: defaultValue,
environmentURL: "http://remote2:8080",
argumentURL: "",
expectedURL: "http://remote2:8080",
},
}

fails := 0
for _, testCase := range testCases {
url := getGatewayURL(testCase.argumentURL, testCase.defaultURL, testCase.yamlURL, testCase.environmentURL)
if url != testCase.expectedURL {
t.Logf("gatewayURL %s\nwant: %s, got: %s", testCase.name, testCase.expectedURL, url)
fails++
}
}
if fails > 0 {
t.Fail()
}
}
30 changes: 30 additions & 0 deletions commands/config_priorty.go
@@ -0,0 +1,30 @@
// Copyright (c) Alex Ellis 2017. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

package commands

import (
"fmt"
"strings"
)

func getGatewayURL(argumentURL, defaultURL, yamlURL, environmentURL string) string {
var gatewayURL string

if len(argumentURL) > 0 && argumentURL != defaultURL {
gatewayURL = argumentURL
} else if len(yamlURL) > 0 && yamlURL != defaultURL {
gatewayURL = yamlURL
} else if len(environmentURL) > 0 {
gatewayURL = environmentURL
} else {
gatewayURL = defaultURL
}

gatewayURL = strings.ToLower(strings.TrimRight(gatewayURL, "/"))
if !strings.HasPrefix(gatewayURL, "http") {
gatewayURL = fmt.Sprintf("http://%s", gatewayURL)
}

return gatewayURL
}
21 changes: 1 addition & 20 deletions commands/deploy.go
Expand Up @@ -119,7 +119,7 @@ func runDeployCommand(args []string, image string, fprocess string, functionName
return err
}

parsedServices.Provider.GatewayURL = getGatewayURL(gateway, defaultGateway, parsedServices.Provider.GatewayURL)
parsedServices.Provider.GatewayURL = getGatewayURL(gateway, defaultGateway, parsedServices.Provider.GatewayURL, os.Getenv("OPENFAAS_URL"))

// Override network if passed
if len(network) > 0 && network != defaultNetwork {
Expand Down Expand Up @@ -303,25 +303,6 @@ func mergeMap(i map[string]string, j map[string]string) map[string]string {
return merged
}

func getGatewayURL(argumentURL string, defaultURL string, yamlURL string) string {
var gatewayURL string

if len(argumentURL) > 0 && argumentURL != defaultURL {
gatewayURL = argumentURL
} else if len(yamlURL) > 0 {
gatewayURL = yamlURL
} else {
gatewayURL = defaultURL
}

gatewayURL = strings.ToLower(strings.TrimRight(gatewayURL, "/"))
if !strings.HasPrefix(gatewayURL, "http") {
gatewayURL = fmt.Sprintf("http://%s", gatewayURL)
}

return gatewayURL
}

func compileEnvironment(envvarOpts []string, yamlEnvironment map[string]string, fileEnvironment map[string]string) (map[string]string, error) {
envvarArguments, err := parseMap(envvarOpts, "env")
if err != nil {
Expand Down
59 changes: 0 additions & 59 deletions commands/deploy_test.go
Expand Up @@ -11,65 +11,6 @@ import (
"github.com/openfaas/faas-cli/test"
)

func Test_getGatewayURL(t *testing.T) {
defaultValue := "http://localhost:8080"
testCases := []struct {
name string
defaultURL string
yamlURL string
argumentURL string
expectedURL string
}{
{
name: "Nothing provided",
defaultURL: defaultValue,
yamlURL: "",
argumentURL: "",
expectedURL: "http://localhost:8080",
},
{
name: "Only YAML provided",
defaultURL: defaultValue,
yamlURL: "http://remote1:8080",
argumentURL: "",
expectedURL: "http://remote1:8080",
},
{
name: "Only argument override",
defaultURL: defaultValue,
yamlURL: "",
argumentURL: "http://remote2:8080",
expectedURL: "http://remote2:8080",
},
{
name: "Prioritize argument over YAML when argument is not default",
defaultURL: defaultValue,
yamlURL: "http://remote-yml:8080",
argumentURL: "http://remote-arg:8080",
expectedURL: "http://remote-arg:8080",
},
{
name: "When argument is default use YAML",
defaultURL: defaultValue,
yamlURL: "http://remote-yml:8080",
argumentURL: defaultValue,
expectedURL: "http://remote-yml:8080",
},
}

fails := 0
for _, testCase := range testCases {
url := getGatewayURL(testCase.argumentURL, testCase.defaultURL, testCase.yamlURL)
if url != testCase.expectedURL {
t.Logf("gatewayURL %s\nwant: %s, got: %s", testCase.name, testCase.expectedURL, url)
fails++
}
}
if fails > 0 {
t.Fail()
}
}

func Test_deploy(t *testing.T) {
s := test.MockHttpServer(t, []test.Request{
{
Expand Down
2 changes: 1 addition & 1 deletion commands/faas.go
Expand Up @@ -13,7 +13,7 @@ import (
)

const (
defaultGateway = "http://localhost:8080"
defaultGateway = "http://127.0.0.1:8080"
defaultNetwork = "func_functions"
defaultYAML = "stack.yml"
)
Expand Down
2 changes: 1 addition & 1 deletion commands/invoke.go
Expand Up @@ -70,7 +70,7 @@ func runInvoke(cmd *cobra.Command, args []string) error {
}
}

gatewayAddress := getGatewayURL(gateway, defaultGateway, yamlGateway)
gatewayAddress := getGatewayURL(gateway, defaultGateway, yamlGateway, os.Getenv("OPENFAAS_URL"))

stat, _ := os.Stdin.Stat()
if (stat.Mode() & os.ModeCharDevice) != 0 {
Expand Down
5 changes: 3 additions & 2 deletions commands/list.go
Expand Up @@ -5,6 +5,7 @@ package commands

import (
"fmt"
"os"

"github.com/openfaas/faas-cli/proxy"
"github.com/openfaas/faas-cli/stack"
Expand All @@ -30,7 +31,7 @@ var listCmd = &cobra.Command{
Short: "List OpenFaaS functions",
Long: `Lists OpenFaaS functions either on a local or remote gateway`,
Example: ` faas-cli list
faas-cli list --gateway https://localhost:8080 --verbose`,
faas-cli list --gateway https://127.0.0.1:8080 --verbose`,
RunE: runList,
}

Expand All @@ -50,7 +51,7 @@ func runList(cmd *cobra.Command, args []string) error {
}
}

gatewayAddress = getGatewayURL(gateway, defaultGateway, yamlGateway)
gatewayAddress = getGatewayURL(gateway, defaultGateway, yamlGateway, os.Getenv("OPENFAAS_URL"))

functions, err := proxy.ListFunctions(gatewayAddress)
if err != nil {
Expand Down
6 changes: 4 additions & 2 deletions commands/login.go
Expand Up @@ -35,7 +35,7 @@ var loginCmd = &cobra.Command{
Use: `login [--username USERNAME] [--password PASSWORD] [--gateway GATEWAY_URL]`,
Short: "Log in to OpenFaaS gateway",
Long: "Log in to OpenFaaS gateway.\nIf no gateway is specified, the default local one will be used.",
Example: ` faas-cli login -u user -p password --gateway http://localhost:8080
Example: ` faas-cli login -u user -p password --gateway http://127.0.0.1:8080
cat ~/faas_pass.txt | faas-cli login -u user --password-stdin --gateway https://openfaas.mydomain.com`,
RunE: runLogin,
}
Expand Down Expand Up @@ -76,7 +76,9 @@ func runLogin(cmd *cobra.Command, args []string) error {
}

fmt.Println("Calling the OpenFaaS server to validate the credentials...")
gateway = getGatewayURL(gateway, "", "")

gateway = getGatewayURL(gateway, "", "", os.Getenv("OPENFAAS_URL"))

if err := validateLogin(gateway, username, password); err != nil {
return err
}
Expand Down
3 changes: 2 additions & 1 deletion commands/remove.go
Expand Up @@ -5,6 +5,7 @@ package commands

import (
"fmt"
"os"

"github.com/openfaas/faas-cli/proxy"
"github.com/openfaas/faas-cli/stack"
Expand Down Expand Up @@ -52,7 +53,7 @@ func runDelete(cmd *cobra.Command, args []string) error {
}
}

gatewayAddress = getGatewayURL(gateway, defaultGateway, yamlGateway)
gatewayAddress = getGatewayURL(gateway, defaultGateway, yamlGateway, os.Getenv("OPENFAAS_URL"))

if len(services.Functions) > 0 {
if len(services.Provider.Network) == 0 {
Expand Down
2 changes: 1 addition & 1 deletion commands/store_deploy.go
Expand Up @@ -43,7 +43,7 @@ var storeDeployCmd = &cobra.Command{
Long: `Same as faas-cli deploy except that function is pre-loaded with arguments from the store`,
Example: ` faas-cli store deploy figlet
faas-cli store deploy figlet \
--gateway=http://localhost:8080 \
--gateway=http://127.0.0.1:8080 \
--env=MYVAR=myval`,
RunE: runStoreDeploy,
}
Expand Down