Files
services/cmd/publisher/main.go
Dominic Wong 901e637687 Display name (#225)
* add displayname

* Commit from GitHub Actions (Publish APIs & Clients)

Co-authored-by: domwong <domwong@users.noreply.github.com>
2021-10-07 14:58:26 +01:00

191 lines
4.8 KiB
Go

package main
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
"log"
"net/http"
"os"
"os/exec"
"path/filepath"
"strings"
"github.com/getkin/kin-openapi/openapi3"
)
type PublicAPI struct {
Name string `json:"name"`
Category string `json:"category,omitempty"`
Description string `json:"description"`
Icon string `json:"icon,omitempty"`
OpenAPIJson string `json:"open_api_json"`
Pricing map[string]int64 `json:"pricing,omitempty"`
ExamplesJson string `json:"examples_json,omitempty"`
PostmanJson string `json:"postman_json,omitempty"`
DisplayName string `json:"display_name,omitempty"`
}
func publishAPI(apiSpec *PublicAPI) error {
client := &http.Client{}
//Encode the data
postBody, _ := json.Marshal(map[string]interface{}{
"api": apiSpec,
})
rbody := bytes.NewBuffer(postBody)
//Leverage Go's HTTP Post function to make request
req, err := http.NewRequest("POST", "https://api.m3o.com/publicapi/Publish", rbody)
// Add auth headers here if needed
req.Header.Add("Authorization", `Bearer `+os.Getenv("MICRO_ADMIN_TOKEN"))
resp, err := client.Do(req)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
b, _ := ioutil.ReadAll(resp.Body)
return errors.New(string(b))
}
io.Copy(ioutil.Discard, resp.Body)
return nil
}
func main() {
files, err := ioutil.ReadDir(os.Args[1])
if err != nil {
log.Fatal(err)
}
workDir, _ := os.Getwd()
for _, f := range files {
if strings.Contains(f.Name(), "clients") || strings.Contains(f.Name(), "examples") {
continue
}
if f.IsDir() && !strings.HasPrefix(f.Name(), ".") {
serviceDir := filepath.Join(workDir, f.Name())
serviceFiles, err := ioutil.ReadDir(serviceDir)
if err != nil {
fmt.Println("Failed to read service dir", err)
os.Exit(1)
}
skip := false
for _, serviceFile := range serviceFiles {
if serviceFile.Name() == "skip" {
skip = true
}
}
if skip {
continue
}
fmt.Println("Processing folder", serviceDir)
makeProto := exec.Command("make", "api")
makeProto.Dir = serviceDir
fmt.Println(serviceDir)
outp, err := makeProto.CombinedOutput()
if err != nil {
fmt.Println("Failed to make api", string(outp))
os.Exit(1)
}
serviceName := f.Name()
// generate the Postman collection
postman := exec.Command("openapi2postmanv2", "-s", fmt.Sprintf("api-%s.json", serviceName), "-o", "postman.json")
postman.Dir = serviceDir
outp, err = postman.CombinedOutput()
if err != nil {
fmt.Printf("Failed to generate postman collection %s %s\n", string(outp), err)
os.Exit(1)
}
dat, err := ioutil.ReadFile(filepath.Join(serviceDir, "README.md"))
if err != nil {
fmt.Println("Failed to read readme", string(outp))
os.Exit(1)
}
apiJSON := filepath.Join(serviceDir, "api-"+serviceName+".json")
js, err := ioutil.ReadFile(apiJSON)
if err != nil {
apiJSON := filepath.Join(serviceDir, "api-protobuf.json")
js, err = ioutil.ReadFile(apiJSON)
if err != nil {
fmt.Println("Failed to read json spec", err)
os.Exit(1)
}
}
spec := &openapi3.Swagger{}
// we have to read an openapi spec otherwise we can't publish
if err := json.Unmarshal(js, &spec); err != nil {
fmt.Println("Failed to unmarshal", err)
os.Exit(1)
}
// define the default public api values
publicApi := new(PublicAPI)
// if we find a public api definition we load it
if b, err := ioutil.ReadFile(filepath.Join(serviceDir, "publicapi.json")); err == nil {
// unpack the info if we read the file
json.Unmarshal(b, &publicApi)
}
// If we didn't get the default info from a file, populate it
if publicApi.Name == "" {
publicApi.Name = serviceName
}
if publicApi.Description == "" {
publicApi.Description = string(dat)
}
if publicApi.OpenAPIJson == "" {
publicApi.OpenAPIJson = string(js)
}
// load the examples if they exist
if examples, err := ioutil.ReadFile(filepath.Join(serviceDir, "examples.json")); err == nil {
if len(examples) > 0 {
publicApi.ExamplesJson = string(examples)
}
}
// load the separate pricing if it exists
if pricingRaw, err := ioutil.ReadFile(filepath.Join(serviceDir, "pricing.json")); err == nil {
pricing := map[string]int64{}
// unmarshal the pricing info
if len(pricingRaw) > 0 {
json.Unmarshal(pricingRaw, &pricing)
publicApi.Pricing = pricing
}
}
// load the postman json
if postman, err := ioutil.ReadFile(filepath.Join(serviceDir, "postman.json")); err == nil {
if len(postman) > 0 {
publicApi.PostmanJson = string(postman)
}
}
// publish the api
if err := publishAPI(publicApi); err != nil {
fmt.Println("Failed to save data to publicapi service", err)
os.Exit(1)
}
}
}
}