mirror of https://github.com/knative/func.git
initialize using a k8s-friendly name derived from full service name
This commit is contained in:
parent
b75edf2d82
commit
a4565d497f
|
@ -7,6 +7,8 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/lkingland/faas/k8s"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NameMappings are short-name to repository full name mappings,
|
// NameMappings are short-name to repository full name mappings,
|
||||||
|
@ -39,11 +41,14 @@ func (n *Initializer) Initialize(name, language, path string) error {
|
||||||
|
|
||||||
// Appsody does not support domain names as the project name
|
// Appsody does not support domain names as the project name
|
||||||
// (ex: www.example.com), and has extremely strict naming requirements
|
// (ex: www.example.com), and has extremely strict naming requirements
|
||||||
// (only lower case letters, numbers and dashes). So for now replace
|
// (subdomains per rfc 1035). So let's just assume its name must be a valid domain, and
|
||||||
// any dots with dashes.
|
// encode it as a 1035 domain by doubling down on hyphens.
|
||||||
name = strings.ReplaceAll(name, ".", "-")
|
project, err := k8s.ToSubdomain(name)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
// Dereference stack short name
|
// Dereference stack short name. ex. "go" -> "go-ce-functions"
|
||||||
stackName, ok := stackShortNames[language]
|
stackName, ok := stackShortNames[language]
|
||||||
if !ok {
|
if !ok {
|
||||||
languages := []string{}
|
languages := []string{}
|
||||||
|
@ -56,13 +61,12 @@ func (n *Initializer) Initialize(name, language, path string) error {
|
||||||
|
|
||||||
// set up the command, specifying a sanitized project name and connecting
|
// set up the command, specifying a sanitized project name and connecting
|
||||||
// standard output and error.
|
// standard output and error.
|
||||||
cmd := exec.Command("appsody", "init", "boson/"+stackName, "--project-name", name)
|
cmd := exec.Command("appsody", "init", "boson/"+stackName, "--project-name", project)
|
||||||
cmd.Dir = path
|
cmd.Dir = path
|
||||||
|
|
||||||
fmt.Println(cmd)
|
|
||||||
|
|
||||||
// If verbose logging is enabled, echo appsody's chatty stdout.
|
// If verbose logging is enabled, echo appsody's chatty stdout.
|
||||||
if n.Verbose {
|
if n.Verbose {
|
||||||
|
fmt.Println(cmd)
|
||||||
cmd.Stdout = os.Stdout
|
cmd.Stdout = os.Stdout
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
package k8s
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"k8s.io/apimachinery/pkg/util/validation"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ToSubdomain converts a domain to a subdomain.
|
||||||
|
// If the input is not a valid domain an error is thrown.
|
||||||
|
func ToSubdomain(in string) (string, error) {
|
||||||
|
if err := validation.IsFullyQualifiedDomainName(nil, in); err != nil {
|
||||||
|
return "", err.ToAggregate()
|
||||||
|
}
|
||||||
|
|
||||||
|
out := []rune{}
|
||||||
|
for _, c := range in {
|
||||||
|
// convert dots to hyphens
|
||||||
|
if c == '.' {
|
||||||
|
out = append(out, '-')
|
||||||
|
} else if c == '-' {
|
||||||
|
out = append(out, '-')
|
||||||
|
out = append(out, '-')
|
||||||
|
} else {
|
||||||
|
out = append(out, c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return string(out), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// FromSubdomain converts a doman which has been encoded as
|
||||||
|
// a subdomain using the algorithm of ToSubdoman back to a domain.
|
||||||
|
// Input errors if not a 1035 label.
|
||||||
|
func FromSubdomain(in string) (string, error) {
|
||||||
|
if errs := validation.IsDNS1035Label(in); len(errs) > 0 {
|
||||||
|
return "", errors.New(strings.Join(errs, ","))
|
||||||
|
}
|
||||||
|
|
||||||
|
rr := []rune(in)
|
||||||
|
out := []rune{}
|
||||||
|
|
||||||
|
for i := 0; i < len(rr); i++ {
|
||||||
|
c := rr[i]
|
||||||
|
if c == '-' {
|
||||||
|
// If the next rune is either nonexistent
|
||||||
|
// or not also a dash, this is an encoded dot.
|
||||||
|
if i+1 == len(rr) || rr[i+1] != '-' {
|
||||||
|
out = append(out, '.')
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the next rune is also a dash, this is
|
||||||
|
// an escaping dash, so append a slash, and
|
||||||
|
// increment the pointer such that the next
|
||||||
|
// loop begins with the next potential tuple.
|
||||||
|
if rr[i+1] == '-' {
|
||||||
|
out = append(out, '-')
|
||||||
|
i++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out = append(out, c)
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(out), nil
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
package k8s
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
// TestToSubdomain ensures that a valid domain name is
|
||||||
|
// encoded into the expected subdmain.
|
||||||
|
func TestToSubdomain(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
In string
|
||||||
|
Out string
|
||||||
|
Err bool
|
||||||
|
}{
|
||||||
|
{"", "", true}, // invalid domain
|
||||||
|
{"*", "", true}, // invalid domain
|
||||||
|
{"example", "", true}, // invalid domain
|
||||||
|
{"example.com", "example-com", false},
|
||||||
|
{"my-domain.com", "my--domain-com", false},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range cases {
|
||||||
|
out, err := ToSubdomain(c.In)
|
||||||
|
if err != nil && !c.Err {
|
||||||
|
t.Fatalf("Unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
if out != c.Out {
|
||||||
|
t.Fatalf("expected '%v' to yield '%v', got '%v'", c.In, c.Out, out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestFromSubdomain ensures that a valid subdomain is decoded
|
||||||
|
// back into a domain.
|
||||||
|
func TestFromSubdomain(t *testing.T) {
|
||||||
|
cases := []struct {
|
||||||
|
In string
|
||||||
|
Out string
|
||||||
|
Err bool
|
||||||
|
}{
|
||||||
|
{"", "", true}, // invalid subdomain
|
||||||
|
{"*", "", true}, // invalid subdomain
|
||||||
|
{"example-com", "example.com", false},
|
||||||
|
{"my--domain-com", "my-domain.com", false},
|
||||||
|
{"cdn----1-my--domain-com", "cdn--1.my-domain.com", false},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, c := range cases {
|
||||||
|
out, err := FromSubdomain(c.In)
|
||||||
|
if err != nil && !c.Err {
|
||||||
|
t.Fatalf("Unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
if out != c.Out {
|
||||||
|
t.Fatalf("expected '%v' to yield '%v', got '%v'", c.In, c.Out, out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue