Skip to content

Commit

Permalink
decouple function name from function domain
Browse files Browse the repository at this point in the history
Signed-off-by: Zbynek Roubalik <zroubali@redhat.com>
  • Loading branch information
Zbynek Roubalik committed Sep 18, 2020
1 parent 5b93955 commit 233de05
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 45 deletions.
13 changes: 6 additions & 7 deletions client.go
Expand Up @@ -306,6 +306,12 @@ func (c *Client) Create(cfg Function) (err error) {
// Initialize creates a new Function project locally using the settings
// provided on a Function object.
func (c *Client) Initialize(cfg Function) (err error) {

// Create project root directory, if it doesn't already exist
if err = os.MkdirAll(cfg.Root, 0755); err != nil {
return
}

// Create Function of the given root path.
f, err := NewFunction(cfg.Root)
if err != nil {
Expand All @@ -322,13 +328,6 @@ func (c *Client) Initialize(cfg Function) (err error) {

// Set the name to that provided, defaulting to path derivation if empty.
f.Name = cfg.Name
if cfg.Name == "" {
f.Name = pathToDomain(f.Root, c.domainSearchLimit)
if f.Name == "" {
err = errors.New("Function name must be deriveable from path or explicitly provided")
return
}
}

// Assert runtime was provided, or default.
f.Runtime = cfg.Runtime
Expand Down
14 changes: 7 additions & 7 deletions cmd/create.go
Expand Up @@ -20,7 +20,6 @@ func init() {
createCmd.Flags().BoolP("confirm", "c", false, "Prompt to confirm all configuration options - $FAAS_CONFIRM")
createCmd.Flags().StringP("image", "i", "", "Optional full image name, in form [registry]/[namespace]/[name]:[tag] for example quay.io/myrepo/project.name:latest (overrides --repository) - $FAAS_IMAGE")
createCmd.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")
createCmd.Flags().StringP("path", "p", cwd(), "Path to the new project directory - $FAAS_PATH")
createCmd.Flags().StringP("repository", "r", "", "Repository for built images, ex 'docker.io/myuser' or just 'myuser'. Optional if --image provided. - $FAAS_REPOSITORY")
createCmd.Flags().StringP("runtime", "l", faas.DefaultRuntime, "Function runtime language/framework. - $FAAS_RUNTIME")
createCmd.Flags().StringP("templates", "", filepath.Join(configPath(), "faas", "templates"), "Extensible templates path. - $FAAS_TEMPLATES")
Expand All @@ -41,15 +40,15 @@ var createCmd = &cobra.Command{
Use: "create <name> [options]",
Short: "Create a new Function, including initialization of local files and deployment.",
SuggestFor: []string{"cerate", "new"},
PreRunE: bindEnv("image", "namespace", "path", "repository", "runtime", "templates", "trigger", "confirm"),
PreRunE: bindEnv("image", "namespace", "repository", "runtime", "templates", "trigger", "confirm"),
RunE: runCreate,
}

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

function := faas.Function{
Name: config.Name,
Name: config.initConfig.Name,
Root: config.initConfig.Path,
Runtime: config.initConfig.Runtime,
Trigger: config.Trigger,
Expand Down Expand Up @@ -110,19 +109,20 @@ func newCreateConfig(args []string) createConfig {
// Skipped if not in an interactive terminal (non-TTY), or if --confirm (agree to
// all prompts) was not explicitly set.
func (c createConfig) Prompt() createConfig {
name := deriveName(c.Name, c.initConfig.Path)
if !interactiveTerminal() || !c.initConfig.Confirm {
// Just print the basics if not confirming
fmt.Printf("Project path: %v\n", c.initConfig.Path)
fmt.Printf("Project name: %v\n", name)
fmt.Printf("Project name: %v\n", c.initConfig.Name)
fmt.Printf("Runtime: %v\n", c.Runtime)
fmt.Printf("Trigger: %v\n", c.Trigger)
return c
}

derivedName, derivedPath := deriveNameAndPath(prompt.ForString("Project name", "", prompt.WithRequired(true)))
return createConfig{
initConfig: initConfig{
Path: prompt.ForString("Project path", c.initConfig.Path),
Name: prompt.ForString("Project name", name, prompt.WithRequired(true)),
Name: derivedName,
Path: derivedPath,
Runtime: prompt.ForString("Runtime", c.Runtime),
Trigger: prompt.ForString("Trigger", c.Trigger),
// Templates intentionally omitted from prompt for being an edge case.
Expand Down
20 changes: 11 additions & 9 deletions cmd/init.go
Expand Up @@ -14,7 +14,6 @@ import (
func init() {
root.AddCommand(initCmd)
initCmd.Flags().BoolP("confirm", "c", false, "Prompt to confirm all configuration options - $FAAS_CONFIRM")
initCmd.Flags().StringP("path", "p", cwd(), "Path to the new project directory - $FAAS_PATH")
initCmd.Flags().StringP("runtime", "l", faas.DefaultRuntime, "Function runtime language/framework. - $FAAS_RUNTIME")
initCmd.Flags().StringP("templates", "", filepath.Join(configPath(), "faas", "templates"), "Extensible templates path. - $FAAS_TEMPLATES")
initCmd.Flags().StringP("trigger", "t", faas.DefaultTrigger, "Function trigger (ex: 'http','events') - $FAAS_TRIGGER")
Expand All @@ -28,7 +27,7 @@ var initCmd = &cobra.Command{
Use: "init <name> [options]",
Short: "Initialize a new Function project",
SuggestFor: []string{"inti", "new"},
PreRunE: bindEnv("path", "runtime", "templates", "trigger", "confirm"),
PreRunE: bindEnv("runtime", "templates", "trigger", "confirm"),
RunE: runInit,
// TODO: autocomplate Functions for runtime and trigger.
}
Expand All @@ -49,10 +48,10 @@ func runInit(cmd *cobra.Command, args []string) error {
}

type initConfig struct {
// Name of the service in DNS-compatible format (ex myfunc.example.com)
// Name of the function.
Name string

// Path to files on disk. Defaults to current working directory.
// Absolute path to project on disk.
Path string

// Runtime language/framework.
Expand Down Expand Up @@ -82,9 +81,11 @@ func newInitConfig(args []string) initConfig {
if len(args) > 0 {
name = args[0] // If explicitly provided, use.
}

derivedName, derivedPath := deriveNameAndPath(name)
return initConfig{
Name: deriveName(name, viper.GetString("path")), // args[0] or derived
Path: viper.GetString("path"),
Name: derivedName,
Path: derivedPath,
Runtime: viper.GetString("runtime"),
Templates: viper.GetString("templates"),
Trigger: viper.GetString("trigger"),
Expand All @@ -105,10 +106,11 @@ func (c initConfig) Prompt() initConfig {
fmt.Printf("Trigger: %v\n", c.Trigger)
return c
}

derivedName, derivedPath := deriveNameAndPath(prompt.ForString("Project name", "", prompt.WithRequired(true)))
return initConfig{
// TODO: Path should be prompted for and set prior to name attempting path derivation. Test/fix this if necessary.
Path: prompt.ForString("Project path", c.Path),
Name: prompt.ForString("Project name", name, prompt.WithRequired(true)),
Name: derivedName,
Path: derivedPath,
Runtime: prompt.ForString("Runtime", c.Runtime),
Trigger: prompt.ForString("Trigger", c.Trigger),
// Templates intentiopnally omitted from prompt for being an edge case.
Expand Down
24 changes: 24 additions & 0 deletions cmd/root.go
Expand Up @@ -3,6 +3,8 @@ package cmd
import (
"fmt"
"os"
"path/filepath"
"strings"

"github.com/mitchellh/go-homedir"
"github.com/ory/viper"
Expand Down Expand Up @@ -182,6 +184,28 @@ func deriveName(explicitName string, path string) string {
return derivedName
}

// deriveNameAndPath returns resolved function name and absolute path
// to the function project root. The input parameter name could be one of:
// 'relative/path/to/foo', '/absolute/path/to/foo', 'foo' or '.'
func deriveNameAndPath(name string) (string, string) {
var absPath string

// If '.' is specified as a function name, we would like to use current working dir
if name == "." {
name = cwd()
}

// Expand the passed function name to its absolute path
absPath, err := filepath.Abs(name)
if err != nil {
return "", ""
}

// Get the name of the function, which equals to name of the current directory
pathParts := strings.Split(name, string(os.PathSeparator))
return pathParts[len(pathParts)-1], absPath
}

// deriveImage returns the same image name which will be used if no explicit
// image is provided. I.e. derived from the configured repository (registry
// plus username) and the Function's name.
Expand Down
1 change: 1 addition & 0 deletions function.go
Expand Up @@ -209,6 +209,7 @@ func isEffectivelyEmpty(dir string) (bool, error) {
return true, nil
}

// TODO
// Convert a path to a domain.
// Searches up the path string until a domain (TLD+1) is detected.
// Subdirectories are considered subdomains.
Expand Down
3 changes: 0 additions & 3 deletions k8s/names.go
Expand Up @@ -10,9 +10,6 @@ import (
// 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 {
Expand Down
19 changes: 0 additions & 19 deletions knative/deployer.go
Expand Up @@ -5,7 +5,6 @@ import (
"fmt"
"io"
"os"
"strings"

commands "knative.dev/client/pkg/kn/commands"
"knative.dev/client/pkg/kn/core"
Expand Down Expand Up @@ -46,22 +45,6 @@ func (d *Deployer) Deploy(f faas.Function) (err error) {
output = &bytes.Buffer{}
}

// FIXME(lkinglan): The labels set explicitly here may interfere with the
// cluster configuraiton steps described in the documentation, and may also
// break on multi-level subdomains or if they are out of sync with that
// configuration. These could be removed from here, and instead the cluster
// expeted to be configured correctly. It is a future enhancement that an
// attempt to deploy a publicly accessible Function of a hithertoo unseen
// TLD+1 will modify this config-map.
// See https://github.com/boson-project/faas/issues/47
nn := strings.Split(f.Name, ".")
if len(nn) < 3 {
err = fmt.Errorf("invalid service name '%v', must be at least three parts.\n", f.Name)
return
}
subDomain := nn[0]
domain := strings.Join(nn[1:], ".")

params := commands.KnParams{}
params.Initialize()
params.Output = output
Expand All @@ -71,8 +54,6 @@ func (d *Deployer) Deploy(f faas.Function) (err error) {
"service", "create", encodedName,
"--image", f.Image,
"--env", "VERBOSE=true",
"--label", fmt.Sprintf("faas.domain=%s", domain),
"--annotation", fmt.Sprintf("faas.subdomain=%s", subDomain),
"--label", "bosonFunction=true",
}
if d.Namespace != "" {
Expand Down

0 comments on commit 233de05

Please sign in to comment.