Skip to content
Permalink
Browse files

Add openfaas-ingress app installation command

Signed-off-by: Alistair Hey <alistair.hey@gmail.com>
  • Loading branch information...
Waterdrips authored and alexellis committed Oct 24, 2019
1 parent 02a5c25 commit e6c9b8cda4fb3e1bb2747186da9e90529f4ebd7a
Showing with 246 additions and 1 deletion.
  1. +1 −0 .gitignore
  2. +2 −1 pkg/cmd/apps.go
  3. +175 −0 pkg/cmd/openfaas_ingress_app.go
  4. +68 −0 pkg/cmd/openfaas_ingress_app_test.go
@@ -2,3 +2,4 @@ k3sup
bin/**
kubeconfig
.DS_Store
.idea/
@@ -41,10 +41,11 @@ func MakeApps() *cobra.Command {
install.AddCommand(makeInstallMetricsServer())
install.AddCommand(makeInstallInletsOperator())
install.AddCommand(makeInstallCertManager())
install.AddCommand(makeInstallOpenFaaSIngress())

return command
}

func getApps() []string {
return []string{"openfaas", "metrics-server", "cert-manager", "inlets-operator"}
return []string{"openfaas", "metrics-server", "cert-manager", "inlets-operator", "openfaas-ingress"}
}
@@ -0,0 +1,175 @@
package cmd

import (
"bytes"
"fmt"
"io/ioutil"
"log"
"os"
"path/filepath"

"text/template"

"github.com/spf13/cobra"
)

type InputData struct {
IngressDomain string
CertmanagerEmail string
}


func makeInstallOpenFaaSIngress() *cobra.Command {
var openfaasIngress = &cobra.Command{
Use: "openfaas-ingress",
Short: "Install openfaas ingress with TLS",
Long: `Install openfaas ingress. Requires cert-manager installation in the cluster. Please set --domain to your custom domain and set --email to your email - this email is used by letsencrypt for domain expiry etc.`,
Example: ` k3sup app install openfaas-ingress --domain openfaas.example.com --email openfaas@example.com`,
SilenceUsage: true,
}

openfaasIngress.Flags().StringP("domain", "d", "openfaas.example.com", "Custom Ingress Domain")
openfaasIngress.Flags().StringP("email", "e", "openfaas@example.com", "Letsencrypt Email")

openfaasIngress.RunE = func(command *cobra.Command, args []string) error {
kubeConfigPath := getDefaultKubeconfig()

if command.Flags().Changed("kubeconfig") {
kubeConfigPath, _ = command.Flags().GetString("kubeconfig")
}

fmt.Printf("Using kubeconfig: %s\n", kubeConfigPath)

email, _ := command.Flags().GetString("email")
domain, _ := command.Flags().GetString("domain")
yamlBytes := buildYaml(domain, email)

tempFile := writeTempFile(yamlBytes)

res, err := kubectlTask("apply", "-f", tempFile)

if err != nil {
log.Print(err)
return err
}

if res.Stderr != "" {
log.Printf("Unable to install this application. Have you got OpenFaas running in the openfaas namespace and cert-managet installed in cert-manager namespace? %s", res.Stderr)
return err
}





fmt.Println(`=======================================================================
= OpenFaaS Ingress and cert-manager ClusterIssuer have been installed =
=======================================================================
# You will need to ensure that your domain points to your cluster and is
# accessible through ports 80 and 443.
#
# This is used to validate your ownership of this domain by LetsEncrypt
# and then you can use https with your installation.
# Ingress to your domain has been installed for OpenFaas
# to see the ingress record run
kubectl get -n openfaas Ingress openfaas-gateway
# A cert-manager ClusterIssuer has been installed into the default
# namespace - to see the resource run
kubectl describe ClusterIssuer letsencrypt-prod
# To check the status of your certificate you can run
kubectl describe -n openfaas Certificate gw-openfaas
# It may take a while to be issued by LetsEncrypt, in the meantime a
# Self Signed cert will be installed
Thank you for using k3sup!`)

return nil
}

return openfaasIngress
}


func writeTempFile(input []byte) string {
var filename = filepath.Join(os.TempDir(), "temp_openfaas_ingress.yaml")

err := ioutil.WriteFile(filename,input, 0644)
if err != nil {
log.Panic("Could not open a temporary file to write our Yaml")
}
return filename
}

func buildYaml(domain string, email string) []byte {
tmpl, err := template.New("yaml").Parse(yamlTemplate)

if err != nil {
log.Panic("Error loading Yaml Template: ", err)
}

inputData := InputData{
IngressDomain: domain,
CertmanagerEmail: email,
}
var tpl bytes.Buffer

err = tmpl.Execute(&tpl, inputData)

if err != nil {
log.Panic("Error executing template: ", err)
}

return tpl.Bytes()
}


var yamlTemplate = `
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: openfaas-gateway
namespace: openfaas
annotations:
certmanager.k8s.io/acme-challenge-type: http01
cert-manager.io/cluster-issuer: letsencrypt-prod
kubernetes.io/ingress.class: nginx
spec:
rules:
- host: {{.IngressDomain}}
http:
paths:
- backend:
serviceName: gateway
servicePort: 8080
path: /
tls:
- hosts:
- {{.IngressDomain}}
secretName: gw-openfaas
---
apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
# You must replace this email address with your own.
# Let's Encrypt will use this to contact you about expiring
# certificates, and issues related to your account.
email: {{.CertmanagerEmail}}
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
# Secret resource used to store the account's private key.
name: example-issuer-account-key
# Add a single challenge solver, HTTP01 using nginx
solvers:
- http01:
ingress:
class: nginx`
@@ -0,0 +1,68 @@
package cmd

import (
"io/ioutil"
"testing"
)

func Test_build_yaml_returns_correct_substitutions(t *testing.T) {
got := string(buildYaml("openfaas.subdomain.example.com", "openfaas@subdomain.example.com"))
if want != got {
t.Errorf("suffix, want:%s, got:%s", want, got)
}
}


var want = `
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: openfaas-gateway
namespace: openfaas
annotations:
certmanager.k8s.io/acme-challenge-type: http01
cert-manager.io/cluster-issuer: letsencrypt-prod
kubernetes.io/ingress.class: nginx
spec:
rules:
- host: openfaas.subdomain.example.com
http:
paths:
- backend:
serviceName: gateway
servicePort: 8080
path: /
tls:
- hosts:
- openfaas.subdomain.example.com
secretName: gw-openfaas
---
apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
# You must replace this email address with your own.
# Let's Encrypt will use this to contact you about expiring
# certificates, and issues related to your account.
email: openfaas@subdomain.example.com
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
# Secret resource used to store the account's private key.
name: example-issuer-account-key
# Add a single challenge solver, HTTP01 using nginx
solvers:
- http01:
ingress:
class: nginx`

func Test_writeTempFile_writes_to_tmp(t *testing.T) {
var expected = ("some input string")
tmpLocation := writeTempFile([]byte(expected))

got, _:= ioutil.ReadFile(tmpLocation)
if string(got) != expected {
t.Errorf("suffix, want:%s, got:%s", want, got)
}
}

0 comments on commit e6c9b8c

Please sign in to comment.
You can’t perform that action at this time.