Skip to content

Commit

Permalink
Add template pull stack
Browse files Browse the repository at this point in the history
Adding tempalte pull stack command which will pull tempaltes
from configuration field in the function yaml or from separate
yaml file with that same field

Signed-off-by: Martin Dekov <mvdekov@gmail.com>
  • Loading branch information
martindekov committed Sep 3, 2019
1 parent 7af2864 commit c0b6790
Show file tree
Hide file tree
Showing 6 changed files with 220 additions and 24 deletions.
24 changes: 24 additions & 0 deletions commands/fetch_templates.go
Expand Up @@ -116,3 +116,27 @@ func moveTemplates(repoPath string, overwrite bool) ([]string, []string, error)

return existingLanguages, fetchedLanguages, nil
}

func pullTemplate(repository string) error {
if _, err := os.Stat(repository); err != nil {
if !versioncontrol.IsGitRemote(repository) && !versioncontrol.IsPinnedGitRemote(repository) {
return fmt.Errorf("The repository URL must be a valid git repo uri")
}
}

repository, refName := versioncontrol.ParsePinnedRemote(repository)

if err := versioncontrol.GitCheckRefName.Invoke("", map[string]string{"refname": refName}); err != nil {
fmt.Printf("Invalid tag or branch name `%s`\n", refName)
fmt.Println("See https://git-scm.com/docs/git-check-ref-format for more details of the rules Git enforces on branch and reference names.")

return err
}

fmt.Printf("Fetch templates from repository: %s at %s\n", repository, refName)
if err := fetchTemplates(repository, refName, overwrite); err != nil {
return fmt.Errorf("error while fetching templates: %s", err)
}

return nil
}
24 changes: 1 addition & 23 deletions commands/template_pull.go
Expand Up @@ -4,9 +4,7 @@ package commands

import (
"fmt"
"os"

"github.com/openfaas/faas-cli/versioncontrol"
"github.com/spf13/cobra"
)

Expand Down Expand Up @@ -44,28 +42,8 @@ func runTemplatePull(cmd *cobra.Command, args []string) error {
if len(args) > 0 {
repository = args[0]
}
repository = getTemplateURL(repository, os.Getenv(templateURLEnvironment), DefaultTemplateRepository)

if _, err := os.Stat(repository); err != nil {
if !versioncontrol.IsGitRemote(repository) && !versioncontrol.IsPinnedGitRemote(repository) {
return fmt.Errorf("The repository URL must be a valid git repo uri")
}
}

repository, refName := versioncontrol.ParsePinnedRemote(repository)

if err := versioncontrol.GitCheckRefName.Invoke("", map[string]string{"refname": refName}); err != nil {
fmt.Printf("Invalid tag or branch name `%s`\n", refName)
fmt.Println("See https://git-scm.com/docs/git-check-ref-format for more details of the rules Git enforces on branch and reference names.")

return err
}

fmt.Printf("Fetch templates from repository: %s at %s\n", repository, refName)
if err := fetchTemplates(repository, refName, overwrite); err != nil {
return fmt.Errorf("error while fetching templates: %s", err)
}
return nil
return pullTemplate(repository)
}

