mirror of
https://github.com/openfaas/faasd.git
synced 2025-06-08 16:06:47 +00:00
Add and enable basic auth to the gateway. This allows users to put their gateway on the internet and expose it to public networks without anyone being able to control their deployments. Added information to the README that allows users to get their gatewau basic auth password and username Signed-off-by: Alistair Hey <alistair@heyal.co.uk>
246 lines
5.3 KiB
Go
246 lines
5.3 KiB
Go
package cmd
|
|
|
|
import (
|
|
"fmt"
|
|
"github.com/pkg/errors"
|
|
"io/ioutil"
|
|
"log"
|
|
"os"
|
|
"os/signal"
|
|
"path"
|
|
"sync"
|
|
"syscall"
|
|
"time"
|
|
|
|
"github.com/alexellis/faasd/pkg"
|
|
"github.com/alexellis/k3sup/pkg/env"
|
|
"github.com/sethvargo/go-password/password"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
var upCmd = &cobra.Command{
|
|
Use: "up",
|
|
Short: "Start faasd",
|
|
RunE: runUp,
|
|
}
|
|
|
|
func runUp(_ *cobra.Command, _ []string) error {
|
|
|
|
clientArch, clientOS := env.GetClientArch()
|
|
|
|
if clientOS != "Linux" {
|
|
return fmt.Errorf("You can only use faasd on Linux")
|
|
}
|
|
clientSuffix := ""
|
|
switch clientArch {
|
|
case "x86_64":
|
|
clientSuffix = ""
|
|
break
|
|
case "armhf":
|
|
case "armv7l":
|
|
clientSuffix = "-armhf"
|
|
break
|
|
case "arm64":
|
|
case "aarch64":
|
|
clientSuffix = "-arm64"
|
|
}
|
|
|
|
authFileErr := errors.Wrap(makeBasicAuthFiles(), "Could not create gateway auth files")
|
|
if authFileErr != nil {
|
|
return authFileErr
|
|
}
|
|
|
|
services := makeServiceDefinitions(clientSuffix)
|
|
|
|
start := time.Now()
|
|
supervisor, err := pkg.NewSupervisor("/run/containerd/containerd.sock")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
log.Printf("Supervisor created in: %s\n", time.Since(start).String())
|
|
|
|
start = time.Now()
|
|
|
|
err = supervisor.Start(services)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
defer supervisor.Close()
|
|
|
|
log.Printf("Supervisor init done in: %s\n", time.Since(start).String())
|
|
|
|
shutdownTimeout := time.Second * 1
|
|
timeout := time.Second * 60
|
|
|
|
wg := sync.WaitGroup{}
|
|
wg.Add(1)
|
|
go func() {
|
|
sig := make(chan os.Signal, 1)
|
|
signal.Notify(sig, syscall.SIGTERM, syscall.SIGINT)
|
|
|
|
log.Printf("faasd: waiting for SIGTERM or SIGINT\n")
|
|
<-sig
|
|
|
|
log.Printf("Signal received.. shutting down server in %s\n", shutdownTimeout.String())
|
|
err := supervisor.Remove(services)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
}
|
|
time.AfterFunc(shutdownTimeout, func() {
|
|
wg.Done()
|
|
})
|
|
}()
|
|
|
|
go func() {
|
|
wd, _ := os.Getwd()
|
|
proxy := pkg.NewProxy(path.Join(wd, "hosts"), timeout)
|
|
proxy.Start()
|
|
}()
|
|
|
|
wg.Wait()
|
|
return nil
|
|
}
|
|
|
|
func makeBasicAuthFiles() error {
|
|
wd, _ := os.Getwd()
|
|
pwdFile := wd + "/basic-auth-password"
|
|
authPassword, err := password.Generate(63, 10, 0, false, true)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = makeFile(pwdFile, authPassword)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
userFile := wd + "/basic-auth-user"
|
|
err = makeFile(userFile, "admin")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func makeFile(filePath, fileContents string) error {
|
|
_, err := os.Stat(filePath)
|
|
if err == nil {
|
|
log.Printf("File exists: %q, Using data from this file",filePath)
|
|
return nil
|
|
} else if os.IsNotExist(err) {
|
|
log.Printf("Writing file: %q", filePath)
|
|
return ioutil.WriteFile(filePath, []byte(fileContents), 0644)
|
|
} else {
|
|
return err
|
|
}
|
|
}
|
|
|
|
func makeServiceDefinitions(archSuffix string) []pkg.Service {
|
|
wd, _ := os.Getwd()
|
|
|
|
secretMountDir := "/run/secrets/"
|
|
|
|
return []pkg.Service{
|
|
pkg.Service{
|
|
Name: "basic-auth-plugin",
|
|
Image: "docker.io/openfaas/basic-auth-plugin:0.18.10" + archSuffix,
|
|
Env: []string{
|
|
"port=8080",
|
|
"secret_mount_path=" + secretMountDir,
|
|
"user_filename=basic-auth-user",
|
|
"pass_filename=basic-auth-password",
|
|
},
|
|
Mounts: []pkg.Mount{
|
|
pkg.Mount{
|
|
Src:path.Join(wd, "/basic-auth-password"),
|
|
Dest:secretMountDir + "basic-auth-password",
|
|
},
|
|
pkg.Mount{
|
|
Src: path.Join(wd, "/basic-auth-user"),
|
|
Dest: secretMountDir + "basic-auth-user",
|
|
},
|
|
},
|
|
Caps: []string{"CAP_NET_RAW"},
|
|
Args: nil,
|
|
},
|
|
pkg.Service{
|
|
Name: "nats",
|
|
Env: []string{""},
|
|
Image: "docker.io/library/nats-streaming:0.11.2",
|
|
Caps: []string{},
|
|
Args: []string{"/nats-streaming-server", "-m", "8222", "--store=memory", "--cluster_id=faas-cluster"},
|
|
},
|
|
pkg.Service{
|
|
Name: "prometheus",
|
|
Env: []string{},
|
|
Image: "docker.io/prom/prometheus:v2.14.0",
|
|
Mounts: []pkg.Mount{
|
|
pkg.Mount{
|
|
Src: path.Join(wd, "prometheus.yml"),
|
|
Dest: "/etc/prometheus/prometheus.yml",
|
|
},
|
|
},
|
|
Caps: []string{"CAP_NET_RAW"},
|
|
},
|
|
pkg.Service{
|
|
Name: "gateway",
|
|
Env: []string{
|
|
"basic_auth=true",
|
|
"functions_provider_url=http://faas-containerd:8081/",
|
|
"direct_functions=false",
|
|
"read_timeout=60s",
|
|
"write_timeout=60s",
|
|
"upstream_timeout=65s",
|
|
"faas_nats_address=nats",
|
|
"faas_nats_port=4222",
|
|
"auth_proxy_url=http://basic-auth-plugin:8080/validate",
|
|
"auth_proxy_pass_body=false",
|
|
"secret_mount_path=" + secretMountDir,
|
|
},
|
|
Image: "docker.io/openfaas/gateway:0.18.8" + archSuffix,
|
|
Mounts: []pkg.Mount{
|
|
pkg.Mount{
|
|
Src:path.Join(wd, "/basic-auth-password"),
|
|
Dest:secretMountDir + "basic-auth-password",
|
|
},
|
|
pkg.Mount{
|
|
Src: path.Join(wd, "/basic-auth-user"),
|
|
Dest: secretMountDir + "basic-auth-user",
|
|
},
|
|
},
|
|
Caps: []string{"CAP_NET_RAW"},
|
|
},
|
|
pkg.Service{
|
|
Name: "queue-worker",
|
|
Env: []string{
|
|
"faas_nats_address=nats",
|
|
"faas_nats_port=4222",
|
|
"gateway_invoke=true",
|
|
"faas_gateway_address=gateway",
|
|
"ack_wait=5m5s",
|
|
"max_inflight=1",
|
|
"write_debug=false",
|
|
"basic_auth=true",
|
|
"secret_mount_path=" + secretMountDir,
|
|
},
|
|
Image: "docker.io/openfaas/queue-worker:0.9.0",
|
|
Mounts: []pkg.Mount{
|
|
pkg.Mount{
|
|
Src:path.Join(wd, "/basic-auth-password"),
|
|
Dest:secretMountDir + "basic-auth-password",
|
|
},
|
|
pkg.Mount{
|
|
Src: path.Join(wd, "/basic-auth-user"),
|
|
Dest: secretMountDir + "basic-auth-user",
|
|
},
|
|
},
|
|
Caps: []string{"CAP_NET_RAW"},
|
|
},
|
|
}
|
|
}
|