weldr: add support for toml blueprints
This commit is contained in:
parent
bddac13048
commit
20bb60f3fd
4 changed files with 118 additions and 9 deletions
1
go.mod
1
go.mod
|
|
@ -4,6 +4,7 @@ go 1.12
|
|||
|
||||
require (
|
||||
github.com/Azure/azure-storage-blob-go v0.8.0
|
||||
github.com/BurntSushi/toml v0.3.1
|
||||
github.com/aws/aws-sdk-go v1.25.37
|
||||
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f
|
||||
github.com/gobwas/glob v0.2.3
|
||||
|
|
|
|||
2
go.sum
2
go.sum
|
|
@ -2,6 +2,8 @@ github.com/Azure/azure-pipeline-go v0.2.1 h1:OLBdZJ3yvOn2MezlWvbrBMTEUQC72zAftRZ
|
|||
github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4=
|
||||
github.com/Azure/azure-storage-blob-go v0.8.0 h1:53qhf0Oxa0nOjgbDeeYPUeyiNmafAFEY95rZLK0Tj6o=
|
||||
github.com/Azure/azure-storage-blob-go v0.8.0/go.mod h1:lPI3aLPpuLTeUwh1sViKXFxwl2B6teiRqI0deQUvsw0=
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/aws/aws-sdk-go v1.25.37 h1:gBtB/F3dophWpsUQKN/Kni+JzYEH2mGHF4hWNtfED1w=
|
||||
github.com/aws/aws-sdk-go v1.25.37/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f h1:JOrtw2xFKzlg+cbHpyrpLDmnN1HqhBfnX7WDiW7eG2c=
|
||||
|
|
|
|||
|
|
@ -2,15 +2,18 @@ package weldr
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
"github.com/google/uuid"
|
||||
"github.com/julienschmidt/httprouter"
|
||||
|
||||
|
|
@ -701,11 +704,44 @@ func (api *API) blueprintsInfoHandler(writer http.ResponseWriter, request *http.
|
|||
changes = append(changes, change{changed, blueprint.Name})
|
||||
}
|
||||
|
||||
json.NewEncoder(writer).Encode(reply{
|
||||
Blueprints: blueprints,
|
||||
Changes: changes,
|
||||
Errors: []responseError{},
|
||||
})
|
||||
q, err := url.ParseQuery(request.URL.RawQuery)
|
||||
if err != nil {
|
||||
errors := responseError{
|
||||
ID: "InvalidChars",
|
||||
Msg: fmt.Sprintf("invalid query string: %v", err),
|
||||
}
|
||||
statusResponseError(writer, http.StatusBadRequest, errors)
|
||||
return
|
||||
}
|
||||
|
||||
format := q.Get("format")
|
||||
if format == "json" || format == "" {
|
||||
json.NewEncoder(writer).Encode(reply{
|
||||
Blueprints: blueprints,
|
||||
Changes: changes,
|
||||
Errors: []responseError{},
|
||||
})
|
||||
} else if format == "toml" {
|
||||
// lorax concatenates multiple blueprints with `\n\n` here,
|
||||
// which is never useful. Deviate by only returning the first
|
||||
// blueprint.
|
||||
if len(blueprints) > 1 {
|
||||
errors := responseError{
|
||||
ID: "HTTPError",
|
||||
Msg: "toml format only supported when requesting one blueprint",
|
||||
}
|
||||
statusResponseError(writer, http.StatusBadRequest, errors)
|
||||
return
|
||||
}
|
||||
toml.NewEncoder(writer).Encode(blueprints[0])
|
||||
} else {
|
||||
errors := responseError{
|
||||
ID: "InvalidChars",
|
||||
Msg: fmt.Sprintf("invalid `format` parameter: %s", format),
|
||||
}
|
||||
statusResponseError(writer, http.StatusBadRequest, errors)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (api *API) blueprintsDepsolveHandler(writer http.ResponseWriter, request *http.Request, params httprouter.Params) {
|
||||
|
|
@ -1030,21 +1066,29 @@ func (api *API) blueprintsNewHandler(writer http.ResponseWriter, request *http.R
|
|||
}
|
||||
|
||||
contentType := request.Header["Content-Type"]
|
||||
if len(contentType) != 1 || contentType[0] != "application/json" {
|
||||
if len(contentType) != 1 {
|
||||
errors := responseError{
|
||||
ID: "BlueprintsError",
|
||||
Msg: "'blueprint must be json'",
|
||||
Msg: "missing Content-Type header",
|
||||
}
|
||||
statusResponseError(writer, http.StatusBadRequest, errors)
|
||||
return
|
||||
}
|
||||
|
||||
var blueprint blueprint.Blueprint
|
||||
err := json.NewDecoder(request.Body).Decode(&blueprint)
|
||||
var err error
|
||||
if contentType[0] == "application/json" {
|
||||
err = json.NewDecoder(request.Body).Decode(&blueprint)
|
||||
} else if contentType[0] == "text/x-toml" {
|
||||
_, err = toml.DecodeReader(request.Body, &blueprint)
|
||||
} else {
|
||||
err = errors.New("blueprint must be in json or toml format")
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
errors := responseError{
|
||||
ID: "BlueprintsError",
|
||||
Msg: "400 Bad Request: The browser (or proxy) sent a request that this server could not understand.",
|
||||
Msg: "400 Bad Request: The browser (or proxy) sent a request that this server could not understand: " + err.Error(),
|
||||
}
|
||||
statusResponseError(writer, http.StatusBadRequest, errors)
|
||||
return
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
package weldr_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
|
@ -17,6 +19,7 @@ import (
|
|||
"github.com/osbuild/osbuild-composer/internal/test"
|
||||
"github.com/osbuild/osbuild-composer/internal/weldr"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
)
|
||||
|
||||
|
|
@ -72,6 +75,29 @@ func TestBlueprintsNew(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestBlueprintsNewToml(t *testing.T) {
|
||||
blueprint := `
|
||||
name = "test"
|
||||
description = "Test"
|
||||
version = "0.0.0"
|
||||
|
||||
[[packages]]
|
||||
name = "httpd"
|
||||
version = "2.4.*"`
|
||||
|
||||
req := httptest.NewRequest("POST", "/api/v0/blueprints/new", bytes.NewReader([]byte(blueprint)))
|
||||
req.Header.Set("Content-Type", "text/x-toml")
|
||||
recorder := httptest.NewRecorder()
|
||||
|
||||
api, _ := createWeldrAPI(rpmmd_mock.BaseFixture)
|
||||
api.ServeHTTP(recorder, req)
|
||||
|
||||
r := recorder.Result()
|
||||
if r.StatusCode != http.StatusOK {
|
||||
t.Fatalf("unexpected status %v", r.StatusCode)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBlueprintsWorkspace(t *testing.T) {
|
||||
var cases = []struct {
|
||||
Method string
|
||||
|
|
@ -115,6 +141,42 @@ func TestBlueprintsInfo(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestBlueprintsInfoToml(t *testing.T) {
|
||||
api, _ := createWeldrAPI(rpmmd_mock.BaseFixture)
|
||||
test.SendHTTP(api, true, "POST", "/api/v0/blueprints/new", `{"name":"test1","description":"Test","packages":[{"name":"httpd","version":"2.4.*"}],"version":"0.0.0"}`)
|
||||
|
||||
req := httptest.NewRequest("GET", "/api/v0/blueprints/info/test1?format=toml", nil)
|
||||
recorder := httptest.NewRecorder()
|
||||
api.ServeHTTP(recorder, req)
|
||||
|
||||
resp := recorder.Result()
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
t.Fatalf("unexpected status %v", resp.StatusCode)
|
||||
}
|
||||
|
||||
var got blueprint.Blueprint
|
||||
_, err := toml.DecodeReader(resp.Body, &got)
|
||||
if err != nil {
|
||||
t.Fatalf("error decoding toml file: %v", err)
|
||||
}
|
||||
|
||||
t.Logf("%v", got)
|
||||
|
||||
expected := blueprint.Blueprint{
|
||||
Name: "test1",
|
||||
Description: "Test",
|
||||
Version: "0.0.0",
|
||||
Packages: []blueprint.Package{
|
||||
{ "httpd", "2.4.*" },
|
||||
},
|
||||
Groups: []blueprint.Group{},
|
||||
Modules: []blueprint.Package{},
|
||||
}
|
||||
if diff := cmp.Diff(got, expected); diff != "" {
|
||||
t.Fatalf("received unexpected blueprint: %s", diff)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBlueprintsFreeze(t *testing.T) {
|
||||
var cases = []struct {
|
||||
Fixture rpmmd_mock.FixtureGenerator
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue