mirror of
https://github.com/fnproject/fn.git
synced 2022-10-28 21:29:17 +03:00
Switch to go-swagger for client lib and checks for IRON_TOKEN (#406)
* wip - for review, using go-swagger client and checking for IRON_TOKEN and passing as auth header. * wip - auth header * add golang builder * finish client builder * change gh username * fix git command * update readme and small fixes * some improvements * using go-swagger * fn new client * revert swagger * make fn routes and apps work with new client (go-swagger) * some fixes in fn apps * update functions_go
This commit is contained in:
@@ -24,6 +24,12 @@ ruby build.rb
|
||||
|
||||
Boom. That's it.
|
||||
|
||||
## Building with the Go Builder
|
||||
|
||||
```sh
|
||||
go run main.go
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
Sometimes this will fail due to github caching or something and versions will be off. Just bump version and retry.
|
||||
|
||||
@@ -22,7 +22,7 @@ ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
||||
def clone(lang)
|
||||
Dir.chdir 'tmp'
|
||||
ldir = "functions_#{lang}"
|
||||
if !Dir.exists? ldir
|
||||
if !Dir.exist? ldir
|
||||
cmd = "git clone https://github.com/iron-io/#{ldir}"
|
||||
stream_exec(cmd)
|
||||
else
|
||||
@@ -84,6 +84,12 @@ languages.each do |l|
|
||||
next
|
||||
end
|
||||
p options
|
||||
if l == 'go'
|
||||
puts "SKIPPING GO, it's manual for now."
|
||||
# This is using https://goswagger.io/ instead
|
||||
# TODO: run this build command instead: this works if run manually
|
||||
# glide install -v && docker run --rm -it -v $HOME/dev/go:/go -w /go/src/github.com/iron-io/functions_go quay.io/goswagger/swagger generate client -f https://raw.githubusercontent.com/iron-io/functions/master/docs/swagger.yml -A functions
|
||||
else
|
||||
gen = JSON.parse(HTTP.post("https://generator.swagger.io/api/gen/clients/#{l}",
|
||||
json: {
|
||||
swaggerUrl: swaggerUrl,
|
||||
@@ -96,6 +102,7 @@ languages.each do |l|
|
||||
zipfile = "tmp/#{lv}.zip"
|
||||
stream_exec "curl -o #{zipfile} #{gen['link']} -k"
|
||||
stream_exec "unzip -o #{zipfile} -d tmp/#{lv}"
|
||||
end
|
||||
|
||||
# delete the skip_files
|
||||
skip_files.each do |sf|
|
||||
|
||||
315
clients/main.go
Normal file
315
clients/main.go
Normal file
@@ -0,0 +1,315 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/go-openapi/loads/fmts"
|
||||
"github.com/go-openapi/spec"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"os/user"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
swaggerURL = "../docs/swagger.yml"
|
||||
rootTmpDir = "tmp"
|
||||
)
|
||||
|
||||
var cwd string
|
||||
|
||||
func main() {
|
||||
os.RemoveAll(rootTmpDir)
|
||||
cwd, _ = os.Getwd()
|
||||
defer func() {
|
||||
os.RemoveAll(rootTmpDir)
|
||||
}()
|
||||
|
||||
// Download swagger yaml and convert to JSON
|
||||
d, err := fmts.YAMLDoc(swaggerURL)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to convert swagger yaml to json: %v", err)
|
||||
}
|
||||
|
||||
var sw spec.Swagger
|
||||
if err := json.Unmarshal(d, &sw); err != nil {
|
||||
log.Fatalf("Failed to convert swagger yaml to json: %v", err)
|
||||
}
|
||||
|
||||
version := sw.Info.Version
|
||||
fmt.Printf("VERSION: %s\n", version)
|
||||
|
||||
swg, err := ioutil.ReadFile(swaggerURL)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to load swagger file: %v", err)
|
||||
}
|
||||
gistURL := createGist(swg)
|
||||
|
||||
var only string
|
||||
if len(os.Args) > 1 && os.Args[1] != "" {
|
||||
only = os.Args[1]
|
||||
}
|
||||
|
||||
var languages []string
|
||||
if only != "" {
|
||||
languages = append(languages, only)
|
||||
} else {
|
||||
// Download available languages from swagger generator api
|
||||
languages = getLanguages()
|
||||
}
|
||||
|
||||
for _, language := range languages {
|
||||
var skipFiles []string
|
||||
tmpDir := filepath.Join(rootTmpDir, language)
|
||||
srcDir := filepath.Join(tmpDir, "src")
|
||||
clientDir := filepath.Join(tmpDir, fmt.Sprintf("%s-client", language))
|
||||
short := language
|
||||
|
||||
options := make(map[string]interface{})
|
||||
var deploy [][]string
|
||||
|
||||
// Specfic language configurations
|
||||
switch language {
|
||||
case "go":
|
||||
options["packageName"] = "functions"
|
||||
options["packageVersion"] = version
|
||||
case "ruby":
|
||||
skipFiles = append(skipFiles, "#{gem_name}.gemspec")
|
||||
deploy = append(deploy, []string{"gem", "build #{gem_name}.gemspec", "gem push #{gem_name}-#{version}.gem"})
|
||||
options["gemName"] = "iron_functions"
|
||||
options["moduleName"] = "IronFunctions"
|
||||
options["gemVersion"] = version
|
||||
options["gemHomepage"] = "https://github.com/iron-io/functions_ruby"
|
||||
options["gemSummary"] = "Ruby gem for IronFunctions"
|
||||
options["gemDescription"] = "Ruby gem for IronFunctions."
|
||||
options["gemAuthorEmail"] = "travis@iron.io"
|
||||
case "javascript":
|
||||
short = "js"
|
||||
options["projectName"] = "iron_functions"
|
||||
deploy = append(deploy, []string{"npm", "publish"})
|
||||
default:
|
||||
continue
|
||||
}
|
||||
|
||||
log.Printf("Generating `%s` client...\n", language)
|
||||
err = os.MkdirAll(clientDir, 0777)
|
||||
if err != nil {
|
||||
log.Printf("Failed to create temporary directory for %s client. Skipping...", language)
|
||||
}
|
||||
|
||||
// Generate client
|
||||
if language == "go" {
|
||||
err := genSwaggerClient(clientDir)
|
||||
if err != nil {
|
||||
log.Printf("Failed to (swagger-go) generated %s client. Skipping...", language)
|
||||
continue
|
||||
}
|
||||
} else {
|
||||
gen, err := generateClient(gistURL, language, options)
|
||||
if err != nil {
|
||||
log.Printf("Failed to generated %s client. Skipping...", language)
|
||||
continue
|
||||
}
|
||||
|
||||
// Download generated client
|
||||
log.Printf("Downloading `%s` client...\n", language)
|
||||
gf, err := getFile(strings.Replace(gen.Link, "https", "http", 1))
|
||||
if err != nil {
|
||||
log.Printf("Failed to download generated %s client. Skipping...", language)
|
||||
}
|
||||
ioutil.WriteFile(filepath.Join(tmpDir, "gen.zip"), gf, 0777)
|
||||
|
||||
// Unzip
|
||||
log.Printf("Unzipping `%s` client...\n", language)
|
||||
exec.Command("unzip", "-o", filepath.Join(tmpDir, "gen.zip"), "-d", tmpDir).Run()
|
||||
os.Remove(filepath.Join(tmpDir, "gen.zip"))
|
||||
}
|
||||
|
||||
branch := fmt.Sprintf("update-version-%s", version)
|
||||
|
||||
log.Printf("Cloning previous `%s` source...\n", language)
|
||||
exec.Command("git", "clone", fmt.Sprintf("git@github.com:iron-io/functions_%s.git", short), srcDir).Run()
|
||||
|
||||
// Skip language specific files
|
||||
for _, skip := range skipFiles {
|
||||
os.Remove(filepath.Join(tmpDir, clientDir, skip))
|
||||
}
|
||||
|
||||
// Copying new client
|
||||
log.Printf("Copying new `%s` client to src directory\n", language)
|
||||
|
||||
// Only solution I found
|
||||
filepath.Walk(clientDir, func(path string, info os.FileInfo, err error) error {
|
||||
if path == clientDir {
|
||||
return nil
|
||||
}
|
||||
exec.Command("cp", "-r", path, srcDir).Run()
|
||||
if info.IsDir() {
|
||||
return filepath.SkipDir
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
f, err := os.OpenFile(filepath.Join(srcDir, "VERSION"), os.O_TRUNC|os.O_WRONLY, 0644)
|
||||
if err != nil {
|
||||
log.Printf("Failed to save new `%s` VERSION file. Skipping...", language)
|
||||
continue
|
||||
}
|
||||
f.WriteString(version)
|
||||
f.Close()
|
||||
|
||||
os.Chdir(srcDir)
|
||||
exec.Command("git", "checkout", "-b", branch).Run()
|
||||
exec.Command("git", "add", ".").Run()
|
||||
exec.Command("git", "commit", "-am", fmt.Sprintf("Updated to api version %s", version)).Run()
|
||||
|
||||
log.Printf("Pushing new `%s` client\n", language)
|
||||
r := exec.Command("git", "push", "origin", branch).Run()
|
||||
if r != nil && r.Error() != "" {
|
||||
log.Printf("Failed to push new version: %s\n", r.Error())
|
||||
break
|
||||
}
|
||||
|
||||
log.Printf("Releasing new `%s` client\n", language)
|
||||
for _, d := range deploy {
|
||||
exec.Command(d[0], d[1])
|
||||
}
|
||||
|
||||
log.Printf("Updated `%s` client to `%s` \n", language, version)
|
||||
|
||||
os.Chdir(cwd)
|
||||
}
|
||||
}
|
||||
|
||||
type generatedClient struct {
|
||||
Link string `json:"link"`
|
||||
}
|
||||
|
||||
func generateClient(url, lang string, options map[string]interface{}) (gc generatedClient, err error) {
|
||||
payload := map[string]interface{}{
|
||||
"swaggerUrl": url,
|
||||
"options": options,
|
||||
}
|
||||
|
||||
data, err := json.Marshal(payload)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := http.Post(fmt.Sprintf("http://generator.swagger.io/api/gen/clients/%s", lang), "application/json", bytes.NewBuffer(data))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
result, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = json.Unmarshal(result, &gc)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func getFile(url string) ([]byte, error) {
|
||||
resp, err := http.Get(url)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func getLanguages() (langs []string) {
|
||||
data, err := getFile("http://generator.swagger.io/api/gen/clients")
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to load swagger languages: %v", err)
|
||||
os.Exit(-1)
|
||||
}
|
||||
|
||||
err = json.Unmarshal(data, &langs)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to load swagger languages: %v", err)
|
||||
os.Exit(-1)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
type GistFile struct {
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
type Gist struct {
|
||||
Description string `json:"description"`
|
||||
Public bool `json:"public"`
|
||||
Files map[string]GistFile `json:"files"`
|
||||
}
|
||||
|
||||
type GistResponse struct {
|
||||
Files map[string]struct {
|
||||
RawURL string `json:"raw_url"`
|
||||
} `json:"files"`
|
||||
}
|
||||
|
||||
func createGist(b []byte) string {
|
||||
var responseObj GistResponse
|
||||
|
||||
gist := Gist{
|
||||
"",
|
||||
false,
|
||||
map[string]GistFile{
|
||||
"swaggerSpec": {string(b)},
|
||||
},
|
||||
}
|
||||
|
||||
b, err := json.Marshal(gist)
|
||||
if err != nil {
|
||||
log.Fatal("JSON Error: ", err)
|
||||
}
|
||||
|
||||
br := bytes.NewBuffer(b)
|
||||
resp, err := http.Post("https://api.github.com/gists", "application/json", br)
|
||||
if err != nil {
|
||||
log.Fatal("HTTP Error: ", err)
|
||||
}
|
||||
|
||||
err = json.NewDecoder(resp.Body).Decode(&responseObj)
|
||||
if err != nil {
|
||||
log.Fatal("Response JSON Error: ", err)
|
||||
}
|
||||
|
||||
return responseObj.Files["swaggerSpec"].RawURL
|
||||
}
|
||||
|
||||
const (
|
||||
goSwaggerImage = "quay.io/goswagger/swagger"
|
||||
)
|
||||
|
||||
func genSwaggerClient(target string) error {
|
||||
u, err := user.Current()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd := exec.Command("docker", "run", "--rm", "-u", fmt.Sprintf("%s:%s", u.Uid, u.Gid), "-v", fmt.Sprintf("%s/%s:/go/src/github.com/iron-io/functions_go", cwd, target), "-v", fmt.Sprintf("%s/%s:/go/swagger.spec", cwd, swaggerURL), "-w", "/go/src", "quay.io/goswagger/swagger", "generate", "client", "-f", "/go/swagger.spec", "-t", "github.com/iron-io/functions_go", "-A", "functions")
|
||||
d, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
log.Printf("Error running go-swagger: %s\n", d)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
37
fn/api.go
Normal file
37
fn/api.go
Normal file
@@ -0,0 +1,37 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
httptransport "github.com/go-openapi/runtime/client"
|
||||
"github.com/go-openapi/strfmt"
|
||||
fnclient "github.com/iron-io/functions_go/client"
|
||||
"log"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
func host() string {
|
||||
apiURL := os.Getenv("API_URL")
|
||||
if apiURL == "" {
|
||||
apiURL = "http://localhost:8080"
|
||||
}
|
||||
|
||||
u, err := url.Parse(apiURL)
|
||||
if err != nil {
|
||||
log.Fatalln("Couldn't parse API URL:", err)
|
||||
}
|
||||
|
||||
return u.Host
|
||||
}
|
||||
|
||||
func apiClient() *fnclient.Functions {
|
||||
transport := httptransport.New(host(), "/v1", []string{"http"})
|
||||
if os.Getenv("IRON_TOKEN") != "" {
|
||||
transport.DefaultAuthentication = httptransport.BearerToken(os.Getenv("IRON_TOKEN"))
|
||||
}
|
||||
|
||||
// create the API client, with the transport
|
||||
client := fnclient.New(transport, strfmt.Default)
|
||||
|
||||
return client
|
||||
}
|
||||
189
fn/apps.go
189
fn/apps.go
@@ -4,20 +4,22 @@ import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"text/tabwriter"
|
||||
|
||||
"github.com/iron-io/functions_go"
|
||||
"context"
|
||||
fnclient "github.com/iron-io/functions_go/client"
|
||||
apiapps "github.com/iron-io/functions_go/client/apps"
|
||||
"github.com/iron-io/functions_go/models"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
type appsCmd struct {
|
||||
*functions.AppsApi
|
||||
client *fnclient.Functions
|
||||
}
|
||||
|
||||
func apps() cli.Command {
|
||||
a := appsCmd{AppsApi: functions.NewAppsApi()}
|
||||
a := appsCmd{client: apiClient()}
|
||||
|
||||
return cli.Command{
|
||||
Name: "apps",
|
||||
@@ -90,25 +92,26 @@ func apps() cli.Command {
|
||||
}
|
||||
|
||||
func (a *appsCmd) list(c *cli.Context) error {
|
||||
if err := resetBasePath(a.Configuration); err != nil {
|
||||
return fmt.Errorf("error setting endpoint: %v", err)
|
||||
}
|
||||
resp, err := a.client.Apps.GetApps(&apiapps.GetAppsParams{
|
||||
Context: context.Background(),
|
||||
})
|
||||
|
||||
wrapper, _, err := a.AppsGet()
|
||||
if err != nil {
|
||||
return fmt.Errorf("error getting app: %v", err)
|
||||
switch err.(type) {
|
||||
case *apiapps.GetAppsAppNotFound:
|
||||
return fmt.Errorf("error: %v", err.(*apiapps.GetAppsAppNotFound).Payload.Error.Message)
|
||||
case *apiapps.GetAppsAppDefault:
|
||||
return fmt.Errorf("unexpected error: %v", err.(*apiapps.GetAppsAppDefault).Payload.Error.Message)
|
||||
}
|
||||
return fmt.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if msg := wrapper.Error_.Message; msg != "" {
|
||||
return errors.New(msg)
|
||||
}
|
||||
|
||||
if len(wrapper.Apps) == 0 {
|
||||
if len(resp.Payload.Apps) == 0 {
|
||||
fmt.Println("no apps found")
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, app := range wrapper.Apps {
|
||||
for _, app := range resp.Payload.Apps {
|
||||
fmt.Println(app.Name)
|
||||
}
|
||||
|
||||
@@ -120,24 +123,29 @@ func (a *appsCmd) create(c *cli.Context) error {
|
||||
return errors.New("error: app creating takes one argument, an app name")
|
||||
}
|
||||
|
||||
if err := resetBasePath(a.Configuration); err != nil {
|
||||
return fmt.Errorf("error setting endpoint: %v", err)
|
||||
}
|
||||
|
||||
body := functions.AppWrapper{App: functions.App{
|
||||
body := &models.AppWrapper{App: &models.App{
|
||||
Name: c.Args().Get(0),
|
||||
Config: extractEnvConfig(c.StringSlice("config")),
|
||||
}}
|
||||
wrapper, _, err := a.AppsPost(body)
|
||||
|
||||
resp, err := a.client.Apps.PostApps(&apiapps.PostAppsParams{
|
||||
Context: context.Background(),
|
||||
Body: body,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating app: %v", err)
|
||||
switch err.(type) {
|
||||
case *apiapps.PostAppsBadRequest:
|
||||
return fmt.Errorf("error: %v", err.(*apiapps.PostAppsBadRequest).Payload.Error.Message)
|
||||
case *apiapps.PostAppsConflict:
|
||||
return fmt.Errorf("error: %v", err.(*apiapps.PostAppsConflict).Payload.Error.Message)
|
||||
case *apiapps.PostAppsDefault:
|
||||
return fmt.Errorf("unexpected error: %v", err.(*apiapps.PostAppsDefault).Payload.Error.Message)
|
||||
}
|
||||
return fmt.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if msg := wrapper.Error_.Message; msg != "" {
|
||||
return errors.New(msg)
|
||||
}
|
||||
|
||||
fmt.Println(wrapper.App.Name, "created")
|
||||
fmt.Println(resp.Payload.App.Name, "created")
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -146,21 +154,24 @@ func (a *appsCmd) configList(c *cli.Context) error {
|
||||
return errors.New("error: app description takes one argument, an app name")
|
||||
}
|
||||
|
||||
if err := resetBasePath(a.Configuration); err != nil {
|
||||
return fmt.Errorf("error setting endpoint: %v", err)
|
||||
}
|
||||
|
||||
appName := c.Args().Get(0)
|
||||
wrapper, _, err := a.AppsAppGet(appName)
|
||||
|
||||
resp, err := a.client.Apps.GetAppsApp(&apiapps.GetAppsAppParams{
|
||||
Context: context.Background(),
|
||||
App: appName,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating app: %v", err)
|
||||
switch err.(type) {
|
||||
case *apiapps.GetAppsAppNotFound:
|
||||
return fmt.Errorf("error: %v", err.(*apiapps.GetAppsAppNotFound).Payload.Error.Message)
|
||||
case *apiapps.GetAppsAppDefault:
|
||||
return fmt.Errorf("unexpected error: %v", err.(*apiapps.GetAppsAppDefault).Payload.Error.Message)
|
||||
}
|
||||
return fmt.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if msg := wrapper.Error_.Message; msg != "" {
|
||||
return errors.New(msg)
|
||||
}
|
||||
|
||||
config := wrapper.App.Config
|
||||
config := resp.Payload.App.Config
|
||||
if len(config) == 0 {
|
||||
return errors.New("this application has no configurations")
|
||||
}
|
||||
@@ -171,11 +182,11 @@ func (a *appsCmd) configList(c *cli.Context) error {
|
||||
os.Exit(1)
|
||||
}
|
||||
} else if c.Bool("shell") {
|
||||
for k, v := range wrapper.App.Config {
|
||||
for k, v := range resp.Payload.App.Config {
|
||||
fmt.Print("export ", k, "=", v, "\n")
|
||||
}
|
||||
} else {
|
||||
fmt.Println(wrapper.App.Name, "configuration:")
|
||||
fmt.Println(resp.Payload.App.Name, "configuration:")
|
||||
w := tabwriter.NewWriter(os.Stdout, 0, 8, 1, ' ', 0)
|
||||
for k, v := range config {
|
||||
fmt.Fprint(w, k, ":\t", v, "\n")
|
||||
@@ -190,24 +201,26 @@ func (a *appsCmd) configSet(c *cli.Context) error {
|
||||
return errors.New("error: application configuration setting takes three arguments: an app name, a key and a value")
|
||||
}
|
||||
|
||||
if err := resetBasePath(a.Configuration); err != nil {
|
||||
return fmt.Errorf("error setting endpoint: %v", err)
|
||||
}
|
||||
|
||||
appName := c.Args().Get(0)
|
||||
key := c.Args().Get(1)
|
||||
value := c.Args().Get(2)
|
||||
|
||||
wrapper, _, err := a.AppsAppGet(appName)
|
||||
resp, err := a.client.Apps.GetAppsApp(&apiapps.GetAppsAppParams{
|
||||
Context: context.Background(),
|
||||
App: appName,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating app: %v", err)
|
||||
switch err.(type) {
|
||||
case *apiapps.GetAppsAppNotFound:
|
||||
return fmt.Errorf("error: %v", err.(*apiapps.GetAppsAppNotFound).Payload.Error.Message)
|
||||
case *apiapps.GetAppsAppDefault:
|
||||
return fmt.Errorf("unexpected error: %v", err.(*apiapps.GetAppsAppDefault).Payload.Error.Message)
|
||||
}
|
||||
return fmt.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if msg := wrapper.Error_.Message; msg != "" {
|
||||
return errors.New(msg)
|
||||
}
|
||||
|
||||
config := wrapper.App.Config
|
||||
config := resp.Payload.App.Config
|
||||
|
||||
if config == nil {
|
||||
config = make(map[string]string)
|
||||
@@ -215,11 +228,11 @@ func (a *appsCmd) configSet(c *cli.Context) error {
|
||||
|
||||
config[key] = value
|
||||
|
||||
if err := a.storeApp(appName, config); err != nil {
|
||||
if err := a.patchApp(appName, config); err != nil {
|
||||
return fmt.Errorf("error updating app configuration: %v", err)
|
||||
}
|
||||
|
||||
fmt.Println(wrapper.App.Name, "updated", key, "with", value)
|
||||
fmt.Println(resp.Payload.App.Name, "updated", key, "with", value)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -228,23 +241,25 @@ func (a *appsCmd) configUnset(c *cli.Context) error {
|
||||
return errors.New("error: application configuration setting takes three arguments: an app name, a key and a value")
|
||||
}
|
||||
|
||||
if err := resetBasePath(a.Configuration); err != nil {
|
||||
return fmt.Errorf("error setting endpoint: %v", err)
|
||||
}
|
||||
|
||||
appName := c.Args().Get(0)
|
||||
key := c.Args().Get(1)
|
||||
|
||||
wrapper, _, err := a.AppsAppGet(appName)
|
||||
resp, err := a.client.Apps.GetAppsApp(&apiapps.GetAppsAppParams{
|
||||
Context: context.Background(),
|
||||
App: appName,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating app: %v", err)
|
||||
switch err.(type) {
|
||||
case *apiapps.GetAppsAppNotFound:
|
||||
return fmt.Errorf("error: %v", err.(*apiapps.GetAppsAppNotFound).Payload.Error.Message)
|
||||
case *apiapps.GetAppsAppDefault:
|
||||
return fmt.Errorf("unexpected error: %v", err.(*apiapps.GetAppsAppDefault).Payload.Error.Message)
|
||||
}
|
||||
return fmt.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if msg := wrapper.Error_.Message; msg != "" {
|
||||
return errors.New(msg)
|
||||
}
|
||||
|
||||
config := wrapper.App.Config
|
||||
config := resp.Payload.App.Config
|
||||
|
||||
if config == nil {
|
||||
config = make(map[string]string)
|
||||
@@ -256,23 +271,37 @@ func (a *appsCmd) configUnset(c *cli.Context) error {
|
||||
|
||||
delete(config, key)
|
||||
|
||||
if err := a.storeApp(appName, config); err != nil {
|
||||
if err := a.patchApp(appName, config); err != nil {
|
||||
return fmt.Errorf("error updating app configuration: %v", err)
|
||||
}
|
||||
|
||||
fmt.Println(wrapper.App.Name, "removed", key)
|
||||
fmt.Println(resp.Payload.App.Name, "removed", key)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *appsCmd) storeApp(appName string, config map[string]string) error {
|
||||
body := functions.AppWrapper{App: functions.App{
|
||||
Name: appName,
|
||||
func (a *appsCmd) patchApp(appName string, config map[string]string) error {
|
||||
body := &models.AppWrapper{App: &models.App{
|
||||
Config: config,
|
||||
}}
|
||||
|
||||
if _, _, err := a.AppsPost(body); err != nil {
|
||||
return fmt.Errorf("error updating app configuration: %v", err)
|
||||
_, err := a.client.Apps.PatchAppsApp(&apiapps.PatchAppsAppParams{
|
||||
Context: context.Background(),
|
||||
App: appName,
|
||||
Body: body,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case *apiapps.PatchAppsAppBadRequest:
|
||||
return errors.New(err.(*apiapps.PatchAppsAppBadRequest).Payload.Error.Message)
|
||||
case *apiapps.PatchAppsAppNotFound:
|
||||
return errors.New(err.(*apiapps.PatchAppsAppNotFound).Payload.Error.Message)
|
||||
case *apiapps.PatchAppsAppDefault:
|
||||
return errors.New(err.(*apiapps.PatchAppsAppDefault).Payload.Error.Message)
|
||||
}
|
||||
return fmt.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -282,17 +311,19 @@ func (a *appsCmd) delete(c *cli.Context) error {
|
||||
return errors.New("error: deleting an app takes one argument, an app name")
|
||||
}
|
||||
|
||||
if err := resetBasePath(a.Configuration); err != nil {
|
||||
return fmt.Errorf("error setting endpoint: %v", err)
|
||||
}
|
||||
_, err := a.client.Apps.DeleteAppsApp(&apiapps.DeleteAppsAppParams{
|
||||
Context: context.Background(),
|
||||
App: appName,
|
||||
})
|
||||
|
||||
resp, err := a.AppsAppDelete(appName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error deleting app: %v", err)
|
||||
switch err.(type) {
|
||||
case *apiapps.DeleteAppsAppNotFound:
|
||||
return errors.New(err.(*apiapps.DeleteAppsAppNotFound).Payload.Error.Message)
|
||||
case *apiapps.DeleteAppsAppDefault:
|
||||
return errors.New(err.(*apiapps.DeleteAppsAppDefault).Payload.Error.Message)
|
||||
}
|
||||
|
||||
if resp.StatusCode == http.StatusBadRequest {
|
||||
return errors.New("could not delete this application - pending routes")
|
||||
return fmt.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
fmt.Println(appName, "deleted")
|
||||
|
||||
91
fn/glide.lock
generated
91
fn/glide.lock
generated
@@ -1,8 +1,10 @@
|
||||
hash: 9356255bb45ddb833b045e985b2dbf0721791b431849a4f36a50b0897e888c3c
|
||||
updated: 2016-12-29T19:40:42.322381915-02:00
|
||||
hash: a586a0b85eb753b0b618a3e763123480deb2ba6389496c1f1b897a9305326026
|
||||
updated: 2016-12-07T11:54:35.937180292-08:00
|
||||
imports:
|
||||
- name: github.com/asaskevich/govalidator
|
||||
version: 7b3beb6df3c42abd3509abfc3bcacc0fbfb7c877
|
||||
- name: github.com/aws/aws-sdk-go
|
||||
version: 90dec2183a5f5458ee79cbaf4b8e9ab910bc81a6
|
||||
version: db9509b01e2e00890091ca164aebf0b1ca62eef8
|
||||
subpackages:
|
||||
- aws
|
||||
- aws/awserr
|
||||
@@ -12,33 +14,42 @@ imports:
|
||||
- aws/corehandlers
|
||||
- aws/credentials
|
||||
- aws/credentials/ec2rolecreds
|
||||
- aws/credentials/endpointcreds
|
||||
- aws/credentials/stscreds
|
||||
- aws/defaults
|
||||
- aws/ec2metadata
|
||||
- aws/endpoints
|
||||
- aws/request
|
||||
- aws/session
|
||||
- aws/signer/v4
|
||||
- private/endpoints
|
||||
- private/protocol
|
||||
- private/protocol/json/jsonutil
|
||||
- private/protocol/jsonrpc
|
||||
- private/protocol/query
|
||||
- private/protocol/query/queryutil
|
||||
- private/protocol/rest
|
||||
- private/protocol/restjson
|
||||
- private/protocol/xml/xmlutil
|
||||
- service/lambda
|
||||
- service/sts
|
||||
- name: github.com/Azure/go-ansiterm
|
||||
version: fa152c58bc15761d0200cb75fe958b89a9d4888e
|
||||
subpackages:
|
||||
- winterm
|
||||
- name: github.com/coreos/go-semver
|
||||
version: 8ab6407b697782a06568d4b7f1db25550ec2e4c6
|
||||
version: 9474efc580562cce8f761659fbce31b6feb8ce88
|
||||
subpackages:
|
||||
- semver
|
||||
- name: github.com/docker/docker
|
||||
version: fae5a9e053ad06bea0429babae2507762d8cc1de
|
||||
version: eefbf1ddd3ee4e6b6e6dc7e938e77a96ceb40163
|
||||
subpackages:
|
||||
- api/types
|
||||
- api/types/blkiodev
|
||||
- api/types/container
|
||||
- api/types/filters
|
||||
- api/types/mount
|
||||
- api/types/network
|
||||
- api/types/registry
|
||||
- api/types/strslice
|
||||
- api/types/swarm
|
||||
- api/types/versions
|
||||
@@ -58,26 +69,55 @@ imports:
|
||||
- pkg/term
|
||||
- pkg/term/windows
|
||||
- name: github.com/docker/go-connections
|
||||
version: f512407a188ecb16f31a33dbc9c4e4814afc1b03
|
||||
version: 4ccf312bf1d35e5dbda654e57a9be4c3f3cd0366
|
||||
subpackages:
|
||||
- nat
|
||||
- name: github.com/docker/go-units
|
||||
version: 8a7beacffa3009a9ac66bad506b18ffdd110cf97
|
||||
version: e30f1e79f3cd72542f2026ceec18d3bd67ab859c
|
||||
- name: github.com/fsouza/go-dockerclient
|
||||
version: ece08f96ac5f26f4073ab5c38f198c3e5000c554
|
||||
version: a633c5ee3344bd557a9a22e9b7259cab6447cd22
|
||||
- name: github.com/giantswarm/semver-bump
|
||||
version: 7ec6ac8985c24dd50b4942f9a908d13cdfe70f23
|
||||
subpackages:
|
||||
- bump
|
||||
- storage
|
||||
- name: github.com/go-ini/ini
|
||||
version: 6e4869b434bd001f6983749881c7ead3545887d8
|
||||
version: 2ba15ac2dc9cdf88c110ec2dc0ced7fa45f5678c
|
||||
- name: github.com/go-openapi/analysis
|
||||
version: 7222828b8ce19afee3c595aef6643b9e42150120
|
||||
- name: github.com/go-openapi/errors
|
||||
version: 49fe8b3a0e0d32a617d8d50c67f856ad6e45b28b
|
||||
- name: github.com/go-openapi/jsonpointer
|
||||
version: 8d96a2dc61536b690bd36b2e9df0b3c0b62825b2
|
||||
- name: github.com/go-openapi/jsonreference
|
||||
version: 36d33bfe519efae5632669801b180bf1a245da3b
|
||||
- name: github.com/go-openapi/loads
|
||||
version: 315567415dfd74b651f7a62cabfc82a57ed7b9ad
|
||||
- name: github.com/go-openapi/runtime
|
||||
version: 14b161b40ece9dac8e244ab2fde2d209e108c6f5
|
||||
subpackages:
|
||||
- client
|
||||
- name: github.com/go-openapi/spec
|
||||
version: f7ae86df5bc115a2744343016c789a89f065a4bd
|
||||
- name: github.com/go-openapi/strfmt
|
||||
version: 34fc3ba7c0f5fb615fda47a2b4fbd4c641b215f2
|
||||
- name: github.com/go-openapi/swag
|
||||
version: 3b6d86cd965820f968760d5d419cb4add096bdd7
|
||||
- name: github.com/go-openapi/validate
|
||||
version: 027696d4b54399770f1cdcc6c6daa56975f9e14e
|
||||
- name: github.com/go-resty/resty
|
||||
version: 24dc7ba4bc1ef9215048b28e7248f99c42901db5
|
||||
- name: github.com/hashicorp/go-cleanhttp
|
||||
version: ad28ea4487f05916463e2423a55166280e8254b5
|
||||
- name: github.com/iron-io/functions_go
|
||||
version: f38f2174656467ec3ed404b7294e9ee172573e43
|
||||
version: 69e4dec8454c3c710045263c2ede76139c141146
|
||||
subpackages:
|
||||
- client
|
||||
- client/apps
|
||||
- client/routes
|
||||
- client/tasks
|
||||
- client/version
|
||||
- models
|
||||
- name: github.com/iron-io/iron_go3
|
||||
version: b50ecf8ff90187fc5fabccd9d028dd461adce4ee
|
||||
subpackages:
|
||||
@@ -85,7 +125,7 @@ imports:
|
||||
- config
|
||||
- worker
|
||||
- name: github.com/iron-io/lambda
|
||||
version: d883e4b5ef216c3fcda72cf6628d9d72dd53be49
|
||||
version: 4a046af3249dd5933a8d328f965e9717c97fef24
|
||||
subpackages:
|
||||
- lambda
|
||||
- name: github.com/jmespath/go-jmespath
|
||||
@@ -96,30 +136,49 @@ imports:
|
||||
version: 08cceb5d0b5331634b9826762a8fd53b29b86ad8
|
||||
subpackages:
|
||||
- errors
|
||||
- name: github.com/mailru/easyjson
|
||||
version: 159cdb893c982e3d1bc6450322fedd514f9c9de3
|
||||
subpackages:
|
||||
- buffer
|
||||
- jlexer
|
||||
- jwriter
|
||||
- name: github.com/Microsoft/go-winio
|
||||
version: ce2922f643c8fd76b46cadc7f404a06282678b34
|
||||
version: 24a3e3d3fc7451805e09d11e11e95d9a0a4f205e
|
||||
- name: github.com/mitchellh/mapstructure
|
||||
version: f3009df150dadf309fdee4a54ed65c124afad715
|
||||
- name: github.com/opencontainers/runc
|
||||
version: 49ed0a10e4edba88f9221ec730d668099f6d6de8
|
||||
version: 8893fa693bf9bf29e5a156369bc51b887df43924
|
||||
subpackages:
|
||||
- libcontainer/system
|
||||
- libcontainer/user
|
||||
- name: github.com/PuerkitoBio/purell
|
||||
version: 0bcb03f4b4d0a9428594752bd2a3b9aa0a9d4bd4
|
||||
- name: github.com/PuerkitoBio/urlesc
|
||||
version: 5bd2802263f21d8788851d5305584c82a5c75d7e
|
||||
- name: github.com/satori/go.uuid
|
||||
version: 879c5887cd475cd7864858769793b2ceb0d44feb
|
||||
- name: github.com/Sirupsen/logrus
|
||||
version: d26492970760ca5d33129d2d799e34be5c4782eb
|
||||
- name: github.com/urfave/cli
|
||||
version: d86a009f5e13f83df65d0d6cee9a2e3f1445f0da
|
||||
version: 0bdeddeeb0f650497d603c4ad7b20cfe685682f6
|
||||
- name: golang.org/x/net
|
||||
version: f315505cf3349909cdf013ea56690da34e96a451
|
||||
subpackages:
|
||||
- context
|
||||
- context/ctxhttp
|
||||
- idna
|
||||
- publicsuffix
|
||||
- name: golang.org/x/sys
|
||||
version: c200b10b5d5e122be351b67af224adc6128af5bf
|
||||
version: d5645953809d8b4752afb2c3224b1f1ad73dfa70
|
||||
subpackages:
|
||||
- unix
|
||||
- windows
|
||||
- name: golang.org/x/text
|
||||
version: 5c6cf4f9a2357d38515014cea8c488ed22bdab90
|
||||
subpackages:
|
||||
- transform
|
||||
- unicode/norm
|
||||
- width
|
||||
- name: gopkg.in/yaml.v2
|
||||
version: a5b47d31c556af34a302ce5d659e6fea44d90de0
|
||||
testImports: []
|
||||
|
||||
407
fn/routes.go
407
fn/routes.go
@@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
@@ -13,17 +14,20 @@ import (
|
||||
"text/tabwriter"
|
||||
"time"
|
||||
|
||||
functions "github.com/iron-io/functions_go"
|
||||
fnclient "github.com/iron-io/functions_go/client"
|
||||
apiroutes "github.com/iron-io/functions_go/client/routes"
|
||||
"github.com/iron-io/functions_go/models"
|
||||
"github.com/jmoiron/jsonq"
|
||||
"github.com/urfave/cli"
|
||||
)
|
||||
|
||||
type routesCmd struct {
|
||||
*functions.RoutesApi
|
||||
client *fnclient.Functions
|
||||
}
|
||||
|
||||
func routes() cli.Command {
|
||||
r := routesCmd{RoutesApi: functions.NewRoutesApi()}
|
||||
|
||||
r := routesCmd{client: apiClient()}
|
||||
|
||||
return cli.Command{
|
||||
Name: "routes",
|
||||
@@ -167,7 +171,7 @@ func routes() cli.Command {
|
||||
}
|
||||
|
||||
func call() cli.Command {
|
||||
r := routesCmd{RoutesApi: functions.NewRoutesApi()}
|
||||
r := routesCmd{client: apiClient()}
|
||||
|
||||
return cli.Command{
|
||||
Name: "call",
|
||||
@@ -183,35 +187,33 @@ func (a *routesCmd) list(c *cli.Context) error {
|
||||
return errors.New("error: routes listing takes one argument, an app name")
|
||||
}
|
||||
|
||||
if err := resetBasePath(a.Configuration); err != nil {
|
||||
return fmt.Errorf("error setting endpoint: %v", err)
|
||||
}
|
||||
|
||||
appName := c.Args().Get(0)
|
||||
wrapper, _, err := a.AppsAppRoutesGet(appName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error getting routes: %v", err)
|
||||
}
|
||||
|
||||
if msg := wrapper.Error_.Message; msg != "" {
|
||||
return errors.New(msg)
|
||||
}
|
||||
resp, err := a.client.Routes.GetAppsAppRoutes(&apiroutes.GetAppsAppRoutesParams{
|
||||
Context: context.Background(),
|
||||
App: appName,
|
||||
})
|
||||
|
||||
baseURL, err := url.Parse(a.Configuration.BasePath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error parsing base path: %v", err)
|
||||
switch err.(type) {
|
||||
case *apiroutes.GetAppsAppRoutesNotFound:
|
||||
return fmt.Errorf("error: %v", err.(*apiroutes.GetAppsAppRoutesNotFound).Payload.Error.Message)
|
||||
case *apiroutes.GetAppsAppRoutesDefault:
|
||||
return fmt.Errorf("unexpected error: %v", err.(*apiroutes.GetAppsAppRoutesDefault).Payload.Error.Message)
|
||||
}
|
||||
return fmt.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
w := tabwriter.NewWriter(os.Stdout, 0, 8, 0, '\t', 0)
|
||||
fmt.Fprint(w, "path", "\t", "image", "\t", "endpoint", "\n")
|
||||
for _, route := range wrapper.Routes {
|
||||
for _, route := range resp.Payload.Routes {
|
||||
u, err := url.Parse("../")
|
||||
u.Path = path.Join(u.Path, "r", appName, route.Path)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error parsing functions route path: %v", err)
|
||||
}
|
||||
|
||||
fmt.Fprint(w, route.Path, "\t", route.Image, "\t", baseURL.ResolveReference(u).String(), "\n")
|
||||
fmt.Fprint(w, route.Path, "\t", route.Image, "\n")
|
||||
}
|
||||
w.Flush()
|
||||
|
||||
@@ -223,23 +225,17 @@ func (a *routesCmd) call(c *cli.Context) error {
|
||||
return errors.New("error: routes listing takes three arguments: an app name and a route")
|
||||
}
|
||||
|
||||
if err := resetBasePath(a.Configuration); err != nil {
|
||||
return fmt.Errorf("error setting endpoint: %v", err)
|
||||
}
|
||||
|
||||
appName := c.Args().Get(0)
|
||||
route := c.Args().Get(1)
|
||||
|
||||
baseURL, err := url.Parse(a.Configuration.BasePath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error parsing base path: %v", err)
|
||||
u := url.URL{
|
||||
Scheme: "http",
|
||||
Host: host(),
|
||||
}
|
||||
|
||||
u, err := url.Parse("../")
|
||||
u.Path = path.Join(u.Path, "r", appName, route)
|
||||
content := stdin()
|
||||
|
||||
return callfn(baseURL.ResolveReference(u).String(), content, os.Stdout, c.StringSlice("e"))
|
||||
return callfn(u.String(), content, os.Stdout, c.StringSlice("e"))
|
||||
}
|
||||
|
||||
func callfn(u string, content io.Reader, output io.Writer, env []string) error {
|
||||
@@ -281,10 +277,6 @@ func (a *routesCmd) create(c *cli.Context) error {
|
||||
return errors.New("error: routes creation takes at least one argument: an app name")
|
||||
}
|
||||
|
||||
if err := resetBasePath(a.Configuration); err != nil {
|
||||
return fmt.Errorf("error setting endpoint: %v", err)
|
||||
}
|
||||
|
||||
appName := c.Args().Get(0)
|
||||
route := c.Args().Get(1)
|
||||
image := c.Args().Get(2)
|
||||
@@ -298,9 +290,8 @@ func (a *routesCmd) create(c *cli.Context) error {
|
||||
if err != nil {
|
||||
if _, ok := err.(*notFoundError); ok {
|
||||
return errors.New("error: image name is missing or no function file found")
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
return err
|
||||
}
|
||||
image = ff.FullName()
|
||||
if ff.Format != nil {
|
||||
@@ -334,29 +325,39 @@ func (a *routesCmd) create(c *cli.Context) error {
|
||||
timeout = t
|
||||
}
|
||||
|
||||
body := functions.RouteWrapper{
|
||||
Route: functions.Route{
|
||||
to := int64(timeout.Seconds())
|
||||
body := &models.RouteWrapper{
|
||||
Route: &models.Route{
|
||||
Path: route,
|
||||
Image: image,
|
||||
Memory: c.Int64("memory"),
|
||||
Type_: c.String("type"),
|
||||
Type: c.String("type"),
|
||||
Config: extractEnvConfig(c.StringSlice("config")),
|
||||
Format: format,
|
||||
MaxConcurrency: int32(maxC),
|
||||
Timeout: int32(timeout.Seconds()),
|
||||
Timeout: &to,
|
||||
},
|
||||
}
|
||||
|
||||
wrapper, _, err := a.AppsAppRoutesPost(appName, body)
|
||||
resp, err := a.client.Routes.PostAppsAppRoutes(&apiroutes.PostAppsAppRoutesParams{
|
||||
Context: context.Background(),
|
||||
App: appName,
|
||||
Body: body,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating route: %v", err)
|
||||
switch err.(type) {
|
||||
case *apiroutes.PostAppsAppRoutesBadRequest:
|
||||
return fmt.Errorf("error: %v", err.(*apiroutes.PostAppsAppRoutesBadRequest).Payload.Error.Message)
|
||||
case *apiroutes.PostAppsAppRoutesConflict:
|
||||
return fmt.Errorf("error: %v", err.(*apiroutes.PostAppsAppRoutesConflict).Payload.Error.Message)
|
||||
case *apiroutes.PostAppsAppRoutesDefault:
|
||||
return fmt.Errorf("unexpected error: %v", err.(*apiroutes.PostAppsAppRoutesDefault).Payload.Error.Message)
|
||||
}
|
||||
return fmt.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if msg := wrapper.Error_.Message; msg != "" {
|
||||
return errors.New(msg)
|
||||
}
|
||||
|
||||
fmt.Println(wrapper.Route.Path, "created with", wrapper.Route.Image)
|
||||
fmt.Println(resp.Payload.Route.Path, "created with", resp.Payload.Route.Image)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -365,63 +366,118 @@ func (a *routesCmd) delete(c *cli.Context) error {
|
||||
return errors.New("error: routes listing takes three arguments: an app name and a path")
|
||||
}
|
||||
|
||||
if err := resetBasePath(a.Configuration); err != nil {
|
||||
return fmt.Errorf("error setting endpoint: %v", err)
|
||||
}
|
||||
|
||||
appName := c.Args().Get(0)
|
||||
route := c.Args().Get(1)
|
||||
|
||||
resp, err := a.AppsAppRoutesRouteDelete(appName, route)
|
||||
_, err := a.client.Routes.DeleteAppsAppRoutesRoute(&apiroutes.DeleteAppsAppRoutesRouteParams{
|
||||
Context: context.Background(),
|
||||
App: appName,
|
||||
Route: route,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("error deleting route: %v", err)
|
||||
switch err.(type) {
|
||||
case *apiroutes.DeleteAppsAppRoutesRouteNotFound:
|
||||
return fmt.Errorf("error: %v", err.(*apiroutes.DeleteAppsAppRoutesRouteNotFound).Payload.Error.Message)
|
||||
case *apiroutes.DeleteAppsAppRoutesRouteDefault:
|
||||
return fmt.Errorf("unexpected error: %v", err.(*apiroutes.DeleteAppsAppRoutesRouteDefault).Payload.Error.Message)
|
||||
}
|
||||
|
||||
if resp.StatusCode >= http.StatusBadRequest {
|
||||
return fmt.Errorf("route not found: %s", route)
|
||||
return fmt.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
fmt.Println(route, "deleted")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *routesCmd) update(c *cli.Context) error {
|
||||
if c.Args().Get(0) == "" {
|
||||
return errors.New("error: routes creation takes at least one argument: an app name")
|
||||
}
|
||||
// _, err = a.client.Routes.PatchAppsAppRoutesRoute(&apiroutes.PatchAppsAppRoutesRouteParams{
|
||||
// Context: context.Background(),
|
||||
// App: appName,
|
||||
// Route: route,
|
||||
// Body: resp.Payload,
|
||||
// })
|
||||
|
||||
if err := resetBasePath(a.Configuration); err != nil {
|
||||
return fmt.Errorf("error setting endpoint: %v", err)
|
||||
// if err != nil {
|
||||
// switch err.(type) {
|
||||
// case *apiroutes.PatchAppsAppRoutesRouteBadRequest:
|
||||
// return fmt.Errorf("error: %v", err.(*apiroutes.PatchAppsAppRoutesRouteBadRequest).Payload.Error.Message)
|
||||
// case *apiroutes.PatchAppsAppRoutesRouteNotFound:
|
||||
// return fmt.Errorf("error: %v", err.(*apiroutes.PatchAppsAppRoutesRouteNotFound).Payload.Error.Message)
|
||||
// case *apiroutes.PatchAppsAppRoutesRouteDefault:
|
||||
// return fmt.Errorf("unexpected error: %v", err.(*apiroutes.PatchAppsAppRoutesRouteDefault).Payload.Error.Message)
|
||||
// }
|
||||
// return fmt.Errorf("unexpected error: %v", err)
|
||||
// }
|
||||
|
||||
func (a *routesCmd) update(c *cli.Context) error {
|
||||
if c.Args().Get(0) == "" || c.Args().Get(1) == "" {
|
||||
return errors.New("error: route configuration description takes two arguments: an app name and a route")
|
||||
}
|
||||
|
||||
appName := c.Args().Get(0)
|
||||
route := c.Args().Get(1)
|
||||
|
||||
if route == "" {
|
||||
return errors.New("error: route path is missing")
|
||||
}
|
||||
|
||||
headers := map[string][]string{}
|
||||
for _, header := range c.StringSlice("headers") {
|
||||
parts := strings.Split(header, "=")
|
||||
headers[parts[0]] = strings.Split(parts[1], ";")
|
||||
}
|
||||
|
||||
patchRoute := &functions.Route{
|
||||
Image: c.String("image"),
|
||||
Memory: c.Int64("memory"),
|
||||
Type_: c.String("type"),
|
||||
Config: extractEnvConfig(c.StringSlice("config")),
|
||||
Headers: headers,
|
||||
Format: c.String("format"),
|
||||
MaxConcurrency: int32(c.Int64("max-concurrency")),
|
||||
Timeout: int32(c.Int64("timeout")),
|
||||
}
|
||||
|
||||
err := a.patchRoute(appName, route, patchRoute)
|
||||
resp, err := a.client.Routes.GetAppsAppRoutesRoute(&apiroutes.GetAppsAppRoutesRouteParams{
|
||||
Context: context.Background(),
|
||||
App: appName,
|
||||
Route: route,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
switch err.(type) {
|
||||
case *apiroutes.GetAppsAppRoutesRouteNotFound:
|
||||
return fmt.Errorf("error: %v", err.(*apiroutes.GetAppsAppRoutesRouteNotFound).Payload.Error.Message)
|
||||
case *apiroutes.GetAppsAppRoutesRouteDefault:
|
||||
return fmt.Errorf("unexpected error: %v", err.(*apiroutes.GetAppsAppRoutesRouteDefault).Payload.Error.Message)
|
||||
}
|
||||
return fmt.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
config := resp.Payload.Route.Config
|
||||
if len(config) == 0 {
|
||||
return errors.New("this route has no configurations")
|
||||
}
|
||||
|
||||
if c.Bool("json") {
|
||||
if err := json.NewEncoder(os.Stdout).Encode(config); err != nil {
|
||||
fmt.Fprintln(os.Stderr, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
} else if c.Bool("shell") {
|
||||
for k, v := range config {
|
||||
fmt.Print("export ", k, "=", v, "\n")
|
||||
}
|
||||
} else {
|
||||
fmt.Println(appName, resp.Payload.Route.Path, "configuration:")
|
||||
w := tabwriter.NewWriter(os.Stdout, 0, 8, 1, ' ', 0)
|
||||
for k, v := range config {
|
||||
fmt.Fprint(w, k, ":\t", v, "\n")
|
||||
}
|
||||
w.Flush()
|
||||
}
|
||||
|
||||
// if route == "" {
|
||||
// return errors.New("error: route path is missing")
|
||||
// }
|
||||
|
||||
// headers := map[string][]string{}
|
||||
// for _, header := range c.StringSlice("headers") {
|
||||
// parts := strings.Split(header, "=")
|
||||
// headers[parts[0]] = strings.Split(parts[1], ";")
|
||||
// }
|
||||
|
||||
// patchRoute := &functions.Route{
|
||||
// Image: c.String("image"),
|
||||
// Memory: c.Int64("memory"),
|
||||
// Type_: c.String("type"),
|
||||
// Config: extractEnvConfig(c.StringSlice("config")),
|
||||
// Headers: headers,
|
||||
// Format: c.String("format"),
|
||||
// MaxConcurrency: int32(c.Int64("max-concurrency")),
|
||||
// Timeout: int32(c.Int64("timeout")),
|
||||
// }
|
||||
|
||||
// err := a.patchRoute(appName, route, patchRoute)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
fmt.Println(appName, route, "updated")
|
||||
return nil
|
||||
@@ -432,27 +488,69 @@ func (a *routesCmd) configSet(c *cli.Context) error {
|
||||
return errors.New("error: route configuration setting takes four arguments: an app name, a route, a key and a value")
|
||||
}
|
||||
|
||||
if err := resetBasePath(a.Configuration); err != nil {
|
||||
return fmt.Errorf("error setting endpoint: %v", err)
|
||||
}
|
||||
|
||||
appName := c.Args().Get(0)
|
||||
route := c.Args().Get(1)
|
||||
key := c.Args().Get(2)
|
||||
value := c.Args().Get(3)
|
||||
|
||||
patchRoute := functions.Route{
|
||||
Config: make(map[string]string),
|
||||
}
|
||||
resp, err := a.client.Routes.GetAppsAppRoutesRoute(&apiroutes.GetAppsAppRoutesRouteParams{
|
||||
Context: context.Background(),
|
||||
App: appName,
|
||||
Route: route,
|
||||
})
|
||||
|
||||
patchRoute.Config[key] = value
|
||||
|
||||
err := a.patchRoute(appName, route, &patchRoute)
|
||||
if err != nil {
|
||||
return err
|
||||
switch err.(type) {
|
||||
case *apiroutes.GetAppsAppRoutesRouteNotFound:
|
||||
return fmt.Errorf("error: %v", err.(*apiroutes.GetAppsAppRoutesRouteNotFound).Payload.Error.Message)
|
||||
case *apiroutes.GetAppsAppRoutesRouteDefault:
|
||||
return fmt.Errorf("unexpected error: %v", err.(*apiroutes.GetAppsAppRoutesRouteDefault).Payload.Error.Message)
|
||||
}
|
||||
return fmt.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
fmt.Println(appName, route, "updated", key, "with", value)
|
||||
config := resp.Payload.Route.Config
|
||||
|
||||
if config == nil {
|
||||
config = make(map[string]string)
|
||||
}
|
||||
|
||||
config[key] = value
|
||||
resp.Payload.Route.Config = config
|
||||
|
||||
_, err = a.client.Routes.PatchAppsAppRoutesRoute(&apiroutes.PatchAppsAppRoutesRouteParams{
|
||||
Context: context.Background(),
|
||||
App: appName,
|
||||
Route: route,
|
||||
Body: resp.Payload,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case *apiroutes.PatchAppsAppRoutesRouteBadRequest:
|
||||
return fmt.Errorf("error: %v", err.(*apiroutes.PatchAppsAppRoutesRouteBadRequest).Payload.Error.Message)
|
||||
case *apiroutes.PatchAppsAppRoutesRouteNotFound:
|
||||
return fmt.Errorf("error: %v", err.(*apiroutes.PatchAppsAppRoutesRouteNotFound).Payload.Error.Message)
|
||||
case *apiroutes.PatchAppsAppRoutesRouteDefault:
|
||||
return fmt.Errorf("unexpected error: %v", err.(*apiroutes.PatchAppsAppRoutesRouteDefault).Payload.Error.Message)
|
||||
}
|
||||
return fmt.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
fmt.Println(appName, resp.Payload.Route.Path, "updated", key, "with", value)
|
||||
|
||||
// patchRoute := functions.Route{
|
||||
// Config: make(map[string]string),
|
||||
// }
|
||||
|
||||
// patchRoute.Config[key] = value
|
||||
|
||||
// err := a.patchRoute(appName, route, &patchRoute)
|
||||
// if err != nil {
|
||||
// return err
|
||||
// }
|
||||
|
||||
// fmt.Println(appName, route, "updated", key, "with", value)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -461,84 +559,40 @@ func (a *routesCmd) configUnset(c *cli.Context) error {
|
||||
return errors.New("error: route configuration setting takes four arguments: an app name, a route and a key")
|
||||
}
|
||||
|
||||
if err := resetBasePath(a.Configuration); err != nil {
|
||||
return fmt.Errorf("error setting endpoint: %v", err)
|
||||
}
|
||||
|
||||
appName := c.Args().Get(0)
|
||||
route := c.Args().Get(1)
|
||||
key := c.Args().Get(2)
|
||||
|
||||
patchRoute := functions.Route{
|
||||
Config: make(map[string]string),
|
||||
}
|
||||
resp, err := a.client.Routes.GetAppsAppRoutesRoute(&apiroutes.GetAppsAppRoutesRouteParams{
|
||||
Context: context.Background(),
|
||||
App: appName,
|
||||
Route: route,
|
||||
})
|
||||
|
||||
patchRoute.Config["-"+key] = ""
|
||||
|
||||
err := a.patchRoute(appName, route, &patchRoute)
|
||||
if err != nil {
|
||||
return err
|
||||
switch err.(type) {
|
||||
case *apiroutes.GetAppsAppRoutesRouteNotFound:
|
||||
return fmt.Errorf("error: %v", err.(*apiroutes.GetAppsAppRoutesRouteNotFound).Payload.Error.Message)
|
||||
case *apiroutes.GetAppsAppRoutesRouteDefault:
|
||||
return fmt.Errorf("unexpected error: %v", err.(*apiroutes.GetAppsAppRoutesRouteDefault).Payload.Error.Message)
|
||||
}
|
||||
return fmt.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
fmt.Println(appName, route, "removed", key)
|
||||
return nil
|
||||
}
|
||||
config := resp.Payload.Route.Config
|
||||
|
||||
func (a *routesCmd) patchRoute(appName, routePath string, r *functions.Route) error {
|
||||
wrapper, _, err := a.AppsAppRoutesRouteGet(appName, routePath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error loading route: %v", err)
|
||||
if config == nil {
|
||||
config = make(map[string]string)
|
||||
}
|
||||
|
||||
if msg := wrapper.Error_.Message; msg != "" {
|
||||
return errors.New(msg)
|
||||
if _, ok := config[key]; !ok {
|
||||
return fmt.Errorf("configuration key %s not found", key)
|
||||
}
|
||||
|
||||
wrapper.Route.Path = ""
|
||||
if r != nil {
|
||||
if r.Config != nil {
|
||||
for k, v := range r.Config {
|
||||
if string(k[0]) == "-" {
|
||||
delete(r.Config, string(k[1:]))
|
||||
continue
|
||||
}
|
||||
wrapper.Route.Config[k] = v
|
||||
}
|
||||
}
|
||||
if r.Headers != nil {
|
||||
for k, v := range r.Headers {
|
||||
if v[0] == "" {
|
||||
delete(r.Headers, k)
|
||||
continue
|
||||
}
|
||||
wrapper.Route.Headers[k] = v
|
||||
}
|
||||
}
|
||||
if r.Image != "" {
|
||||
wrapper.Route.Image = r.Image
|
||||
}
|
||||
if r.Format != "" {
|
||||
wrapper.Route.Format = r.Format
|
||||
}
|
||||
if r.MaxConcurrency > 0 {
|
||||
wrapper.Route.MaxConcurrency = r.MaxConcurrency
|
||||
}
|
||||
if r.Memory > 0 {
|
||||
wrapper.Route.Memory = r.Memory
|
||||
}
|
||||
if r.Timeout > 0 {
|
||||
wrapper.Route.Timeout = r.Timeout
|
||||
}
|
||||
}
|
||||
|
||||
if wrapper, _, err = a.AppsAppRoutesRoutePatch(appName, routePath, *wrapper); err != nil {
|
||||
return fmt.Errorf("error updating route: %v", err)
|
||||
}
|
||||
|
||||
if msg := wrapper.Error_.Message; msg != "" {
|
||||
return errors.New(msg)
|
||||
}
|
||||
delete(config, key)
|
||||
resp.Payload.Route.Config = config
|
||||
|
||||
fmt.Println(appName, resp.Payload.Route.Path, "removed", key)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -547,38 +601,35 @@ func (a *routesCmd) inspect(c *cli.Context) error {
|
||||
return errors.New("error: routes listing takes three arguments: an app name and a path")
|
||||
}
|
||||
|
||||
if err := resetBasePath(a.Configuration); err != nil {
|
||||
return fmt.Errorf("error setting endpoint: %v", err)
|
||||
}
|
||||
|
||||
appName := c.Args().Get(0)
|
||||
route := c.Args().Get(1)
|
||||
prop := c.Args().Get(2)
|
||||
|
||||
wrapper, resp, err := a.AppsAppRoutesRouteGet(appName, route)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error retrieving route: %v", err)
|
||||
}
|
||||
resp, err := a.client.Routes.GetAppsAppRoutesRoute(&apiroutes.GetAppsAppRoutesRouteParams{
|
||||
Context: context.Background(),
|
||||
App: appName,
|
||||
Route: route,
|
||||
})
|
||||
|
||||
if msg := wrapper.Error_.Message; msg != "" {
|
||||
return errors.New(msg)
|
||||
if err != nil {
|
||||
switch err.(type) {
|
||||
case *apiroutes.GetAppsAppRoutesRouteNotFound:
|
||||
return fmt.Errorf("error: %v", err.(*apiroutes.GetAppsAppRoutesRouteNotFound).Payload.Error.Message)
|
||||
case *apiroutes.GetAppsAppRoutesRouteDefault:
|
||||
return fmt.Errorf("unexpected error: %v", err.(*apiroutes.GetAppsAppRoutesRouteDefault).Payload.Error.Message)
|
||||
}
|
||||
return fmt.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
enc := json.NewEncoder(os.Stdout)
|
||||
enc.SetIndent("", "\t")
|
||||
|
||||
if prop == "" {
|
||||
enc.Encode(wrapper.Route)
|
||||
enc.Encode(resp.Payload.Route)
|
||||
return nil
|
||||
}
|
||||
|
||||
var inspect struct{ Route map[string]interface{} }
|
||||
err = json.Unmarshal(resp.Payload, &inspect)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error inspect route: %v", err)
|
||||
}
|
||||
|
||||
jq := jsonq.NewQuery(inspect.Route)
|
||||
jq := jsonq.NewQuery(resp.Payload.Route)
|
||||
field, err := jq.Interface(strings.Split(prop, ".")...)
|
||||
if err != nil {
|
||||
return errors.New("failed to inspect the property")
|
||||
|
||||
Reference in New Issue
Block a user