Merge branch 'master' into alund/home-v1
@@ -0,0 +1,29 @@
|
||||
name: Scaffolder CI
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'backend/scaffolder/**'
|
||||
- '.github/workflows/scaffolder.yml'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v1
|
||||
with:
|
||||
go-version: 1.12
|
||||
- name: checkout code
|
||||
uses: actions/checkout@v1
|
||||
- name: setup env
|
||||
run: |
|
||||
echo "::set-env name=GOPATH::$(go env GOPATH)"
|
||||
echo "::add-path::$(go env GOPATH)/bin"
|
||||
shell: bash
|
||||
- name: build
|
||||
run: go build -v ./...
|
||||
working-directory: ./backend/scaffolder
|
||||
- name: test
|
||||
run: go test ./... -short
|
||||
working-directory: ./backend/scaffolder
|
||||
@@ -0,0 +1,2 @@
|
||||
secrets.env
|
||||
.DS_Store
|
||||
@@ -1 +0,0 @@
|
||||
main
|
||||
@@ -16,6 +16,8 @@ RUN go build .
|
||||
FROM debian:buster
|
||||
ARG service
|
||||
|
||||
RUN apt-get update && apt-get install -y ca-certificates
|
||||
|
||||
WORKDIR /app/
|
||||
|
||||
COPY --from=build /build/$service/$service /app/service
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
package ghactions
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
)
|
||||
|
||||
type Client struct {
|
||||
client *http.Client
|
||||
baseURL string
|
||||
accessToken string
|
||||
}
|
||||
|
||||
func NewFromEnv() (*Client, error) {
|
||||
accessToken := os.Getenv("BOSS_GH_ACCESS_TOKEN")
|
||||
|
||||
if accessToken == "" {
|
||||
return nil, fmt.Errorf("BOSS_GH_ACCESS_TOKEN not set")
|
||||
}
|
||||
|
||||
return New(http.DefaultClient, "https://api.github.com", accessToken), nil
|
||||
}
|
||||
|
||||
func New(client *http.Client, baseURL, accessToken string) *Client {
|
||||
return &Client{
|
||||
client: client,
|
||||
baseURL: baseURL,
|
||||
accessToken: accessToken,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) createRequest(ctx context.Context, owner, repo, path string) (*http.Request, error) {
|
||||
url := fmt.Sprintf("%s/repos/%s/%s/actions%s", c.baseURL, owner, repo, path)
|
||||
req, err := http.NewRequest(http.MethodGet, url, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req.Header.Add("Authorization", "Bearer "+c.accessToken)
|
||||
|
||||
return req.WithContext(ctx), nil
|
||||
}
|
||||
|
||||
func (c *Client) ListWorkflowRuns(ctx context.Context, owner, repo string) (*WorkflowRunsListResponse, error) {
|
||||
req, err := c.createRequest(ctx, owner, repo, "/runs")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res, err := c.client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
|
||||
var resData WorkflowRunsListResponse
|
||||
if err := json.NewDecoder(res.Body).Decode(&resData); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &resData, nil
|
||||
}
|
||||
|
||||
func (c *Client) GetWorkflowRun(ctx context.Context, owner, repo, runId string) (*WorkflowRunResponse, error) {
|
||||
req, err := c.createRequest(ctx, owner, repo, fmt.Sprintf("/runs/%s", runId))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
res, err := c.client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
|
||||
var resData WorkflowRunResponse
|
||||
if err := json.NewDecoder(res.Body).Decode(&resData); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &resData, nil
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package ghactions
|
||||
|
||||
type User struct {
|
||||
Name string `json:"name"` // "Octo Cat"
|
||||
Email string `json:"email"` // "octocat@github.com"
|
||||
}
|
||||
|
||||
type Commit struct {
|
||||
ID string `json:"id"` // "acb5820ced9479c074f688cc328bf03f341a511d"
|
||||
TreeID string `json:"tree_id"` // "d23f6eedb1e1b9610bbc754ddb5197bfe7271223"
|
||||
Message string `json:"message"` // "Create linter.yml"
|
||||
Timestamp string `json:"timestamp"` // "2020-01-22T19:33:05Z"
|
||||
Author User `json:"author"`
|
||||
Committer User `json:"committer"`
|
||||
}
|
||||
|
||||
type Repository struct {
|
||||
ID int64 `json:"id"` // 217723378
|
||||
NodeID string `json:"node_id"` // MDEwOlJlcG9zaXRvcnkyMTc3MjMzNzg="
|
||||
Name string `json:"name"` // o-repo"
|
||||
FullName string `json:"full_name"` // "octo-org/octo-repo"
|
||||
HTMLURL string `json:"html_url"` // "https://github.com/octo-org/octo-repo"
|
||||
}
|
||||
|
||||
type WorkflowRunResponse struct {
|
||||
ID int64 `json:"id"` // 30433642
|
||||
NodeID string `json:"node_id"` // "MDEyOldvcmtmbG93IFJ1bjI2OTI4OQ=="
|
||||
HeadBranch string `json:"head_branch"` // "master"
|
||||
HeadSha string `json:"head_sha"` // "acb5820ced9479c074f688cc328bf03f341a511d"
|
||||
RunNumber int64 `json:"run_number"` // 562
|
||||
CheckSuiteID int64 `json:"check_suite_id"` // 414944374
|
||||
Event string `json:"event"` // "push"
|
||||
Status string `json:"status"` // "queued"
|
||||
Conclusion *string `json:"conclusion"` // null
|
||||
URL string `json:"url"` // "https://api.github.com/repos/octo-org/octo-repo/actions/runs/30433642"
|
||||
HTMLURL string `json:"html_url"` // "https://github.com/octo-org/octo-repo/actions/runs/30433642"
|
||||
CreatedAt string `json:"created_at"` // "2020-01-22T19:33:08Z"
|
||||
UpdatedAt string `json:"updated_at"` // "2020-01-22T19:33:08Z"
|
||||
JobsURL string `json:"jobs_url"` // "https://api.github.com/repos/octo-org/octo-repo/actions/runs/30433642/jobs"
|
||||
LogsURL string `json:"logs_url"` // "https://api.github.com/repos/octo-org/octo-repo/actions/runs/30433642/logs"
|
||||
ArtifactsURL string `json:"artifacts_url"` // "https://api.github.com/repos/octo-org/octo-repo/actions/runs/30433642/artifacts"
|
||||
CancelURL string `json:"cancel_url"` // "https://api.github.com/repos/octo-org/octo-repo/actions/runs/30433642/cancel"
|
||||
RerunURL string `json:"rerun_url"` // "https://api.github.com/repos/octo-org/octo-repo/actions/runs/30433642/rerun"
|
||||
WorkflowURL string `json:"workflow_url"` // "https://api.github.com/repos/octo-org/octo-repo/actions/workflows/30433642"
|
||||
HeadCommit Commit `json:"head_commit"`
|
||||
Repository Repository `json:"repository"`
|
||||
HeadRepository Repository `json:"head_repository"`
|
||||
}
|
||||
|
||||
type WorkflowRunsListResponse struct {
|
||||
TotalCount int64 `json:"total_count"`
|
||||
Runs []WorkflowRunResponse `json:"workflow_runs"`
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
module github.com/spotify/backstage/builds
|
||||
|
||||
go 1.12
|
||||
|
||||
replace github.com/spotify/backstage/proto => ../proto
|
||||
|
||||
require (
|
||||
github.com/spotify/backstage/proto v0.0.0-00010101000000-000000000000
|
||||
google.golang.org/grpc v1.27.1
|
||||
)
|
||||
@@ -0,0 +1,54 @@
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.27.0 h1:rRYRFMVgRv6E0D70Skyfsr28tDXIuuPZyWGMPdMcnXg=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/grpc v1.27.1 h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk=
|
||||
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
@@ -0,0 +1,34 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net"
|
||||
|
||||
"github.com/spotify/backstage/builds/ghactions"
|
||||
"github.com/spotify/backstage/builds/service"
|
||||
buildsv1 "github.com/spotify/backstage/proto/builds/v1"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
const (
|
||||
port = ":50051"
|
||||
)
|
||||
|
||||
func main() {
|
||||
lis, err := net.Listen("tcp", port)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to listen: %v", err)
|
||||
}
|
||||
grpcServer := grpc.NewServer()
|
||||
|
||||
ghClient, err := ghactions.NewFromEnv()
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to create github client, %s", err)
|
||||
}
|
||||
|
||||
buildsv1.RegisterBuildsServer(grpcServer, service.New(ghClient))
|
||||
|
||||
log.Println("Serving Builds Service")
|
||||
grpcServer.Serve(lis)
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"regexp"
|
||||
|
||||
"github.com/spotify/backstage/builds/ghactions"
|
||||
buildsv1 "github.com/spotify/backstage/proto/builds/v1"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
type service struct {
|
||||
ghClient *ghactions.Client
|
||||
}
|
||||
|
||||
var _ buildsv1.BuildsServer = (*service)(nil)
|
||||
|
||||
// New creates a new identity data server
|
||||
func New(ghClient *ghactions.Client) buildsv1.BuildsServer {
|
||||
return &service{ghClient}
|
||||
}
|
||||
|
||||
func (s *service) ListBuilds(ctx context.Context, req *buildsv1.ListBuildsRequest) (*buildsv1.ListBuildsReply, error) {
|
||||
owner := "spotify"
|
||||
repo := "backstage"
|
||||
|
||||
result, err := s.ghClient.ListWorkflowRuns(ctx, owner, repo)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Failed to fetch workflow runs for %s/%s, %s", owner, repo, err)
|
||||
}
|
||||
|
||||
builds := make([]*buildsv1.Build, len(result.Runs))
|
||||
|
||||
for i, run := range result.Runs {
|
||||
builds[i] = s.transformBuild(owner, repo, &run)
|
||||
}
|
||||
|
||||
return &buildsv1.ListBuildsReply{
|
||||
EntityUri: "",
|
||||
Builds: builds,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *service) GetBuild(ctx context.Context, req *buildsv1.GetBuildRequest) (*buildsv1.GetBuildReply, error) {
|
||||
uri := req.GetBuildUri()
|
||||
|
||||
owner, repo, runID, err := s.parseBuildURI(uri)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.InvalidArgument, "Invalid build URI '%s', %s", uri, err)
|
||||
}
|
||||
|
||||
run, err := s.ghClient.GetWorkflowRun(ctx, owner, repo, runID)
|
||||
if err != nil {
|
||||
return nil, status.Errorf(codes.Internal, "Failed to fetch workflow run for %s/%s/%s, %s", owner, repo, runID, err)
|
||||
}
|
||||
|
||||
return &buildsv1.GetBuildReply{
|
||||
Build: s.transformBuild(owner, repo, run),
|
||||
Details: &buildsv1.BuildDetails{
|
||||
Author: run.HeadCommit.Author.Name,
|
||||
LogUrl: run.LogsURL,
|
||||
OverviewUrl: run.HTMLURL,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *service) transformBuild(owner, repo string, run *ghactions.WorkflowRunResponse) *buildsv1.Build {
|
||||
stat := buildsv1.BuildStatus_NULL
|
||||
switch run.Status {
|
||||
case "queued":
|
||||
stat = buildsv1.BuildStatus_PENDING
|
||||
case "in_progress":
|
||||
stat = buildsv1.BuildStatus_RUNNING
|
||||
case "completed":
|
||||
if run.Conclusion != nil {
|
||||
switch *run.Conclusion {
|
||||
case "success":
|
||||
stat = buildsv1.BuildStatus_SUCCESS
|
||||
case "neutral":
|
||||
stat = buildsv1.BuildStatus_SUCCESS
|
||||
case "failure":
|
||||
stat = buildsv1.BuildStatus_FAILURE
|
||||
case "cancelled":
|
||||
stat = buildsv1.BuildStatus_FAILURE
|
||||
case "timed_out":
|
||||
stat = buildsv1.BuildStatus_FAILURE
|
||||
case "action_required":
|
||||
stat = buildsv1.BuildStatus_RUNNING
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return &buildsv1.Build{
|
||||
Uri: fmt.Sprintf("entity:build:%s/%s/%d", owner, repo, run.ID),
|
||||
CommitId: run.HeadCommit.ID,
|
||||
Message: run.HeadCommit.Message,
|
||||
Status: stat,
|
||||
}
|
||||
}
|
||||
|
||||
var entityURIRegex = regexp.MustCompile("^entity:build:([^/:]+)/([^/:]+)/([^/:]+)$")
|
||||
|
||||
func (s *service) parseBuildURI(uri string) (owner, repo, runID string, err error) {
|
||||
if uri == "" {
|
||||
return "", "", "", fmt.Errorf("uri is empty")
|
||||
}
|
||||
|
||||
match := entityURIRegex.FindStringSubmatch(uri)
|
||||
if err != nil {
|
||||
return "", "", "", fmt.Errorf("uri does not match")
|
||||
}
|
||||
|
||||
return match[1], match[2], match[3], nil
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package app
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/spotify/backstage/inventory/storage"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
@@ -15,27 +16,58 @@ type Server struct {
|
||||
Storage *storage.Storage
|
||||
}
|
||||
|
||||
func (s *Server) ListEntities(ctx context.Context, req *pb.ListEntitiesRequest) (*pb.ListEntitiesReply, error) {
|
||||
entities, err := s.Storage.ListEntities(req.UriPrefix)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, "could not list entities")
|
||||
}
|
||||
|
||||
result := make([]*pb.Entity, len(entities))
|
||||
for i, v := range entities {
|
||||
result[i] = &pb.Entity{Uri: v}
|
||||
}
|
||||
|
||||
return &pb.ListEntitiesReply{Entities: result}, nil
|
||||
}
|
||||
|
||||
func (s *Server) CreateEntity(ctx context.Context, req *pb.CreateEntityRequest) (*pb.CreateEntityReply, error) {
|
||||
err := s.Storage.CreateEntity(req.GetEntity().GetUri())
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, "could not create entity")
|
||||
return nil, status.Error(codes.Internal, "could not create entity")
|
||||
}
|
||||
return &pb.CreateEntityReply{Entity: req.GetEntity()} , nil
|
||||
return &pb.CreateEntityReply{Entity: req.GetEntity()}, nil
|
||||
}
|
||||
|
||||
// GetEntity returns an inventory Entity with the selected facts
|
||||
func (s *Server) GetEntity(ctx context.Context, req *pb.GetEntityRequest) (*pb.GetEntityReply, error) {
|
||||
var facts []*pb.Fact
|
||||
entityUri, err := s.Storage.GetEntity(req.GetEntity().GetUri())
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, fmt.Sprintf("could not get entity %v", err))
|
||||
}
|
||||
return &pb.GetEntityReply{Entity: &pb.Entity{Uri: entityUri}}, nil
|
||||
for _, factName := range req.GetIncludeFacts() {
|
||||
value, err := s.Storage.GetFact(entityUri, factName)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, fmt.Sprintf("could not get fact %v for %v", factName, entityUri))
|
||||
}
|
||||
facts = append(facts, &pb.Fact{Name: factName, Value: value})
|
||||
}
|
||||
|
||||
return &pb.GetEntityReply{Entity: &pb.Entity{Uri: entityUri}, Facts: facts}, nil
|
||||
}
|
||||
|
||||
func (s *Server) SetFact(ctx context.Context, req *pb.SetFactRequest) (*pb.SetFactReply, error) {
|
||||
factUri, err := s.Storage.SetFact(req.EntityUri, req.Name, req.Value)
|
||||
err := s.Storage.SetFact(req.EntityUri, req.Name, req.Value)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, "could not set fact")
|
||||
}
|
||||
return &pb.SetFactReply{FactUri: factUri} , nil
|
||||
return &pb.SetFactReply{Fact: &pb.Fact{Name: req.GetName(), Value: req.GetValue()}}, nil
|
||||
}
|
||||
|
||||
func (s *Server) GetFact(ctx context.Context, req *pb.GetFactRequest) (*pb.GetFactReply, error) {
|
||||
val, err := s.Storage.GetFact(req.EntityUri, req.Name)
|
||||
if err != nil {
|
||||
return nil, status.Error(codes.Internal, "could not set fact")
|
||||
}
|
||||
return &pb.GetFactReply{Fact: &pb.Fact{Name: req.GetName(), Value: val}}, nil
|
||||
}
|
||||
|
||||
@@ -3,14 +3,48 @@ package app
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/spotify/backstage/inventory/storage"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/spotify/backstage/inventory/storage"
|
||||
|
||||
pb "github.com/spotify/backstage/proto/inventory/v1"
|
||||
)
|
||||
|
||||
func TestServerListEntities(t *testing.T) {
|
||||
testStorage := NewTestStorage()
|
||||
defer testStorage.Close()
|
||||
s := Server{Storage: testStorage.Storage}
|
||||
|
||||
entity := &pb.Entity{Uri: "boss://test/test"}
|
||||
|
||||
_, err := s.CreateEntity(context.Background(), &pb.CreateEntityRequest{Entity: entity})
|
||||
if err != nil {
|
||||
t.Errorf("ServerTest(TestServerListEntities) could not create: %v", err)
|
||||
}
|
||||
|
||||
list, err := s.ListEntities(context.Background(), &pb.ListEntitiesRequest{UriPrefix: ""})
|
||||
if err != nil {
|
||||
t.Errorf("ServerTest(TestServerListEntities) could not list: %v", err)
|
||||
}
|
||||
if len(list.GetEntities()) != 1 {
|
||||
t.Errorf("ServerTest(TestServerListEntities) expected %v items, got %v", 1, len(list.GetEntities()))
|
||||
}
|
||||
if list.GetEntities()[0].GetUri() != "boss://test/test" {
|
||||
t.Errorf("ServerTest(TestServerListEntities) expected uri %v, got %v", "boss://test/test", list.GetEntities()[0].GetUri())
|
||||
}
|
||||
|
||||
list, err = s.ListEntities(context.Background(), &pb.ListEntitiesRequest{UriPrefix: "boss://test2"})
|
||||
if err != nil {
|
||||
t.Errorf("ServerTest(TestServerListEntities) could not list: %v", err)
|
||||
}
|
||||
if len(list.GetEntities()) != 0 {
|
||||
t.Errorf("ServerTest(TestServerListEntities) expected %v items, got %v", 0, len(list.GetEntities()))
|
||||
}
|
||||
}
|
||||
|
||||
func TestServerCreateEntity(t *testing.T) {
|
||||
testStorage := NewTestStorage()
|
||||
defer testStorage.Close()
|
||||
@@ -22,7 +56,7 @@ func TestServerCreateEntity(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Errorf("ServerTest(CreateEntity) got unexpected error %v", err)
|
||||
}
|
||||
if resp.GetEntity().GetUri() != entity.GetUri() {
|
||||
if resp.GetEntity().GetUri() != entity.GetUri() {
|
||||
t.Errorf("ServerTest(CreateEntity) expected %v, but got %v", entity.GetUri(), resp.GetEntity().GetUri())
|
||||
}
|
||||
}
|
||||
@@ -49,6 +83,31 @@ func TestServerGetEntity(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestServerGetEntityWithIncludedFacts(t *testing.T) {
|
||||
testStorage := NewTestStorage()
|
||||
defer testStorage.Close()
|
||||
s := Server{Storage: testStorage.Storage}
|
||||
|
||||
entityUri := "boss://test/test"
|
||||
setFactReq := &pb.SetFactRequest{EntityUri: entityUri, Name: "test-name", Value: "test-value"}
|
||||
s.SetFact(context.Background(), setFactReq)
|
||||
|
||||
entity := &pb.Entity{Uri: entityUri}
|
||||
req := &pb.GetEntityRequest{Entity: entity, IncludeFacts: []string{"test-name"}}
|
||||
|
||||
resp, err := s.GetEntity(context.Background(), req)
|
||||
if err != nil {
|
||||
t.Errorf("ServerTest(GetEntity) got unexpected error %v", err)
|
||||
}
|
||||
if resp == nil {
|
||||
t.Errorf("ServerTest(GetEntity) returned nil")
|
||||
}
|
||||
expectedFacts := []*pb.Fact{{Name: "test-name", Value: "test-value"}}
|
||||
if !reflect.DeepEqual(resp.GetFacts(), expectedFacts) {
|
||||
t.Errorf("ServerTest(GetEntity) got %v, wanted %v", resp.GetFacts(), expectedFacts)
|
||||
}
|
||||
}
|
||||
|
||||
func TestServerSetFactForExistingEntity(t *testing.T) {
|
||||
testStorage := NewTestStorage()
|
||||
defer testStorage.Close()
|
||||
@@ -66,8 +125,9 @@ func TestServerSetFactForExistingEntity(t *testing.T) {
|
||||
if resp == nil {
|
||||
t.Errorf("ServerTest(SetFact) returned nil")
|
||||
}
|
||||
if resp.GetFactUri() != entity.GetUri() + "/" + req.Name {
|
||||
t.Errorf("ServerTest(SetFact) got %v, wanted %v", resp.GetFactUri(), entity.GetUri() + "/" + req.Name)
|
||||
fact := &pb.Fact{Name: req.GetName(), Value: req.GetValue()}
|
||||
if !reflect.DeepEqual(resp.GetFact(), fact) {
|
||||
t.Errorf("ServerTest(SetFact) got %v, wanted %v", resp.GetFact(), fact)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,14 +145,16 @@ func TestServerSetFactForNonExistingEntity(t *testing.T) {
|
||||
if resp == nil {
|
||||
t.Errorf("ServerTest(SetFact) returned nil")
|
||||
}
|
||||
if resp.GetFactUri() != entityUri + "/" + req.Name {
|
||||
t.Errorf("ServerTest(SetFact) got %v, wanted %v", resp.GetFactUri(), entityUri + "/" + req.Name)
|
||||
|
||||
fact := &pb.Fact{Name: req.GetName(), Value: req.GetValue()}
|
||||
if !reflect.DeepEqual(resp.GetFact(), fact) {
|
||||
t.Errorf("ServerTest(SetFact) got %v, wanted %v", resp.GetFact(), fact)
|
||||
}
|
||||
}
|
||||
|
||||
type TestStorage struct {
|
||||
Storage *storage.Storage
|
||||
Path string
|
||||
Path string
|
||||
}
|
||||
|
||||
// NewTestStorage returns a TestStorage using a temporary path.
|
||||
@@ -114,4 +176,3 @@ func (db *TestStorage) Close() {
|
||||
defer os.Remove(db.Path)
|
||||
db.Storage.Close()
|
||||
}
|
||||
|
||||
|
||||
@@ -8,8 +8,5 @@ require (
|
||||
github.com/golang/protobuf v1.3.3
|
||||
github.com/spotify/backstage/proto v0.0.0-00010101000000-000000000000
|
||||
go.etcd.io/bbolt v1.3.3
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3 // indirect
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135 // indirect
|
||||
google.golang.org/grpc v1.27.0
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc // indirect
|
||||
)
|
||||
|
||||
@@ -3,6 +3,7 @@ package storage
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"go.etcd.io/bbolt"
|
||||
)
|
||||
@@ -37,8 +38,8 @@ func (s *Storage) Close() error {
|
||||
return s.db.Close()
|
||||
}
|
||||
|
||||
func (s *Storage) SetFact(entityUri, name, value string) (factUri string, err error) {
|
||||
err = s.db.Update(func(tx *bbolt.Tx) error {
|
||||
func (s *Storage) SetFact(entityUri, name, value string) (err error) {
|
||||
return s.db.Update(func(tx *bbolt.Tx) error {
|
||||
b, err := tx.CreateBucketIfNotExists([]byte(entityUri))
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -49,11 +50,6 @@ func (s *Storage) SetFact(entityUri, name, value string) (factUri string, err er
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return entityUri + "/" + name, nil
|
||||
}
|
||||
|
||||
func (s *Storage) GetFact(entityUri, name string) (string, error) {
|
||||
@@ -67,6 +63,7 @@ func (s *Storage) GetFact(entityUri, name string) (string, error) {
|
||||
value = string(b.Get([]byte(name)))
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -74,6 +71,31 @@ func (s *Storage) GetFact(entityUri, name string) (string, error) {
|
||||
return value, nil
|
||||
}
|
||||
|
||||
func (s *Storage) ListEntities(uriPrefix string) ([]string, error) {
|
||||
entities := []string{}
|
||||
err := s.db.View(func(tx *bbolt.Tx) error {
|
||||
err := tx.ForEach(func(name []byte, b *bbolt.Bucket) error {
|
||||
namestring := string(name)
|
||||
if uriPrefix == "" || strings.HasPrefix(namestring, uriPrefix) {
|
||||
entities = append(entities, namestring)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return entities, nil
|
||||
}
|
||||
|
||||
func (s *Storage) CreateEntity(entityUri string) error {
|
||||
return s.db.Update(func(tx *bbolt.Tx) error {
|
||||
_, err := tx.CreateBucketIfNotExists([]byte(entityUri))
|
||||
|
||||
@@ -0,0 +1,509 @@
|
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: builds/v1/builds.proto
|
||||
|
||||
package buildsv1
|
||||
|
||||
import (
|
||||
context "context"
|
||||
fmt "fmt"
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
status "google.golang.org/grpc/status"
|
||||
math "math"
|
||||
)
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ = proto.Marshal
|
||||
var _ = fmt.Errorf
|
||||
var _ = math.Inf
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the proto package it is being compiled against.
|
||||
// A compilation error at this line likely means your copy of the
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
type BuildStatus int32
|
||||
|
||||
const (
|
||||
BuildStatus_NULL BuildStatus = 0
|
||||
BuildStatus_SUCCESS BuildStatus = 1
|
||||
BuildStatus_FAILURE BuildStatus = 2
|
||||
BuildStatus_PENDING BuildStatus = 3
|
||||
BuildStatus_RUNNING BuildStatus = 4
|
||||
)
|
||||
|
||||
var BuildStatus_name = map[int32]string{
|
||||
0: "NULL",
|
||||
1: "SUCCESS",
|
||||
2: "FAILURE",
|
||||
3: "PENDING",
|
||||
4: "RUNNING",
|
||||
}
|
||||
|
||||
var BuildStatus_value = map[string]int32{
|
||||
"NULL": 0,
|
||||
"SUCCESS": 1,
|
||||
"FAILURE": 2,
|
||||
"PENDING": 3,
|
||||
"RUNNING": 4,
|
||||
}
|
||||
|
||||
func (x BuildStatus) String() string {
|
||||
return proto.EnumName(BuildStatus_name, int32(x))
|
||||
}
|
||||
|
||||
func (BuildStatus) EnumDescriptor() ([]byte, []int) {
|
||||
return fileDescriptor_05a627abb7f9adb4, []int{0}
|
||||
}
|
||||
|
||||
type ListBuildsRequest struct {
|
||||
EntityUri string `protobuf:"bytes,1,opt,name=entity_uri,json=entityUri,proto3" json:"entity_uri,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *ListBuildsRequest) Reset() { *m = ListBuildsRequest{} }
|
||||
func (m *ListBuildsRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*ListBuildsRequest) ProtoMessage() {}
|
||||
func (*ListBuildsRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_05a627abb7f9adb4, []int{0}
|
||||
}
|
||||
|
||||
func (m *ListBuildsRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_ListBuildsRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *ListBuildsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_ListBuildsRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *ListBuildsRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_ListBuildsRequest.Merge(m, src)
|
||||
}
|
||||
func (m *ListBuildsRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_ListBuildsRequest.Size(m)
|
||||
}
|
||||
func (m *ListBuildsRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_ListBuildsRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_ListBuildsRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *ListBuildsRequest) GetEntityUri() string {
|
||||
if m != nil {
|
||||
return m.EntityUri
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type ListBuildsReply struct {
|
||||
EntityUri string `protobuf:"bytes,1,opt,name=entity_uri,json=entityUri,proto3" json:"entity_uri,omitempty"`
|
||||
Builds []*Build `protobuf:"bytes,2,rep,name=builds,proto3" json:"builds,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *ListBuildsReply) Reset() { *m = ListBuildsReply{} }
|
||||
func (m *ListBuildsReply) String() string { return proto.CompactTextString(m) }
|
||||
func (*ListBuildsReply) ProtoMessage() {}
|
||||
func (*ListBuildsReply) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_05a627abb7f9adb4, []int{1}
|
||||
}
|
||||
|
||||
func (m *ListBuildsReply) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_ListBuildsReply.Unmarshal(m, b)
|
||||
}
|
||||
func (m *ListBuildsReply) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_ListBuildsReply.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *ListBuildsReply) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_ListBuildsReply.Merge(m, src)
|
||||
}
|
||||
func (m *ListBuildsReply) XXX_Size() int {
|
||||
return xxx_messageInfo_ListBuildsReply.Size(m)
|
||||
}
|
||||
func (m *ListBuildsReply) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_ListBuildsReply.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_ListBuildsReply proto.InternalMessageInfo
|
||||
|
||||
func (m *ListBuildsReply) GetEntityUri() string {
|
||||
if m != nil {
|
||||
return m.EntityUri
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *ListBuildsReply) GetBuilds() []*Build {
|
||||
if m != nil {
|
||||
return m.Builds
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type GetBuildRequest struct {
|
||||
BuildUri string `protobuf:"bytes,1,opt,name=build_uri,json=buildUri,proto3" json:"build_uri,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *GetBuildRequest) Reset() { *m = GetBuildRequest{} }
|
||||
func (m *GetBuildRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*GetBuildRequest) ProtoMessage() {}
|
||||
func (*GetBuildRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_05a627abb7f9adb4, []int{2}
|
||||
}
|
||||
|
||||
func (m *GetBuildRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_GetBuildRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *GetBuildRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_GetBuildRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *GetBuildRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_GetBuildRequest.Merge(m, src)
|
||||
}
|
||||
func (m *GetBuildRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_GetBuildRequest.Size(m)
|
||||
}
|
||||
func (m *GetBuildRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_GetBuildRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_GetBuildRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *GetBuildRequest) GetBuildUri() string {
|
||||
if m != nil {
|
||||
return m.BuildUri
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type GetBuildReply struct {
|
||||
Build *Build `protobuf:"bytes,1,opt,name=build,proto3" json:"build,omitempty"`
|
||||
Details *BuildDetails `protobuf:"bytes,2,opt,name=details,proto3" json:"details,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *GetBuildReply) Reset() { *m = GetBuildReply{} }
|
||||
func (m *GetBuildReply) String() string { return proto.CompactTextString(m) }
|
||||
func (*GetBuildReply) ProtoMessage() {}
|
||||
func (*GetBuildReply) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_05a627abb7f9adb4, []int{3}
|
||||
}
|
||||
|
||||
func (m *GetBuildReply) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_GetBuildReply.Unmarshal(m, b)
|
||||
}
|
||||
func (m *GetBuildReply) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_GetBuildReply.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *GetBuildReply) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_GetBuildReply.Merge(m, src)
|
||||
}
|
||||
func (m *GetBuildReply) XXX_Size() int {
|
||||
return xxx_messageInfo_GetBuildReply.Size(m)
|
||||
}
|
||||
func (m *GetBuildReply) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_GetBuildReply.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_GetBuildReply proto.InternalMessageInfo
|
||||
|
||||
func (m *GetBuildReply) GetBuild() *Build {
|
||||
if m != nil {
|
||||
return m.Build
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *GetBuildReply) GetDetails() *BuildDetails {
|
||||
if m != nil {
|
||||
return m.Details
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Build struct {
|
||||
Uri string `protobuf:"bytes,1,opt,name=uri,proto3" json:"uri,omitempty"`
|
||||
CommitId string `protobuf:"bytes,2,opt,name=commit_id,json=commitId,proto3" json:"commit_id,omitempty"`
|
||||
Message string `protobuf:"bytes,3,opt,name=message,proto3" json:"message,omitempty"`
|
||||
Status BuildStatus `protobuf:"varint,4,opt,name=status,proto3,enum=spotify.backstage.builds.v1.BuildStatus" json:"status,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *Build) Reset() { *m = Build{} }
|
||||
func (m *Build) String() string { return proto.CompactTextString(m) }
|
||||
func (*Build) ProtoMessage() {}
|
||||
func (*Build) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_05a627abb7f9adb4, []int{4}
|
||||
}
|
||||
|
||||
func (m *Build) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_Build.Unmarshal(m, b)
|
||||
}
|
||||
func (m *Build) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_Build.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *Build) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_Build.Merge(m, src)
|
||||
}
|
||||
func (m *Build) XXX_Size() int {
|
||||
return xxx_messageInfo_Build.Size(m)
|
||||
}
|
||||
func (m *Build) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_Build.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_Build proto.InternalMessageInfo
|
||||
|
||||
func (m *Build) GetUri() string {
|
||||
if m != nil {
|
||||
return m.Uri
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Build) GetCommitId() string {
|
||||
if m != nil {
|
||||
return m.CommitId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Build) GetMessage() string {
|
||||
if m != nil {
|
||||
return m.Message
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Build) GetStatus() BuildStatus {
|
||||
if m != nil {
|
||||
return m.Status
|
||||
}
|
||||
return BuildStatus_NULL
|
||||
}
|
||||
|
||||
type BuildDetails struct {
|
||||
Author string `protobuf:"bytes,1,opt,name=author,proto3" json:"author,omitempty"`
|
||||
OverviewUrl string `protobuf:"bytes,2,opt,name=overview_url,json=overviewUrl,proto3" json:"overview_url,omitempty"`
|
||||
LogUrl string `protobuf:"bytes,3,opt,name=log_url,json=logUrl,proto3" json:"log_url,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *BuildDetails) Reset() { *m = BuildDetails{} }
|
||||
func (m *BuildDetails) String() string { return proto.CompactTextString(m) }
|
||||
func (*BuildDetails) ProtoMessage() {}
|
||||
func (*BuildDetails) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_05a627abb7f9adb4, []int{5}
|
||||
}
|
||||
|
||||
func (m *BuildDetails) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_BuildDetails.Unmarshal(m, b)
|
||||
}
|
||||
func (m *BuildDetails) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_BuildDetails.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *BuildDetails) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_BuildDetails.Merge(m, src)
|
||||
}
|
||||
func (m *BuildDetails) XXX_Size() int {
|
||||
return xxx_messageInfo_BuildDetails.Size(m)
|
||||
}
|
||||
func (m *BuildDetails) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_BuildDetails.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_BuildDetails proto.InternalMessageInfo
|
||||
|
||||
func (m *BuildDetails) GetAuthor() string {
|
||||
if m != nil {
|
||||
return m.Author
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *BuildDetails) GetOverviewUrl() string {
|
||||
if m != nil {
|
||||
return m.OverviewUrl
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *BuildDetails) GetLogUrl() string {
|
||||
if m != nil {
|
||||
return m.LogUrl
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterEnum("spotify.backstage.builds.v1.BuildStatus", BuildStatus_name, BuildStatus_value)
|
||||
proto.RegisterType((*ListBuildsRequest)(nil), "spotify.backstage.builds.v1.ListBuildsRequest")
|
||||
proto.RegisterType((*ListBuildsReply)(nil), "spotify.backstage.builds.v1.ListBuildsReply")
|
||||
proto.RegisterType((*GetBuildRequest)(nil), "spotify.backstage.builds.v1.GetBuildRequest")
|
||||
proto.RegisterType((*GetBuildReply)(nil), "spotify.backstage.builds.v1.GetBuildReply")
|
||||
proto.RegisterType((*Build)(nil), "spotify.backstage.builds.v1.Build")
|
||||
proto.RegisterType((*BuildDetails)(nil), "spotify.backstage.builds.v1.BuildDetails")
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("builds/v1/builds.proto", fileDescriptor_05a627abb7f9adb4) }
|
||||
|
||||
var fileDescriptor_05a627abb7f9adb4 = []byte{
|
||||
// 447 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x53, 0x41, 0x6f, 0xd3, 0x30,
|
||||
0x18, 0x25, 0x6b, 0x97, 0xb6, 0x5f, 0x07, 0x0b, 0x3e, 0x8c, 0x68, 0x13, 0x52, 0xc9, 0xa9, 0x4c,
|
||||
0x28, 0x53, 0xcb, 0x05, 0x71, 0x82, 0x75, 0x65, 0xaa, 0xa8, 0x22, 0xe4, 0x2a, 0x17, 0x2e, 0x55,
|
||||
0xda, 0x98, 0x62, 0x70, 0x71, 0xb0, 0x9d, 0xa0, 0xfc, 0x09, 0x0e, 0xfc, 0x3c, 0x7e, 0x0d, 0xb2,
|
||||
0x9d, 0xa8, 0x11, 0x93, 0xda, 0xde, 0xfc, 0xbe, 0xf7, 0xbd, 0xbc, 0xf7, 0x49, 0x2f, 0x70, 0xb1,
|
||||
0xca, 0x29, 0x4b, 0xe5, 0x4d, 0x31, 0xba, 0xb1, 0xaf, 0x30, 0x13, 0x5c, 0x71, 0x74, 0x25, 0x33,
|
||||
0xae, 0xe8, 0x97, 0x32, 0x5c, 0x25, 0xeb, 0xef, 0x52, 0x25, 0x1b, 0x12, 0x56, 0x7c, 0x31, 0x0a,
|
||||
0xc6, 0xf0, 0x74, 0x4e, 0xa5, 0xba, 0x35, 0x03, 0x4c, 0x7e, 0xe6, 0x44, 0x2a, 0xf4, 0x1c, 0x80,
|
||||
0xfc, 0x50, 0x54, 0x95, 0xcb, 0x5c, 0x50, 0xdf, 0x19, 0x38, 0xc3, 0x1e, 0xee, 0xd9, 0x49, 0x2c,
|
||||
0x68, 0xc0, 0xe0, 0xbc, 0xa9, 0xc9, 0x58, 0x79, 0x40, 0x81, 0xde, 0x82, 0x6b, 0x2d, 0xfd, 0x93,
|
||||
0x41, 0x6b, 0xd8, 0x1f, 0x07, 0xe1, 0x9e, 0x4c, 0xa1, 0xf9, 0x30, 0xae, 0x14, 0x41, 0x08, 0xe7,
|
||||
0xf7, 0xc4, 0x9a, 0xd5, 0xf9, 0xae, 0xa0, 0x67, 0xc8, 0x86, 0x59, 0xd7, 0x0c, 0x74, 0xba, 0xdf,
|
||||
0x0e, 0x3c, 0xde, 0x09, 0x74, 0xb8, 0x37, 0x70, 0x6a, 0x58, 0xb3, 0x7a, 0x9c, 0xb9, 0x15, 0xa0,
|
||||
0x09, 0x74, 0x52, 0xa2, 0x12, 0xca, 0x74, 0x70, 0xad, 0x7d, 0x79, 0x58, 0x7b, 0x67, 0x05, 0xb8,
|
||||
0x56, 0x06, 0x7f, 0x1c, 0x38, 0x35, 0x0c, 0xf2, 0xa0, 0xb5, 0x4b, 0xac, 0x9f, 0xfa, 0x92, 0x35,
|
||||
0xdf, 0x6e, 0xa9, 0x5a, 0xd2, 0xd4, 0x58, 0xf4, 0x70, 0xd7, 0x0e, 0x66, 0x29, 0xf2, 0xa1, 0xb3,
|
||||
0x25, 0x52, 0x26, 0x1b, 0xe2, 0xb7, 0x0c, 0x55, 0x43, 0xf4, 0x0e, 0x5c, 0xa9, 0x12, 0x95, 0x4b,
|
||||
0xbf, 0x3d, 0x70, 0x86, 0x4f, 0xc6, 0xc3, 0xc3, 0xb1, 0x16, 0x66, 0x1f, 0x57, 0xba, 0x60, 0x05,
|
||||
0x67, 0xcd, 0xb4, 0xe8, 0x02, 0xdc, 0x24, 0x57, 0x5f, 0xb9, 0xa8, 0xd2, 0x55, 0x08, 0xbd, 0x80,
|
||||
0x33, 0x5e, 0x10, 0x51, 0x50, 0xf2, 0x6b, 0x99, 0x0b, 0x56, 0x65, 0xec, 0xd7, 0xb3, 0x58, 0x30,
|
||||
0xf4, 0x0c, 0x3a, 0x8c, 0x6f, 0x0c, 0x6b, 0x63, 0xba, 0x8c, 0x6f, 0x62, 0xc1, 0xae, 0x3f, 0x42,
|
||||
0xbf, 0x61, 0x8d, 0xba, 0xd0, 0x8e, 0xe2, 0xf9, 0xdc, 0x7b, 0x84, 0xfa, 0xd0, 0x59, 0xc4, 0x93,
|
||||
0xc9, 0x74, 0xb1, 0xf0, 0x1c, 0x0d, 0x3e, 0xbc, 0x9f, 0xcd, 0x63, 0x3c, 0xf5, 0x4e, 0x34, 0xf8,
|
||||
0x34, 0x8d, 0xee, 0x66, 0xd1, 0xbd, 0xd7, 0xd2, 0x00, 0xc7, 0x51, 0xa4, 0x41, 0x7b, 0xfc, 0xd7,
|
||||
0x01, 0xd7, 0x36, 0x0e, 0x7d, 0x03, 0xd8, 0xf5, 0x0f, 0x85, 0x7b, 0x6f, 0x7f, 0x50, 0xee, 0xcb,
|
||||
0x57, 0x47, 0xef, 0xeb, 0xee, 0xa4, 0xd0, 0xad, 0xcb, 0x84, 0xf6, 0x2b, 0xff, 0x2b, 0xe9, 0xe5,
|
||||
0xf5, 0x91, 0xdb, 0x19, 0x2b, 0x6f, 0xe1, 0xb3, 0xed, 0xaf, 0x2c, 0x46, 0x2b, 0xd7, 0xfc, 0xb5,
|
||||
0xaf, 0xff, 0x05, 0x00, 0x00, 0xff, 0xff, 0x40, 0xf3, 0x96, 0x0b, 0xcf, 0x03, 0x00, 0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
var _ context.Context
|
||||
var _ grpc.ClientConnInterface
|
||||
|
||||
// This is a compile-time assertion to ensure that this generated file
|
||||
// is compatible with the grpc package it is being compiled against.
|
||||
const _ = grpc.SupportPackageIsVersion6
|
||||
|
||||
// BuildsClient is the client API for Builds service.
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
|
||||
type BuildsClient interface {
|
||||
ListBuilds(ctx context.Context, in *ListBuildsRequest, opts ...grpc.CallOption) (*ListBuildsReply, error)
|
||||
GetBuild(ctx context.Context, in *GetBuildRequest, opts ...grpc.CallOption) (*GetBuildReply, error)
|
||||
}
|
||||
|
||||
type buildsClient struct {
|
||||
cc grpc.ClientConnInterface
|
||||
}
|
||||
|
||||
func NewBuildsClient(cc grpc.ClientConnInterface) BuildsClient {
|
||||
return &buildsClient{cc}
|
||||
}
|
||||
|
||||
func (c *buildsClient) ListBuilds(ctx context.Context, in *ListBuildsRequest, opts ...grpc.CallOption) (*ListBuildsReply, error) {
|
||||
out := new(ListBuildsReply)
|
||||
err := c.cc.Invoke(ctx, "/spotify.backstage.builds.v1.Builds/ListBuilds", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *buildsClient) GetBuild(ctx context.Context, in *GetBuildRequest, opts ...grpc.CallOption) (*GetBuildReply, error) {
|
||||
out := new(GetBuildReply)
|
||||
err := c.cc.Invoke(ctx, "/spotify.backstage.builds.v1.Builds/GetBuild", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// BuildsServer is the server API for Builds service.
|
||||
type BuildsServer interface {
|
||||
ListBuilds(context.Context, *ListBuildsRequest) (*ListBuildsReply, error)
|
||||
GetBuild(context.Context, *GetBuildRequest) (*GetBuildReply, error)
|
||||
}
|
||||
|
||||
// UnimplementedBuildsServer can be embedded to have forward compatible implementations.
|
||||
type UnimplementedBuildsServer struct {
|
||||
}
|
||||
|
||||
func (*UnimplementedBuildsServer) ListBuilds(ctx context.Context, req *ListBuildsRequest) (*ListBuildsReply, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method ListBuilds not implemented")
|
||||
}
|
||||
func (*UnimplementedBuildsServer) GetBuild(ctx context.Context, req *GetBuildRequest) (*GetBuildReply, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetBuild not implemented")
|
||||
}
|
||||
|
||||
func RegisterBuildsServer(s *grpc.Server, srv BuildsServer) {
|
||||
s.RegisterService(&_Builds_serviceDesc, srv)
|
||||
}
|
||||
|
||||
func _Builds_ListBuilds_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ListBuildsRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(BuildsServer).ListBuilds(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/spotify.backstage.builds.v1.Builds/ListBuilds",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(BuildsServer).ListBuilds(ctx, req.(*ListBuildsRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Builds_GetBuild_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetBuildRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(BuildsServer).GetBuild(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/spotify.backstage.builds.v1.Builds/GetBuild",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(BuildsServer).GetBuild(ctx, req.(*GetBuildRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
var _Builds_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "spotify.backstage.builds.v1.Builds",
|
||||
HandlerType: (*BuildsServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "ListBuilds",
|
||||
Handler: _Builds_ListBuilds_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetBuild",
|
||||
Handler: _Builds_GetBuild_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "builds/v1/builds.proto",
|
||||
}
|
||||
@@ -24,6 +24,84 @@ var _ = math.Inf
|
||||
// proto package needs to be updated.
|
||||
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
|
||||
|
||||
type ListEntitiesRequest struct {
|
||||
UriPrefix string `protobuf:"bytes,1,opt,name=uriPrefix,proto3" json:"uriPrefix,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *ListEntitiesRequest) Reset() { *m = ListEntitiesRequest{} }
|
||||
func (m *ListEntitiesRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*ListEntitiesRequest) ProtoMessage() {}
|
||||
func (*ListEntitiesRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_70be9028e322f9d8, []int{0}
|
||||
}
|
||||
|
||||
func (m *ListEntitiesRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_ListEntitiesRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *ListEntitiesRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_ListEntitiesRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *ListEntitiesRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_ListEntitiesRequest.Merge(m, src)
|
||||
}
|
||||
func (m *ListEntitiesRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_ListEntitiesRequest.Size(m)
|
||||
}
|
||||
func (m *ListEntitiesRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_ListEntitiesRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_ListEntitiesRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *ListEntitiesRequest) GetUriPrefix() string {
|
||||
if m != nil {
|
||||
return m.UriPrefix
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type ListEntitiesReply struct {
|
||||
Entities []*Entity `protobuf:"bytes,1,rep,name=entities,proto3" json:"entities,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *ListEntitiesReply) Reset() { *m = ListEntitiesReply{} }
|
||||
func (m *ListEntitiesReply) String() string { return proto.CompactTextString(m) }
|
||||
func (*ListEntitiesReply) ProtoMessage() {}
|
||||
func (*ListEntitiesReply) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_70be9028e322f9d8, []int{1}
|
||||
}
|
||||
|
||||
func (m *ListEntitiesReply) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_ListEntitiesReply.Unmarshal(m, b)
|
||||
}
|
||||
func (m *ListEntitiesReply) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_ListEntitiesReply.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *ListEntitiesReply) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_ListEntitiesReply.Merge(m, src)
|
||||
}
|
||||
func (m *ListEntitiesReply) XXX_Size() int {
|
||||
return xxx_messageInfo_ListEntitiesReply.Size(m)
|
||||
}
|
||||
func (m *ListEntitiesReply) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_ListEntitiesReply.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_ListEntitiesReply proto.InternalMessageInfo
|
||||
|
||||
func (m *ListEntitiesReply) GetEntities() []*Entity {
|
||||
if m != nil {
|
||||
return m.Entities
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type GetEntityRequest struct {
|
||||
Entity *Entity `protobuf:"bytes,1,opt,name=entity,proto3" json:"entity,omitempty"`
|
||||
IncludeFacts []string `protobuf:"bytes,2,rep,name=include_facts,json=includeFacts,proto3" json:"include_facts,omitempty"`
|
||||
@@ -36,7 +114,7 @@ func (m *GetEntityRequest) Reset() { *m = GetEntityRequest{} }
|
||||
func (m *GetEntityRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*GetEntityRequest) ProtoMessage() {}
|
||||
func (*GetEntityRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_70be9028e322f9d8, []int{0}
|
||||
return fileDescriptor_70be9028e322f9d8, []int{2}
|
||||
}
|
||||
|
||||
func (m *GetEntityRequest) XXX_Unmarshal(b []byte) error {
|
||||
@@ -83,7 +161,7 @@ func (m *GetEntityReply) Reset() { *m = GetEntityReply{} }
|
||||
func (m *GetEntityReply) String() string { return proto.CompactTextString(m) }
|
||||
func (*GetEntityReply) ProtoMessage() {}
|
||||
func (*GetEntityReply) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_70be9028e322f9d8, []int{1}
|
||||
return fileDescriptor_70be9028e322f9d8, []int{3}
|
||||
}
|
||||
|
||||
func (m *GetEntityReply) XXX_Unmarshal(b []byte) error {
|
||||
@@ -129,7 +207,7 @@ func (m *CreateEntityRequest) Reset() { *m = CreateEntityRequest{} }
|
||||
func (m *CreateEntityRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*CreateEntityRequest) ProtoMessage() {}
|
||||
func (*CreateEntityRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_70be9028e322f9d8, []int{2}
|
||||
return fileDescriptor_70be9028e322f9d8, []int{4}
|
||||
}
|
||||
|
||||
func (m *CreateEntityRequest) XXX_Unmarshal(b []byte) error {
|
||||
@@ -168,7 +246,7 @@ func (m *CreateEntityReply) Reset() { *m = CreateEntityReply{} }
|
||||
func (m *CreateEntityReply) String() string { return proto.CompactTextString(m) }
|
||||
func (*CreateEntityReply) ProtoMessage() {}
|
||||
func (*CreateEntityReply) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_70be9028e322f9d8, []int{3}
|
||||
return fileDescriptor_70be9028e322f9d8, []int{5}
|
||||
}
|
||||
|
||||
func (m *CreateEntityReply) XXX_Unmarshal(b []byte) error {
|
||||
@@ -209,7 +287,7 @@ func (m *SetFactRequest) Reset() { *m = SetFactRequest{} }
|
||||
func (m *SetFactRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*SetFactRequest) ProtoMessage() {}
|
||||
func (*SetFactRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_70be9028e322f9d8, []int{4}
|
||||
return fileDescriptor_70be9028e322f9d8, []int{6}
|
||||
}
|
||||
|
||||
func (m *SetFactRequest) XXX_Unmarshal(b []byte) error {
|
||||
@@ -252,7 +330,7 @@ func (m *SetFactRequest) GetValue() string {
|
||||
}
|
||||
|
||||
type SetFactReply struct {
|
||||
FactUri string `protobuf:"bytes,1,opt,name=factUri,proto3" json:"factUri,omitempty"`
|
||||
Fact *Fact `protobuf:"bytes,1,opt,name=fact,proto3" json:"fact,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
@@ -262,7 +340,7 @@ func (m *SetFactReply) Reset() { *m = SetFactReply{} }
|
||||
func (m *SetFactReply) String() string { return proto.CompactTextString(m) }
|
||||
func (*SetFactReply) ProtoMessage() {}
|
||||
func (*SetFactReply) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_70be9028e322f9d8, []int{5}
|
||||
return fileDescriptor_70be9028e322f9d8, []int{7}
|
||||
}
|
||||
|
||||
func (m *SetFactReply) XXX_Unmarshal(b []byte) error {
|
||||
@@ -283,13 +361,99 @@ func (m *SetFactReply) XXX_DiscardUnknown() {
|
||||
|
||||
var xxx_messageInfo_SetFactReply proto.InternalMessageInfo
|
||||
|
||||
func (m *SetFactReply) GetFactUri() string {
|
||||
func (m *SetFactReply) GetFact() *Fact {
|
||||
if m != nil {
|
||||
return m.FactUri
|
||||
return m.Fact
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type GetFactRequest struct {
|
||||
EntityUri string `protobuf:"bytes,1,opt,name=entityUri,proto3" json:"entityUri,omitempty"`
|
||||
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *GetFactRequest) Reset() { *m = GetFactRequest{} }
|
||||
func (m *GetFactRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*GetFactRequest) ProtoMessage() {}
|
||||
func (*GetFactRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_70be9028e322f9d8, []int{8}
|
||||
}
|
||||
|
||||
func (m *GetFactRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_GetFactRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *GetFactRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_GetFactRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *GetFactRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_GetFactRequest.Merge(m, src)
|
||||
}
|
||||
func (m *GetFactRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_GetFactRequest.Size(m)
|
||||
}
|
||||
func (m *GetFactRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_GetFactRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_GetFactRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *GetFactRequest) GetEntityUri() string {
|
||||
if m != nil {
|
||||
return m.EntityUri
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *GetFactRequest) GetName() string {
|
||||
if m != nil {
|
||||
return m.Name
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type GetFactReply struct {
|
||||
Fact *Fact `protobuf:"bytes,1,opt,name=fact,proto3" json:"fact,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *GetFactReply) Reset() { *m = GetFactReply{} }
|
||||
func (m *GetFactReply) String() string { return proto.CompactTextString(m) }
|
||||
func (*GetFactReply) ProtoMessage() {}
|
||||
func (*GetFactReply) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_70be9028e322f9d8, []int{9}
|
||||
}
|
||||
|
||||
func (m *GetFactReply) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_GetFactReply.Unmarshal(m, b)
|
||||
}
|
||||
func (m *GetFactReply) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_GetFactReply.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *GetFactReply) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_GetFactReply.Merge(m, src)
|
||||
}
|
||||
func (m *GetFactReply) XXX_Size() int {
|
||||
return xxx_messageInfo_GetFactReply.Size(m)
|
||||
}
|
||||
func (m *GetFactReply) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_GetFactReply.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_GetFactReply proto.InternalMessageInfo
|
||||
|
||||
func (m *GetFactReply) GetFact() *Fact {
|
||||
if m != nil {
|
||||
return m.Fact
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Entity struct {
|
||||
Uri string `protobuf:"bytes,1,opt,name=uri,proto3" json:"uri,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
@@ -301,7 +465,7 @@ func (m *Entity) Reset() { *m = Entity{} }
|
||||
func (m *Entity) String() string { return proto.CompactTextString(m) }
|
||||
func (*Entity) ProtoMessage() {}
|
||||
func (*Entity) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_70be9028e322f9d8, []int{6}
|
||||
return fileDescriptor_70be9028e322f9d8, []int{10}
|
||||
}
|
||||
|
||||
func (m *Entity) XXX_Unmarshal(b []byte) error {
|
||||
@@ -330,9 +494,8 @@ func (m *Entity) GetUri() string {
|
||||
}
|
||||
|
||||
type Fact struct {
|
||||
EntityUri string `protobuf:"bytes,1,opt,name=entityUri,proto3" json:"entityUri,omitempty"`
|
||||
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Value string `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"`
|
||||
Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
|
||||
Value string `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
@@ -342,7 +505,7 @@ func (m *Fact) Reset() { *m = Fact{} }
|
||||
func (m *Fact) String() string { return proto.CompactTextString(m) }
|
||||
func (*Fact) ProtoMessage() {}
|
||||
func (*Fact) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_70be9028e322f9d8, []int{7}
|
||||
return fileDescriptor_70be9028e322f9d8, []int{11}
|
||||
}
|
||||
|
||||
func (m *Fact) XXX_Unmarshal(b []byte) error {
|
||||
@@ -363,13 +526,6 @@ func (m *Fact) XXX_DiscardUnknown() {
|
||||
|
||||
var xxx_messageInfo_Fact proto.InternalMessageInfo
|
||||
|
||||
func (m *Fact) GetEntityUri() string {
|
||||
if m != nil {
|
||||
return m.EntityUri
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *Fact) GetName() string {
|
||||
if m != nil {
|
||||
return m.Name
|
||||
@@ -385,12 +541,16 @@ func (m *Fact) GetValue() string {
|
||||
}
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*ListEntitiesRequest)(nil), "spotify.backstage.inventory.v1.ListEntitiesRequest")
|
||||
proto.RegisterType((*ListEntitiesReply)(nil), "spotify.backstage.inventory.v1.ListEntitiesReply")
|
||||
proto.RegisterType((*GetEntityRequest)(nil), "spotify.backstage.inventory.v1.GetEntityRequest")
|
||||
proto.RegisterType((*GetEntityReply)(nil), "spotify.backstage.inventory.v1.GetEntityReply")
|
||||
proto.RegisterType((*CreateEntityRequest)(nil), "spotify.backstage.inventory.v1.CreateEntityRequest")
|
||||
proto.RegisterType((*CreateEntityReply)(nil), "spotify.backstage.inventory.v1.CreateEntityReply")
|
||||
proto.RegisterType((*SetFactRequest)(nil), "spotify.backstage.inventory.v1.SetFactRequest")
|
||||
proto.RegisterType((*SetFactReply)(nil), "spotify.backstage.inventory.v1.SetFactReply")
|
||||
proto.RegisterType((*GetFactRequest)(nil), "spotify.backstage.inventory.v1.GetFactRequest")
|
||||
proto.RegisterType((*GetFactReply)(nil), "spotify.backstage.inventory.v1.GetFactReply")
|
||||
proto.RegisterType((*Entity)(nil), "spotify.backstage.inventory.v1.Entity")
|
||||
proto.RegisterType((*Fact)(nil), "spotify.backstage.inventory.v1.Fact")
|
||||
}
|
||||
@@ -398,29 +558,36 @@ func init() {
|
||||
func init() { proto.RegisterFile("inventory/v1/inventory.proto", fileDescriptor_70be9028e322f9d8) }
|
||||
|
||||
var fileDescriptor_70be9028e322f9d8 = []byte{
|
||||
// 346 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x53, 0x4d, 0x4b, 0xc3, 0x40,
|
||||
0x10, 0x25, 0xfd, 0x92, 0x4c, 0x3f, 0xa8, 0xab, 0x87, 0x50, 0x8a, 0x94, 0x55, 0xa4, 0xa7, 0xd4,
|
||||
0xb4, 0x37, 0x0f, 0x1e, 0x14, 0x15, 0x2f, 0x1e, 0x52, 0x0a, 0xe2, 0x45, 0xb6, 0x75, 0x2a, 0xc1,
|
||||
0x34, 0x89, 0xc9, 0x66, 0x25, 0xff, 0xc1, 0x5f, 0xeb, 0x2f, 0x90, 0xdd, 0xa4, 0x49, 0x15, 0xb1,
|
||||
0x14, 0x73, 0xdb, 0x79, 0xb3, 0xef, 0xcd, 0xcb, 0xcb, 0x2c, 0xf4, 0x1d, 0x4f, 0xa0, 0xc7, 0xfd,
|
||||
0x30, 0x19, 0x09, 0x6b, 0x94, 0x17, 0x66, 0x10, 0xfa, 0xdc, 0x27, 0x47, 0x51, 0xe0, 0x73, 0x67,
|
||||
0x99, 0x98, 0x73, 0xb6, 0x78, 0x8d, 0x38, 0x7b, 0x41, 0xb3, 0xb8, 0x22, 0x2c, 0xfa, 0x0e, 0xdd,
|
||||
0x5b, 0xe4, 0xd7, 0x1e, 0x77, 0x78, 0x62, 0xe3, 0x5b, 0x8c, 0x11, 0x27, 0x17, 0xd0, 0x40, 0x05,
|
||||
0x18, 0xda, 0x40, 0x1b, 0x36, 0xc7, 0xa7, 0xe6, 0xdf, 0x22, 0x66, 0x46, 0xcf, 0x58, 0xe4, 0x18,
|
||||
0xda, 0x8e, 0xb7, 0x70, 0xe3, 0x67, 0x7c, 0x5a, 0xb2, 0x05, 0x8f, 0x8c, 0xca, 0xa0, 0x3a, 0xd4,
|
||||
0xed, 0x56, 0x06, 0xde, 0x48, 0x8c, 0x7e, 0x68, 0xd0, 0xd9, 0x98, 0x1c, 0xb8, 0xc9, 0xbf, 0xe7,
|
||||
0x9e, 0x43, 0xbd, 0x98, 0xd7, 0x1c, 0x9f, 0x6c, 0xa3, 0x4b, 0x23, 0x76, 0x4a, 0xa1, 0x33, 0x38,
|
||||
0xb8, 0x0a, 0x91, 0x71, 0x2c, 0x35, 0x0a, 0x3a, 0x85, 0xfd, 0xef, 0xb2, 0x25, 0x7c, 0x27, 0x7d,
|
||||
0x80, 0xce, 0x14, 0xb9, 0x72, 0x9f, 0xd9, 0xec, 0x83, 0x9e, 0xf6, 0x66, 0xa1, 0xa3, 0x44, 0x75,
|
||||
0xbb, 0x00, 0x08, 0x81, 0x9a, 0xc7, 0x56, 0x68, 0x54, 0x54, 0x43, 0x9d, 0xc9, 0x21, 0xd4, 0x05,
|
||||
0x73, 0x63, 0x34, 0xaa, 0x0a, 0x4c, 0x0b, 0x3a, 0x84, 0x56, 0xae, 0x2c, 0x9d, 0x1a, 0xb0, 0x27,
|
||||
0xe3, 0x29, 0x54, 0xd7, 0x25, 0xed, 0x41, 0x23, 0x75, 0x45, 0xba, 0x50, 0x8d, 0xf3, 0xbe, 0x3c,
|
||||
0xd2, 0x7b, 0xa8, 0x49, 0x89, 0xb2, 0x5c, 0x8d, 0x3f, 0x35, 0xd0, 0xef, 0xd6, 0x79, 0x90, 0x15,
|
||||
0xe8, 0xf9, 0xde, 0x90, 0xb3, 0x6d, 0xd1, 0xfd, 0x5c, 0xee, 0x9e, 0xb9, 0x03, 0x43, 0x46, 0x20,
|
||||
0xa0, 0xb5, 0xf9, 0x07, 0xc9, 0x64, 0x1b, 0xff, 0x97, 0x35, 0xea, 0x59, 0xbb, 0x91, 0x02, 0x37,
|
||||
0xb9, 0x6c, 0x3f, 0x36, 0xf3, 0x1b, 0xc2, 0x9a, 0x37, 0xd4, 0x73, 0x9e, 0x7c, 0x05, 0x00, 0x00,
|
||||
0xff, 0xff, 0xae, 0xd9, 0x2b, 0x51, 0xee, 0x03, 0x00, 0x00,
|
||||
// 457 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x55, 0x41, 0x8f, 0x93, 0x40,
|
||||
0x14, 0x0e, 0x85, 0xad, 0xf2, 0xca, 0x6e, 0x76, 0x67, 0x3d, 0x10, 0xb2, 0x31, 0xcd, 0x68, 0x4c,
|
||||
0x0f, 0x86, 0x5d, 0xda, 0x8b, 0xf1, 0xe0, 0xa1, 0x46, 0xd1, 0xc4, 0x83, 0xa1, 0x69, 0x34, 0x5e,
|
||||
0x0c, 0xad, 0xd3, 0x66, 0x62, 0x0b, 0x15, 0x06, 0x94, 0xff, 0xe0, 0x4f, 0xf2, 0xc7, 0x99, 0x19,
|
||||
0xa6, 0x03, 0xd5, 0x66, 0xa1, 0x69, 0x6f, 0x33, 0xef, 0xcd, 0xf7, 0xbe, 0xef, 0x3d, 0xde, 0x17,
|
||||
0xe0, 0x86, 0x46, 0x39, 0x89, 0x58, 0x9c, 0x14, 0xb7, 0xb9, 0x77, 0xab, 0x2e, 0xee, 0x26, 0x89,
|
||||
0x59, 0x8c, 0x1e, 0xa7, 0x9b, 0x98, 0xd1, 0x45, 0xe1, 0xce, 0xc2, 0xf9, 0xf7, 0x94, 0x85, 0x4b,
|
||||
0xe2, 0x56, 0x4f, 0x72, 0x0f, 0x8f, 0xe0, 0xfa, 0x03, 0x4d, 0xd9, 0x9b, 0x88, 0x51, 0x46, 0x49,
|
||||
0x1a, 0x90, 0x1f, 0x19, 0x49, 0x19, 0xba, 0x01, 0x33, 0x4b, 0xe8, 0xc7, 0x84, 0x2c, 0xe8, 0x2f,
|
||||
0x5b, 0xeb, 0x6b, 0x03, 0x33, 0xa8, 0x02, 0xf8, 0x13, 0x5c, 0xed, 0x82, 0x36, 0xab, 0x02, 0x8d,
|
||||
0xe1, 0x21, 0x91, 0x01, 0x5b, 0xeb, 0xeb, 0x83, 0xde, 0xf0, 0x99, 0x7b, 0x3f, 0xb9, 0x2b, 0x0a,
|
||||
0x14, 0x81, 0xc2, 0xe1, 0x9f, 0x70, 0xe9, 0x13, 0x26, 0xc3, 0x52, 0xca, 0x2b, 0xe8, 0x8a, 0x7c,
|
||||
0x21, 0x74, 0xb4, 0xaf, 0x2a, 0x51, 0xe8, 0x09, 0x9c, 0xd3, 0x68, 0xbe, 0xca, 0xbe, 0x91, 0xaf,
|
||||
0x8b, 0x70, 0xce, 0x52, 0xbb, 0xd3, 0xd7, 0x07, 0x66, 0x60, 0xc9, 0xe0, 0x5b, 0x1e, 0xc3, 0xbf,
|
||||
0x35, 0xb8, 0xa8, 0x31, 0xf3, 0x7e, 0x8e, 0xe5, 0x7d, 0x09, 0x67, 0x15, 0x5f, 0x6f, 0xf8, 0xb4,
|
||||
0x09, 0xce, 0x85, 0x04, 0x25, 0x04, 0x4f, 0xe1, 0xfa, 0x75, 0x42, 0x42, 0x46, 0x4e, 0x3a, 0x0a,
|
||||
0x3c, 0x81, 0xab, 0xdd, 0xb2, 0x27, 0xe8, 0x13, 0x7f, 0x86, 0x8b, 0x09, 0x61, 0x42, 0x7d, 0xb5,
|
||||
0x3c, 0x65, 0x6e, 0x9a, 0xd0, 0xed, 0xf2, 0xa8, 0x00, 0x42, 0x60, 0x44, 0xe1, 0x9a, 0xd8, 0x1d,
|
||||
0x91, 0x10, 0x67, 0xf4, 0x08, 0xce, 0xf2, 0x70, 0x95, 0x11, 0x5b, 0x17, 0xc1, 0xf2, 0x82, 0xdf,
|
||||
0x81, 0xa5, 0x2a, 0x73, 0xa5, 0x2f, 0xc0, 0xe0, 0xe3, 0x91, 0x3a, 0xdb, 0x0d, 0x54, 0x20, 0xf0,
|
||||
0x58, 0x7c, 0xdd, 0xa3, 0x34, 0x72, 0x35, 0xfe, 0x69, 0xd4, 0x38, 0xd0, 0x2d, 0x67, 0x88, 0x2e,
|
||||
0x41, 0xcf, 0x14, 0x3f, 0x3f, 0xe2, 0x3b, 0x30, 0xf8, 0x4b, 0xa5, 0x40, 0xdb, 0x37, 0xa5, 0x4e,
|
||||
0x6d, 0x4a, 0xc3, 0x3f, 0x06, 0x98, 0xef, 0xb7, 0x4c, 0x28, 0x07, 0xab, 0x6e, 0x4d, 0x34, 0x6a,
|
||||
0xd2, 0xb5, 0xc7, 0xfd, 0x8e, 0x77, 0x18, 0x88, 0x4f, 0x63, 0x0d, 0xa6, 0xf2, 0x0f, 0xba, 0x6b,
|
||||
0xc2, 0xff, 0x6b, 0x72, 0xc7, 0x3d, 0x00, 0xc1, 0xe9, 0x72, 0xb0, 0xea, 0x9b, 0xdc, 0xdc, 0xe6,
|
||||
0x1e, 0x3b, 0x35, 0xb7, 0xf9, 0xbf, 0x59, 0x96, 0xf0, 0x40, 0xae, 0x24, 0x6a, 0x94, 0xbc, 0xeb,
|
||||
0x0a, 0xe7, 0x79, 0xeb, 0xf7, 0x92, 0xc8, 0x6f, 0x4b, 0xe4, 0x1f, 0x48, 0x54, 0x5f, 0xe3, 0xf1,
|
||||
0xf9, 0x97, 0x9e, 0x4a, 0xe6, 0xde, 0xac, 0x2b, 0x7e, 0x1b, 0xa3, 0xbf, 0x01, 0x00, 0x00, 0xff,
|
||||
0xff, 0x0f, 0x08, 0x7c, 0x37, 0x56, 0x06, 0x00, 0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
@@ -435,8 +602,11 @@ const _ = grpc.SupportPackageIsVersion6
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
|
||||
type InventoryClient interface {
|
||||
ListEntities(ctx context.Context, in *ListEntitiesRequest, opts ...grpc.CallOption) (*ListEntitiesReply, error)
|
||||
GetEntity(ctx context.Context, in *GetEntityRequest, opts ...grpc.CallOption) (*GetEntityReply, error)
|
||||
CreateEntity(ctx context.Context, in *CreateEntityRequest, opts ...grpc.CallOption) (*CreateEntityReply, error)
|
||||
SetFact(ctx context.Context, in *SetFactRequest, opts ...grpc.CallOption) (*SetFactReply, error)
|
||||
GetFact(ctx context.Context, in *GetFactRequest, opts ...grpc.CallOption) (*GetFactReply, error)
|
||||
}
|
||||
|
||||
type inventoryClient struct {
|
||||
@@ -447,6 +617,15 @@ func NewInventoryClient(cc grpc.ClientConnInterface) InventoryClient {
|
||||
return &inventoryClient{cc}
|
||||
}
|
||||
|
||||
func (c *inventoryClient) ListEntities(ctx context.Context, in *ListEntitiesRequest, opts ...grpc.CallOption) (*ListEntitiesReply, error) {
|
||||
out := new(ListEntitiesReply)
|
||||
err := c.cc.Invoke(ctx, "/spotify.backstage.inventory.v1.Inventory/ListEntities", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *inventoryClient) GetEntity(ctx context.Context, in *GetEntityRequest, opts ...grpc.CallOption) (*GetEntityReply, error) {
|
||||
out := new(GetEntityReply)
|
||||
err := c.cc.Invoke(ctx, "/spotify.backstage.inventory.v1.Inventory/GetEntity", in, out, opts...)
|
||||
@@ -465,27 +644,75 @@ func (c *inventoryClient) CreateEntity(ctx context.Context, in *CreateEntityRequ
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *inventoryClient) SetFact(ctx context.Context, in *SetFactRequest, opts ...grpc.CallOption) (*SetFactReply, error) {
|
||||
out := new(SetFactReply)
|
||||
err := c.cc.Invoke(ctx, "/spotify.backstage.inventory.v1.Inventory/SetFact", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *inventoryClient) GetFact(ctx context.Context, in *GetFactRequest, opts ...grpc.CallOption) (*GetFactReply, error) {
|
||||
out := new(GetFactReply)
|
||||
err := c.cc.Invoke(ctx, "/spotify.backstage.inventory.v1.Inventory/GetFact", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// InventoryServer is the server API for Inventory service.
|
||||
type InventoryServer interface {
|
||||
ListEntities(context.Context, *ListEntitiesRequest) (*ListEntitiesReply, error)
|
||||
GetEntity(context.Context, *GetEntityRequest) (*GetEntityReply, error)
|
||||
CreateEntity(context.Context, *CreateEntityRequest) (*CreateEntityReply, error)
|
||||
SetFact(context.Context, *SetFactRequest) (*SetFactReply, error)
|
||||
GetFact(context.Context, *GetFactRequest) (*GetFactReply, error)
|
||||
}
|
||||
|
||||
// UnimplementedInventoryServer can be embedded to have forward compatible implementations.
|
||||
type UnimplementedInventoryServer struct {
|
||||
}
|
||||
|
||||
func (*UnimplementedInventoryServer) ListEntities(ctx context.Context, req *ListEntitiesRequest) (*ListEntitiesReply, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method ListEntities not implemented")
|
||||
}
|
||||
func (*UnimplementedInventoryServer) GetEntity(ctx context.Context, req *GetEntityRequest) (*GetEntityReply, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetEntity not implemented")
|
||||
}
|
||||
func (*UnimplementedInventoryServer) CreateEntity(ctx context.Context, req *CreateEntityRequest) (*CreateEntityReply, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method CreateEntity not implemented")
|
||||
}
|
||||
func (*UnimplementedInventoryServer) SetFact(ctx context.Context, req *SetFactRequest) (*SetFactReply, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method SetFact not implemented")
|
||||
}
|
||||
func (*UnimplementedInventoryServer) GetFact(ctx context.Context, req *GetFactRequest) (*GetFactReply, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetFact not implemented")
|
||||
}
|
||||
|
||||
func RegisterInventoryServer(s *grpc.Server, srv InventoryServer) {
|
||||
s.RegisterService(&_Inventory_serviceDesc, srv)
|
||||
}
|
||||
|
||||
func _Inventory_ListEntities_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(ListEntitiesRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(InventoryServer).ListEntities(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/spotify.backstage.inventory.v1.Inventory/ListEntities",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(InventoryServer).ListEntities(ctx, req.(*ListEntitiesRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Inventory_GetEntity_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetEntityRequest)
|
||||
if err := dec(in); err != nil {
|
||||
@@ -522,10 +749,50 @@ func _Inventory_CreateEntity_Handler(srv interface{}, ctx context.Context, dec f
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Inventory_SetFact_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(SetFactRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(InventoryServer).SetFact(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/spotify.backstage.inventory.v1.Inventory/SetFact",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(InventoryServer).SetFact(ctx, req.(*SetFactRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Inventory_GetFact_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(GetFactRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(InventoryServer).GetFact(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/spotify.backstage.inventory.v1.Inventory/GetFact",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(InventoryServer).GetFact(ctx, req.(*GetFactRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
var _Inventory_serviceDesc = grpc.ServiceDesc{
|
||||
ServiceName: "spotify.backstage.inventory.v1.Inventory",
|
||||
HandlerType: (*InventoryServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "ListEntities",
|
||||
Handler: _Inventory_ListEntities_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetEntity",
|
||||
Handler: _Inventory_GetEntity_Handler,
|
||||
@@ -534,6 +801,14 @@ var _Inventory_serviceDesc = grpc.ServiceDesc{
|
||||
MethodName: "CreateEntity",
|
||||
Handler: _Inventory_CreateEntity_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "SetFact",
|
||||
Handler: _Inventory_SetFact_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "GetFact",
|
||||
Handler: _Inventory_GetFact_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
Metadata: "inventory/v1/inventory.proto",
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
context "context"
|
||||
fmt "fmt"
|
||||
proto "github.com/golang/protobuf/proto"
|
||||
_struct "github.com/golang/protobuf/ptypes/struct"
|
||||
v1 "github.com/spotify/backstage/backend/proto/identity/v1"
|
||||
grpc "google.golang.org/grpc"
|
||||
codes "google.golang.org/grpc/codes"
|
||||
@@ -56,45 +57,158 @@ func (m *Empty) XXX_DiscardUnknown() {
|
||||
|
||||
var xxx_messageInfo_Empty proto.InternalMessageInfo
|
||||
|
||||
type GetAllTemplatesReply struct {
|
||||
type ListTemplatesReply struct {
|
||||
Templates []*Template `protobuf:"bytes,1,rep,name=templates,proto3" json:"templates,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *GetAllTemplatesReply) Reset() { *m = GetAllTemplatesReply{} }
|
||||
func (m *GetAllTemplatesReply) String() string { return proto.CompactTextString(m) }
|
||||
func (*GetAllTemplatesReply) ProtoMessage() {}
|
||||
func (*GetAllTemplatesReply) Descriptor() ([]byte, []int) {
|
||||
func (m *ListTemplatesReply) Reset() { *m = ListTemplatesReply{} }
|
||||
func (m *ListTemplatesReply) String() string { return proto.CompactTextString(m) }
|
||||
func (*ListTemplatesReply) ProtoMessage() {}
|
||||
func (*ListTemplatesReply) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_6737326b433dc57d, []int{1}
|
||||
}
|
||||
|
||||
func (m *GetAllTemplatesReply) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_GetAllTemplatesReply.Unmarshal(m, b)
|
||||
func (m *ListTemplatesReply) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_ListTemplatesReply.Unmarshal(m, b)
|
||||
}
|
||||
func (m *GetAllTemplatesReply) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_GetAllTemplatesReply.Marshal(b, m, deterministic)
|
||||
func (m *ListTemplatesReply) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_ListTemplatesReply.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *GetAllTemplatesReply) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_GetAllTemplatesReply.Merge(m, src)
|
||||
func (m *ListTemplatesReply) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_ListTemplatesReply.Merge(m, src)
|
||||
}
|
||||
func (m *GetAllTemplatesReply) XXX_Size() int {
|
||||
return xxx_messageInfo_GetAllTemplatesReply.Size(m)
|
||||
func (m *ListTemplatesReply) XXX_Size() int {
|
||||
return xxx_messageInfo_ListTemplatesReply.Size(m)
|
||||
}
|
||||
func (m *GetAllTemplatesReply) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_GetAllTemplatesReply.DiscardUnknown(m)
|
||||
func (m *ListTemplatesReply) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_ListTemplatesReply.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_GetAllTemplatesReply proto.InternalMessageInfo
|
||||
var xxx_messageInfo_ListTemplatesReply proto.InternalMessageInfo
|
||||
|
||||
func (m *GetAllTemplatesReply) GetTemplates() []*Template {
|
||||
func (m *ListTemplatesReply) GetTemplates() []*Template {
|
||||
if m != nil {
|
||||
return m.Templates
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type CreateReply struct {
|
||||
ComponentId string `protobuf:"bytes,1,opt,name=component_id,json=componentId,proto3" json:"component_id,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *CreateReply) Reset() { *m = CreateReply{} }
|
||||
func (m *CreateReply) String() string { return proto.CompactTextString(m) }
|
||||
func (*CreateReply) ProtoMessage() {}
|
||||
func (*CreateReply) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_6737326b433dc57d, []int{2}
|
||||
}
|
||||
|
||||
func (m *CreateReply) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_CreateReply.Unmarshal(m, b)
|
||||
}
|
||||
func (m *CreateReply) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_CreateReply.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *CreateReply) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_CreateReply.Merge(m, src)
|
||||
}
|
||||
func (m *CreateReply) XXX_Size() int {
|
||||
return xxx_messageInfo_CreateReply.Size(m)
|
||||
}
|
||||
func (m *CreateReply) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_CreateReply.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_CreateReply proto.InternalMessageInfo
|
||||
|
||||
func (m *CreateReply) GetComponentId() string {
|
||||
if m != nil {
|
||||
return m.ComponentId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
type CreateRequest struct {
|
||||
TemplateId string `protobuf:"bytes,1,opt,name=template_id,json=templateId,proto3" json:"template_id,omitempty"`
|
||||
Org string `protobuf:"bytes,2,opt,name=org,proto3" json:"org,omitempty"`
|
||||
ComponentId string `protobuf:"bytes,3,opt,name=component_id,json=componentId,proto3" json:"component_id,omitempty"`
|
||||
Private bool `protobuf:"varint,4,opt,name=private,proto3" json:"private,omitempty"`
|
||||
// here's the cookiecutter.json that is used for the request.
|
||||
// make as a struct so that we can pass through the data in a nice way
|
||||
// withouth having to mess around with stuff and special types.
|
||||
Metadata *_struct.Struct `protobuf:"bytes,5,opt,name=metadata,proto3" json:"metadata,omitempty"`
|
||||
XXX_NoUnkeyedLiteral struct{} `json:"-"`
|
||||
XXX_unrecognized []byte `json:"-"`
|
||||
XXX_sizecache int32 `json:"-"`
|
||||
}
|
||||
|
||||
func (m *CreateRequest) Reset() { *m = CreateRequest{} }
|
||||
func (m *CreateRequest) String() string { return proto.CompactTextString(m) }
|
||||
func (*CreateRequest) ProtoMessage() {}
|
||||
func (*CreateRequest) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_6737326b433dc57d, []int{3}
|
||||
}
|
||||
|
||||
func (m *CreateRequest) XXX_Unmarshal(b []byte) error {
|
||||
return xxx_messageInfo_CreateRequest.Unmarshal(m, b)
|
||||
}
|
||||
func (m *CreateRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
|
||||
return xxx_messageInfo_CreateRequest.Marshal(b, m, deterministic)
|
||||
}
|
||||
func (m *CreateRequest) XXX_Merge(src proto.Message) {
|
||||
xxx_messageInfo_CreateRequest.Merge(m, src)
|
||||
}
|
||||
func (m *CreateRequest) XXX_Size() int {
|
||||
return xxx_messageInfo_CreateRequest.Size(m)
|
||||
}
|
||||
func (m *CreateRequest) XXX_DiscardUnknown() {
|
||||
xxx_messageInfo_CreateRequest.DiscardUnknown(m)
|
||||
}
|
||||
|
||||
var xxx_messageInfo_CreateRequest proto.InternalMessageInfo
|
||||
|
||||
func (m *CreateRequest) GetTemplateId() string {
|
||||
if m != nil {
|
||||
return m.TemplateId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *CreateRequest) GetOrg() string {
|
||||
if m != nil {
|
||||
return m.Org
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *CreateRequest) GetComponentId() string {
|
||||
if m != nil {
|
||||
return m.ComponentId
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (m *CreateRequest) GetPrivate() bool {
|
||||
if m != nil {
|
||||
return m.Private
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (m *CreateRequest) GetMetadata() *_struct.Struct {
|
||||
if m != nil {
|
||||
return m.Metadata
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
type Template struct {
|
||||
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
|
||||
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
|
||||
@@ -109,7 +223,7 @@ func (m *Template) Reset() { *m = Template{} }
|
||||
func (m *Template) String() string { return proto.CompactTextString(m) }
|
||||
func (*Template) ProtoMessage() {}
|
||||
func (*Template) Descriptor() ([]byte, []int) {
|
||||
return fileDescriptor_6737326b433dc57d, []int{2}
|
||||
return fileDescriptor_6737326b433dc57d, []int{4}
|
||||
}
|
||||
|
||||
func (m *Template) XXX_Unmarshal(b []byte) error {
|
||||
@@ -160,31 +274,42 @@ func (m *Template) GetUser() *v1.User {
|
||||
|
||||
func init() {
|
||||
proto.RegisterType((*Empty)(nil), "spotify.backstage.scaffolder.v1.Empty")
|
||||
proto.RegisterType((*GetAllTemplatesReply)(nil), "spotify.backstage.scaffolder.v1.GetAllTemplatesReply")
|
||||
proto.RegisterType((*ListTemplatesReply)(nil), "spotify.backstage.scaffolder.v1.ListTemplatesReply")
|
||||
proto.RegisterType((*CreateReply)(nil), "spotify.backstage.scaffolder.v1.CreateReply")
|
||||
proto.RegisterType((*CreateRequest)(nil), "spotify.backstage.scaffolder.v1.CreateRequest")
|
||||
proto.RegisterType((*Template)(nil), "spotify.backstage.scaffolder.v1.Template")
|
||||
}
|
||||
|
||||
func init() { proto.RegisterFile("scaffolder/v1/scaffolder.proto", fileDescriptor_6737326b433dc57d) }
|
||||
|
||||
var fileDescriptor_6737326b433dc57d = []byte{
|
||||
// 270 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x84, 0x91, 0x4f, 0x4b, 0xc4, 0x30,
|
||||
0x10, 0xc5, 0xe9, 0x6e, 0xfd, 0xb3, 0x53, 0x59, 0x21, 0x78, 0x28, 0x3d, 0x68, 0xa9, 0x20, 0xf5,
|
||||
0x92, 0xa5, 0x15, 0xf1, 0xac, 0x20, 0x7b, 0xaf, 0x7a, 0xf1, 0x22, 0xdd, 0x76, 0x2a, 0xc1, 0xb6,
|
||||
0x09, 0xc9, 0x58, 0xe8, 0xc5, 0xbb, 0xdf, 0x5a, 0x8c, 0x74, 0xbb, 0xc8, 0x42, 0x6f, 0x93, 0x97,
|
||||
0xf7, 0x4b, 0xe6, 0xcd, 0xc0, 0xb9, 0x29, 0xf2, 0xaa, 0x92, 0x75, 0x89, 0x7a, 0xd5, 0x25, 0xab,
|
||||
0xf1, 0xc4, 0x95, 0x96, 0x24, 0xd9, 0x85, 0x51, 0x92, 0x44, 0xd5, 0xf3, 0x4d, 0x5e, 0x7c, 0x18,
|
||||
0xca, 0xdf, 0x91, 0xef, 0x78, 0xba, 0x24, 0x08, 0x44, 0x89, 0x2d, 0x09, 0xea, 0x7f, 0xf1, 0xa1,
|
||||
0xfe, 0x83, 0xa3, 0x23, 0x38, 0x78, 0x6c, 0x14, 0xf5, 0xd1, 0x1b, 0x9c, 0xad, 0x91, 0xee, 0xeb,
|
||||
0xfa, 0x19, 0x1b, 0x55, 0xe7, 0x84, 0x26, 0x43, 0x55, 0xf7, 0x6c, 0x0d, 0x0b, 0x1a, 0x14, 0xdf,
|
||||
0x09, 0xe7, 0xb1, 0x97, 0x5e, 0xf3, 0x89, 0x1f, 0xf9, 0xf0, 0x46, 0x36, 0xb2, 0xd1, 0xb7, 0x03,
|
||||
0xc7, 0x83, 0xce, 0x96, 0x30, 0x13, 0xa5, 0xef, 0x84, 0x4e, 0xbc, 0xc8, 0x66, 0xa2, 0x64, 0x0c,
|
||||
0xdc, 0x36, 0x6f, 0xd0, 0x9f, 0x59, 0xc5, 0xd6, 0x2c, 0x04, 0xaf, 0x44, 0x53, 0x68, 0xa1, 0x48,
|
||||
0xc8, 0xd6, 0x9f, 0xdb, 0xab, 0x5d, 0x89, 0xdd, 0x81, 0xfb, 0x69, 0x50, 0xfb, 0x6e, 0xe8, 0xc4,
|
||||
0x5e, 0x7a, 0xb9, 0xa7, 0xad, 0x6d, 0xda, 0x2e, 0xe1, 0x2f, 0x06, 0x75, 0x66, 0x81, 0xf4, 0x0b,
|
||||
0xe0, 0x69, 0xdb, 0x30, 0x53, 0x70, 0xfa, 0x2f, 0x3a, 0xbb, 0x9a, 0x8c, 0x68, 0xa7, 0x16, 0xdc,
|
||||
0x4e, 0xfa, 0xf6, 0x0d, 0xf5, 0x61, 0xf9, 0x7a, 0x32, 0xba, 0xba, 0x64, 0x73, 0x68, 0x97, 0x71,
|
||||
0xf3, 0x13, 0x00, 0x00, 0xff, 0xff, 0x5b, 0x4d, 0x79, 0x5e, 0xeb, 0x01, 0x00, 0x00,
|
||||
// 411 bytes of a gzipped FileDescriptorProto
|
||||
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x8c, 0x52, 0xd1, 0x8a, 0xd3, 0x40,
|
||||
0x14, 0x25, 0x6d, 0x77, 0xb7, 0x7b, 0xb3, 0xbb, 0xc8, 0xbc, 0x18, 0x82, 0xb8, 0x31, 0x82, 0x54,
|
||||
0x90, 0xa9, 0x6d, 0x1f, 0x7c, 0x57, 0x44, 0x16, 0x7c, 0xca, 0xea, 0x8b, 0x20, 0x32, 0x4d, 0x6e,
|
||||
0xca, 0x60, 0x92, 0x19, 0x67, 0x6e, 0x03, 0xf9, 0x04, 0xff, 0xc7, 0x2f, 0xf2, 0x4b, 0xa4, 0x53,
|
||||
0x27, 0xdd, 0x65, 0x0b, 0xd9, 0xb7, 0x7b, 0xcf, 0xbd, 0xe7, 0xce, 0xe1, 0x9c, 0x81, 0xe7, 0x36,
|
||||
0x17, 0x65, 0xa9, 0xaa, 0x02, 0xcd, 0xbc, 0x5d, 0xcc, 0x0f, 0x1d, 0xd7, 0x46, 0x91, 0x62, 0xd7,
|
||||
0x56, 0x2b, 0x92, 0x65, 0xc7, 0xd7, 0x22, 0xff, 0x69, 0x49, 0x6c, 0x90, 0xdf, 0xd9, 0x69, 0x17,
|
||||
0x71, 0x2c, 0x0b, 0x6c, 0x48, 0x52, 0xb7, 0xa3, 0xfb, 0x7a, 0x4f, 0x8e, 0x9f, 0x6d, 0x94, 0xda,
|
||||
0x54, 0x38, 0x77, 0xdd, 0x7a, 0x5b, 0xce, 0x2d, 0x99, 0x6d, 0x4e, 0xfb, 0x69, 0x7a, 0x06, 0x27,
|
||||
0x1f, 0x6b, 0x4d, 0x5d, 0xfa, 0x1d, 0xd8, 0x67, 0x69, 0xe9, 0x0b, 0xd6, 0xba, 0x12, 0x84, 0x36,
|
||||
0x43, 0x5d, 0x75, 0xec, 0x13, 0x9c, 0x93, 0x47, 0xa2, 0x20, 0x19, 0xcf, 0xc2, 0xe5, 0x6b, 0x3e,
|
||||
0xa0, 0x86, 0xfb, 0x1b, 0xd9, 0x81, 0x9b, 0xbe, 0x85, 0xf0, 0x83, 0xc1, 0x1d, 0xe8, 0xee, 0xbe,
|
||||
0x80, 0x8b, 0x5c, 0xd5, 0x5a, 0x35, 0xd8, 0xd0, 0x0f, 0x59, 0x44, 0x41, 0x12, 0xcc, 0xce, 0xb3,
|
||||
0xb0, 0xc7, 0x6e, 0x8a, 0xf4, 0x4f, 0x00, 0x97, 0x9e, 0xf2, 0x6b, 0x8b, 0x96, 0xd8, 0x35, 0x84,
|
||||
0xfe, 0xe0, 0x81, 0x03, 0x1e, 0xba, 0x29, 0xd8, 0x13, 0x18, 0x2b, 0xb3, 0x89, 0x46, 0x6e, 0xb0,
|
||||
0x2b, 0x1f, 0xbc, 0x33, 0x7e, 0xf0, 0x0e, 0x8b, 0xe0, 0x4c, 0x1b, 0xd9, 0x0a, 0xc2, 0x68, 0x92,
|
||||
0x04, 0xb3, 0x69, 0xe6, 0x5b, 0xb6, 0x82, 0x69, 0x8d, 0x24, 0x0a, 0x41, 0x22, 0x3a, 0x49, 0x82,
|
||||
0x59, 0xb8, 0x7c, 0xca, 0xf7, 0x66, 0x72, 0x6f, 0x26, 0xbf, 0x75, 0x66, 0x66, 0xfd, 0x62, 0xfa,
|
||||
0x3b, 0x80, 0xa9, 0x37, 0x80, 0x5d, 0xc1, 0xa8, 0x17, 0x3a, 0x92, 0x05, 0x63, 0x30, 0x69, 0x44,
|
||||
0x8d, 0xff, 0x15, 0xba, 0x9a, 0x25, 0x10, 0x16, 0x68, 0x73, 0x23, 0x35, 0x49, 0xd5, 0x78, 0x85,
|
||||
0x77, 0x20, 0xf6, 0x0e, 0x26, 0x5b, 0x8b, 0xc6, 0xc9, 0x0b, 0x97, 0x2f, 0x8f, 0xf8, 0xdf, 0x47,
|
||||
0xde, 0x2e, 0xf8, 0x57, 0x8b, 0x26, 0x73, 0x84, 0xe5, 0xdf, 0x00, 0xe0, 0xb6, 0x8f, 0x86, 0x55,
|
||||
0x70, 0x79, 0x2f, 0x62, 0xf6, 0x6a, 0x30, 0x4a, 0xf7, 0x37, 0xe2, 0xd5, 0xe0, 0xde, 0x91, 0xaf,
|
||||
0x53, 0xc2, 0xe9, 0x3e, 0x3e, 0xc6, 0x07, 0xe9, 0xf7, 0x72, 0x8e, 0xdf, 0x3c, 0x7a, 0x5f, 0x57,
|
||||
0xdd, 0xfb, 0xab, 0x6f, 0x17, 0x87, 0x61, 0xbb, 0x58, 0x9f, 0xba, 0x6c, 0x56, 0xff, 0x02, 0x00,
|
||||
0x00, 0xff, 0xff, 0xfc, 0x1f, 0xfc, 0xf0, 0x55, 0x03, 0x00, 0x00,
|
||||
}
|
||||
|
||||
// Reference imports to suppress errors if they are not otherwise used.
|
||||
@@ -199,7 +324,8 @@ const _ = grpc.SupportPackageIsVersion6
|
||||
//
|
||||
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
|
||||
type ScaffolderClient interface {
|
||||
GetAllTemplates(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*GetAllTemplatesReply, error)
|
||||
ListTemplates(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*ListTemplatesReply, error)
|
||||
Create(ctx context.Context, in *CreateRequest, opts ...grpc.CallOption) (*CreateReply, error)
|
||||
}
|
||||
|
||||
type scaffolderClient struct {
|
||||
@@ -210,9 +336,18 @@ func NewScaffolderClient(cc grpc.ClientConnInterface) ScaffolderClient {
|
||||
return &scaffolderClient{cc}
|
||||
}
|
||||
|
||||
func (c *scaffolderClient) GetAllTemplates(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*GetAllTemplatesReply, error) {
|
||||
out := new(GetAllTemplatesReply)
|
||||
err := c.cc.Invoke(ctx, "/spotify.backstage.scaffolder.v1.Scaffolder/GetAllTemplates", in, out, opts...)
|
||||
func (c *scaffolderClient) ListTemplates(ctx context.Context, in *Empty, opts ...grpc.CallOption) (*ListTemplatesReply, error) {
|
||||
out := new(ListTemplatesReply)
|
||||
err := c.cc.Invoke(ctx, "/spotify.backstage.scaffolder.v1.Scaffolder/ListTemplates", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *scaffolderClient) Create(ctx context.Context, in *CreateRequest, opts ...grpc.CallOption) (*CreateReply, error) {
|
||||
out := new(CreateReply)
|
||||
err := c.cc.Invoke(ctx, "/spotify.backstage.scaffolder.v1.Scaffolder/Create", in, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -221,35 +356,57 @@ func (c *scaffolderClient) GetAllTemplates(ctx context.Context, in *Empty, opts
|
||||
|
||||
// ScaffolderServer is the server API for Scaffolder service.
|
||||
type ScaffolderServer interface {
|
||||
GetAllTemplates(context.Context, *Empty) (*GetAllTemplatesReply, error)
|
||||
ListTemplates(context.Context, *Empty) (*ListTemplatesReply, error)
|
||||
Create(context.Context, *CreateRequest) (*CreateReply, error)
|
||||
}
|
||||
|
||||
// UnimplementedScaffolderServer can be embedded to have forward compatible implementations.
|
||||
type UnimplementedScaffolderServer struct {
|
||||
}
|
||||
|
||||
func (*UnimplementedScaffolderServer) GetAllTemplates(ctx context.Context, req *Empty) (*GetAllTemplatesReply, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method GetAllTemplates not implemented")
|
||||
func (*UnimplementedScaffolderServer) ListTemplates(ctx context.Context, req *Empty) (*ListTemplatesReply, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method ListTemplates not implemented")
|
||||
}
|
||||
func (*UnimplementedScaffolderServer) Create(ctx context.Context, req *CreateRequest) (*CreateReply, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method Create not implemented")
|
||||
}
|
||||
|
||||
func RegisterScaffolderServer(s *grpc.Server, srv ScaffolderServer) {
|
||||
s.RegisterService(&_Scaffolder_serviceDesc, srv)
|
||||
}
|
||||
|
||||
func _Scaffolder_GetAllTemplates_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
func _Scaffolder_ListTemplates_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(Empty)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ScaffolderServer).GetAllTemplates(ctx, in)
|
||||
return srv.(ScaffolderServer).ListTemplates(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/spotify.backstage.scaffolder.v1.Scaffolder/GetAllTemplates",
|
||||
FullMethod: "/spotify.backstage.scaffolder.v1.Scaffolder/ListTemplates",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ScaffolderServer).GetAllTemplates(ctx, req.(*Empty))
|
||||
return srv.(ScaffolderServer).ListTemplates(ctx, req.(*Empty))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
|
||||
func _Scaffolder_Create_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
|
||||
in := new(CreateRequest)
|
||||
if err := dec(in); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if interceptor == nil {
|
||||
return srv.(ScaffolderServer).Create(ctx, in)
|
||||
}
|
||||
info := &grpc.UnaryServerInfo{
|
||||
Server: srv,
|
||||
FullMethod: "/spotify.backstage.scaffolder.v1.Scaffolder/Create",
|
||||
}
|
||||
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
|
||||
return srv.(ScaffolderServer).Create(ctx, req.(*CreateRequest))
|
||||
}
|
||||
return interceptor(ctx, in, info, handler)
|
||||
}
|
||||
@@ -259,8 +416,12 @@ var _Scaffolder_serviceDesc = grpc.ServiceDesc{
|
||||
HandlerType: (*ScaffolderServer)(nil),
|
||||
Methods: []grpc.MethodDesc{
|
||||
{
|
||||
MethodName: "GetAllTemplates",
|
||||
Handler: _Scaffolder_GetAllTemplates_Handler,
|
||||
MethodName: "ListTemplates",
|
||||
Handler: _Scaffolder_ListTemplates_Handler,
|
||||
},
|
||||
{
|
||||
MethodName: "Create",
|
||||
Handler: _Scaffolder_Create_Handler,
|
||||
},
|
||||
},
|
||||
Streams: []grpc.StreamDesc{},
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
FROM envoyproxy/envoy:latest
|
||||
FROM envoyproxy/envoy:v1.13.0
|
||||
|
||||
COPY ./envoy.yaml /etc/envoy/envoy.yaml
|
||||
|
||||
|
||||
@@ -28,6 +28,10 @@ static_resources:
|
||||
route:
|
||||
cluster: identity_service
|
||||
max_grpc_timeout: 0s
|
||||
- match: { prefix: '/spotify.backstage.builds.v1.Builds/' }
|
||||
route:
|
||||
cluster: builds_service
|
||||
max_grpc_timeout: 0s
|
||||
- match: { prefix: '/inventory' }
|
||||
route:
|
||||
cluster: inventory_service
|
||||
@@ -58,6 +62,15 @@ static_resources:
|
||||
- socket_address:
|
||||
address: identity
|
||||
port_value: 50051
|
||||
- name: builds_service
|
||||
connect_timeout: 0.25s
|
||||
type: logical_dns
|
||||
http2_protocol_options: {}
|
||||
lb_policy: round_robin
|
||||
hosts:
|
||||
- socket_address:
|
||||
address: builds
|
||||
port_value: 50051
|
||||
- name: inventory_service
|
||||
connect_timeout: 0.25s
|
||||
type: logical_dns
|
||||
|
||||
@@ -2,20 +2,56 @@ package app
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
identity "github.com/spotify/backstage/backend/proto/identity/v1"
|
||||
pb "github.com/spotify/backstage/proto/scaffolder/v1"
|
||||
pb "github.com/spotify/backstage/backend/proto/scaffolder/v1"
|
||||
"github.com/spotify/backstage/scaffolder/fs"
|
||||
"github.com/spotify/backstage/scaffolder/remote"
|
||||
"github.com/spotify/backstage/scaffolder/repository"
|
||||
)
|
||||
|
||||
// Server is the inventory Grpc server
|
||||
type Server struct {
|
||||
Repository *repository.Repository
|
||||
repository *repository.Repository
|
||||
github *remote.Github
|
||||
fs *fs.Filesystem
|
||||
}
|
||||
|
||||
// GetAllTemplates returns the local templatess
|
||||
func (s *Server) GetAllTemplates(ctx context.Context, req *pb.Empty) (*pb.GetAllTemplatesReply, error) {
|
||||
// NewServer creates a new server for with all the things
|
||||
func NewServer() *Server {
|
||||
return &Server{
|
||||
github: remote.NewGithubClient(),
|
||||
}
|
||||
}
|
||||
|
||||
// Create scaffolds the repo in github and then will create push to the repository
|
||||
func (s *Server) Create(ctx context.Context, req *pb.CreateRequest) (*pb.CreateReply, error) {
|
||||
// first create the repository with github
|
||||
fmt.Sprintf("Creating repository for Component %s", req.ComponentId)
|
||||
repo := remote.Repository{
|
||||
Name: req.ComponentId,
|
||||
Org: req.Org,
|
||||
Private: req.Private,
|
||||
}
|
||||
if _, err := s.github.CreateRepository(repo); err != nil {
|
||||
return nil, status.Error(codes.Internal, fmt.Sprintf("Could not create repository %s/%s", req.Org, req.ComponentId))
|
||||
}
|
||||
|
||||
// move the template into a temporary directory
|
||||
tempFolder, _ := s.fs.PrepareTemplate(fs.Template{req.TemplateId})
|
||||
|
||||
fmt.Sprintf("Created temporary folder %s", tempFolder)
|
||||
// use git bindings to add the remote with access token and push to the directory
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// ListTemplates returns the local templatess
|
||||
func (s *Server) ListTemplates(ctx context.Context, req *pb.Empty) (*pb.ListTemplatesReply, error) {
|
||||
// todo (blam): yes we currently read the disk on every load. but it's fine for now 🤷♂️
|
||||
definitions, err := s.Repository.Load()
|
||||
definitions, err := s.repository.Load()
|
||||
var templates []*pb.Template
|
||||
|
||||
for _, definition := range definitions {
|
||||
@@ -34,7 +70,7 @@ func (s *Server) GetAllTemplates(ctx context.Context, req *pb.Empty) (*pb.GetAll
|
||||
templates = append(templates, template)
|
||||
}
|
||||
|
||||
return &pb.GetAllTemplatesReply{
|
||||
return &pb.ListTemplatesReply{
|
||||
Templates: templates,
|
||||
}, err
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
package app
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSample(t *testing.T) {
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package fs
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path"
|
||||
)
|
||||
|
||||
// Filesystem Repository
|
||||
type Filesystem struct{}
|
||||
|
||||
func file(src, dst string) error {
|
||||
var err error
|
||||
var srcfd *os.File
|
||||
var dstfd *os.File
|
||||
var srcinfo os.FileInfo
|
||||
|
||||
if srcfd, err = os.Open(src); err != nil {
|
||||
return err
|
||||
}
|
||||
defer srcfd.Close()
|
||||
|
||||
if dstfd, err = os.Create(dst); err != nil {
|
||||
return err
|
||||
}
|
||||
defer dstfd.Close()
|
||||
|
||||
if _, err = io.Copy(dstfd, srcfd); err != nil {
|
||||
return err
|
||||
}
|
||||
if srcinfo, err = os.Stat(src); err != nil {
|
||||
return err
|
||||
}
|
||||
return os.Chmod(dst, srcinfo.Mode())
|
||||
}
|
||||
|
||||
func dir(src string, dst string) error {
|
||||
var err error
|
||||
var fds []os.FileInfo
|
||||
var srcinfo os.FileInfo
|
||||
|
||||
if srcinfo, err = os.Stat(src); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = os.MkdirAll(dst, srcinfo.Mode()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if fds, err = ioutil.ReadDir(src); err != nil {
|
||||
return err
|
||||
}
|
||||
for _, fd := range fds {
|
||||
srcfp := path.Join(src, fd.Name())
|
||||
dstfp := path.Join(dst, fd.Name())
|
||||
|
||||
if fd.IsDir() {
|
||||
if err = dir(srcfp, dstfp); err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
} else {
|
||||
if err = file(srcfp, dstfp); err != nil {
|
||||
fmt.Println(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Template holds the template ID for copying
|
||||
type Template struct {
|
||||
ID string
|
||||
}
|
||||
|
||||
// PrepareTemplate will copy the local template to temp folder
|
||||
// and return the temp location
|
||||
func (f *Filesystem) PrepareTemplate(template Template) (string, error) {
|
||||
tempDirectory, _ := ioutil.TempDir(os.TempDir(), template.ID)
|
||||
fmt.Println(tempDirectory)
|
||||
if err := dir("./templates/"+template.ID, tempDirectory); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return tempDirectory, nil
|
||||
}
|
||||
@@ -2,13 +2,16 @@ module github.com/spotify/backstage/scaffolder
|
||||
|
||||
go 1.13
|
||||
|
||||
replace github.com/spotify/backstage/proto => ../proto
|
||||
|
||||
replace github.com/spotify/backstage/backend/proto => ../proto
|
||||
replace (
|
||||
github.com/spotify/backstage/backend/proto => ./../proto
|
||||
github.com/spotify/backstage/proto => ../proto
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/golang/protobuf v1.3.3
|
||||
github.com/google/go-github/v29 v29.0.2
|
||||
github.com/spotify/backstage/backend/proto v0.0.0-00010101000000-000000000000
|
||||
github.com/spotify/backstage/proto v0.0.0-00010101000000-000000000000
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be
|
||||
google.golang.org/grpc v1.27.0
|
||||
)
|
||||
|
||||
@@ -14,7 +14,13 @@ github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY=
|
||||
github.com/google/go-github/v29 v29.0.2 h1:opYN6Wc7DOz7Ku3Oh4l7prmkOMwEcQxpFtxdU8N8Pts=
|
||||
github.com/google/go-github/v29 v29.0.2/go.mod h1:CHKiKKPHJ0REzfwc14QMklvtHwCveD0PxlMjLlzAM5E=
|
||||
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
@@ -25,6 +31,7 @@ golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73r
|
||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
||||
@@ -4,9 +4,8 @@ import (
|
||||
"log"
|
||||
"net"
|
||||
|
||||
pb "github.com/spotify/backstage/proto/scaffolder/v1"
|
||||
pb "github.com/spotify/backstage/backend/proto/scaffolder/v1"
|
||||
"github.com/spotify/backstage/scaffolder/app"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
@@ -21,7 +20,9 @@ func main() {
|
||||
}
|
||||
|
||||
grpcServer := grpc.NewServer()
|
||||
pb.RegisterScaffolderServer(grpcServer, &app.Server{})
|
||||
serverHandler := app.NewServer()
|
||||
|
||||
pb.RegisterScaffolderServer(grpcServer, serverHandler)
|
||||
log.Println("Serving Scaffolder Service")
|
||||
grpcServer.Serve(lis)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
package remote
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
gh "github.com/google/go-github/v29/github"
|
||||
"golang.org/x/oauth2"
|
||||
"os"
|
||||
)
|
||||
|
||||
// Github is the exported struct
|
||||
type Github struct {
|
||||
client *gh.Client
|
||||
ctx *context.Context
|
||||
}
|
||||
|
||||
// NewGithubClient returns a new client with the correct access token enabled
|
||||
func NewGithubClient() *Github {
|
||||
accessToken := os.Getenv("BOSS_GH_ACCESS_TOKEN")
|
||||
|
||||
if accessToken == "" {
|
||||
fmt.Println("No BOSS_GH_ACCESS_TOKEN set. Cannot continue")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
ts := oauth2.StaticTokenSource(
|
||||
&oauth2.Token{AccessToken: accessToken},
|
||||
)
|
||||
tc := oauth2.NewClient(ctx, ts)
|
||||
client := gh.NewClient(tc)
|
||||
|
||||
return &Github{
|
||||
client: client,
|
||||
ctx: &ctx,
|
||||
}
|
||||
}
|
||||
|
||||
// Repository holds the information of the created repo
|
||||
type Repository struct {
|
||||
Org string
|
||||
Name string
|
||||
Private bool
|
||||
}
|
||||
|
||||
// CreateRepository will create the repository in Github ready for use by the scaffolder
|
||||
func (g *Github) CreateRepository(repo Repository) (*gh.Repository, error) {
|
||||
ghRepo := &gh.Repository{
|
||||
Name: &repo.Name,
|
||||
Private: &repo.Private,
|
||||
}
|
||||
|
||||
var org string
|
||||
|
||||
if repo.Org != "" {
|
||||
org = repo.Org
|
||||
}
|
||||
|
||||
created, _, err := g.client.Repositories.Create(*g.ctx, org, ghRepo)
|
||||
|
||||
return created, err
|
||||
}
|
||||
@@ -20,9 +20,10 @@ type TemplateDefinition struct {
|
||||
|
||||
// Load will return all the Repository templates
|
||||
func (s *Repository) Load() ([]*TemplateDefinition, error) {
|
||||
templateInfoFilePaths, err := filepath.Glob("templates/**/template-info.json")
|
||||
var templateDefinitions []*TemplateDefinition
|
||||
|
||||
templateInfoFilePaths, err := filepath.Glob("templates/**/template-info.json")
|
||||
|
||||
if err != nil {
|
||||
fmt.Errorf("failed to load template-info files")
|
||||
return nil, err
|
||||
@@ -45,5 +46,5 @@ func (s *Repository) Load() ([]*TemplateDefinition, error) {
|
||||
templateDefinitions = append(templateDefinitions, &definition)
|
||||
}
|
||||
|
||||
return templateDefinitions, err
|
||||
return templateDefinitions, nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"app_id": "com.example.app",
|
||||
"app_name": "SampleApp",
|
||||
"owner": "",
|
||||
"description": "We promise to update this description /{{cookiecutter.owner}}"
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"schema": [
|
||||
{
|
||||
"id": "app_name",
|
||||
"title": "App name",
|
||||
"type": "text",
|
||||
"description": "App name used to generate Android Studio files and class names. CamelCase e.g. 'MyAndroidApp'",
|
||||
"validators": [
|
||||
{
|
||||
"type": "required"
|
||||
},
|
||||
{
|
||||
"type": "regex",
|
||||
"match": "^[A-Z][A-Za-z]+$",
|
||||
"message": "Project name must be CamelCase"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "app_id",
|
||||
"title": "App ID",
|
||||
"type": "text",
|
||||
"description": "App id used as package for the new app. FQDN e.g. 'com.example.app'",
|
||||
"validators": [
|
||||
{
|
||||
"type": "required"
|
||||
},
|
||||
{
|
||||
"type": "regex",
|
||||
"match": "^[a-z][a-z.]+$",
|
||||
"message": "App ID must be a fully qualified domain name"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "owner",
|
||||
"title": "owner",
|
||||
"type": "text",
|
||||
"description": "The owner name used to identify the owner of this component",
|
||||
"validators": [
|
||||
{
|
||||
"type": "required"
|
||||
},
|
||||
{
|
||||
"type": "string-range",
|
||||
"min": 4,
|
||||
"max": 33
|
||||
},
|
||||
{
|
||||
"type": "regex",
|
||||
"match": "^[a-z][a-z0-9]+$",
|
||||
"message": "Owner names must consist only of lowercase letters"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea/caches
|
||||
/.idea/libraries
|
||||
/.idea/modules.xml
|
||||
/.idea/workspace.xml
|
||||
/.idea/navEditor.xml
|
||||
/.idea/assetWizardSettings.xml
|
||||
.DS_Store
|
||||
/build
|
||||
/captures
|
||||
.externalNativeBuild
|
||||
.cxx
|
||||
@@ -0,0 +1 @@
|
||||
/build
|
||||
@@ -0,0 +1,37 @@
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
apply plugin: 'kotlin-android-extensions'
|
||||
|
||||
android {
|
||||
compileSdkVersion 29
|
||||
buildToolsVersion "29.0.2"
|
||||
|
||||
defaultConfig {
|
||||
applicationId "{{cookiecutter.app_id}}"
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 29
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
implementation 'androidx.appcompat:appcompat:1.1.0'
|
||||
implementation 'androidx.core:core-ktx:1.1.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
||||
testImplementation 'junit:junit:4.12'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
@@ -0,0 +1,24 @@
|
||||
package {{cookiecutter.app_id}}
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* See [testing documentation](http://d.android.com/tools/testing).
|
||||
*/
|
||||
@RunWith(AndroidJUnit4::class)
|
||||
class ExampleInstrumentedTest {
|
||||
@Test
|
||||
fun useAppContext() {
|
||||
// Context of the app under test.
|
||||
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
|
||||
assertEquals("com.example.mytemplate", appContext.packageName)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="{{cookiecutter.app_id}}">
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme">
|
||||
<activity android:name=".MainActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -0,0 +1,12 @@
|
||||
package {{cookiecutter.app_id}}
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import android.os.Bundle
|
||||
|
||||
class MainActivity : AppCompatActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
setContentView(R.layout.activity_main)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:endX="85.84757"
|
||||
android:endY="92.4963"
|
||||
android:startX="42.9492"
|
||||
android:startY="49.59793"
|
||||
android:type="linear">
|
||||
<item
|
||||
android:color="#44000000"
|
||||
android:offset="0.0" />
|
||||
<item
|
||||
android:color="#00000000"
|
||||
android:offset="1.0" />
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillType="nonZero"
|
||||
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
|
||||
android:strokeWidth="1"
|
||||
android:strokeColor="#00000000" />
|
||||
</vector>
|
||||
@@ -0,0 +1,170 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path
|
||||
android:fillColor="#3DDC84"
|
||||
android:pathData="M0,0h108v108h-108z" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M9,0L9,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,0L19,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,0L29,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,0L39,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,0L49,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,0L59,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,0L69,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,0L79,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M89,0L89,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M99,0L99,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,9L108,9"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,19L108,19"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,29L108,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,39L108,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,49L108,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,59L108,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,69L108,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,79L108,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,89L108,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,99L108,99"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,29L89,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,39L89,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,49L89,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,59L89,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,69L89,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,79L89,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,19L29,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,19L39,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,19L49,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,19L59,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,19L69,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,19L79,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
</vector>
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".MainActivity">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Hello Backsage!"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 5.2 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 4.8 KiB |
|
After Width: | Height: | Size: 7.3 KiB |
|
After Width: | Height: | Size: 7.7 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 16 KiB |
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="colorPrimary">#6200EE</color>
|
||||
<color name="colorPrimaryDark">#3700B3</color>
|
||||
<color name="colorAccent">#03DAC5</color>
|
||||
</resources>
|
||||
@@ -0,0 +1,3 @@
|
||||
<resources>
|
||||
<string name="app_name">{{cookiecutter.app_name}}</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,11 @@
|
||||
<resources>
|
||||
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
<item name="colorAccent">@color/colorAccent</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
@@ -0,0 +1,17 @@
|
||||
package {{cookiecutter.app_id}}
|
||||
|
||||
import org.junit.Test
|
||||
|
||||
import org.junit.Assert.*
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
*
|
||||
* See [testing documentation](http://d.android.com/tools/testing).
|
||||
*/
|
||||
class ExampleUnitTest {
|
||||
@Test
|
||||
fun addition_isCorrect() {
|
||||
assertEquals(4, 2 + 2)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.3.61'
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.6.0-rc01'
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
google()
|
||||
jcenter()
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
# Project-wide Gradle settings.
|
||||
# IDE (e.g. Android Studio) users:
|
||||
# Gradle settings configured through the IDE *will override*
|
||||
# any settings specified in this file.
|
||||
# For more details on how to configure your build environment visit
|
||||
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||
# Specifies the JVM arguments used for the daemon process.
|
||||
# The setting is particularly useful for tweaking memory settings.
|
||||
org.gradle.jvmargs=-Xmx1536m
|
||||
# When configured, Gradle will run in incubating parallel mode.
|
||||
# This option should only be used with decoupled projects. More details, visit
|
||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||
# org.gradle.parallel=true
|
||||
# AndroidX package structure to make it clearer which packages are bundled with the
|
||||
# Android operating system, and which are packaged with your app's APK
|
||||
# https://developer.android.com/topic/libraries/support-library/androidx-rn
|
||||
android.useAndroidX=true
|
||||
# Automatically convert third-party libraries to use AndroidX
|
||||
android.enableJetifier=true
|
||||
# Kotlin code style for this project: "official" or "obsolete":
|
||||
kotlin.code.style=official
|
||||
@@ -0,0 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
@@ -0,0 +1,183 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
# Copyright 2015 the original author or authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
case $i in
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=`save "$@"`
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
@@ -0,0 +1,100 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
@@ -0,0 +1,2 @@
|
||||
rootProject.name='{{cookiecutter.app_name}}'
|
||||
include ':app'
|
||||
@@ -21,6 +21,15 @@ services:
|
||||
volumes:
|
||||
- ./backend/identity/identity-data.json:/app/identity-data.json
|
||||
|
||||
builds:
|
||||
container_name: boss-builds
|
||||
build:
|
||||
context: backend
|
||||
args:
|
||||
service: builds
|
||||
restart: unless-stopped
|
||||
env_file: secrets.env
|
||||
|
||||
scaffolder:
|
||||
container_name: boss-scaffolder
|
||||
build:
|
||||
@@ -28,3 +37,4 @@ services:
|
||||
args:
|
||||
service: scaffolder
|
||||
restart: unless-stopped
|
||||
env_file: secrets.env
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import {
|
||||
createEntityKind,
|
||||
createWidgetView,
|
||||
createEntityView,
|
||||
createEntityPage,
|
||||
} from '@backstage/core';
|
||||
import ComputerIcon from '@material-ui/icons/Computer';
|
||||
import MockEntityPage from './MockEntityPage';
|
||||
@@ -13,10 +13,10 @@ const serviceOverviewPage = createWidgetView()
|
||||
.addComponent(MockEntityCard)
|
||||
.addComponent(MockEntityCard);
|
||||
|
||||
const serviceView = createEntityView()
|
||||
.addPage('Overview', 'overview', serviceOverviewPage)
|
||||
const serviceView = createEntityPage()
|
||||
.addPage('Overview', '/overview', serviceOverviewPage)
|
||||
.register(GithubActionsPlugin)
|
||||
.addComponent('Deployment', 'deployment', MockEntityPage);
|
||||
.addComponent('Deployment', '/deployment', MockEntityPage);
|
||||
|
||||
const serviceEntity = createEntityKind({
|
||||
kind: 'service',
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import AppBuilder from './app/AppBuilder';
|
||||
import EntityKind, { EntityConfig } from './entity/EntityKind';
|
||||
import WidgetViewBuilder from './widgetView/WidgetViewBuilder';
|
||||
import EntityViewBuilder from './entityView/EntityViewPageBuilder';
|
||||
import EntityPageBuilder from './entityView/EntityPageBuilder';
|
||||
import BackstagePlugin, { PluginConfig } from './plugin/Plugin';
|
||||
|
||||
export function createApp() {
|
||||
@@ -16,8 +16,8 @@ export function createWidgetView() {
|
||||
return new WidgetViewBuilder();
|
||||
}
|
||||
|
||||
export function createEntityView() {
|
||||
return new EntityViewBuilder();
|
||||
export function createEntityPage() {
|
||||
return new EntityPageBuilder();
|
||||
}
|
||||
|
||||
export function createPlugin(config: PluginConfig): BackstagePlugin {
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import React, { ComponentType, FC } from 'react';
|
||||
import { Route, Switch, useParams } from 'react-router-dom';
|
||||
import { Route, Switch, useParams, Redirect } from 'react-router-dom';
|
||||
import { AppContextProvider } from './AppContext';
|
||||
import { App, AppComponentBuilder } from './types';
|
||||
import EntityKind, { EntityConfig } from '../entity/EntityKind';
|
||||
import { EntityContextProvider } from '../entityView/EntityContext';
|
||||
import BackstagePlugin, { registerSymbol } from '../plugin/Plugin';
|
||||
import BackstagePlugin from '../plugin/Plugin';
|
||||
|
||||
class AppImpl implements App {
|
||||
constructor(private readonly entities: Map<string, EntityKind>) {}
|
||||
@@ -97,8 +97,31 @@ export default class AppBuilder {
|
||||
const pluginRoutes = new Array<JSX.Element>();
|
||||
|
||||
for (const plugin of this.plugins.values()) {
|
||||
const { routes = [] } = plugin[registerSymbol]();
|
||||
pluginRoutes.push(...routes);
|
||||
for (const output of plugin.output()) {
|
||||
switch (output.type) {
|
||||
case 'route': {
|
||||
const { path, component, options = {} } = output;
|
||||
const { exact = true } = options;
|
||||
pluginRoutes.push(
|
||||
<Route
|
||||
key={path}
|
||||
path={path}
|
||||
component={component}
|
||||
exact={exact}
|
||||
/>,
|
||||
);
|
||||
break;
|
||||
}
|
||||
case 'redirect-route': {
|
||||
const { path, target, options = {} } = output;
|
||||
const { exact = true } = options;
|
||||
pluginRoutes.push(
|
||||
<Redirect key={path} path={path} to={target} exact={exact} />,
|
||||
);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const routes = [...pluginRoutes, ...entityRoutes];
|
||||
|
||||
@@ -5,8 +5,7 @@ import ListItem from '@material-ui/core/ListItem';
|
||||
import { AppComponentBuilder, App } from '../app/types';
|
||||
import { useEntity, useEntityUri, useEntityConfig } from './EntityContext';
|
||||
import EntityLink from '../../components/EntityLink/EntityLink';
|
||||
import BackstagePlugin, { outputSymbol } from '../plugin/Plugin';
|
||||
import { entityViewPage } from '../plugin/outputs';
|
||||
import BackstagePlugin from '../plugin/Plugin';
|
||||
|
||||
const EntityLayout: FC<{}> = ({ children }) => {
|
||||
const config = useEntityConfig();
|
||||
@@ -34,43 +33,48 @@ const EntitySidebarItem: FC<{ title: string; path: string }> = ({
|
||||
);
|
||||
};
|
||||
|
||||
type EntityViewPage = {
|
||||
type EntityPageNavItem = {
|
||||
title: string;
|
||||
target: string;
|
||||
};
|
||||
|
||||
type EntityPageView = {
|
||||
path: string;
|
||||
component: ComponentType<any>;
|
||||
};
|
||||
|
||||
type Props = {
|
||||
pages: EntityViewPage[];
|
||||
navItems: EntityPageNavItem[];
|
||||
views: EntityPageView[];
|
||||
};
|
||||
|
||||
const EntityViewComponent: FC<Props> = ({ pages }) => {
|
||||
const EntityPageComponent: FC<Props> = ({ navItems, views }) => {
|
||||
const { kind, id } = useEntity();
|
||||
const basePath = `/entity/${kind}/${id}`;
|
||||
|
||||
return (
|
||||
<EntityLayout>
|
||||
<EntitySidebar>
|
||||
{pages.map(({ title, path }) => (
|
||||
<EntitySidebarItem key={path} title={title} path={path} />
|
||||
{navItems.map(({ title, target }) => (
|
||||
<EntitySidebarItem key={target} title={title} path={target} />
|
||||
))}
|
||||
</EntitySidebar>
|
||||
<Switch>
|
||||
{pages.map(({ path, component }) => (
|
||||
{views.map(({ path, component }) => (
|
||||
<Route
|
||||
key={path}
|
||||
exact={false}
|
||||
path={`${basePath}/${path}`}
|
||||
exact
|
||||
path={`${basePath}${path}`}
|
||||
component={component}
|
||||
/>
|
||||
))}
|
||||
<Redirect from={basePath} to={`${basePath}/${pages[0].path}`} />
|
||||
<Redirect from={basePath} to={`${basePath}${views[0].path}`} />
|
||||
</Switch>
|
||||
</EntityLayout>
|
||||
);
|
||||
};
|
||||
|
||||
type EntityViewRegistration =
|
||||
type EntityPageRegistration =
|
||||
| {
|
||||
type: 'page';
|
||||
title: string;
|
||||
@@ -88,14 +92,14 @@ type EntityViewRegistration =
|
||||
component: ComponentType<any>;
|
||||
};
|
||||
|
||||
export default class EntityViewBuilder extends AppComponentBuilder {
|
||||
private readonly registrations = new Array<EntityViewRegistration>();
|
||||
export default class EntityPageBuilder extends AppComponentBuilder {
|
||||
private readonly registrations = new Array<EntityPageRegistration>();
|
||||
|
||||
addPage(
|
||||
title: string,
|
||||
path: string,
|
||||
page: AppComponentBuilder,
|
||||
): EntityViewBuilder {
|
||||
): EntityPageBuilder {
|
||||
this.registrations.push({ type: 'page', title, path, page });
|
||||
return this;
|
||||
}
|
||||
@@ -104,42 +108,60 @@ export default class EntityViewBuilder extends AppComponentBuilder {
|
||||
title: string,
|
||||
path: string,
|
||||
component: ComponentType<any>,
|
||||
): EntityViewBuilder {
|
||||
): EntityPageBuilder {
|
||||
this.registrations.push({ type: 'component', title, path, component });
|
||||
return this;
|
||||
}
|
||||
|
||||
register(plugin: BackstagePlugin): EntityViewBuilder {
|
||||
register(plugin: BackstagePlugin): EntityPageBuilder {
|
||||
this.registrations.push({ type: 'plugin', plugin });
|
||||
return this;
|
||||
}
|
||||
|
||||
build(app: App): ComponentType<any> {
|
||||
const pages = this.registrations.map(registration => {
|
||||
switch (registration.type) {
|
||||
const navItems = new Array<EntityPageNavItem>();
|
||||
const views = new Array<EntityPageView>();
|
||||
|
||||
for (const reg of this.registrations) {
|
||||
switch (reg.type) {
|
||||
case 'page': {
|
||||
const { title, path, page } = registration;
|
||||
return { title, path, component: page.build(app) };
|
||||
const { title, path, page } = reg;
|
||||
navItems.push({ title, target: path });
|
||||
views.push({ path, component: page.build(app) });
|
||||
break;
|
||||
}
|
||||
case 'component': {
|
||||
const { title, path, component } = registration;
|
||||
return { title, path, component };
|
||||
const { title, path, component } = reg;
|
||||
navItems.push({ title, target: path });
|
||||
views.push({ path, component });
|
||||
break;
|
||||
}
|
||||
case 'plugin': {
|
||||
const { plugin } = registration;
|
||||
const output = plugin[outputSymbol](entityViewPage);
|
||||
if (!output) {
|
||||
let added = false;
|
||||
for (const output of reg.plugin.output()) {
|
||||
switch (output.type) {
|
||||
case 'entity-page-nav-item':
|
||||
const { title, target } = output;
|
||||
navItems.push({ title, target });
|
||||
added = true;
|
||||
break;
|
||||
case 'entity-page-view-route':
|
||||
const { path, component } = output;
|
||||
views.push({ path, component });
|
||||
added = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!added) {
|
||||
throw new Error(
|
||||
`Plugin ${plugin} was registered as entity view, but did not have any output`,
|
||||
`Plugin ${reg.plugin} was registered as entity view, but did not provide any output`,
|
||||
);
|
||||
}
|
||||
return output;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw new Error(`Unknown EntityViewBuilder registration`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return () => <EntityViewComponent pages={pages} />;
|
||||
return () => <EntityPageComponent navItems={navItems} views={views} />;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
import React from 'react';
|
||||
import { Route, Redirect } from 'react-router-dom';
|
||||
import PluginOutputHook from './PluginOutputHook';
|
||||
import { ComponentType } from 'react';
|
||||
import { PluginOutput, RoutePath, RouteOptions } from './types';
|
||||
|
||||
export type PluginConfig = {
|
||||
id: string;
|
||||
@@ -8,101 +7,98 @@ export type PluginConfig = {
|
||||
};
|
||||
|
||||
export type PluginHooks = {
|
||||
router: Router;
|
||||
provide<T>(ref: PluginOutputHook<T>, value: T): void;
|
||||
router: RouterHooks;
|
||||
entityPage: EntityPageHooks;
|
||||
};
|
||||
|
||||
export type RouteOptions = {
|
||||
// Whether the route path must match exactly, defaults to true.
|
||||
exact?: boolean;
|
||||
};
|
||||
|
||||
export type RedirectOptions = {
|
||||
// Whether the route path must match exactly, defaults to true.
|
||||
exact?: boolean;
|
||||
};
|
||||
|
||||
export type Router = {
|
||||
export type RouterHooks = {
|
||||
registerRoute(
|
||||
path: string,
|
||||
Component: React.ComponentType<any>,
|
||||
path: RoutePath,
|
||||
Component: ComponentType<any>,
|
||||
options?: RouteOptions,
|
||||
): void;
|
||||
|
||||
registerRedirect(
|
||||
path: string,
|
||||
target: string,
|
||||
options?: RedirectOptions,
|
||||
path: RoutePath,
|
||||
target: RoutePath,
|
||||
options?: RouteOptions,
|
||||
): void;
|
||||
};
|
||||
|
||||
export type PluginRegistrationResult = {
|
||||
routes?: JSX.Element[];
|
||||
outputs?: Map<PluginOutputHook<any>, any>;
|
||||
type EntityPageSidebarItemOptions = {
|
||||
title: string;
|
||||
target: RoutePath;
|
||||
};
|
||||
|
||||
export type EntityPageHooks = {
|
||||
navItem(options: EntityPageSidebarItemOptions): void;
|
||||
route(
|
||||
path: RoutePath,
|
||||
component: ComponentType<any>,
|
||||
options?: RouteOptions,
|
||||
): void;
|
||||
};
|
||||
|
||||
export const registerSymbol = Symbol('plugin-register');
|
||||
export const outputSymbol = Symbol('plugin-output');
|
||||
|
||||
export default class Plugin {
|
||||
private result?: PluginRegistrationResult;
|
||||
private storedOutput?: PluginOutput[];
|
||||
|
||||
constructor(private readonly config: PluginConfig) {}
|
||||
|
||||
[registerSymbol](): PluginRegistrationResult {
|
||||
if (this.result) {
|
||||
return this.result;
|
||||
output(): PluginOutput[] {
|
||||
if (this.storedOutput) {
|
||||
return this.storedOutput;
|
||||
}
|
||||
if (!this.config.register) {
|
||||
return {};
|
||||
return [];
|
||||
}
|
||||
|
||||
const { id } = this.config;
|
||||
|
||||
const routes = new Array<JSX.Element>();
|
||||
const outputs = new Map<PluginOutputHook<any>, any>();
|
||||
const outputs = new Array<PluginOutput>();
|
||||
|
||||
this.config.register({
|
||||
router: {
|
||||
registerRoute(path, component, options = {}) {
|
||||
registerRoute(path, component, options) {
|
||||
if (path.startsWith('/entity/')) {
|
||||
throw new Error(
|
||||
`Plugin ${id} tried to register forbidden route ${path}`,
|
||||
);
|
||||
}
|
||||
const { exact = true } = options;
|
||||
routes.push(
|
||||
<Route
|
||||
key={path}
|
||||
path={path}
|
||||
component={component}
|
||||
exact={exact}
|
||||
/>,
|
||||
);
|
||||
outputs.push({ type: 'route', path, component, options });
|
||||
},
|
||||
registerRedirect(path, target, options = {}) {
|
||||
registerRedirect(path, target, options) {
|
||||
if (path.startsWith('/entity/')) {
|
||||
throw new Error(
|
||||
`Plugin ${id} tried to register forbidden redirect ${path}`,
|
||||
);
|
||||
}
|
||||
const { exact = true } = options;
|
||||
routes.push(
|
||||
<Redirect key={path} path={path} to={target} exact={exact} />,
|
||||
);
|
||||
outputs.push({ type: 'redirect-route', path, target, options });
|
||||
},
|
||||
},
|
||||
provide(hook, value) {
|
||||
outputs.set(hook, value);
|
||||
entityPage: {
|
||||
navItem({ title, target }) {
|
||||
outputs.push({
|
||||
type: 'entity-page-nav-item',
|
||||
target,
|
||||
title,
|
||||
});
|
||||
},
|
||||
route(path, component, options) {
|
||||
outputs.push({
|
||||
type: 'entity-page-view-route',
|
||||
path,
|
||||
component,
|
||||
options,
|
||||
});
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
this.result = { routes, outputs };
|
||||
return this.result;
|
||||
}
|
||||
|
||||
[outputSymbol]<T>(outputHook: PluginOutputHook<T>): T | undefined {
|
||||
const { outputs } = this[registerSymbol]();
|
||||
return outputs?.get(outputHook) as T;
|
||||
this.storedOutput = outputs;
|
||||
return this.storedOutput;
|
||||
}
|
||||
|
||||
toString() {
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
export default class PluginOutputHook<T> {
|
||||
constructor(private readonly name: string) {}
|
||||
|
||||
get T(): T {
|
||||
throw new Error('use typeof instead');
|
||||
}
|
||||
|
||||
toString() {
|
||||
return `pluginOutput{${this.name}}`;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
import PluginOutputHook from './PluginOutputHook';
|
||||
import { ComponentType } from 'react';
|
||||
|
||||
export const entityViewPage = new PluginOutputHook<{
|
||||
title: string;
|
||||
path: string;
|
||||
component: ComponentType<any>;
|
||||
}>('entity-view-page');
|
||||
@@ -0,0 +1,41 @@
|
||||
import { ComponentType } from 'react';
|
||||
|
||||
export type RouteOptions = {
|
||||
// Whether the route path must match exactly, defaults to true.
|
||||
exact?: boolean;
|
||||
};
|
||||
|
||||
export type RoutePath = string;
|
||||
|
||||
export type RouteOutput = {
|
||||
type: 'route';
|
||||
path: RoutePath;
|
||||
component: ComponentType<{}>;
|
||||
options?: RouteOptions;
|
||||
};
|
||||
|
||||
export type RedirectRouteOutput = {
|
||||
type: 'redirect-route';
|
||||
path: RoutePath;
|
||||
target: RoutePath;
|
||||
options?: RouteOptions;
|
||||
};
|
||||
|
||||
export type EntityPageViewRouteOutput = {
|
||||
type: 'entity-page-view-route';
|
||||
path: RoutePath;
|
||||
component: ComponentType<any>;
|
||||
options?: RouteOptions;
|
||||
};
|
||||
|
||||
export type EntityPageNavItemOutput = {
|
||||
type: 'entity-page-nav-item';
|
||||
title: string;
|
||||
target: RoutePath;
|
||||
};
|
||||
|
||||
export type PluginOutput =
|
||||
| RouteOutput
|
||||
| RedirectRouteOutput
|
||||
| EntityPageViewRouteOutput
|
||||
| EntityPageNavItemOutput;
|
||||
@@ -16,7 +16,7 @@ type Props = {
|
||||
export function buildPath(kind: string, id?: string, subPath?: string) {
|
||||
if (id) {
|
||||
if (subPath) {
|
||||
return `/entity/${kind}/${id}/${subPath}`;
|
||||
return `/entity/${kind}/${id}/${subPath.replace(/^\//, '')}`;
|
||||
}
|
||||
return `/entity/${kind}/${id}`;
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
"main:src": "src/index.ts",
|
||||
"devDependencies": {
|
||||
"@backstage/core": "0.0.0",
|
||||
"@backstage/protobuf-definitions": "0.0.0",
|
||||
"@spotify/web-scripts": "^6.0.0",
|
||||
"@testing-library/jest-dom": "^4.2.4",
|
||||
"@testing-library/react": "^9.3.2",
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
import { buildsV1 } from '@backstage/protobuf-definitions';
|
||||
import { BuildStatus, Build, BuildDetails } from './types';
|
||||
|
||||
const statusTable = {
|
||||
[buildsV1.BuildStatus.NULL]: BuildStatus.Null,
|
||||
[buildsV1.BuildStatus.SUCCESS]: BuildStatus.Success,
|
||||
[buildsV1.BuildStatus.FAILURE]: BuildStatus.Failure,
|
||||
[buildsV1.BuildStatus.PENDING]: BuildStatus.Pending,
|
||||
[buildsV1.BuildStatus.RUNNING]: BuildStatus.Running,
|
||||
};
|
||||
|
||||
export default class BuildsClient {
|
||||
static create(grpcAddress: string): BuildsClient {
|
||||
return new BuildsClient(new buildsV1.Client(grpcAddress));
|
||||
}
|
||||
|
||||
constructor(private readonly client: buildsV1.Client) {}
|
||||
|
||||
async listBuilds(entityUri: string): Promise<Build[]> {
|
||||
const req = new buildsV1.ListBuildsRequest();
|
||||
req.setEntityUri(entityUri);
|
||||
|
||||
const res = await this.client.listBuilds(req);
|
||||
|
||||
return res.getBuildsList().map(this.transformBuild);
|
||||
}
|
||||
|
||||
async getBuild(buildUri: string): Promise<BuildDetails> {
|
||||
const req = new buildsV1.GetBuildRequest();
|
||||
req.setBuildUri(buildUri);
|
||||
|
||||
const res = await this.client.getBuild(req);
|
||||
|
||||
const build = res.getBuild();
|
||||
if (!build) {
|
||||
throw new Error('No build in GetBuild response');
|
||||
}
|
||||
const details = res.getDetails();
|
||||
if (!details) {
|
||||
throw new Error('No details in GetBuild response');
|
||||
}
|
||||
|
||||
return {
|
||||
build: this.transformBuild(build),
|
||||
author: details.getAuthor(),
|
||||
logUrl: details.getLogUrl(),
|
||||
overviewUrl: details.getOverviewUrl(),
|
||||
};
|
||||
}
|
||||
|
||||
private transformBuild = (build: buildsV1.Build): Build => {
|
||||
return {
|
||||
commitId: build.getCommitId(),
|
||||
message: build.getMessage(),
|
||||
status: statusTable[build.getStatus()] || BuildStatus.Null,
|
||||
uri: build.getUri(),
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './types';
|
||||
export { default as BuildsClient } from './BuildsClient';
|
||||
@@ -0,0 +1,21 @@
|
||||
export enum BuildStatus {
|
||||
Null,
|
||||
Success,
|
||||
Failure,
|
||||
Pending,
|
||||
Running,
|
||||
}
|
||||
|
||||
export type Build = {
|
||||
commitId: string;
|
||||
message: string;
|
||||
status: BuildStatus;
|
||||
uri: string;
|
||||
};
|
||||
|
||||
export type BuildDetails = {
|
||||
build: Build;
|
||||
author: string;
|
||||
logUrl: string;
|
||||
overviewUrl: string;
|
||||
};
|
||||
@@ -1,19 +1,101 @@
|
||||
import React, { FC } from 'react';
|
||||
import Button from '@material-ui/core/Button';
|
||||
import { BuildsClient } from '../../apis/builds';
|
||||
import { useAsync } from 'react-use';
|
||||
import { useRouteMatch } from 'react-router-dom';
|
||||
import {
|
||||
LinearProgress,
|
||||
Typography,
|
||||
TableContainer,
|
||||
Paper,
|
||||
Table,
|
||||
TableBody,
|
||||
TableRow,
|
||||
TableCell,
|
||||
Link,
|
||||
makeStyles,
|
||||
ButtonGroup,
|
||||
Button,
|
||||
} from '@material-ui/core';
|
||||
|
||||
type Props = {
|
||||
buildId: string;
|
||||
};
|
||||
const useStyles = makeStyles({
|
||||
root: {
|
||||
maxWidth: 720,
|
||||
},
|
||||
});
|
||||
|
||||
type Props = {};
|
||||
|
||||
const client = BuildsClient.create('http://localhost:8080');
|
||||
|
||||
const BuildDetailsPage: FC<Props> = () => {
|
||||
const classes = useStyles();
|
||||
const match = useRouteMatch<{ buildUri: string }>();
|
||||
const buildUri = decodeURIComponent(match.params.buildUri);
|
||||
const status = useAsync(() => client.getBuild(buildUri), [buildUri]);
|
||||
|
||||
if (status.loading) {
|
||||
return <LinearProgress />;
|
||||
}
|
||||
if (status.error) {
|
||||
return (
|
||||
<Typography variant="h4" color="error">
|
||||
Failed to load build, {status.error}
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
|
||||
const details = status.value;
|
||||
|
||||
const BuildDetailsPage: FC<Props> = ({ buildId }) => {
|
||||
return (
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
onClick={() => window.location.reload()}
|
||||
>
|
||||
Hello! Build details for {buildId}
|
||||
</Button>
|
||||
<TableContainer component={Paper} className={classes.root}>
|
||||
<Table>
|
||||
<TableBody>
|
||||
<TableRow>
|
||||
<TableCell>
|
||||
<Typography noWrap>Message</Typography>
|
||||
</TableCell>
|
||||
<TableCell>{details?.build.message}</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell>
|
||||
<Typography noWrap>Commit ID</Typography>
|
||||
</TableCell>
|
||||
<TableCell>{details?.build.commitId}</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell>
|
||||
<Typography noWrap>Status</Typography>
|
||||
</TableCell>
|
||||
<TableCell>{details?.build.status}</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell>
|
||||
<Typography noWrap>Author</Typography>
|
||||
</TableCell>
|
||||
<TableCell>{details?.author}</TableCell>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TableCell>
|
||||
<Typography noWrap>Links</Typography>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<ButtonGroup
|
||||
variant="text"
|
||||
color="primary"
|
||||
aria-label="text primary button group"
|
||||
>
|
||||
<Button>
|
||||
<Link href={details?.overviewUrl}>GitHub</Link>
|
||||
</Button>
|
||||
<Button>
|
||||
<Link href={details?.logUrl}>Logs</Link>
|
||||
</Button>
|
||||
</ButtonGroup>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -7,39 +7,79 @@ import {
|
||||
TableCell,
|
||||
Paper,
|
||||
TableBody,
|
||||
LinearProgress,
|
||||
Typography,
|
||||
Tooltip,
|
||||
} from '@material-ui/core';
|
||||
import { RelativeEntityLink } from '@backstage/core';
|
||||
import { BuildsClient } from '../../apis/builds';
|
||||
import { useAsync } from 'react-use';
|
||||
|
||||
const client = BuildsClient.create('http://localhost:8080');
|
||||
|
||||
const LongText: FC<{ text: string; max: number }> = ({ text, max }) => {
|
||||
if (text.length < max) {
|
||||
return <span>{text}</span>;
|
||||
}
|
||||
return (
|
||||
<Tooltip title={text}>
|
||||
<span>{text.slice(0, max)}...</span>
|
||||
</Tooltip>
|
||||
);
|
||||
};
|
||||
|
||||
const BuildListPage: FC<{}> = () => {
|
||||
const rows = [
|
||||
{ message: 'Fixed a Bar', commit: 'fb46ca3dfbd7af5bc43da', id: 165 },
|
||||
{ message: 'Fixed a Foo', commit: 'd7af5bc43dafb46ca3dfb', id: 164 },
|
||||
];
|
||||
const status = useAsync(() => client.listBuilds('entity:spotify:backstage'));
|
||||
|
||||
if (status.loading) {
|
||||
return <LinearProgress />;
|
||||
}
|
||||
if (status.error) {
|
||||
return (
|
||||
<Typography variant="h4" color="error">
|
||||
Failed to load builds, {status.error}
|
||||
</Typography>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<TableContainer component={Paper}>
|
||||
<Table aria-label="CI/CD builds table">
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell>Message</TableCell>
|
||||
<TableCell>Commit</TableCell>
|
||||
<TableCell>Build ID</TableCell>
|
||||
</TableRow>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{rows.map(row => (
|
||||
<TableRow key={row.commit}>
|
||||
<TableCell>{row.message}</TableCell>
|
||||
<TableCell>{row.commit}</TableCell>
|
||||
<TableCell>
|
||||
<RelativeEntityLink view={`builds/${row.id}`}>
|
||||
{row.commit}
|
||||
</RelativeEntityLink>
|
||||
</TableCell>
|
||||
<>
|
||||
<Typography variant="h4">CI/CD Builds</Typography>
|
||||
<TableContainer component={Paper}>
|
||||
<Table aria-label="CI/CD builds table">
|
||||
<TableHead>
|
||||
<TableRow>
|
||||
<TableCell>Message</TableCell>
|
||||
<TableCell>Commit</TableCell>
|
||||
<TableCell>Status</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</TableHead>
|
||||
<TableBody>
|
||||
{status.value!.map(build => (
|
||||
<TableRow key={build.uri}>
|
||||
<TableCell>
|
||||
<RelativeEntityLink
|
||||
view={`builds/${encodeURIComponent(build.uri)}`}
|
||||
>
|
||||
<Typography color="primary">
|
||||
<LongText text={build.message} max={60} />
|
||||
</Typography>
|
||||
</RelativeEntityLink>
|
||||
</TableCell>
|
||||
<TableCell>
|
||||
<Tooltip title={build.commitId}>
|
||||
<Typography noWrap>
|
||||
{build.commitId.slice(0, 10)}
|
||||
</Typography>
|
||||
</Tooltip>
|
||||
</TableCell>
|
||||
<TableCell>{build.status}</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</TableContainer>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
import React, { FC } from 'react';
|
||||
import { Switch, Route } from 'react-router-dom';
|
||||
import BuildListPage from '../BuildListPage';
|
||||
import BuildDetailsPage from '../BuildDetailsPage';
|
||||
import { useRouteMatch } from 'react-router-dom';
|
||||
|
||||
const BuildPage: FC<{}> = () => {
|
||||
const match = useRouteMatch();
|
||||
return (
|
||||
<Switch>
|
||||
<Route
|
||||
path={`${match.path}/:buildId`}
|
||||
render={({ match }) => (
|
||||
<BuildDetailsPage buildId={match.params.buildId} />
|
||||
)}
|
||||
/>
|
||||
<Route path={match.path} component={BuildListPage} />
|
||||
</Switch>
|
||||
);
|
||||
};
|
||||
|
||||
export default BuildPage;
|
||||
@@ -1 +0,0 @@
|
||||
export { default } from './BuildPage';
|
||||
@@ -1,6 +1,6 @@
|
||||
import { createPlugin } from '@backstage/core';
|
||||
import { entityViewPage } from '@backstage/core/src/api/plugin/outputs';
|
||||
import BuildPage from './components/BuildPage';
|
||||
import BuildDetailsPage from './components/BuildDetailsPage';
|
||||
import BuildListPage from './components/BuildListPage';
|
||||
|
||||
// export const buildListRoute = createEntityRoute<[]>('/builds')
|
||||
// export const buildDetailsRoute = createEntityRoute<[number]>('/builds/:buildId')
|
||||
@@ -8,11 +8,9 @@ import BuildPage from './components/BuildPage';
|
||||
export default createPlugin({
|
||||
id: 'github-actions',
|
||||
|
||||
register({ provide }) {
|
||||
provide(entityViewPage, {
|
||||
title: 'CI/CD',
|
||||
path: 'builds',
|
||||
component: BuildPage,
|
||||
});
|
||||
register({ entityPage }) {
|
||||
entityPage.navItem({ title: 'CI/CD', target: '/builds' });
|
||||
entityPage.route('/builds', BuildListPage);
|
||||
entityPage.route('/builds/:buildUri', BuildDetailsPage);
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "@backstage/protobuf-definitions",
|
||||
"main": "src/index.ts",
|
||||
"main:src": "src/index.ts",
|
||||
"version": "0.0.0",
|
||||
"devDependencies": {
|
||||
"ts-protoc-gen": "^0.12.0"
|
||||
"dependencies": {
|
||||
"google-protobuf": "^3.11.2",
|
||||
"grpc-web": "^1.0.7"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
export { BuildsPromiseClient as Client } from './generated/builds/v1/builds_grpc_web_pb';
|
||||
export * from './generated/builds/v1/builds_pb';
|
||||
@@ -0,0 +1,46 @@
|
||||
import * as grpcWeb from 'grpc-web';
|
||||
|
||||
import {
|
||||
GetBuildReply,
|
||||
GetBuildRequest,
|
||||
ListBuildsReply,
|
||||
ListBuildsRequest} from './builds_pb';
|
||||
|
||||
export class BuildsClient {
|
||||
constructor (hostname: string,
|
||||
credentials?: null | { [index: string]: string; },
|
||||
options?: null | { [index: string]: string; });
|
||||
|
||||
listBuilds(
|
||||
request: ListBuildsRequest,
|
||||
metadata: grpcWeb.Metadata | undefined,
|
||||
callback: (err: grpcWeb.Error,
|
||||
response: ListBuildsReply) => void
|
||||
): grpcWeb.ClientReadableStream<ListBuildsReply>;
|
||||
|
||||
getBuild(
|
||||
request: GetBuildRequest,
|
||||
metadata: grpcWeb.Metadata | undefined,
|
||||
callback: (err: grpcWeb.Error,
|
||||
response: GetBuildReply) => void
|
||||
): grpcWeb.ClientReadableStream<GetBuildReply>;
|
||||
|
||||
}
|
||||
|
||||
export class BuildsPromiseClient {
|
||||
constructor (hostname: string,
|
||||
credentials?: null | { [index: string]: string; },
|
||||
options?: null | { [index: string]: string; });
|
||||
|
||||
listBuilds(
|
||||
request: ListBuildsRequest,
|
||||
metadata?: grpcWeb.Metadata
|
||||
): Promise<ListBuildsReply>;
|
||||
|
||||
getBuild(
|
||||
request: GetBuildRequest,
|
||||
metadata?: grpcWeb.Metadata
|
||||
): Promise<GetBuildReply>;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,233 @@
|
||||
/**
|
||||
* @fileoverview gRPC-Web generated client stub for spotify.backstage.builds.v1
|
||||
* @enhanceable
|
||||
* @public
|
||||
*/
|
||||
|
||||
// GENERATED CODE -- DO NOT EDIT!
|
||||
|
||||
|
||||
|
||||
const grpc = {};
|
||||
grpc.web = require('grpc-web');
|
||||
|
||||
const proto = {};
|
||||
proto.spotify = {};
|
||||
proto.spotify.backstage = {};
|
||||
proto.spotify.backstage.builds = {};
|
||||
proto.spotify.backstage.builds.v1 = require('./builds_pb.js');
|
||||
|
||||
/**
|
||||
* @param {string} hostname
|
||||
* @param {?Object} credentials
|
||||
* @param {?Object} options
|
||||
* @constructor
|
||||
* @struct
|
||||
* @final
|
||||
*/
|
||||
proto.spotify.backstage.builds.v1.BuildsClient =
|
||||
function(hostname, credentials, options) {
|
||||
if (!options) options = {};
|
||||
options['format'] = 'text';
|
||||
|
||||
/**
|
||||
* @private @const {!grpc.web.GrpcWebClientBase} The client
|
||||
*/
|
||||
this.client_ = new grpc.web.GrpcWebClientBase(options);
|
||||
|
||||
/**
|
||||
* @private @const {string} The hostname
|
||||
*/
|
||||
this.hostname_ = hostname;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} hostname
|
||||
* @param {?Object} credentials
|
||||
* @param {?Object} options
|
||||
* @constructor
|
||||
* @struct
|
||||
* @final
|
||||
*/
|
||||
proto.spotify.backstage.builds.v1.BuildsPromiseClient =
|
||||
function(hostname, credentials, options) {
|
||||
if (!options) options = {};
|
||||
options['format'] = 'text';
|
||||
|
||||
/**
|
||||
* @private @const {!grpc.web.GrpcWebClientBase} The client
|
||||
*/
|
||||
this.client_ = new grpc.web.GrpcWebClientBase(options);
|
||||
|
||||
/**
|
||||
* @private @const {string} The hostname
|
||||
*/
|
||||
this.hostname_ = hostname;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {!grpc.web.MethodDescriptor<
|
||||
* !proto.spotify.backstage.builds.v1.ListBuildsRequest,
|
||||
* !proto.spotify.backstage.builds.v1.ListBuildsReply>}
|
||||
*/
|
||||
const methodDescriptor_Builds_ListBuilds = new grpc.web.MethodDescriptor(
|
||||
'/spotify.backstage.builds.v1.Builds/ListBuilds',
|
||||
grpc.web.MethodType.UNARY,
|
||||
proto.spotify.backstage.builds.v1.ListBuildsRequest,
|
||||
proto.spotify.backstage.builds.v1.ListBuildsReply,
|
||||
/**
|
||||
* @param {!proto.spotify.backstage.builds.v1.ListBuildsRequest} request
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
function(request) {
|
||||
return request.serializeBinary();
|
||||
},
|
||||
proto.spotify.backstage.builds.v1.ListBuildsReply.deserializeBinary
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {!grpc.web.AbstractClientBase.MethodInfo<
|
||||
* !proto.spotify.backstage.builds.v1.ListBuildsRequest,
|
||||
* !proto.spotify.backstage.builds.v1.ListBuildsReply>}
|
||||
*/
|
||||
const methodInfo_Builds_ListBuilds = new grpc.web.AbstractClientBase.MethodInfo(
|
||||
proto.spotify.backstage.builds.v1.ListBuildsReply,
|
||||
/**
|
||||
* @param {!proto.spotify.backstage.builds.v1.ListBuildsRequest} request
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
function(request) {
|
||||
return request.serializeBinary();
|
||||
},
|
||||
proto.spotify.backstage.builds.v1.ListBuildsReply.deserializeBinary
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.spotify.backstage.builds.v1.ListBuildsRequest} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @param {function(?grpc.web.Error, ?proto.spotify.backstage.builds.v1.ListBuildsReply)}
|
||||
* callback The callback function(error, response)
|
||||
* @return {!grpc.web.ClientReadableStream<!proto.spotify.backstage.builds.v1.ListBuildsReply>|undefined}
|
||||
* The XHR Node Readable Stream
|
||||
*/
|
||||
proto.spotify.backstage.builds.v1.BuildsClient.prototype.listBuilds =
|
||||
function(request, metadata, callback) {
|
||||
return this.client_.rpcCall(this.hostname_ +
|
||||
'/spotify.backstage.builds.v1.Builds/ListBuilds',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_Builds_ListBuilds,
|
||||
callback);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.spotify.backstage.builds.v1.ListBuildsRequest} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @return {!Promise<!proto.spotify.backstage.builds.v1.ListBuildsReply>}
|
||||
* A native promise that resolves to the response
|
||||
*/
|
||||
proto.spotify.backstage.builds.v1.BuildsPromiseClient.prototype.listBuilds =
|
||||
function(request, metadata) {
|
||||
return this.client_.unaryCall(this.hostname_ +
|
||||
'/spotify.backstage.builds.v1.Builds/ListBuilds',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_Builds_ListBuilds);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {!grpc.web.MethodDescriptor<
|
||||
* !proto.spotify.backstage.builds.v1.GetBuildRequest,
|
||||
* !proto.spotify.backstage.builds.v1.GetBuildReply>}
|
||||
*/
|
||||
const methodDescriptor_Builds_GetBuild = new grpc.web.MethodDescriptor(
|
||||
'/spotify.backstage.builds.v1.Builds/GetBuild',
|
||||
grpc.web.MethodType.UNARY,
|
||||
proto.spotify.backstage.builds.v1.GetBuildRequest,
|
||||
proto.spotify.backstage.builds.v1.GetBuildReply,
|
||||
/**
|
||||
* @param {!proto.spotify.backstage.builds.v1.GetBuildRequest} request
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
function(request) {
|
||||
return request.serializeBinary();
|
||||
},
|
||||
proto.spotify.backstage.builds.v1.GetBuildReply.deserializeBinary
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {!grpc.web.AbstractClientBase.MethodInfo<
|
||||
* !proto.spotify.backstage.builds.v1.GetBuildRequest,
|
||||
* !proto.spotify.backstage.builds.v1.GetBuildReply>}
|
||||
*/
|
||||
const methodInfo_Builds_GetBuild = new grpc.web.AbstractClientBase.MethodInfo(
|
||||
proto.spotify.backstage.builds.v1.GetBuildReply,
|
||||
/**
|
||||
* @param {!proto.spotify.backstage.builds.v1.GetBuildRequest} request
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
function(request) {
|
||||
return request.serializeBinary();
|
||||
},
|
||||
proto.spotify.backstage.builds.v1.GetBuildReply.deserializeBinary
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.spotify.backstage.builds.v1.GetBuildRequest} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @param {function(?grpc.web.Error, ?proto.spotify.backstage.builds.v1.GetBuildReply)}
|
||||
* callback The callback function(error, response)
|
||||
* @return {!grpc.web.ClientReadableStream<!proto.spotify.backstage.builds.v1.GetBuildReply>|undefined}
|
||||
* The XHR Node Readable Stream
|
||||
*/
|
||||
proto.spotify.backstage.builds.v1.BuildsClient.prototype.getBuild =
|
||||
function(request, metadata, callback) {
|
||||
return this.client_.rpcCall(this.hostname_ +
|
||||
'/spotify.backstage.builds.v1.Builds/GetBuild',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_Builds_GetBuild,
|
||||
callback);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.spotify.backstage.builds.v1.GetBuildRequest} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @return {!Promise<!proto.spotify.backstage.builds.v1.GetBuildReply>}
|
||||
* A native promise that resolves to the response
|
||||
*/
|
||||
proto.spotify.backstage.builds.v1.BuildsPromiseClient.prototype.getBuild =
|
||||
function(request, metadata) {
|
||||
return this.client_.unaryCall(this.hostname_ +
|
||||
'/spotify.backstage.builds.v1.Builds/GetBuild',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_Builds_GetBuild);
|
||||
};
|
||||
|
||||
|
||||
module.exports = proto.spotify.backstage.builds.v1;
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
import * as jspb from "google-protobuf"
|
||||
|
||||
export class ListBuildsRequest extends jspb.Message {
|
||||
getEntityUri(): string;
|
||||
setEntityUri(value: string): void;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): ListBuildsRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: ListBuildsRequest): ListBuildsRequest.AsObject;
|
||||
static serializeBinaryToWriter(message: ListBuildsRequest, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): ListBuildsRequest;
|
||||
static deserializeBinaryFromReader(message: ListBuildsRequest, reader: jspb.BinaryReader): ListBuildsRequest;
|
||||
}
|
||||
|
||||
export namespace ListBuildsRequest {
|
||||
export type AsObject = {
|
||||
entityUri: string,
|
||||
}
|
||||
}
|
||||
|
||||
export class ListBuildsReply extends jspb.Message {
|
||||
getEntityUri(): string;
|
||||
setEntityUri(value: string): void;
|
||||
|
||||
getBuildsList(): Array<Build>;
|
||||
setBuildsList(value: Array<Build>): void;
|
||||
clearBuildsList(): void;
|
||||
addBuilds(value?: Build, index?: number): Build;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): ListBuildsReply.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: ListBuildsReply): ListBuildsReply.AsObject;
|
||||
static serializeBinaryToWriter(message: ListBuildsReply, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): ListBuildsReply;
|
||||
static deserializeBinaryFromReader(message: ListBuildsReply, reader: jspb.BinaryReader): ListBuildsReply;
|
||||
}
|
||||
|
||||
export namespace ListBuildsReply {
|
||||
export type AsObject = {
|
||||
entityUri: string,
|
||||
buildsList: Array<Build.AsObject>,
|
||||
}
|
||||
}
|
||||
|
||||
export class GetBuildRequest extends jspb.Message {
|
||||
getBuildUri(): string;
|
||||
setBuildUri(value: string): void;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): GetBuildRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: GetBuildRequest): GetBuildRequest.AsObject;
|
||||
static serializeBinaryToWriter(message: GetBuildRequest, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): GetBuildRequest;
|
||||
static deserializeBinaryFromReader(message: GetBuildRequest, reader: jspb.BinaryReader): GetBuildRequest;
|
||||
}
|
||||
|
||||
export namespace GetBuildRequest {
|
||||
export type AsObject = {
|
||||
buildUri: string,
|
||||
}
|
||||
}
|
||||
|
||||
export class GetBuildReply extends jspb.Message {
|
||||
getBuild(): Build | undefined;
|
||||
setBuild(value?: Build): void;
|
||||
hasBuild(): boolean;
|
||||
clearBuild(): void;
|
||||
|
||||
getDetails(): BuildDetails | undefined;
|
||||
setDetails(value?: BuildDetails): void;
|
||||
hasDetails(): boolean;
|
||||
clearDetails(): void;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): GetBuildReply.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: GetBuildReply): GetBuildReply.AsObject;
|
||||
static serializeBinaryToWriter(message: GetBuildReply, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): GetBuildReply;
|
||||
static deserializeBinaryFromReader(message: GetBuildReply, reader: jspb.BinaryReader): GetBuildReply;
|
||||
}
|
||||
|
||||
export namespace GetBuildReply {
|
||||
export type AsObject = {
|
||||
build?: Build.AsObject,
|
||||
details?: BuildDetails.AsObject,
|
||||
}
|
||||
}
|
||||
|
||||
export class Build extends jspb.Message {
|
||||
getUri(): string;
|
||||
setUri(value: string): void;
|
||||
|
||||
getCommitId(): string;
|
||||
setCommitId(value: string): void;
|
||||
|
||||
getMessage(): string;
|
||||
setMessage(value: string): void;
|
||||
|
||||
getStatus(): BuildStatus;
|
||||
setStatus(value: BuildStatus): void;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): Build.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: Build): Build.AsObject;
|
||||
static serializeBinaryToWriter(message: Build, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): Build;
|
||||
static deserializeBinaryFromReader(message: Build, reader: jspb.BinaryReader): Build;
|
||||
}
|
||||
|
||||
export namespace Build {
|
||||
export type AsObject = {
|
||||
uri: string,
|
||||
commitId: string,
|
||||
message: string,
|
||||
status: BuildStatus,
|
||||
}
|
||||
}
|
||||
|
||||
export class BuildDetails extends jspb.Message {
|
||||
getAuthor(): string;
|
||||
setAuthor(value: string): void;
|
||||
|
||||
getOverviewUrl(): string;
|
||||
setOverviewUrl(value: string): void;
|
||||
|
||||
getLogUrl(): string;
|
||||
setLogUrl(value: string): void;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): BuildDetails.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: BuildDetails): BuildDetails.AsObject;
|
||||
static serializeBinaryToWriter(message: BuildDetails, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): BuildDetails;
|
||||
static deserializeBinaryFromReader(message: BuildDetails, reader: jspb.BinaryReader): BuildDetails;
|
||||
}
|
||||
|
||||
export namespace BuildDetails {
|
||||
export type AsObject = {
|
||||
author: string,
|
||||
overviewUrl: string,
|
||||
logUrl: string,
|
||||
}
|
||||
}
|
||||
|
||||
export enum BuildStatus {
|
||||
NULL = 0,
|
||||
SUCCESS = 1,
|
||||
FAILURE = 2,
|
||||
PENDING = 3,
|
||||
RUNNING = 4,
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
import * as grpcWeb from 'grpc-web';
|
||||
|
||||
import {
|
||||
GetGroupReply,
|
||||
GetGroupRequest,
|
||||
GetUserReply,
|
||||
GetUserRequest} from './identity_pb';
|
||||
|
||||
export class IdentityClient {
|
||||
constructor (hostname: string,
|
||||
credentials?: null | { [index: string]: string; },
|
||||
options?: null | { [index: string]: string; });
|
||||
|
||||
getUser(
|
||||
request: GetUserRequest,
|
||||
metadata: grpcWeb.Metadata | undefined,
|
||||
callback: (err: grpcWeb.Error,
|
||||
response: GetUserReply) => void
|
||||
): grpcWeb.ClientReadableStream<GetUserReply>;
|
||||
|
||||
getGroup(
|
||||
request: GetGroupRequest,
|
||||
metadata: grpcWeb.Metadata | undefined,
|
||||
callback: (err: grpcWeb.Error,
|
||||
response: GetGroupReply) => void
|
||||
): grpcWeb.ClientReadableStream<GetGroupReply>;
|
||||
|
||||
}
|
||||
|
||||
export class IdentityPromiseClient {
|
||||
constructor (hostname: string,
|
||||
credentials?: null | { [index: string]: string; },
|
||||
options?: null | { [index: string]: string; });
|
||||
|
||||
getUser(
|
||||
request: GetUserRequest,
|
||||
metadata?: grpcWeb.Metadata
|
||||
): Promise<GetUserReply>;
|
||||
|
||||
getGroup(
|
||||
request: GetGroupRequest,
|
||||
metadata?: grpcWeb.Metadata
|
||||
): Promise<GetGroupReply>;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,233 @@
|
||||
/**
|
||||
* @fileoverview gRPC-Web generated client stub for spotify.backstage.identity.v1
|
||||
* @enhanceable
|
||||
* @public
|
||||
*/
|
||||
|
||||
// GENERATED CODE -- DO NOT EDIT!
|
||||
|
||||
|
||||
|
||||
const grpc = {};
|
||||
grpc.web = require('grpc-web');
|
||||
|
||||
const proto = {};
|
||||
proto.spotify = {};
|
||||
proto.spotify.backstage = {};
|
||||
proto.spotify.backstage.identity = {};
|
||||
proto.spotify.backstage.identity.v1 = require('./identity_pb.js');
|
||||
|
||||
/**
|
||||
* @param {string} hostname
|
||||
* @param {?Object} credentials
|
||||
* @param {?Object} options
|
||||
* @constructor
|
||||
* @struct
|
||||
* @final
|
||||
*/
|
||||
proto.spotify.backstage.identity.v1.IdentityClient =
|
||||
function(hostname, credentials, options) {
|
||||
if (!options) options = {};
|
||||
options['format'] = 'text';
|
||||
|
||||
/**
|
||||
* @private @const {!grpc.web.GrpcWebClientBase} The client
|
||||
*/
|
||||
this.client_ = new grpc.web.GrpcWebClientBase(options);
|
||||
|
||||
/**
|
||||
* @private @const {string} The hostname
|
||||
*/
|
||||
this.hostname_ = hostname;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} hostname
|
||||
* @param {?Object} credentials
|
||||
* @param {?Object} options
|
||||
* @constructor
|
||||
* @struct
|
||||
* @final
|
||||
*/
|
||||
proto.spotify.backstage.identity.v1.IdentityPromiseClient =
|
||||
function(hostname, credentials, options) {
|
||||
if (!options) options = {};
|
||||
options['format'] = 'text';
|
||||
|
||||
/**
|
||||
* @private @const {!grpc.web.GrpcWebClientBase} The client
|
||||
*/
|
||||
this.client_ = new grpc.web.GrpcWebClientBase(options);
|
||||
|
||||
/**
|
||||
* @private @const {string} The hostname
|
||||
*/
|
||||
this.hostname_ = hostname;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {!grpc.web.MethodDescriptor<
|
||||
* !proto.spotify.backstage.identity.v1.GetUserRequest,
|
||||
* !proto.spotify.backstage.identity.v1.GetUserReply>}
|
||||
*/
|
||||
const methodDescriptor_Identity_GetUser = new grpc.web.MethodDescriptor(
|
||||
'/spotify.backstage.identity.v1.Identity/GetUser',
|
||||
grpc.web.MethodType.UNARY,
|
||||
proto.spotify.backstage.identity.v1.GetUserRequest,
|
||||
proto.spotify.backstage.identity.v1.GetUserReply,
|
||||
/**
|
||||
* @param {!proto.spotify.backstage.identity.v1.GetUserRequest} request
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
function(request) {
|
||||
return request.serializeBinary();
|
||||
},
|
||||
proto.spotify.backstage.identity.v1.GetUserReply.deserializeBinary
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {!grpc.web.AbstractClientBase.MethodInfo<
|
||||
* !proto.spotify.backstage.identity.v1.GetUserRequest,
|
||||
* !proto.spotify.backstage.identity.v1.GetUserReply>}
|
||||
*/
|
||||
const methodInfo_Identity_GetUser = new grpc.web.AbstractClientBase.MethodInfo(
|
||||
proto.spotify.backstage.identity.v1.GetUserReply,
|
||||
/**
|
||||
* @param {!proto.spotify.backstage.identity.v1.GetUserRequest} request
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
function(request) {
|
||||
return request.serializeBinary();
|
||||
},
|
||||
proto.spotify.backstage.identity.v1.GetUserReply.deserializeBinary
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.spotify.backstage.identity.v1.GetUserRequest} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @param {function(?grpc.web.Error, ?proto.spotify.backstage.identity.v1.GetUserReply)}
|
||||
* callback The callback function(error, response)
|
||||
* @return {!grpc.web.ClientReadableStream<!proto.spotify.backstage.identity.v1.GetUserReply>|undefined}
|
||||
* The XHR Node Readable Stream
|
||||
*/
|
||||
proto.spotify.backstage.identity.v1.IdentityClient.prototype.getUser =
|
||||
function(request, metadata, callback) {
|
||||
return this.client_.rpcCall(this.hostname_ +
|
||||
'/spotify.backstage.identity.v1.Identity/GetUser',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_Identity_GetUser,
|
||||
callback);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.spotify.backstage.identity.v1.GetUserRequest} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @return {!Promise<!proto.spotify.backstage.identity.v1.GetUserReply>}
|
||||
* A native promise that resolves to the response
|
||||
*/
|
||||
proto.spotify.backstage.identity.v1.IdentityPromiseClient.prototype.getUser =
|
||||
function(request, metadata) {
|
||||
return this.client_.unaryCall(this.hostname_ +
|
||||
'/spotify.backstage.identity.v1.Identity/GetUser',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_Identity_GetUser);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {!grpc.web.MethodDescriptor<
|
||||
* !proto.spotify.backstage.identity.v1.GetGroupRequest,
|
||||
* !proto.spotify.backstage.identity.v1.GetGroupReply>}
|
||||
*/
|
||||
const methodDescriptor_Identity_GetGroup = new grpc.web.MethodDescriptor(
|
||||
'/spotify.backstage.identity.v1.Identity/GetGroup',
|
||||
grpc.web.MethodType.UNARY,
|
||||
proto.spotify.backstage.identity.v1.GetGroupRequest,
|
||||
proto.spotify.backstage.identity.v1.GetGroupReply,
|
||||
/**
|
||||
* @param {!proto.spotify.backstage.identity.v1.GetGroupRequest} request
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
function(request) {
|
||||
return request.serializeBinary();
|
||||
},
|
||||
proto.spotify.backstage.identity.v1.GetGroupReply.deserializeBinary
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {!grpc.web.AbstractClientBase.MethodInfo<
|
||||
* !proto.spotify.backstage.identity.v1.GetGroupRequest,
|
||||
* !proto.spotify.backstage.identity.v1.GetGroupReply>}
|
||||
*/
|
||||
const methodInfo_Identity_GetGroup = new grpc.web.AbstractClientBase.MethodInfo(
|
||||
proto.spotify.backstage.identity.v1.GetGroupReply,
|
||||
/**
|
||||
* @param {!proto.spotify.backstage.identity.v1.GetGroupRequest} request
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
function(request) {
|
||||
return request.serializeBinary();
|
||||
},
|
||||
proto.spotify.backstage.identity.v1.GetGroupReply.deserializeBinary
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.spotify.backstage.identity.v1.GetGroupRequest} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @param {function(?grpc.web.Error, ?proto.spotify.backstage.identity.v1.GetGroupReply)}
|
||||
* callback The callback function(error, response)
|
||||
* @return {!grpc.web.ClientReadableStream<!proto.spotify.backstage.identity.v1.GetGroupReply>|undefined}
|
||||
* The XHR Node Readable Stream
|
||||
*/
|
||||
proto.spotify.backstage.identity.v1.IdentityClient.prototype.getGroup =
|
||||
function(request, metadata, callback) {
|
||||
return this.client_.rpcCall(this.hostname_ +
|
||||
'/spotify.backstage.identity.v1.Identity/GetGroup',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_Identity_GetGroup,
|
||||
callback);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.spotify.backstage.identity.v1.GetGroupRequest} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @return {!Promise<!proto.spotify.backstage.identity.v1.GetGroupReply>}
|
||||
* A native promise that resolves to the response
|
||||
*/
|
||||
proto.spotify.backstage.identity.v1.IdentityPromiseClient.prototype.getGroup =
|
||||
function(request, metadata) {
|
||||
return this.client_.unaryCall(this.hostname_ +
|
||||
'/spotify.backstage.identity.v1.Identity/GetGroup',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_Identity_GetGroup);
|
||||
};
|
||||
|
||||
|
||||
module.exports = proto.spotify.backstage.identity.v1;
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
// package: spotify.backstage.identity.v1
|
||||
// file: identity/v1/identity.proto
|
||||
|
||||
import * as jspb from "google-protobuf";
|
||||
import * as jspb from "google-protobuf"
|
||||
|
||||
export class GetUserRequest extends jspb.Message {
|
||||
getId(): string;
|
||||
@@ -10,8 +7,6 @@ export class GetUserRequest extends jspb.Message {
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): GetUserRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: GetUserRequest): GetUserRequest.AsObject;
|
||||
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||
static serializeBinaryToWriter(message: GetUserRequest, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): GetUserRequest;
|
||||
static deserializeBinaryFromReader(message: GetUserRequest, reader: jspb.BinaryReader): GetUserRequest;
|
||||
@@ -24,21 +19,19 @@ export namespace GetUserRequest {
|
||||
}
|
||||
|
||||
export class GetUserReply extends jspb.Message {
|
||||
hasUser(): boolean;
|
||||
clearUser(): void;
|
||||
getUser(): User | undefined;
|
||||
setUser(value?: User): void;
|
||||
hasUser(): boolean;
|
||||
clearUser(): void;
|
||||
|
||||
clearGroupsList(): void;
|
||||
getGroupsList(): Array<Group>;
|
||||
setGroupsList(value: Array<Group>): void;
|
||||
clearGroupsList(): void;
|
||||
addGroups(value?: Group, index?: number): Group;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): GetUserReply.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: GetUserReply): GetUserReply.AsObject;
|
||||
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||
static serializeBinaryToWriter(message: GetUserReply, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): GetUserReply;
|
||||
static deserializeBinaryFromReader(message: GetUserReply, reader: jspb.BinaryReader): GetUserReply;
|
||||
@@ -58,8 +51,6 @@ export class GetGroupRequest extends jspb.Message {
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): GetGroupRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: GetGroupRequest): GetGroupRequest.AsObject;
|
||||
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||
static serializeBinaryToWriter(message: GetGroupRequest, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): GetGroupRequest;
|
||||
static deserializeBinaryFromReader(message: GetGroupRequest, reader: jspb.BinaryReader): GetGroupRequest;
|
||||
@@ -72,16 +63,14 @@ export namespace GetGroupRequest {
|
||||
}
|
||||
|
||||
export class GetGroupReply extends jspb.Message {
|
||||
hasGroup(): boolean;
|
||||
clearGroup(): void;
|
||||
getGroup(): Group | undefined;
|
||||
setGroup(value?: Group): void;
|
||||
hasGroup(): boolean;
|
||||
clearGroup(): void;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): GetGroupReply.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: GetGroupReply): GetGroupReply.AsObject;
|
||||
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||
static serializeBinaryToWriter(message: GetGroupReply, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): GetGroupReply;
|
||||
static deserializeBinaryFromReader(message: GetGroupReply, reader: jspb.BinaryReader): GetGroupReply;
|
||||
@@ -103,8 +92,6 @@ export class User extends jspb.Message {
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): User.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: User): User.AsObject;
|
||||
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||
static serializeBinaryToWriter(message: User, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): User;
|
||||
static deserializeBinaryFromReader(message: User, reader: jspb.BinaryReader): User;
|
||||
@@ -121,21 +108,19 @@ export class Group extends jspb.Message {
|
||||
getId(): string;
|
||||
setId(value: string): void;
|
||||
|
||||
clearUsersList(): void;
|
||||
getUsersList(): Array<User>;
|
||||
setUsersList(value: Array<User>): void;
|
||||
clearUsersList(): void;
|
||||
addUsers(value?: User, index?: number): User;
|
||||
|
||||
clearGroupsList(): void;
|
||||
getGroupsList(): Array<Group>;
|
||||
setGroupsList(value: Array<Group>): void;
|
||||
clearGroupsList(): void;
|
||||
addGroups(value?: Group, index?: number): Group;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): Group.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: Group): Group.AsObject;
|
||||
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||
static serializeBinaryToWriter(message: Group, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): Group;
|
||||
static deserializeBinaryFromReader(message: Group, reader: jspb.BinaryReader): Group;
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
// package: spotify.backstage.identity.v1
|
||||
// file: identity/v1/identity.proto
|
||||
|
||||
import * as identity_v1_identity_pb from "../../identity/v1/identity_pb";
|
||||
import {grpc} from "@improbable-eng/grpc-web";
|
||||
|
||||
type IdentityGetUser = {
|
||||
readonly methodName: string;
|
||||
readonly service: typeof Identity;
|
||||
readonly requestStream: false;
|
||||
readonly responseStream: false;
|
||||
readonly requestType: typeof identity_v1_identity_pb.GetUserRequest;
|
||||
readonly responseType: typeof identity_v1_identity_pb.GetUserReply;
|
||||
};
|
||||
|
||||
type IdentityGetGroup = {
|
||||
readonly methodName: string;
|
||||
readonly service: typeof Identity;
|
||||
readonly requestStream: false;
|
||||
readonly responseStream: false;
|
||||
readonly requestType: typeof identity_v1_identity_pb.GetGroupRequest;
|
||||
readonly responseType: typeof identity_v1_identity_pb.GetGroupReply;
|
||||
};
|
||||
|
||||
export class Identity {
|
||||
static readonly serviceName: string;
|
||||
static readonly GetUser: IdentityGetUser;
|
||||
static readonly GetGroup: IdentityGetGroup;
|
||||
}
|
||||
|
||||
export type ServiceError = { message: string, code: number; metadata: grpc.Metadata }
|
||||
export type Status = { details: string, code: number; metadata: grpc.Metadata }
|
||||
|
||||
interface UnaryResponse {
|
||||
cancel(): void;
|
||||
}
|
||||
interface ResponseStream<T> {
|
||||
cancel(): void;
|
||||
on(type: 'data', handler: (message: T) => void): ResponseStream<T>;
|
||||
on(type: 'end', handler: (status?: Status) => void): ResponseStream<T>;
|
||||
on(type: 'status', handler: (status: Status) => void): ResponseStream<T>;
|
||||
}
|
||||
interface RequestStream<T> {
|
||||
write(message: T): RequestStream<T>;
|
||||
end(): void;
|
||||
cancel(): void;
|
||||
on(type: 'end', handler: (status?: Status) => void): RequestStream<T>;
|
||||
on(type: 'status', handler: (status: Status) => void): RequestStream<T>;
|
||||
}
|
||||
interface BidirectionalStream<ReqT, ResT> {
|
||||
write(message: ReqT): BidirectionalStream<ReqT, ResT>;
|
||||
end(): void;
|
||||
cancel(): void;
|
||||
on(type: 'data', handler: (message: ResT) => void): BidirectionalStream<ReqT, ResT>;
|
||||
on(type: 'end', handler: (status?: Status) => void): BidirectionalStream<ReqT, ResT>;
|
||||
on(type: 'status', handler: (status: Status) => void): BidirectionalStream<ReqT, ResT>;
|
||||
}
|
||||
|
||||
export class IdentityClient {
|
||||
readonly serviceHost: string;
|
||||
|
||||
constructor(serviceHost: string, options?: grpc.RpcOptions);
|
||||
getUser(
|
||||
requestMessage: identity_v1_identity_pb.GetUserRequest,
|
||||
metadata: grpc.Metadata,
|
||||
callback: (error: ServiceError|null, responseMessage: identity_v1_identity_pb.GetUserReply|null) => void
|
||||
): UnaryResponse;
|
||||
getUser(
|
||||
requestMessage: identity_v1_identity_pb.GetUserRequest,
|
||||
callback: (error: ServiceError|null, responseMessage: identity_v1_identity_pb.GetUserReply|null) => void
|
||||
): UnaryResponse;
|
||||
getGroup(
|
||||
requestMessage: identity_v1_identity_pb.GetGroupRequest,
|
||||
metadata: grpc.Metadata,
|
||||
callback: (error: ServiceError|null, responseMessage: identity_v1_identity_pb.GetGroupReply|null) => void
|
||||
): UnaryResponse;
|
||||
getGroup(
|
||||
requestMessage: identity_v1_identity_pb.GetGroupRequest,
|
||||
callback: (error: ServiceError|null, responseMessage: identity_v1_identity_pb.GetGroupReply|null) => void
|
||||
): UnaryResponse;
|
||||
}
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
// package: spotify.backstage.identity.v1
|
||||
// file: identity/v1/identity.proto
|
||||
|
||||
var identity_v1_identity_pb = require("../../identity/v1/identity_pb");
|
||||
var grpc = require("@improbable-eng/grpc-web").grpc;
|
||||
|
||||
var Identity = (function () {
|
||||
function Identity() {}
|
||||
Identity.serviceName = "spotify.backstage.identity.v1.Identity";
|
||||
return Identity;
|
||||
}());
|
||||
|
||||
Identity.GetUser = {
|
||||
methodName: "GetUser",
|
||||
service: Identity,
|
||||
requestStream: false,
|
||||
responseStream: false,
|
||||
requestType: identity_v1_identity_pb.GetUserRequest,
|
||||
responseType: identity_v1_identity_pb.GetUserReply
|
||||
};
|
||||
|
||||
Identity.GetGroup = {
|
||||
methodName: "GetGroup",
|
||||
service: Identity,
|
||||
requestStream: false,
|
||||
responseStream: false,
|
||||
requestType: identity_v1_identity_pb.GetGroupRequest,
|
||||
responseType: identity_v1_identity_pb.GetGroupReply
|
||||
};
|
||||
|
||||
exports.Identity = Identity;
|
||||
|
||||
function IdentityClient(serviceHost, options) {
|
||||
this.serviceHost = serviceHost;
|
||||
this.options = options || {};
|
||||
}
|
||||
|
||||
IdentityClient.prototype.getUser = function getUser(requestMessage, metadata, callback) {
|
||||
if (arguments.length === 2) {
|
||||
callback = arguments[1];
|
||||
}
|
||||
var client = grpc.unary(Identity.GetUser, {
|
||||
request: requestMessage,
|
||||
host: this.serviceHost,
|
||||
metadata: metadata,
|
||||
transport: this.options.transport,
|
||||
debug: this.options.debug,
|
||||
onEnd: function (response) {
|
||||
if (callback) {
|
||||
if (response.status !== grpc.Code.OK) {
|
||||
var err = new Error(response.statusMessage);
|
||||
err.code = response.status;
|
||||
err.metadata = response.trailers;
|
||||
callback(err, null);
|
||||
} else {
|
||||
callback(null, response.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return {
|
||||
cancel: function () {
|
||||
callback = null;
|
||||
client.close();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
IdentityClient.prototype.getGroup = function getGroup(requestMessage, metadata, callback) {
|
||||
if (arguments.length === 2) {
|
||||
callback = arguments[1];
|
||||
}
|
||||
var client = grpc.unary(Identity.GetGroup, {
|
||||
request: requestMessage,
|
||||
host: this.serviceHost,
|
||||
metadata: metadata,
|
||||
transport: this.options.transport,
|
||||
debug: this.options.debug,
|
||||
onEnd: function (response) {
|
||||
if (callback) {
|
||||
if (response.status !== grpc.Code.OK) {
|
||||
var err = new Error(response.statusMessage);
|
||||
err.code = response.status;
|
||||
err.metadata = response.trailers;
|
||||
callback(err, null);
|
||||
} else {
|
||||
callback(null, response.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return {
|
||||
cancel: function () {
|
||||
callback = null;
|
||||
client.close();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
exports.IdentityClient = IdentityClient;
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
import * as grpcWeb from 'grpc-web';
|
||||
|
||||
import {
|
||||
CreateEntityReply,
|
||||
CreateEntityRequest,
|
||||
GetEntityReply,
|
||||
GetEntityRequest,
|
||||
GetFactReply,
|
||||
GetFactRequest,
|
||||
ListEntitiesReply,
|
||||
ListEntitiesRequest,
|
||||
SetFactReply,
|
||||
SetFactRequest} from './inventory_pb';
|
||||
|
||||
export class InventoryClient {
|
||||
constructor (hostname: string,
|
||||
credentials?: null | { [index: string]: string; },
|
||||
options?: null | { [index: string]: string; });
|
||||
|
||||
listEntities(
|
||||
request: ListEntitiesRequest,
|
||||
metadata: grpcWeb.Metadata | undefined,
|
||||
callback: (err: grpcWeb.Error,
|
||||
response: ListEntitiesReply) => void
|
||||
): grpcWeb.ClientReadableStream<ListEntitiesReply>;
|
||||
|
||||
getEntity(
|
||||
request: GetEntityRequest,
|
||||
metadata: grpcWeb.Metadata | undefined,
|
||||
callback: (err: grpcWeb.Error,
|
||||
response: GetEntityReply) => void
|
||||
): grpcWeb.ClientReadableStream<GetEntityReply>;
|
||||
|
||||
createEntity(
|
||||
request: CreateEntityRequest,
|
||||
metadata: grpcWeb.Metadata | undefined,
|
||||
callback: (err: grpcWeb.Error,
|
||||
response: CreateEntityReply) => void
|
||||
): grpcWeb.ClientReadableStream<CreateEntityReply>;
|
||||
|
||||
setFact(
|
||||
request: SetFactRequest,
|
||||
metadata: grpcWeb.Metadata | undefined,
|
||||
callback: (err: grpcWeb.Error,
|
||||
response: SetFactReply) => void
|
||||
): grpcWeb.ClientReadableStream<SetFactReply>;
|
||||
|
||||
getFact(
|
||||
request: GetFactRequest,
|
||||
metadata: grpcWeb.Metadata | undefined,
|
||||
callback: (err: grpcWeb.Error,
|
||||
response: GetFactReply) => void
|
||||
): grpcWeb.ClientReadableStream<GetFactReply>;
|
||||
|
||||
}
|
||||
|
||||
export class InventoryPromiseClient {
|
||||
constructor (hostname: string,
|
||||
credentials?: null | { [index: string]: string; },
|
||||
options?: null | { [index: string]: string; });
|
||||
|
||||
listEntities(
|
||||
request: ListEntitiesRequest,
|
||||
metadata?: grpcWeb.Metadata
|
||||
): Promise<ListEntitiesReply>;
|
||||
|
||||
getEntity(
|
||||
request: GetEntityRequest,
|
||||
metadata?: grpcWeb.Metadata
|
||||
): Promise<GetEntityReply>;
|
||||
|
||||
createEntity(
|
||||
request: CreateEntityRequest,
|
||||
metadata?: grpcWeb.Metadata
|
||||
): Promise<CreateEntityReply>;
|
||||
|
||||
setFact(
|
||||
request: SetFactRequest,
|
||||
metadata?: grpcWeb.Metadata
|
||||
): Promise<SetFactReply>;
|
||||
|
||||
getFact(
|
||||
request: GetFactRequest,
|
||||
metadata?: grpcWeb.Metadata
|
||||
): Promise<GetFactReply>;
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,473 @@
|
||||
/**
|
||||
* @fileoverview gRPC-Web generated client stub for spotify.backstage.inventory.v1
|
||||
* @enhanceable
|
||||
* @public
|
||||
*/
|
||||
|
||||
// GENERATED CODE -- DO NOT EDIT!
|
||||
|
||||
|
||||
|
||||
const grpc = {};
|
||||
grpc.web = require('grpc-web');
|
||||
|
||||
const proto = {};
|
||||
proto.spotify = {};
|
||||
proto.spotify.backstage = {};
|
||||
proto.spotify.backstage.inventory = {};
|
||||
proto.spotify.backstage.inventory.v1 = require('./inventory_pb.js');
|
||||
|
||||
/**
|
||||
* @param {string} hostname
|
||||
* @param {?Object} credentials
|
||||
* @param {?Object} options
|
||||
* @constructor
|
||||
* @struct
|
||||
* @final
|
||||
*/
|
||||
proto.spotify.backstage.inventory.v1.InventoryClient =
|
||||
function(hostname, credentials, options) {
|
||||
if (!options) options = {};
|
||||
options['format'] = 'text';
|
||||
|
||||
/**
|
||||
* @private @const {!grpc.web.GrpcWebClientBase} The client
|
||||
*/
|
||||
this.client_ = new grpc.web.GrpcWebClientBase(options);
|
||||
|
||||
/**
|
||||
* @private @const {string} The hostname
|
||||
*/
|
||||
this.hostname_ = hostname;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {string} hostname
|
||||
* @param {?Object} credentials
|
||||
* @param {?Object} options
|
||||
* @constructor
|
||||
* @struct
|
||||
* @final
|
||||
*/
|
||||
proto.spotify.backstage.inventory.v1.InventoryPromiseClient =
|
||||
function(hostname, credentials, options) {
|
||||
if (!options) options = {};
|
||||
options['format'] = 'text';
|
||||
|
||||
/**
|
||||
* @private @const {!grpc.web.GrpcWebClientBase} The client
|
||||
*/
|
||||
this.client_ = new grpc.web.GrpcWebClientBase(options);
|
||||
|
||||
/**
|
||||
* @private @const {string} The hostname
|
||||
*/
|
||||
this.hostname_ = hostname;
|
||||
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {!grpc.web.MethodDescriptor<
|
||||
* !proto.spotify.backstage.inventory.v1.ListEntitiesRequest,
|
||||
* !proto.spotify.backstage.inventory.v1.ListEntitiesReply>}
|
||||
*/
|
||||
const methodDescriptor_Inventory_ListEntities = new grpc.web.MethodDescriptor(
|
||||
'/spotify.backstage.inventory.v1.Inventory/ListEntities',
|
||||
grpc.web.MethodType.UNARY,
|
||||
proto.spotify.backstage.inventory.v1.ListEntitiesRequest,
|
||||
proto.spotify.backstage.inventory.v1.ListEntitiesReply,
|
||||
/**
|
||||
* @param {!proto.spotify.backstage.inventory.v1.ListEntitiesRequest} request
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
function(request) {
|
||||
return request.serializeBinary();
|
||||
},
|
||||
proto.spotify.backstage.inventory.v1.ListEntitiesReply.deserializeBinary
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {!grpc.web.AbstractClientBase.MethodInfo<
|
||||
* !proto.spotify.backstage.inventory.v1.ListEntitiesRequest,
|
||||
* !proto.spotify.backstage.inventory.v1.ListEntitiesReply>}
|
||||
*/
|
||||
const methodInfo_Inventory_ListEntities = new grpc.web.AbstractClientBase.MethodInfo(
|
||||
proto.spotify.backstage.inventory.v1.ListEntitiesReply,
|
||||
/**
|
||||
* @param {!proto.spotify.backstage.inventory.v1.ListEntitiesRequest} request
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
function(request) {
|
||||
return request.serializeBinary();
|
||||
},
|
||||
proto.spotify.backstage.inventory.v1.ListEntitiesReply.deserializeBinary
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.spotify.backstage.inventory.v1.ListEntitiesRequest} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @param {function(?grpc.web.Error, ?proto.spotify.backstage.inventory.v1.ListEntitiesReply)}
|
||||
* callback The callback function(error, response)
|
||||
* @return {!grpc.web.ClientReadableStream<!proto.spotify.backstage.inventory.v1.ListEntitiesReply>|undefined}
|
||||
* The XHR Node Readable Stream
|
||||
*/
|
||||
proto.spotify.backstage.inventory.v1.InventoryClient.prototype.listEntities =
|
||||
function(request, metadata, callback) {
|
||||
return this.client_.rpcCall(this.hostname_ +
|
||||
'/spotify.backstage.inventory.v1.Inventory/ListEntities',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_Inventory_ListEntities,
|
||||
callback);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.spotify.backstage.inventory.v1.ListEntitiesRequest} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @return {!Promise<!proto.spotify.backstage.inventory.v1.ListEntitiesReply>}
|
||||
* A native promise that resolves to the response
|
||||
*/
|
||||
proto.spotify.backstage.inventory.v1.InventoryPromiseClient.prototype.listEntities =
|
||||
function(request, metadata) {
|
||||
return this.client_.unaryCall(this.hostname_ +
|
||||
'/spotify.backstage.inventory.v1.Inventory/ListEntities',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_Inventory_ListEntities);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {!grpc.web.MethodDescriptor<
|
||||
* !proto.spotify.backstage.inventory.v1.GetEntityRequest,
|
||||
* !proto.spotify.backstage.inventory.v1.GetEntityReply>}
|
||||
*/
|
||||
const methodDescriptor_Inventory_GetEntity = new grpc.web.MethodDescriptor(
|
||||
'/spotify.backstage.inventory.v1.Inventory/GetEntity',
|
||||
grpc.web.MethodType.UNARY,
|
||||
proto.spotify.backstage.inventory.v1.GetEntityRequest,
|
||||
proto.spotify.backstage.inventory.v1.GetEntityReply,
|
||||
/**
|
||||
* @param {!proto.spotify.backstage.inventory.v1.GetEntityRequest} request
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
function(request) {
|
||||
return request.serializeBinary();
|
||||
},
|
||||
proto.spotify.backstage.inventory.v1.GetEntityReply.deserializeBinary
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {!grpc.web.AbstractClientBase.MethodInfo<
|
||||
* !proto.spotify.backstage.inventory.v1.GetEntityRequest,
|
||||
* !proto.spotify.backstage.inventory.v1.GetEntityReply>}
|
||||
*/
|
||||
const methodInfo_Inventory_GetEntity = new grpc.web.AbstractClientBase.MethodInfo(
|
||||
proto.spotify.backstage.inventory.v1.GetEntityReply,
|
||||
/**
|
||||
* @param {!proto.spotify.backstage.inventory.v1.GetEntityRequest} request
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
function(request) {
|
||||
return request.serializeBinary();
|
||||
},
|
||||
proto.spotify.backstage.inventory.v1.GetEntityReply.deserializeBinary
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.spotify.backstage.inventory.v1.GetEntityRequest} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @param {function(?grpc.web.Error, ?proto.spotify.backstage.inventory.v1.GetEntityReply)}
|
||||
* callback The callback function(error, response)
|
||||
* @return {!grpc.web.ClientReadableStream<!proto.spotify.backstage.inventory.v1.GetEntityReply>|undefined}
|
||||
* The XHR Node Readable Stream
|
||||
*/
|
||||
proto.spotify.backstage.inventory.v1.InventoryClient.prototype.getEntity =
|
||||
function(request, metadata, callback) {
|
||||
return this.client_.rpcCall(this.hostname_ +
|
||||
'/spotify.backstage.inventory.v1.Inventory/GetEntity',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_Inventory_GetEntity,
|
||||
callback);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.spotify.backstage.inventory.v1.GetEntityRequest} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @return {!Promise<!proto.spotify.backstage.inventory.v1.GetEntityReply>}
|
||||
* A native promise that resolves to the response
|
||||
*/
|
||||
proto.spotify.backstage.inventory.v1.InventoryPromiseClient.prototype.getEntity =
|
||||
function(request, metadata) {
|
||||
return this.client_.unaryCall(this.hostname_ +
|
||||
'/spotify.backstage.inventory.v1.Inventory/GetEntity',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_Inventory_GetEntity);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {!grpc.web.MethodDescriptor<
|
||||
* !proto.spotify.backstage.inventory.v1.CreateEntityRequest,
|
||||
* !proto.spotify.backstage.inventory.v1.CreateEntityReply>}
|
||||
*/
|
||||
const methodDescriptor_Inventory_CreateEntity = new grpc.web.MethodDescriptor(
|
||||
'/spotify.backstage.inventory.v1.Inventory/CreateEntity',
|
||||
grpc.web.MethodType.UNARY,
|
||||
proto.spotify.backstage.inventory.v1.CreateEntityRequest,
|
||||
proto.spotify.backstage.inventory.v1.CreateEntityReply,
|
||||
/**
|
||||
* @param {!proto.spotify.backstage.inventory.v1.CreateEntityRequest} request
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
function(request) {
|
||||
return request.serializeBinary();
|
||||
},
|
||||
proto.spotify.backstage.inventory.v1.CreateEntityReply.deserializeBinary
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {!grpc.web.AbstractClientBase.MethodInfo<
|
||||
* !proto.spotify.backstage.inventory.v1.CreateEntityRequest,
|
||||
* !proto.spotify.backstage.inventory.v1.CreateEntityReply>}
|
||||
*/
|
||||
const methodInfo_Inventory_CreateEntity = new grpc.web.AbstractClientBase.MethodInfo(
|
||||
proto.spotify.backstage.inventory.v1.CreateEntityReply,
|
||||
/**
|
||||
* @param {!proto.spotify.backstage.inventory.v1.CreateEntityRequest} request
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
function(request) {
|
||||
return request.serializeBinary();
|
||||
},
|
||||
proto.spotify.backstage.inventory.v1.CreateEntityReply.deserializeBinary
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.spotify.backstage.inventory.v1.CreateEntityRequest} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @param {function(?grpc.web.Error, ?proto.spotify.backstage.inventory.v1.CreateEntityReply)}
|
||||
* callback The callback function(error, response)
|
||||
* @return {!grpc.web.ClientReadableStream<!proto.spotify.backstage.inventory.v1.CreateEntityReply>|undefined}
|
||||
* The XHR Node Readable Stream
|
||||
*/
|
||||
proto.spotify.backstage.inventory.v1.InventoryClient.prototype.createEntity =
|
||||
function(request, metadata, callback) {
|
||||
return this.client_.rpcCall(this.hostname_ +
|
||||
'/spotify.backstage.inventory.v1.Inventory/CreateEntity',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_Inventory_CreateEntity,
|
||||
callback);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.spotify.backstage.inventory.v1.CreateEntityRequest} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @return {!Promise<!proto.spotify.backstage.inventory.v1.CreateEntityReply>}
|
||||
* A native promise that resolves to the response
|
||||
*/
|
||||
proto.spotify.backstage.inventory.v1.InventoryPromiseClient.prototype.createEntity =
|
||||
function(request, metadata) {
|
||||
return this.client_.unaryCall(this.hostname_ +
|
||||
'/spotify.backstage.inventory.v1.Inventory/CreateEntity',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_Inventory_CreateEntity);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {!grpc.web.MethodDescriptor<
|
||||
* !proto.spotify.backstage.inventory.v1.SetFactRequest,
|
||||
* !proto.spotify.backstage.inventory.v1.SetFactReply>}
|
||||
*/
|
||||
const methodDescriptor_Inventory_SetFact = new grpc.web.MethodDescriptor(
|
||||
'/spotify.backstage.inventory.v1.Inventory/SetFact',
|
||||
grpc.web.MethodType.UNARY,
|
||||
proto.spotify.backstage.inventory.v1.SetFactRequest,
|
||||
proto.spotify.backstage.inventory.v1.SetFactReply,
|
||||
/**
|
||||
* @param {!proto.spotify.backstage.inventory.v1.SetFactRequest} request
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
function(request) {
|
||||
return request.serializeBinary();
|
||||
},
|
||||
proto.spotify.backstage.inventory.v1.SetFactReply.deserializeBinary
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {!grpc.web.AbstractClientBase.MethodInfo<
|
||||
* !proto.spotify.backstage.inventory.v1.SetFactRequest,
|
||||
* !proto.spotify.backstage.inventory.v1.SetFactReply>}
|
||||
*/
|
||||
const methodInfo_Inventory_SetFact = new grpc.web.AbstractClientBase.MethodInfo(
|
||||
proto.spotify.backstage.inventory.v1.SetFactReply,
|
||||
/**
|
||||
* @param {!proto.spotify.backstage.inventory.v1.SetFactRequest} request
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
function(request) {
|
||||
return request.serializeBinary();
|
||||
},
|
||||
proto.spotify.backstage.inventory.v1.SetFactReply.deserializeBinary
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.spotify.backstage.inventory.v1.SetFactRequest} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @param {function(?grpc.web.Error, ?proto.spotify.backstage.inventory.v1.SetFactReply)}
|
||||
* callback The callback function(error, response)
|
||||
* @return {!grpc.web.ClientReadableStream<!proto.spotify.backstage.inventory.v1.SetFactReply>|undefined}
|
||||
* The XHR Node Readable Stream
|
||||
*/
|
||||
proto.spotify.backstage.inventory.v1.InventoryClient.prototype.setFact =
|
||||
function(request, metadata, callback) {
|
||||
return this.client_.rpcCall(this.hostname_ +
|
||||
'/spotify.backstage.inventory.v1.Inventory/SetFact',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_Inventory_SetFact,
|
||||
callback);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.spotify.backstage.inventory.v1.SetFactRequest} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @return {!Promise<!proto.spotify.backstage.inventory.v1.SetFactReply>}
|
||||
* A native promise that resolves to the response
|
||||
*/
|
||||
proto.spotify.backstage.inventory.v1.InventoryPromiseClient.prototype.setFact =
|
||||
function(request, metadata) {
|
||||
return this.client_.unaryCall(this.hostname_ +
|
||||
'/spotify.backstage.inventory.v1.Inventory/SetFact',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_Inventory_SetFact);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {!grpc.web.MethodDescriptor<
|
||||
* !proto.spotify.backstage.inventory.v1.GetFactRequest,
|
||||
* !proto.spotify.backstage.inventory.v1.GetFactReply>}
|
||||
*/
|
||||
const methodDescriptor_Inventory_GetFact = new grpc.web.MethodDescriptor(
|
||||
'/spotify.backstage.inventory.v1.Inventory/GetFact',
|
||||
grpc.web.MethodType.UNARY,
|
||||
proto.spotify.backstage.inventory.v1.GetFactRequest,
|
||||
proto.spotify.backstage.inventory.v1.GetFactReply,
|
||||
/**
|
||||
* @param {!proto.spotify.backstage.inventory.v1.GetFactRequest} request
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
function(request) {
|
||||
return request.serializeBinary();
|
||||
},
|
||||
proto.spotify.backstage.inventory.v1.GetFactReply.deserializeBinary
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @const
|
||||
* @type {!grpc.web.AbstractClientBase.MethodInfo<
|
||||
* !proto.spotify.backstage.inventory.v1.GetFactRequest,
|
||||
* !proto.spotify.backstage.inventory.v1.GetFactReply>}
|
||||
*/
|
||||
const methodInfo_Inventory_GetFact = new grpc.web.AbstractClientBase.MethodInfo(
|
||||
proto.spotify.backstage.inventory.v1.GetFactReply,
|
||||
/**
|
||||
* @param {!proto.spotify.backstage.inventory.v1.GetFactRequest} request
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
function(request) {
|
||||
return request.serializeBinary();
|
||||
},
|
||||
proto.spotify.backstage.inventory.v1.GetFactReply.deserializeBinary
|
||||
);
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.spotify.backstage.inventory.v1.GetFactRequest} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @param {function(?grpc.web.Error, ?proto.spotify.backstage.inventory.v1.GetFactReply)}
|
||||
* callback The callback function(error, response)
|
||||
* @return {!grpc.web.ClientReadableStream<!proto.spotify.backstage.inventory.v1.GetFactReply>|undefined}
|
||||
* The XHR Node Readable Stream
|
||||
*/
|
||||
proto.spotify.backstage.inventory.v1.InventoryClient.prototype.getFact =
|
||||
function(request, metadata, callback) {
|
||||
return this.client_.rpcCall(this.hostname_ +
|
||||
'/spotify.backstage.inventory.v1.Inventory/GetFact',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_Inventory_GetFact,
|
||||
callback);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {!proto.spotify.backstage.inventory.v1.GetFactRequest} request The
|
||||
* request proto
|
||||
* @param {?Object<string, string>} metadata User defined
|
||||
* call metadata
|
||||
* @return {!Promise<!proto.spotify.backstage.inventory.v1.GetFactReply>}
|
||||
* A native promise that resolves to the response
|
||||
*/
|
||||
proto.spotify.backstage.inventory.v1.InventoryPromiseClient.prototype.getFact =
|
||||
function(request, metadata) {
|
||||
return this.client_.unaryCall(this.hostname_ +
|
||||
'/spotify.backstage.inventory.v1.Inventory/GetFact',
|
||||
request,
|
||||
metadata || {},
|
||||
methodDescriptor_Inventory_GetFact);
|
||||
};
|
||||
|
||||
|
||||
module.exports = proto.spotify.backstage.inventory.v1;
|
||||
|
||||
@@ -1,24 +1,57 @@
|
||||
// package: spotify.backstage.inventory.v1
|
||||
// file: inventory/v1/inventory.proto
|
||||
import * as jspb from "google-protobuf"
|
||||
|
||||
import * as jspb from "google-protobuf";
|
||||
export class ListEntitiesRequest extends jspb.Message {
|
||||
getUriprefix(): string;
|
||||
setUriprefix(value: string): void;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): ListEntitiesRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: ListEntitiesRequest): ListEntitiesRequest.AsObject;
|
||||
static serializeBinaryToWriter(message: ListEntitiesRequest, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): ListEntitiesRequest;
|
||||
static deserializeBinaryFromReader(message: ListEntitiesRequest, reader: jspb.BinaryReader): ListEntitiesRequest;
|
||||
}
|
||||
|
||||
export namespace ListEntitiesRequest {
|
||||
export type AsObject = {
|
||||
uriprefix: string,
|
||||
}
|
||||
}
|
||||
|
||||
export class ListEntitiesReply extends jspb.Message {
|
||||
getEntitiesList(): Array<Entity>;
|
||||
setEntitiesList(value: Array<Entity>): void;
|
||||
clearEntitiesList(): void;
|
||||
addEntities(value?: Entity, index?: number): Entity;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): ListEntitiesReply.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: ListEntitiesReply): ListEntitiesReply.AsObject;
|
||||
static serializeBinaryToWriter(message: ListEntitiesReply, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): ListEntitiesReply;
|
||||
static deserializeBinaryFromReader(message: ListEntitiesReply, reader: jspb.BinaryReader): ListEntitiesReply;
|
||||
}
|
||||
|
||||
export namespace ListEntitiesReply {
|
||||
export type AsObject = {
|
||||
entitiesList: Array<Entity.AsObject>,
|
||||
}
|
||||
}
|
||||
|
||||
export class GetEntityRequest extends jspb.Message {
|
||||
hasEntity(): boolean;
|
||||
clearEntity(): void;
|
||||
getEntity(): Entity | undefined;
|
||||
setEntity(value?: Entity): void;
|
||||
hasEntity(): boolean;
|
||||
clearEntity(): void;
|
||||
|
||||
clearIncludeFactsList(): void;
|
||||
getIncludeFactsList(): Array<string>;
|
||||
setIncludeFactsList(value: Array<string>): void;
|
||||
addIncludeFacts(value: string, index?: number): string;
|
||||
clearIncludeFactsList(): void;
|
||||
addIncludeFacts(value: string, index?: number): void;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): GetEntityRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: GetEntityRequest): GetEntityRequest.AsObject;
|
||||
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||
static serializeBinaryToWriter(message: GetEntityRequest, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): GetEntityRequest;
|
||||
static deserializeBinaryFromReader(message: GetEntityRequest, reader: jspb.BinaryReader): GetEntityRequest;
|
||||
@@ -32,21 +65,19 @@ export namespace GetEntityRequest {
|
||||
}
|
||||
|
||||
export class GetEntityReply extends jspb.Message {
|
||||
hasEntity(): boolean;
|
||||
clearEntity(): void;
|
||||
getEntity(): Entity | undefined;
|
||||
setEntity(value?: Entity): void;
|
||||
hasEntity(): boolean;
|
||||
clearEntity(): void;
|
||||
|
||||
clearFactsList(): void;
|
||||
getFactsList(): Array<Fact>;
|
||||
setFactsList(value: Array<Fact>): void;
|
||||
clearFactsList(): void;
|
||||
addFacts(value?: Fact, index?: number): Fact;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): GetEntityReply.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: GetEntityReply): GetEntityReply.AsObject;
|
||||
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||
static serializeBinaryToWriter(message: GetEntityReply, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): GetEntityReply;
|
||||
static deserializeBinaryFromReader(message: GetEntityReply, reader: jspb.BinaryReader): GetEntityReply;
|
||||
@@ -60,16 +91,14 @@ export namespace GetEntityReply {
|
||||
}
|
||||
|
||||
export class CreateEntityRequest extends jspb.Message {
|
||||
hasEntity(): boolean;
|
||||
clearEntity(): void;
|
||||
getEntity(): Entity | undefined;
|
||||
setEntity(value?: Entity): void;
|
||||
hasEntity(): boolean;
|
||||
clearEntity(): void;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): CreateEntityRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: CreateEntityRequest): CreateEntityRequest.AsObject;
|
||||
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||
static serializeBinaryToWriter(message: CreateEntityRequest, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): CreateEntityRequest;
|
||||
static deserializeBinaryFromReader(message: CreateEntityRequest, reader: jspb.BinaryReader): CreateEntityRequest;
|
||||
@@ -82,16 +111,14 @@ export namespace CreateEntityRequest {
|
||||
}
|
||||
|
||||
export class CreateEntityReply extends jspb.Message {
|
||||
hasEntity(): boolean;
|
||||
clearEntity(): void;
|
||||
getEntity(): Entity | undefined;
|
||||
setEntity(value?: Entity): void;
|
||||
hasEntity(): boolean;
|
||||
clearEntity(): void;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): CreateEntityReply.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: CreateEntityReply): CreateEntityReply.AsObject;
|
||||
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||
static serializeBinaryToWriter(message: CreateEntityReply, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): CreateEntityReply;
|
||||
static deserializeBinaryFromReader(message: CreateEntityReply, reader: jspb.BinaryReader): CreateEntityReply;
|
||||
@@ -103,6 +130,94 @@ export namespace CreateEntityReply {
|
||||
}
|
||||
}
|
||||
|
||||
export class SetFactRequest extends jspb.Message {
|
||||
getEntityuri(): string;
|
||||
setEntityuri(value: string): void;
|
||||
|
||||
getName(): string;
|
||||
setName(value: string): void;
|
||||
|
||||
getValue(): string;
|
||||
setValue(value: string): void;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): SetFactRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: SetFactRequest): SetFactRequest.AsObject;
|
||||
static serializeBinaryToWriter(message: SetFactRequest, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): SetFactRequest;
|
||||
static deserializeBinaryFromReader(message: SetFactRequest, reader: jspb.BinaryReader): SetFactRequest;
|
||||
}
|
||||
|
||||
export namespace SetFactRequest {
|
||||
export type AsObject = {
|
||||
entityuri: string,
|
||||
name: string,
|
||||
value: string,
|
||||
}
|
||||
}
|
||||
|
||||
export class SetFactReply extends jspb.Message {
|
||||
getFact(): Fact | undefined;
|
||||
setFact(value?: Fact): void;
|
||||
hasFact(): boolean;
|
||||
clearFact(): void;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): SetFactReply.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: SetFactReply): SetFactReply.AsObject;
|
||||
static serializeBinaryToWriter(message: SetFactReply, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): SetFactReply;
|
||||
static deserializeBinaryFromReader(message: SetFactReply, reader: jspb.BinaryReader): SetFactReply;
|
||||
}
|
||||
|
||||
export namespace SetFactReply {
|
||||
export type AsObject = {
|
||||
fact?: Fact.AsObject,
|
||||
}
|
||||
}
|
||||
|
||||
export class GetFactRequest extends jspb.Message {
|
||||
getEntityuri(): string;
|
||||
setEntityuri(value: string): void;
|
||||
|
||||
getName(): string;
|
||||
setName(value: string): void;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): GetFactRequest.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: GetFactRequest): GetFactRequest.AsObject;
|
||||
static serializeBinaryToWriter(message: GetFactRequest, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): GetFactRequest;
|
||||
static deserializeBinaryFromReader(message: GetFactRequest, reader: jspb.BinaryReader): GetFactRequest;
|
||||
}
|
||||
|
||||
export namespace GetFactRequest {
|
||||
export type AsObject = {
|
||||
entityuri: string,
|
||||
name: string,
|
||||
}
|
||||
}
|
||||
|
||||
export class GetFactReply extends jspb.Message {
|
||||
getFact(): Fact | undefined;
|
||||
setFact(value?: Fact): void;
|
||||
hasFact(): boolean;
|
||||
clearFact(): void;
|
||||
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): GetFactReply.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: GetFactReply): GetFactReply.AsObject;
|
||||
static serializeBinaryToWriter(message: GetFactReply, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): GetFactReply;
|
||||
static deserializeBinaryFromReader(message: GetFactReply, reader: jspb.BinaryReader): GetFactReply;
|
||||
}
|
||||
|
||||
export namespace GetFactReply {
|
||||
export type AsObject = {
|
||||
fact?: Fact.AsObject,
|
||||
}
|
||||
}
|
||||
|
||||
export class Entity extends jspb.Message {
|
||||
getUri(): string;
|
||||
setUri(value: string): void;
|
||||
@@ -110,8 +225,6 @@ export class Entity extends jspb.Message {
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): Entity.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: Entity): Entity.AsObject;
|
||||
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||
static serializeBinaryToWriter(message: Entity, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): Entity;
|
||||
static deserializeBinaryFromReader(message: Entity, reader: jspb.BinaryReader): Entity;
|
||||
@@ -133,8 +246,6 @@ export class Fact extends jspb.Message {
|
||||
serializeBinary(): Uint8Array;
|
||||
toObject(includeInstance?: boolean): Fact.AsObject;
|
||||
static toObject(includeInstance: boolean, msg: Fact): Fact.AsObject;
|
||||
static extensions: {[key: number]: jspb.ExtensionFieldInfo<jspb.Message>};
|
||||
static extensionsBinary: {[key: number]: jspb.ExtensionFieldBinaryInfo<jspb.Message>};
|
||||
static serializeBinaryToWriter(message: Fact, writer: jspb.BinaryWriter): void;
|
||||
static deserializeBinary(bytes: Uint8Array): Fact;
|
||||
static deserializeBinaryFromReader(message: Fact, reader: jspb.BinaryReader): Fact;
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
// package: spotify.backstage.inventory.v1
|
||||
// file: inventory/v1/inventory.proto
|
||||
|
||||
import * as inventory_v1_inventory_pb from "../../inventory/v1/inventory_pb";
|
||||
import {grpc} from "@improbable-eng/grpc-web";
|
||||
|
||||
type InventoryGetEntity = {
|
||||
readonly methodName: string;
|
||||
readonly service: typeof Inventory;
|
||||
readonly requestStream: false;
|
||||
readonly responseStream: false;
|
||||
readonly requestType: typeof inventory_v1_inventory_pb.GetEntityRequest;
|
||||
readonly responseType: typeof inventory_v1_inventory_pb.GetEntityReply;
|
||||
};
|
||||
|
||||
type InventoryCreateEntity = {
|
||||
readonly methodName: string;
|
||||
readonly service: typeof Inventory;
|
||||
readonly requestStream: false;
|
||||
readonly responseStream: false;
|
||||
readonly requestType: typeof inventory_v1_inventory_pb.CreateEntityRequest;
|
||||
readonly responseType: typeof inventory_v1_inventory_pb.CreateEntityReply;
|
||||
};
|
||||
|
||||
export class Inventory {
|
||||
static readonly serviceName: string;
|
||||
static readonly GetEntity: InventoryGetEntity;
|
||||
static readonly CreateEntity: InventoryCreateEntity;
|
||||
}
|
||||
|
||||
export type ServiceError = { message: string, code: number; metadata: grpc.Metadata }
|
||||
export type Status = { details: string, code: number; metadata: grpc.Metadata }
|
||||
|
||||
interface UnaryResponse {
|
||||
cancel(): void;
|
||||
}
|
||||
interface ResponseStream<T> {
|
||||
cancel(): void;
|
||||
on(type: 'data', handler: (message: T) => void): ResponseStream<T>;
|
||||
on(type: 'end', handler: (status?: Status) => void): ResponseStream<T>;
|
||||
on(type: 'status', handler: (status: Status) => void): ResponseStream<T>;
|
||||
}
|
||||
interface RequestStream<T> {
|
||||
write(message: T): RequestStream<T>;
|
||||
end(): void;
|
||||
cancel(): void;
|
||||
on(type: 'end', handler: (status?: Status) => void): RequestStream<T>;
|
||||
on(type: 'status', handler: (status: Status) => void): RequestStream<T>;
|
||||
}
|
||||
interface BidirectionalStream<ReqT, ResT> {
|
||||
write(message: ReqT): BidirectionalStream<ReqT, ResT>;
|
||||
end(): void;
|
||||
cancel(): void;
|
||||
on(type: 'data', handler: (message: ResT) => void): BidirectionalStream<ReqT, ResT>;
|
||||
on(type: 'end', handler: (status?: Status) => void): BidirectionalStream<ReqT, ResT>;
|
||||
on(type: 'status', handler: (status: Status) => void): BidirectionalStream<ReqT, ResT>;
|
||||
}
|
||||
|
||||
export class InventoryClient {
|
||||
readonly serviceHost: string;
|
||||
|
||||
constructor(serviceHost: string, options?: grpc.RpcOptions);
|
||||
getEntity(
|
||||
requestMessage: inventory_v1_inventory_pb.GetEntityRequest,
|
||||
metadata: grpc.Metadata,
|
||||
callback: (error: ServiceError|null, responseMessage: inventory_v1_inventory_pb.GetEntityReply|null) => void
|
||||
): UnaryResponse;
|
||||
getEntity(
|
||||
requestMessage: inventory_v1_inventory_pb.GetEntityRequest,
|
||||
callback: (error: ServiceError|null, responseMessage: inventory_v1_inventory_pb.GetEntityReply|null) => void
|
||||
): UnaryResponse;
|
||||
createEntity(
|
||||
requestMessage: inventory_v1_inventory_pb.CreateEntityRequest,
|
||||
metadata: grpc.Metadata,
|
||||
callback: (error: ServiceError|null, responseMessage: inventory_v1_inventory_pb.CreateEntityReply|null) => void
|
||||
): UnaryResponse;
|
||||
createEntity(
|
||||
requestMessage: inventory_v1_inventory_pb.CreateEntityRequest,
|
||||
callback: (error: ServiceError|null, responseMessage: inventory_v1_inventory_pb.CreateEntityReply|null) => void
|
||||
): UnaryResponse;
|
||||
}
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
// package: spotify.backstage.inventory.v1
|
||||
// file: inventory/v1/inventory.proto
|
||||
|
||||
var inventory_v1_inventory_pb = require("../../inventory/v1/inventory_pb");
|
||||
var grpc = require("@improbable-eng/grpc-web").grpc;
|
||||
|
||||
var Inventory = (function () {
|
||||
function Inventory() {}
|
||||
Inventory.serviceName = "spotify.backstage.inventory.v1.Inventory";
|
||||
return Inventory;
|
||||
}());
|
||||
|
||||
Inventory.GetEntity = {
|
||||
methodName: "GetEntity",
|
||||
service: Inventory,
|
||||
requestStream: false,
|
||||
responseStream: false,
|
||||
requestType: inventory_v1_inventory_pb.GetEntityRequest,
|
||||
responseType: inventory_v1_inventory_pb.GetEntityReply
|
||||
};
|
||||
|
||||
Inventory.CreateEntity = {
|
||||
methodName: "CreateEntity",
|
||||
service: Inventory,
|
||||
requestStream: false,
|
||||
responseStream: false,
|
||||
requestType: inventory_v1_inventory_pb.CreateEntityRequest,
|
||||
responseType: inventory_v1_inventory_pb.CreateEntityReply
|
||||
};
|
||||
|
||||
exports.Inventory = Inventory;
|
||||
|
||||
function InventoryClient(serviceHost, options) {
|
||||
this.serviceHost = serviceHost;
|
||||
this.options = options || {};
|
||||
}
|
||||
|
||||
InventoryClient.prototype.getEntity = function getEntity(requestMessage, metadata, callback) {
|
||||
if (arguments.length === 2) {
|
||||
callback = arguments[1];
|
||||
}
|
||||
var client = grpc.unary(Inventory.GetEntity, {
|
||||
request: requestMessage,
|
||||
host: this.serviceHost,
|
||||
metadata: metadata,
|
||||
transport: this.options.transport,
|
||||
debug: this.options.debug,
|
||||
onEnd: function (response) {
|
||||
if (callback) {
|
||||
if (response.status !== grpc.Code.OK) {
|
||||
var err = new Error(response.statusMessage);
|
||||
err.code = response.status;
|
||||
err.metadata = response.trailers;
|
||||
callback(err, null);
|
||||
} else {
|
||||
callback(null, response.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return {
|
||||
cancel: function () {
|
||||
callback = null;
|
||||
client.close();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
InventoryClient.prototype.createEntity = function createEntity(requestMessage, metadata, callback) {
|
||||
if (arguments.length === 2) {
|
||||
callback = arguments[1];
|
||||
}
|
||||
var client = grpc.unary(Inventory.CreateEntity, {
|
||||
request: requestMessage,
|
||||
host: this.serviceHost,
|
||||
metadata: metadata,
|
||||
transport: this.options.transport,
|
||||
debug: this.options.debug,
|
||||
onEnd: function (response) {
|
||||
if (callback) {
|
||||
if (response.status !== grpc.Code.OK) {
|
||||
var err = new Error(response.statusMessage);
|
||||
err.code = response.status;
|
||||
err.metadata = response.trailers;
|
||||
callback(err, null);
|
||||
} else {
|
||||
callback(null, response.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
return {
|
||||
cancel: function () {
|
||||
callback = null;
|
||||
client.close();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
exports.InventoryClient = InventoryClient;
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
import * as grpcWeb from 'grpc-web';
|
||||
|
||||
import * as identity_v1_identity_pb from '../../identity/v1/identity_pb';
|
||||
import * as google_protobuf_struct_pb from 'google-protobuf/google/protobuf/struct_pb';
|
||||
|
||||
import {
|
||||
CreateReply,
|
||||
CreateRequest,
|
||||
Empty,
|
||||
ListTemplatesReply} from './scaffolder_pb';
|
||||
|
||||
export class ScaffolderClient {
|
||||
constructor (hostname: string,
|
||||
credentials?: null | { [index: string]: string; },
|
||||
options?: null | { [index: string]: string; });
|
||||
|
||||
listTemplates(
|
||||
request: Empty,
|
||||
metadata: grpcWeb.Metadata | undefined,
|
||||
callback: (err: grpcWeb.Error,
|
||||
response: ListTemplatesReply) => void
|
||||
): grpcWeb.ClientReadableStream<ListTemplatesReply>;
|
||||
|
||||
create(
|
||||
request: CreateRequest,
|
||||
metadata: grpcWeb.Metadata | undefined,
|
||||
callback: (err: grpcWeb.Error,
|
||||
response: CreateReply) => void
|
||||
): grpcWeb.ClientReadableStream<CreateReply>;
|
||||
|
||||
}
|
||||
|
||||
export class ScaffolderPromiseClient {
|
||||
constructor (hostname: string,
|
||||
credentials?: null | { [index: string]: string; },
|
||||
options?: null | { [index: string]: string; });
|
||||
|
||||
listTemplates(
|
||||
request: Empty,
|
||||
metadata?: grpcWeb.Metadata
|
||||
): Promise<ListTemplatesReply>;
|
||||
|
||||
create(
|
||||
request: CreateRequest,
|
||||
metadata?: grpcWeb.Metadata
|
||||
): Promise<CreateReply>;
|
||||
|
||||
}
|
||||
|
||||