Fixes #838 Thanks to Lucas Roesler for his PR for buildx support #836 Signed-off-by: Utsav Anand <utsavanand2@gmail.com>
168 lines
3.9 KiB
Go
168 lines
3.9 KiB
Go
// Copyright (c) Alex Ellis 2017. All rights reserved.
|
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
|
|
package commands
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/openfaas/faas-cli/proxy"
|
|
storeV2 "github.com/openfaas/faas-cli/schema/store/v2"
|
|
"github.com/spf13/cobra"
|
|
)
|
|
|
|
var (
|
|
storeAddress string
|
|
verbose bool
|
|
storeDeployFlags DeployFlags
|
|
//Platform platform variable set at build time
|
|
Platform string
|
|
// if the CLI is built using buildx, then the Platform value needs to be mapped to
|
|
// one of the supported values used in the store.
|
|
shortPlatform = map[string]string{
|
|
"linux/arm/v6": "armhf",
|
|
"linux/amd64": "x86_64",
|
|
"linux/arm64": "arm64",
|
|
}
|
|
)
|
|
|
|
const (
|
|
defaultStore = "https://raw.githubusercontent.com/openfaas/store/master/functions.json"
|
|
maxDescriptionLen = 40
|
|
)
|
|
|
|
var platformValue string
|
|
|
|
func init() {
|
|
storeCmd.PersistentFlags().StringVarP(&storeAddress, "url", "u", defaultStore, "Alternative Store URL starting with http(s)://")
|
|
storeCmd.PersistentFlags().StringVarP(&platformValue, "platform", "p", Platform, "Target platform for store")
|
|
|
|
faasCmd.AddCommand(storeCmd)
|
|
}
|
|
|
|
var storeCmd = &cobra.Command{
|
|
Use: `store`,
|
|
Short: "OpenFaaS store commands",
|
|
Long: "Allows browsing and deploying OpenFaaS functions from a store",
|
|
}
|
|
|
|
func storeList(store string) ([]storeV2.StoreFunction, error) {
|
|
|
|
var storeData storeV2.Store
|
|
|
|
store = strings.TrimRight(store, "/")
|
|
|
|
timeout := 60 * time.Second
|
|
tlsInsecure := false
|
|
|
|
client := proxy.MakeHTTPClient(&timeout, tlsInsecure)
|
|
|
|
res, err := client.Get(store)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("cannot connect to OpenFaaS store at URL: %s", store)
|
|
}
|
|
|
|
if res.Body != nil {
|
|
defer res.Body.Close()
|
|
}
|
|
|
|
switch res.StatusCode {
|
|
case http.StatusOK:
|
|
bytesOut, err := ioutil.ReadAll(res.Body)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("cannot read result from OpenFaaS store at URL: %s", store)
|
|
}
|
|
|
|
jsonErr := json.Unmarshal(bytesOut, &storeData)
|
|
if jsonErr != nil {
|
|
return nil, fmt.Errorf("cannot parse result from OpenFaaS store at URL: %s\n%s", store, jsonErr.Error())
|
|
}
|
|
default:
|
|
bytesOut, err := ioutil.ReadAll(res.Body)
|
|
if err == nil {
|
|
return nil, fmt.Errorf("server returned unexpected status code: %d - %s", res.StatusCode, string(bytesOut))
|
|
}
|
|
}
|
|
|
|
return storeData.Functions, nil
|
|
}
|
|
|
|
func filterStoreList(functions []storeV2.StoreFunction, platform string) []storeV2.StoreFunction {
|
|
var filteredList []storeV2.StoreFunction
|
|
|
|
for _, function := range functions {
|
|
|
|
_, ok := getValueIgnoreCase(function.Images, platform)
|
|
|
|
if ok {
|
|
filteredList = append(filteredList, function)
|
|
}
|
|
}
|
|
|
|
return filteredList
|
|
}
|
|
|
|
//getValueIgnoreCase get a key value from map by ignoring case for key
|
|
func getValueIgnoreCase(kv map[string]string, key string) (string, bool) {
|
|
for k, v := range kv {
|
|
if strings.EqualFold(k, key) {
|
|
return v, true
|
|
}
|
|
}
|
|
return "", false
|
|
}
|
|
|
|
func storeFindFunction(functionName string, storeItems []storeV2.StoreFunction) *storeV2.StoreFunction {
|
|
var item storeV2.StoreFunction
|
|
|
|
for _, item = range storeItems {
|
|
if item.Name == functionName || item.Title == functionName {
|
|
return &item
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func getPlatform() string {
|
|
if len(Platform) == 0 {
|
|
return mainPlatform
|
|
}
|
|
return Platform
|
|
}
|
|
|
|
func getTargetPlatform(inputPlatform string) string {
|
|
if len(inputPlatform) == 0 {
|
|
currentPlatform := getPlatform()
|
|
target, ok := shortPlatform[currentPlatform]
|
|
if ok {
|
|
return target
|
|
}
|
|
return currentPlatform
|
|
}
|
|
return inputPlatform
|
|
}
|
|
|
|
func getStorePlatforms(functions []storeV2.StoreFunction) []string {
|
|
var distinctPlatformMap = make(map[string]bool)
|
|
var result []string
|
|
|
|
for _, function := range functions {
|
|
for key := range function.Images {
|
|
_, exists := distinctPlatformMap[key]
|
|
|
|
if !exists {
|
|
distinctPlatformMap[key] = true
|
|
result = append(result, key)
|
|
}
|
|
}
|
|
}
|
|
|
|
return result
|
|
}
|