func pullDebugPrint(message string) {
Expand Down
100 changes: 100 additions & 0 deletions commands/template_pull_stack.go
@@ -0,0 +1,100 @@
package commands

import (
"fmt"
"io/ioutil"

"gopkg.in/yaml.v2"

"github.com/openfaas/faas-cli/stack"
"github.com/spf13/cobra"
)

var (
templateURL string
customRepoName string
)

func init() {
templatePullStackCmd.Flags().BoolVar(&overwrite, "overwrite", false, "Overwrite existing templates?")
templatePullStackCmd.Flags().BoolVar(&pullDebug, "debug", false, "Enable debug output")
templatePullStackCmd.PersistentFlags().StringVarP(&customRepoName, "repo", "r", "", "The custom name of the template repo")

templatePullCmd.AddCommand(templatePullStackCmd)
}

var templatePullStackCmd = &cobra.Command{
Use: `stack`,
Short: `Downloads templates specified in the function definition yaml file`,
Long: `Downloads templates specified in the function yaml file, in the current directory
`,
Example: `
faas-cli template pull stack
faas-cli template pull stack -f myfunction.yml
faas-cli template pull stack -r custom_repo_name
`,
RunE: runTemplatePullStack,
}

func runTemplatePullStack(cmd *cobra.Command, args []string) error {
templatesConfig, err := loadTemplateConfig()
if err != nil {
return err
}
err = pullTemplatesFromConfig(templatesConfig, customRepoName)
if err != nil {
return err
}
return nil
}

func loadTemplateConfig() (map[string]string, error) {
stackConfig, err := readStackConfig()
if err != nil {
return nil, err
}
return stackConfig.StackConfig.TemlpatesConfigs, nil
}

func readStackConfig() (stack.Configuration, error) {
configField := stack.Configuration{}

configFieldBytes, err := ioutil.ReadFile(yamlFile)
if err != nil {
return configField, fmt.Errorf("Error while reading files %s", err.Error())
}
unmarshallErr := yaml.Unmarshal(configFieldBytes, &configField)
if unmarshallErr != nil {
return configField, fmt.Errorf("Error while reading configuration: %s", err.Error())
}
if len(configField.StackConfig.TemlpatesConfigs) == 0 {
return configField, fmt.Errorf("Error while reading configuration: no template repos currently configured")
}
return configField, nil
}

func pullTemplatesFromConfig(templateInfo map[string]string, customName string) error {
if len(customName) > 0 {
templateInfo = findTemplate(templateInfo, customName)
if templateInfo == nil {
return fmt.Errorf("Unable to find template repo with name: `%s`", customName)
}
}
for key, val := range templateInfo {
fmt.Printf("Pulling template repo: `%s` from configuration file: `%s`\n", key, yamlFile)
pullErr := pullTemplate(val)
if pullErr != nil {
return pullErr
}
}
return nil
}

func findTemplate(templateInfo map[string]string, customName string) (specificTemplate map[string]string) {
for key, val := range templateInfo {
if key == customName {
return map[string]string{key: val}
}
}
return nil
}
86 changes: 86 additions & 0 deletions commands/template_pull_stack_test.go
@@ -0,0 +1,86 @@
package commands

import (
"reflect"
"testing"
)

func Test_findTemplate(t *testing.T) {
tests := []struct {
title string
desiredTemplate string
existingTempaltes map[string]string
expectedTemplate map[string]string
}{
{
title: "Desired template is found",
desiredTemplate: "powershell",
existingTempaltes: map[string]string{"powershell": "exampleURL", "rust": "exampleURL"},
expectedTemplate: map[string]string{"powershell": "exampleURL"},
},
{
title: "Desired template is not found",
desiredTemplate: "golang",
existingTempaltes: map[string]string{"powershell": "exampleURL", "rust": "exampleURL"},
expectedTemplate: nil,
},
}
for _, test := range tests {
t.Run(test.title, func(t *testing.T) {
result := findTemplate(test.existingTempaltes, test.desiredTemplate)
if !reflect.DeepEqual(result, test.expectedTemplate) {
t.Errorf("Wanted template: `%s` got `%s`", test.expectedTemplate, result)
}
})
}
}

func Test_pullTemplatesFromConfig(t *testing.T) {
tests := []struct {
title string
desiredTemplate string
existingTempaltes map[string]string
expectedError bool
}{
{
title: "Pull specific tempalte",
desiredTemplate: "my_powershell",
existingTempaltes: map[string]string{
"my_powershell": "https://github.com/openfaas-incubator/powershell-http-template",
"my_rust": "https://github.com/openfaas-incubator/openfaas-rust-template"},
expectedError: false,
},
{
title: "Pull all templates",
desiredTemplate: "",
existingTempaltes: map[string]string{
"my_powershell": "https://github.com/openfaas-incubator/powershell-http-template",
"my_rust": "https://github.com/openfaas-incubator/openfaas-rust-template"},
expectedError: false,
},
{
title: "Pull non-existant template",
desiredTemplate: "my_golang",
existingTempaltes: map[string]string{
"my_powershell": "exampleURL",
"my_rust": "https://github.com/openfaas-incubator/openfaas-rust-template"},
expectedError: true,
},
{
title: "Pull template with invalid URL",
desiredTemplate: "my_golang",
existingTempaltes: map[string]string{
"my_powershell": "invalidURL",
},
expectedError: true,
},
}
for _, test := range tests {
t.Run(test.title, func(t *testing.T) {
actualError := pullTemplatesFromConfig(test.existingTempaltes, test.desiredTemplate)
if actualError != nil && test.expectedError == false {
t.Errorf("Unexpected error: %s", actualError.Error())
}
})
}
}
2 changes: 1 addition & 1 deletion commands/template_pull_test.go
Expand Up @@ -60,7 +60,7 @@ func Test_templatePull(t *testing.T) {
faasCmd.SetArgs([]string{"template", "pull", localTemplateRepository, "--overwrite"})
err = faasCmd.Execute()
if err != nil {
fmt.Errorf("unexpected error while executing template pull with --overwrite: %s", err.Error())
t.Errorf("unexpected error while executing template pull with --overwrite: %s", err.Error())
}

str := buf.String()
Expand Down
8 changes: 8 additions & 0 deletions stack/schema.go
Expand Up @@ -58,6 +58,14 @@ type Function struct {
Annotations *map[string]string `yaml:"annotations"`
}

type Configuration struct {
StackConfig StackConfiguration `yaml:"configuration"`
}

type StackConfiguration struct {
TemlpatesConfigs map[string]string `yaml:"templates"`
}

// FunctionResources Memory and CPU
type FunctionResources struct {
Memory string `yaml:"memory"`
Expand Down

0 comments on commit c0b6790

Please sign in to comment.