diff options
| author | Christine Dodrill <me@christine.website> | 2017-01-27 01:52:24 -0800 |
|---|---|---|
| committer | Christine Dodrill <me@christine.website> | 2017-01-27 01:52:59 -0800 |
| commit | 599d2cfde3054fe0a08fdc35e5a0df934cecda52 (patch) | |
| tree | d322c57a35f2ffa74f5c9a7a0950bb0fa0c94134 | |
| parent | 74df32d62e399a0880195c9003b13de916d8ef6b (diff) | |
| download | x-599d2cfde3054fe0a08fdc35e5a0df934cecda52.tar.xz x-599d2cfde3054fe0a08fdc35e5a0df934cecda52.zip | |
do more work on svc
| -rw-r--r-- | svc/cmd/svc/main.go | 214 | ||||
| -rw-r--r-- | svc/cmd/svcd/dockerswarm-svcd/.gitignore | 3 | ||||
| -rw-r--r-- | svc/cmd/svcd/dockerswarm-svcd/main.go | 253 | ||||
| -rw-r--r-- | svc/credentials/jwt/jwt.go | 24 | ||||
| -rwxr-xr-x | svc/proto/regen.sh | 19 | ||||
| -rw-r--r-- | svc/proto/svc.pb.go | 598 | ||||
| -rw-r--r-- | svc/proto/svc.pb.gw.go | 348 | ||||
| -rw-r--r-- | svc/proto/svc.proto | 92 | ||||
| -rw-r--r-- | svc/proto/svc.swagger.json | 309 |
9 files changed, 1860 insertions, 0 deletions
diff --git a/svc/cmd/svc/main.go b/svc/cmd/svc/main.go new file mode 100644 index 0000000..3a7b30d --- /dev/null +++ b/svc/cmd/svc/main.go @@ -0,0 +1,214 @@ +package main + +import ( + "context" + "encoding/json" + "fmt" + "log" + "os" + "path/filepath" + "time" + + "github.com/Bowery/prompt" + jwtcreds "github.com/Xe/tools/svc/credentials/jwt" + svc "github.com/Xe/tools/svc/proto" + "github.com/Xe/uuid" + jwt "github.com/dgrijalva/jwt-go" + "github.com/olekukonko/tablewriter" + "google.golang.org/grpc" + kingpin "gopkg.in/alecthomas/kingpin.v1" +) + +var ( + app = kingpin.New("svc", "A simple service manager") + debug = app.Flag("debug", "print debugging logs?").Bool() + host = app.Flag("host", "host to do these changes to").String() + dataDir = app.Flag("data-dir", "place for svc to store data").Default("/home/xena/.local/within/svc").String() + + createToken = app.Command("create-token", "Creates the initial server control token") + createTokenJwtSecret = createToken.Flag("jwt-secret", "jwt secret used on the server").Required().String() + createTokenUsername = createToken.Arg("username", "username to create token for").Required().String() + + list = app.Command("list", "List apps running with this backend") + listLabelKey = list.Flag("labelKey", "label key to match for").String() + listLabelValue = list.Flag("labelValue", "label value to match for (with labelKey)").String() + + create = app.Command("create", "Create a new application") + createName = create.Flag("name", "name of the application").Required().String() + createEnvFile = create.Flag("env-file", "file with key->value envvars").String() + createEnvironment = create.Flag("env", "environment variables for the program").StringMap() + createLabels = create.Flag("label", "additional labels to attach to the service").StringMap() + createAuthorizedUsers = create.Flag("authorized-user", "additional user to allow modification access to").Strings() + createExclusive = create.Flag("exclusive", "can this only ever have one copy running at once?").Bool() + createInstances = create.Flag("instances", "number of instances of the backend service").Default("1").Int() + createDockerImage = create.Arg("docker image", "docker image to execute for this service").Required().String() + + update = app.Command("update", "Update an application") + updateImage = update.Flag("image", "new docker image to use for this service").String() + updateEnvAdd = update.Flag("env-add", "new environment variables to set").StringMap() + updateEnvRm = update.Flag("env-rm", "environment variables to remove").StringMap() + updateLabelAdd = update.Flag("label-add", "container labels to addB").StringMap() + updateLabelRm = update.Flag("label-rm", "container labels to remove").StringMap() + updateGrantUsers = update.Flag("grant-user", "grant a user permission to this service").Strings() + updateRevokeUsers = update.Flag("revoke-user", "revoke a user's permission to this service").Strings() + updateInstanceCount = update.Flag("instances", "updates the instance count of the service").Int() + + inspect = app.Command("inspect", "Inspect an application") + inspectName = inspect.Arg("name", "name of the service").String() + + deleteCmd = app.Command("delete", "Deletes an application by name") + deleteName = deleteCmd.Arg("name", "name of the service").String() + + hostCmd = app.Command("host", "Host management") + hostAdd = hostCmd.Command("add", "Add a host to the state file") + hostAddTor = hostAdd.Flag("tor", "connect to this over tor?").Bool() + hostAddName = hostAdd.Arg("name", "name of host to add").Required().String() + hostAddAddr = hostAdd.Arg("addr", "address of taget server (host:port)").Required().String() + hostRemove = hostCmd.Command("remove", "Remove a host from the state file") + hostRemoveName = hostRemove.Arg("name", "name of host to remove").Required().String() +) + +func main() { + cmdline := kingpin.MustParse(app.Parse(os.Args[1:])) + + state, err := readState() + if err != nil { + if os.IsNotExist(err) { + log.Println("Host file does not exist, please add a host with `svc host add`.") + } + + log.Fatal(err) + } + writeState(state) + + switch cmdline { + case "host add": + token, err := prompt.Basic("token: ", true) + if err != nil { + log.Fatal(err) + } + + h := &Host{ + Name: *hostAddName, + Addr: *hostAddAddr, + Token: token, + Tor: *hostAddTor, + } + + state.Hosts[h.Name] = h + writeState(state) + + log.Println("Host added to hosts file.") + return + case "host remove": + log.Println("removing host not yet implemented") + os.Exit(1) + case "create-token": + now := time.Now() + nva := now.AddDate(0, 1, 0) // Expiry time of this token + nb4 := now.AddDate(0, 0, -1) // Not before then is this token valid + + hostname, _ := os.Hostname() + tid := uuid.New() + + token := jwt.NewWithClaims(jwt.SigningMethodHS512, &jwt.StandardClaims{ + IssuedAt: now.Unix(), + NotBefore: nb4.Unix(), + ExpiresAt: nva.Unix(), + Issuer: hostname, + Subject: *createTokenUsername, + Id: tid, + }) + + tokenString, err := token.SignedString([]byte(*createTokenJwtSecret)) + if err != nil { + log.Fatal(err) + } + + fmt.Println(tokenString) + + os.Exit(0) + } + + if *host == "" { + log.Fatal("--host must be supplied") + } + + hostInfo, ok := state.Hosts[*host] + if !ok { + log.Fatalf("Requested host %q that doesn't exist in state", *host) + } + + creds := jwtcreds.NewFromToken(hostInfo.Token) + conn, err := grpc.Dial(hostInfo.Addr, grpc.WithInsecure(), + grpc.WithPerRPCCredentials(creds)) + if err != nil { + log.Fatal(err) + } + + c := svc.NewAppsClient(conn) + + // RPC commands + switch cmdline { + case list.FullCommand(): + apps, err := c.List(context.Background(), &svc.AppsListParams{}) + if err != nil { + log.Fatal(err) + } + + table := tablewriter.NewWriter(os.Stdout) + + table.SetHeader([]string{"ID", "Name", "Image", "Users"}) + + for _, app := range apps.Apps { + table.Append([]string{app.Id, app.Name, app.DockerImage, fmt.Sprintf("%v", app.AuthorizedUsers)}) + } + table.Render() + + case create.FullCommand(): + log.Println("create not implemented") + case update.FullCommand(): + log.Println("update not implemented") + case inspect.FullCommand(): + log.Println("inspect not implemented") + case deleteCmd.FullCommand(): + log.Println("delete not implemented") + } +} + +type state struct { + Hosts map[string]*Host +} + +type Host struct { + Name string + Addr string + Token string + Tor bool +} + +func readState() (*state, error) { + s := &state{} + + fname := filepath.Join(*dataDir, "state.json") + fin, err := os.Open(fname) + if err != nil { + return nil, err + } + defer fin.Close() + + err = json.NewDecoder(fin).Decode(s) + + return s, err +} + +func writeState(s *state) error { + fname := filepath.Join(*dataDir, "state.json") + fout, err := os.Create(fname) + if err != nil { + return err + } + defer fout.Close() + + return json.NewEncoder(fout).Encode(s) +} diff --git a/svc/cmd/svcd/dockerswarm-svcd/.gitignore b/svc/cmd/svcd/dockerswarm-svcd/.gitignore new file mode 100644 index 0000000..39305f0 --- /dev/null +++ b/svc/cmd/svcd/dockerswarm-svcd/.gitignore @@ -0,0 +1,3 @@ +state.json +dockerswarm-svcd +*.pem diff --git a/svc/cmd/svcd/dockerswarm-svcd/main.go b/svc/cmd/svcd/dockerswarm-svcd/main.go new file mode 100644 index 0000000..724e7c9 --- /dev/null +++ b/svc/cmd/svcd/dockerswarm-svcd/main.go @@ -0,0 +1,253 @@ +package main + +import ( + "encoding/json" + "errors" + "flag" + "fmt" + "log" + "net" + "os" + "strings" + "sync" + + svc "github.com/Xe/tools/svc/proto" + jwt "github.com/dgrijalva/jwt-go" + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/swarm" + "github.com/docker/docker/client" + "github.com/facebookgo/flagenv" + _ "github.com/joho/godotenv/autoload" + "golang.org/x/net/context" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/metadata" +) + +var ( + listenAddress = flag.String("listen", "127.0.0.1:23142", "tcp host:port to listen on") + sslCert = flag.String("tls-cert", "cert.pem", "tls certificate to read from") + sslKey = flag.String("tls-key", "key.pem", "tls private key") + jwtSecret = flag.String("jwt-secret", "hunter2", "secret used to sign jwt's") +) + +const admin = "xena" + +type server struct { + docker *client.Client + + sync.Mutex + state map[string][]string +} + +func (s *server) LoadState(fname string) error { + s.Lock() + defer s.Unlock() + + fin, err := os.Open(fname) + if err != nil { + return err + } + defer fin.Close() + + return json.NewDecoder(fin).Decode(&s.state) +} + +func (s *server) SaveState(fname string) error { + s.Lock() + defer s.Unlock() + + fout, err := os.Create(fname) + if err != nil { + return err + } + defer fout.Close() + + return json.NewEncoder(fout).Encode(&s.state) +} + +func (s *server) List(ctx context.Context, params *svc.AppsListParams) (*svc.AppsList, error) { + user, err := s.checkAuth(ctx) + if err != nil { + return nil, err + } + + svcs, err := s.docker.ServiceList(ctx, types.ServiceListOptions{}) + if err != nil { + return nil, err + } + + result := &svc.AppsList{} + + for _, ssvc := range svcs { + env := func(kv []string) map[string]string { + result := map[string]string{} + + for _, pair := range kv { + split := strings.SplitN(pair, "=", 2) + result[split[0]] = split[1] + } + + return result + }(ssvc.Spec.TaskTemplate.ContainerSpec.Env) + + au := s.state[ssvc.Spec.Name] + if au == nil { + s.state[ssvc.Spec.Name] = []string{admin} + s.SaveState("state.json") + } + + allowed := false + + if user == admin { + allowed = true + } + + for _, allowedUser := range au { + if user == allowedUser { + allowed = true + } + } + + if !allowed { + continue + } + + result.Apps = append(result.Apps, &svc.App{ + Id: ssvc.ID, + Name: ssvc.Spec.Name, + DockerImage: ssvc.Spec.TaskTemplate.ContainerSpec.Image, + Environment: env, + Labels: ssvc.Spec.Labels, + AuthorizedUsers: au, + }) + } + + return result, nil +} + +func (s *server) Create(ctx context.Context, manifest *svc.Manifest) (*svc.App, error) { + user, err := s.checkAuth(ctx) + if err != nil { + return nil, err + } + + env := []string{} + + for key, val := range manifest.Environment { + env = append(env, fmt.Sprintf("%s=%s", key, val)) + } + + spec := swarm.ServiceSpec{ + Annotations: swarm.Annotations{ + Name: manifest.Name, + Labels: manifest.Labels, + }, + + TaskTemplate: swarm.TaskSpec{ + ContainerSpec: swarm.ContainerSpec{ + Image: manifest.DockerImage, + Env: env, + }, + }, + + Mode: swarm.ServiceMode{ + Replicated: &swarm.ReplicatedService{}, + }, + } + + resp, err := s.docker.ServiceCreate(ctx, spec, types.ServiceCreateOptions{}) + if err != nil { + return nil, err + } + + ssvc, _, err := s.docker.ServiceInspectWithRaw(ctx, resp.ID) + if err != nil { + return nil, err + } + + app := &svc.App{ + Id: ssvc.ID, + Name: ssvc.Spec.Name, + DockerImage: ssvc.Spec.TaskTemplate.ContainerSpec.Image, + Environment: manifest.Environment, + Labels: ssvc.Spec.Labels, + AuthorizedUsers: []string{user}, + } + + return app, nil +} + +func (s *server) Update(ctx context.Context, params *svc.AppUpdate) (*svc.App, error) { + return nil, errors.New("not implemented") +} + +func (s *server) Inspect(ctx context.Context, params *svc.AppInspect) (*svc.App, error) { + return nil, errors.New("not implemented") +} + +func (s *server) Delete(ctx context.Context, params *svc.AppDelete) (*svc.Ok, error) { + return nil, errors.New("not implemented") +} + +func main() { + flag.Parse() + flagenv.Parse() + + gs := grpc.NewServer() + + defaultHeaders := map[string]string{"User-Agent": "dockerswarm-svcd"} + cli, err := client.NewClient(client.DefaultDockerHost, client.DefaultVersion, nil, defaultHeaders) + if err != nil { + log.Fatal(err) + } + + s := &server{ + docker: cli, + state: map[string][]string{}, + } + + err = s.LoadState("state.json") + if err != nil { + log.Fatal(err) + } + + svc.RegisterAppsServer(gs, s) + + l, err := net.Listen("tcp", *listenAddress) + if err != nil { + log.Fatal(err) + } + + err = gs.Serve(l) + if err != nil { + log.Fatal(err) + } +} + +func (s *server) checkAuth(ctx context.Context) (string, error) { + var err error + + md, ok := metadata.FromContext(ctx) + if !ok { + return "", grpc.Errorf(codes.Unauthenticated, "valid token required.") + } + + jwtToken, ok := md["authorization"] + if !ok { + return "", grpc.Errorf(codes.Unauthenticated, "valid token required.") + } + + clms := &jwt.StandardClaims{} + + p := &jwt.Parser{} + _, err = p.ParseWithClaims(jwtToken[0], clms, jwt.Keyfunc(func(t *jwt.Token) (interface{}, error) { + return []byte(*jwtSecret), nil + })) + if err != nil { + log.Printf("rpc error: %v", err) + return "", grpc.Errorf(codes.Unauthenticated, "valid token requried.") + } + + return clms.Subject, nil +} diff --git a/svc/credentials/jwt/jwt.go b/svc/credentials/jwt/jwt.go new file mode 100644 index 0000000..978c880 --- /dev/null +++ b/svc/credentials/jwt/jwt.go @@ -0,0 +1,24 @@ +package jwt + +import ( + "golang.org/x/net/context" + "google.golang.org/grpc/credentials" +) + +type jwt struct { + token string +} + +func NewFromToken(token string) credentials.PerRPCCredentials { + return jwt{token: token} +} + +func (j jwt) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) { + return map[string]string{ + "authorization": j.token, + }, nil +} + +func (j jwt) RequireTransportSecurity() bool { + return false +} diff --git a/svc/proto/regen.sh b/svc/proto/regen.sh new file mode 100755 index 0000000..cb20e86 --- /dev/null +++ b/svc/proto/regen.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +protoc -I/usr/local/include -I. \ + -I$GOPATH/src \ + -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \ + --go_out=Mgoogle/api/annotations.proto=github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis/google/api,plugins=grpc:. \ + svc.proto + +protoc -I/usr/local/include -I. \ + -I$GOPATH/src \ + -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \ + --grpc-gateway_out=logtostderr=true:. \ + svc.proto + +protoc -I/usr/local/include -I. \ + -I$GOPATH/src \ + -I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \ + --swagger_out=logtostderr=true:. \ + svc.proto diff --git a/svc/proto/svc.pb.go b/svc/proto/svc.pb.go new file mode 100644 index 0000000..445c1ba --- /dev/null +++ b/svc/proto/svc.pb.go @@ -0,0 +1,598 @@ +// Code generated by protoc-gen-go. +// source: svc.proto +// DO NOT EDIT! + +/* +Package svc is a generated protocol buffer package. + +It is generated from these files: + svc.proto + +It has these top-level messages: + AppsListParams + AppsList + Manifest + App + AppUpdate + AppInspect + AppDelete + Ok +*/ +package svc + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import _ "github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis/google/api" + +import ( + context "golang.org/x/net/context" + grpc "google.golang.org/grpc" +) + +// 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.ProtoPackageIsVersion2 // please upgrade the proto package + +type AppsListParams struct { + LabelKey string `protobuf:"bytes,1,opt,name=labelKey" json:"labelKey,omitempty"` + LabelVal string `protobuf:"bytes,2,opt,name=labelVal" json:"labelVal,omitempty"` + // will be matched to app names + Name string `protobuf:"bytes,3,opt,name=name" json:"name,omitempty"` +} + +func (m *AppsListParams) Reset() { *m = AppsListParams{} } +func (m *AppsListParams) String() string { return proto.CompactTextString(m) } +func (*AppsListParams) ProtoMessage() {} +func (*AppsListParams) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } + +func (m *AppsListParams) GetLabelKey() string { + if m != nil { + return m.LabelKey + } + return "" +} + +func (m *AppsListParams) GetLabelVal() string { + if m != nil { + return m.LabelVal + } + return "" +} + +func (m *AppsListParams) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +type AppsList struct { + Message string `protobuf:"bytes,1,opt,name=message" json:"message,omitempty"` + Apps []*App `protobuf:"bytes,2,rep,name=apps" json:"apps,omitempty"` +} + +func (m *AppsList) Reset() { *m = AppsList{} } +func (m *AppsList) String() string { return proto.CompactTextString(m) } +func (*AppsList) ProtoMessage() {} +func (*AppsList) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } + +func (m *AppsList) GetMessage() string { + if m != nil { + return m.Message + } + return "" +} + +func (m *AppsList) GetApps() []*App { + if m != nil { + return m.Apps + } + return nil +} + +type Manifest struct { + Environment map[string]string `protobuf:"bytes,1,rep,name=environment" json:"environment,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + Labels map[string]string `protobuf:"bytes,2,rep,name=labels" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + DockerImage string `protobuf:"bytes,3,opt,name=dockerImage" json:"dockerImage,omitempty"` + Name string `protobuf:"bytes,4,opt,name=name" json:"name,omitempty"` +} + +func (m *Manifest) Reset() { *m = Manifest{} } +func (m *Manifest) String() string { return proto.CompactTextString(m) } +func (*Manifest) ProtoMessage() {} +func (*Manifest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } + +func (m *Manifest) GetEnvironment() map[string]string { + if m != nil { + return m.Environment + } + return nil +} + +func (m *Manifest) GetLabels() map[string]string { + if m != nil { + return m.Labels + } + return nil +} + +func (m *Manifest) GetDockerImage() string { + if m != nil { + return m.DockerImage + } + return "" +} + +func (m *Manifest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +type App struct { + Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` + Name string `protobuf:"bytes,2,opt,name=name" json:"name,omitempty"` + DockerImage string `protobuf:"bytes,3,opt,name=dockerImage" json:"dockerImage,omitempty"` + Environment map[string]string `protobuf:"bytes,4,rep,name=environment" json:"environment,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + Labels map[string]string `protobuf:"bytes,5,rep,name=labels" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + AuthorizedUsers []string `protobuf:"bytes,6,rep,name=authorizedUsers" json:"authorizedUsers,omitempty"` + Instances int32 `protobuf:"varint,7,opt,name=instances" json:"instances,omitempty"` +} + +func (m *App) Reset() { *m = App{} } +func (m *App) String() string { return proto.CompactTextString(m) } +func (*App) ProtoMessage() {} +func (*App) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} } + +func (m *App) GetId() string { + if m != nil { + return m.Id + } + return "" +} + +func (m *App) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *App) GetDockerImage() string { + if m != nil { + return m.DockerImage + } + return "" +} + +func (m *App) GetEnvironment() map[string]string { + if m != nil { + return m.Environment + } + return nil +} + +func (m *App) GetLabels() map[string]string { + if m != nil { + return m.Labels + } + return nil +} + +func (m *App) GetAuthorizedUsers() []string { + if m != nil { + return m.AuthorizedUsers + } + return nil +} + +func (m *App) GetInstances() int32 { + if m != nil { + return m.Instances + } + return 0 +} + +type AppUpdate struct { + Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + NewImage string `protobuf:"bytes,2,opt,name=newImage" json:"newImage,omitempty"` + EnvAdd map[string]string `protobuf:"bytes,3,rep,name=envAdd" json:"envAdd,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + EnvRm map[string]string `protobuf:"bytes,4,rep,name=envRm" json:"envRm,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + LabelAdd map[string]string `protobuf:"bytes,5,rep,name=labelAdd" json:"labelAdd,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + LabelRm map[string]string `protobuf:"bytes,6,rep,name=labelRm" json:"labelRm,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + GrantUsers []string `protobuf:"bytes,7,rep,name=grantUsers" json:"grantUsers,omitempty"` + RevokeUsers []string `protobuf:"bytes,8,rep,name=revokeUsers" json:"revokeUsers,omitempty"` + NewInstanceCount int32 `protobuf:"varint,9,opt,name=newInstanceCount" json:"newInstanceCount,omitempty"` +} + +func (m *AppUpdate) Reset() { *m = AppUpdate{} } +func (m *AppUpdate) String() string { return proto.CompactTextString(m) } +func (*AppUpdate) ProtoMessage() {} +func (*AppUpdate) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} } + +func (m *AppUpdate) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *AppUpdate) GetNewImage() string { + if m != nil { + return m.NewImage + } + return "" +} + +func (m *AppUpdate) GetEnvAdd() map[string]string { + if m != nil { + return m.EnvAdd + } + return nil +} + +func (m *AppUpdate) GetEnvRm() map[string]string { + if m != nil { + return m.EnvRm + } + return nil +} + +func (m *AppUpdate) GetLabelAdd() map[string]string { + if m != nil { + return m.LabelAdd + } + return nil +} + +func (m *AppUpdate) GetLabelRm() map[string]string { + if m != nil { + return m.LabelRm + } + return nil +} + +func (m *AppUpdate) GetGrantUsers() []string { + if m != nil { + return m.GrantUsers + } + return nil +} + +func (m *AppUpdate) GetRevokeUsers() []string { + if m != nil { + return m.RevokeUsers + } + return nil +} + +func (m *AppUpdate) GetNewInstanceCount() int32 { + if m != nil { + return m.NewInstanceCount + } + return 0 +} + +type AppInspect struct { + Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` +} + +func (m *AppInspect) Reset() { *m = AppInspect{} } +func (m *AppInspect) String() string { return proto.CompactTextString(m) } +func (*AppInspect) ProtoMessage() {} +func (*AppInspect) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} } + +func (m *AppInspect) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +type AppDelete struct { + Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` +} + +func (m *AppDelete) Reset() { *m = AppDelete{} } +func (m *AppDelete) String() string { return proto.CompactTextString(m) } +func (*AppDelete) ProtoMessage() {} +func (*AppDelete) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} } + +func (m *AppDelete) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +type Ok struct { + Message string `protobuf:"bytes,1,opt,name=message" json:"message,omitempty"` +} + +func (m *Ok) Reset() { *m = Ok{} } +func (m *Ok) String() string { return proto.CompactTextString(m) } +func (*Ok) ProtoMessage() {} +func (*Ok) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} } + +func (m *Ok) GetMessage() string { + if m != nil { + return m.Message + } + return "" +} + +func init() { + proto.RegisterType((*AppsListParams)(nil), "AppsListParams") + proto.RegisterType((*AppsList)(nil), "AppsList") + proto.RegisterType((*Manifest)(nil), "Manifest") + proto.RegisterType((*App)(nil), "App") + proto.RegisterType((*AppUpdate)(nil), "AppUpdate") + proto.RegisterType((*AppInspect)(nil), "AppInspect") + proto.RegisterType((*AppDelete)(nil), "AppDelete") + proto.RegisterType((*Ok)(nil), "Ok") +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// 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.SupportPackageIsVersion4 + +// Client API for Apps service + +type AppsClient interface { + List(ctx context.Context, in *AppsListParams, opts ...grpc.CallOption) (*AppsList, error) + Create(ctx context.Context, in *Manifest, opts ...grpc.CallOption) (*App, error) + Update(ctx context.Context, in *AppUpdate, opts ...grpc.CallOption) (*App, error) + Inspect(ctx context.Context, in *AppInspect, opts ...grpc.CallOption) (*App, error) + Delete(ctx context.Context, in *AppDelete, opts ...grpc.CallOption) (*Ok, error) +} + +type appsClient struct { + cc *grpc.ClientConn +} + +func NewAppsClient(cc *grpc.ClientConn) AppsClient { + return &appsClient{cc} +} + +func (c *appsClient) List(ctx context.Context, in *AppsListParams, opts ...grpc.CallOption) (*AppsList, error) { + out := new(AppsList) + err := grpc.Invoke(ctx, "/Apps/List", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *appsClient) Create(ctx context.Context, in *Manifest, opts ...grpc.CallOption) (*App, error) { + out := new(App) + err := grpc.Invoke(ctx, "/Apps/Create", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *appsClient) Update(ctx context.Context, in *AppUpdate, opts ...grpc.CallOption) (*App, error) { + out := new(App) + err := grpc.Invoke(ctx, "/Apps/Update", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *appsClient) Inspect(ctx context.Context, in *AppInspect, opts ...grpc.CallOption) (*App, error) { + out := new(App) + err := grpc.Invoke(ctx, "/Apps/Inspect", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *appsClient) Delete(ctx context.Context, in *AppDelete, opts ...grpc.CallOption) (*Ok, error) { + out := new(Ok) + err := grpc.Invoke(ctx, "/Apps/Delete", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// Server API for Apps service + +type AppsServer interface { + List(context.Context, *AppsListParams) (*AppsList, error) + Create(context.Context, *Manifest) (*App, error) + Update(context.Context, *AppUpdate) (*App, error) + Inspect(context.Context, *AppInspect) (*App, error) + Delete(context.Context, *AppDelete) (*Ok, error) +} + +func RegisterAppsServer(s *grpc.Server, srv AppsServer) { + s.RegisterService(&_Apps_serviceDesc, srv) +} + +func _Apps_List_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AppsListParams) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AppsServer).List(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/Apps/List", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AppsServer).List(ctx, req.(*AppsListParams)) + } + return interceptor(ctx, in, info, handler) +} + +func _Apps_Create_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(Manifest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AppsServer).Create(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/Apps/Create", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AppsServer).Create(ctx, req.(*Manifest)) + } + return interceptor(ctx, in, info, handler) +} + +func _Apps_Update_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AppUpdate) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AppsServer).Update(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/Apps/Update", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AppsServer).Update(ctx, req.(*AppUpdate)) + } + return interceptor(ctx, in, info, handler) +} + +func _Apps_Inspect_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AppInspect) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AppsServer).Inspect(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/Apps/Inspect", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AppsServer).Inspect(ctx, req.(*AppInspect)) + } + return interceptor(ctx, in, info, handler) +} + +func _Apps_Delete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(AppDelete) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(AppsServer).Delete(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/Apps/Delete", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(AppsServer).Delete(ctx, req.(*AppDelete)) + } + return interceptor(ctx, in, info, handler) +} + +var _Apps_serviceDesc = grpc.ServiceDesc{ + ServiceName: "Apps", + HandlerType: (*AppsServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "List", + Handler: _Apps_List_Handler, + }, + { + MethodName: "Create", + Handler: _Apps_Create_Handler, + }, + { + MethodName: "Update", + Handler: _Apps_Update_Handler, + }, + { + MethodName: "Inspect", + Handler: _Apps_Inspect_Handler, + }, + { + MethodName: "Delete", + Handler: _Apps_Delete_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "svc.proto", +} + +func init() { proto.RegisterFile("svc.proto", fileDescriptor0) } + +var fileDescriptor0 = []byte{ + // 728 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xc4, 0x55, 0xcd, 0x6e, 0xd3, 0x40, + 0x10, 0x56, 0x1c, 0xe7, 0xc7, 0x13, 0x68, 0xc3, 0x96, 0x82, 0x71, 0x4b, 0x89, 0xcc, 0x25, 0x2a, + 0xc2, 0x51, 0x0b, 0x82, 0x52, 0x68, 0x25, 0xab, 0xf4, 0x50, 0x51, 0x54, |
