Merge remote-tracking branch 'origin/feat/workspaces' into feat/integrate.workflow.changes

This commit is contained in:
Andrey Melnikov
2020-05-01 23:36:59 -07:00
26 changed files with 1014 additions and 267 deletions

View File

@@ -36,4 +36,4 @@ option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = {
value: {}; value: {};
} }
} }
}; };

View File

@@ -1483,6 +1483,38 @@
] ]
} }
}, },
"/apis/v1beta1/{namespace}/workspaces": {
"post": {
"operationId": "CreateWorkspace",
"responses": {
"200": {
"description": "A successful response.",
"schema": {
"$ref": "#/definitions/Workspace"
}
}
},
"parameters": [
{
"name": "namespace",
"in": "path",
"required": true,
"type": "string"
},
{
"name": "body",
"in": "body",
"required": true,
"schema": {
"$ref": "#/definitions/Workspace"
}
}
],
"tags": [
"WorkspaceService"
]
}
},
"/apis/v1beta1/{namespace}/{resource}/{uid}/labels": { "/apis/v1beta1/{namespace}/{resource}/{uid}/labels": {
"get": { "get": {
"operationId": "GetLabels", "operationId": "GetLabels",
@@ -2005,6 +2037,17 @@
} }
} }
}, },
"Parameter": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"value": {
"type": "string"
}
}
},
"Secret": { "Secret": {
"type": "object", "type": "object",
"properties": { "properties": {
@@ -2084,7 +2127,7 @@
"parameters": { "parameters": {
"type": "array", "type": "array",
"items": { "items": {
"$ref": "#/definitions/WorkflowExecutionParameter" "$ref": "#/definitions/Parameter"
} }
}, },
"workflowTemplate": { "workflowTemplate": {
@@ -2098,17 +2141,6 @@
} }
} }
}, },
"WorkflowExecutionParameter": {
"type": "object",
"properties": {
"name": {
"type": "string"
},
"value": {
"type": "string"
}
}
},
"WorkflowExecutionStatisticReport": { "WorkflowExecutionStatisticReport": {
"type": "object", "type": "object",
"properties": { "properties": {
@@ -2178,6 +2210,33 @@
} }
} }
}, },
"Workspace": {
"type": "object",
"properties": {
"uid": {
"type": "string"
},
"name": {
"type": "string"
},
"version": {
"type": "string",
"format": "int64"
},
"createdAt": {
"type": "string"
},
"parameters": {
"type": "array",
"items": {
"$ref": "#/definitions/Parameter"
}
},
"workspaceTemplate": {
"$ref": "#/definitions/WorkspaceTemplate"
}
}
},
"WorkspaceTemplate": { "WorkspaceTemplate": {
"type": "object", "type": "object",
"properties": { "properties": {

84
api/common.pb.go Normal file
View File

@@ -0,0 +1,84 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: common.proto
package api
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
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 Parameter struct {
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:"-"`
}
func (m *Parameter) Reset() { *m = Parameter{} }
func (m *Parameter) String() string { return proto.CompactTextString(m) }
func (*Parameter) ProtoMessage() {}
func (*Parameter) Descriptor() ([]byte, []int) {
return fileDescriptor_555bd8c177793206, []int{0}
}
func (m *Parameter) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Parameter.Unmarshal(m, b)
}
func (m *Parameter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Parameter.Marshal(b, m, deterministic)
}
func (m *Parameter) XXX_Merge(src proto.Message) {
xxx_messageInfo_Parameter.Merge(m, src)
}
func (m *Parameter) XXX_Size() int {
return xxx_messageInfo_Parameter.Size(m)
}
func (m *Parameter) XXX_DiscardUnknown() {
xxx_messageInfo_Parameter.DiscardUnknown(m)
}
var xxx_messageInfo_Parameter proto.InternalMessageInfo
func (m *Parameter) GetName() string {
if m != nil {
return m.Name
}
return ""
}
func (m *Parameter) GetValue() string {
if m != nil {
return m.Value
}
return ""
}
func init() {
proto.RegisterType((*Parameter)(nil), "api.Parameter")
}
func init() { proto.RegisterFile("common.proto", fileDescriptor_555bd8c177793206) }
var fileDescriptor_555bd8c177793206 = []byte{
// 93 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x49, 0xce, 0xcf, 0xcd,
0xcd, 0xcf, 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x4e, 0x2c, 0xc8, 0x54, 0x32, 0xe5,
0xe2, 0x0c, 0x48, 0x2c, 0x4a, 0xcc, 0x4d, 0x2d, 0x49, 0x2d, 0x12, 0x12, 0xe2, 0x62, 0xc9, 0x4b,
0xcc, 0x4d, 0x95, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x0c, 0x02, 0xb3, 0x85, 0x44, 0xb8, 0x58, 0xcb,
0x12, 0x73, 0x4a, 0x53, 0x25, 0x98, 0xc0, 0x82, 0x10, 0x4e, 0x12, 0x1b, 0xd8, 0x08, 0x63, 0x40,
0x00, 0x00, 0x00, 0xff, 0xff, 0x79, 0x38, 0x4a, 0x41, 0x52, 0x00, 0x00, 0x00,
}

8
api/common.proto Normal file
View File

@@ -0,0 +1,8 @@
syntax = "proto3";
package api;
message Parameter {
string name = 1;
string value = 2;
}

View File

@@ -663,19 +663,19 @@ func (m *LogEntry) GetContent() string {
} }
type WorkflowExecution struct { type WorkflowExecution struct {
CreatedAt string `protobuf:"bytes,1,opt,name=createdAt,proto3" json:"createdAt,omitempty"` CreatedAt string `protobuf:"bytes,1,opt,name=createdAt,proto3" json:"createdAt,omitempty"`
Uid string `protobuf:"bytes,2,opt,name=uid,proto3" json:"uid,omitempty"` Uid string `protobuf:"bytes,2,opt,name=uid,proto3" json:"uid,omitempty"`
Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"` Name string `protobuf:"bytes,3,opt,name=name,proto3" json:"name,omitempty"`
Phase string `protobuf:"bytes,4,opt,name=phase,proto3" json:"phase,omitempty"` Phase string `protobuf:"bytes,4,opt,name=phase,proto3" json:"phase,omitempty"`
StartedAt string `protobuf:"bytes,5,opt,name=startedAt,proto3" json:"startedAt,omitempty"` StartedAt string `protobuf:"bytes,5,opt,name=startedAt,proto3" json:"startedAt,omitempty"`
FinishedAt string `protobuf:"bytes,6,opt,name=finishedAt,proto3" json:"finishedAt,omitempty"` FinishedAt string `protobuf:"bytes,6,opt,name=finishedAt,proto3" json:"finishedAt,omitempty"`
Manifest string `protobuf:"bytes,7,opt,name=manifest,proto3" json:"manifest,omitempty"` Manifest string `protobuf:"bytes,7,opt,name=manifest,proto3" json:"manifest,omitempty"`
Parameters []*WorkflowExecutionParameter `protobuf:"bytes,8,rep,name=parameters,proto3" json:"parameters,omitempty"` Parameters []*Parameter `protobuf:"bytes,8,rep,name=parameters,proto3" json:"parameters,omitempty"`
WorkflowTemplate *WorkflowTemplate `protobuf:"bytes,9,opt,name=workflowTemplate,proto3" json:"workflowTemplate,omitempty"` WorkflowTemplate *WorkflowTemplate `protobuf:"bytes,9,opt,name=workflowTemplate,proto3" json:"workflowTemplate,omitempty"`
Labels []*KeyValue `protobuf:"bytes,10,rep,name=labels,proto3" json:"labels,omitempty"` Labels []*KeyValue `protobuf:"bytes,10,rep,name=labels,proto3" json:"labels,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"` XXX_sizecache int32 `json:"-"`
} }
func (m *WorkflowExecution) Reset() { *m = WorkflowExecution{} } func (m *WorkflowExecution) Reset() { *m = WorkflowExecution{} }
@@ -752,7 +752,7 @@ func (m *WorkflowExecution) GetManifest() string {
return "" return ""
} }
func (m *WorkflowExecution) GetParameters() []*WorkflowExecutionParameter { func (m *WorkflowExecution) GetParameters() []*Parameter {
if m != nil { if m != nil {
return m.Parameters return m.Parameters
} }
@@ -773,53 +773,6 @@ func (m *WorkflowExecution) GetLabels() []*KeyValue {
return nil return nil
} }
type WorkflowExecutionParameter struct {
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:"-"`
}
func (m *WorkflowExecutionParameter) Reset() { *m = WorkflowExecutionParameter{} }
func (m *WorkflowExecutionParameter) String() string { return proto.CompactTextString(m) }
func (*WorkflowExecutionParameter) ProtoMessage() {}
func (*WorkflowExecutionParameter) Descriptor() ([]byte, []int) {
return fileDescriptor_892c7f566756b0be, []int{13}
}
func (m *WorkflowExecutionParameter) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_WorkflowExecutionParameter.Unmarshal(m, b)
}
func (m *WorkflowExecutionParameter) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_WorkflowExecutionParameter.Marshal(b, m, deterministic)
}
func (m *WorkflowExecutionParameter) XXX_Merge(src proto.Message) {
xxx_messageInfo_WorkflowExecutionParameter.Merge(m, src)
}
func (m *WorkflowExecutionParameter) XXX_Size() int {
return xxx_messageInfo_WorkflowExecutionParameter.Size(m)
}
func (m *WorkflowExecutionParameter) XXX_DiscardUnknown() {
xxx_messageInfo_WorkflowExecutionParameter.DiscardUnknown(m)
}
var xxx_messageInfo_WorkflowExecutionParameter proto.InternalMessageInfo
func (m *WorkflowExecutionParameter) GetName() string {
if m != nil {
return m.Name
}
return ""
}
func (m *WorkflowExecutionParameter) GetValue() string {
if m != nil {
return m.Value
}
return ""
}
type ArtifactResponse struct { type ArtifactResponse struct {
Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_NoUnkeyedLiteral struct{} `json:"-"`
@@ -831,7 +784,7 @@ func (m *ArtifactResponse) Reset() { *m = ArtifactResponse{} }
func (m *ArtifactResponse) String() string { return proto.CompactTextString(m) } func (m *ArtifactResponse) String() string { return proto.CompactTextString(m) }
func (*ArtifactResponse) ProtoMessage() {} func (*ArtifactResponse) ProtoMessage() {}
func (*ArtifactResponse) Descriptor() ([]byte, []int) { func (*ArtifactResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_892c7f566756b0be, []int{14} return fileDescriptor_892c7f566756b0be, []int{13}
} }
func (m *ArtifactResponse) XXX_Unmarshal(b []byte) error { func (m *ArtifactResponse) XXX_Unmarshal(b []byte) error {
@@ -876,7 +829,7 @@ func (m *File) Reset() { *m = File{} }
func (m *File) String() string { return proto.CompactTextString(m) } func (m *File) String() string { return proto.CompactTextString(m) }
func (*File) ProtoMessage() {} func (*File) ProtoMessage() {}
func (*File) Descriptor() ([]byte, []int) { func (*File) Descriptor() ([]byte, []int) {
return fileDescriptor_892c7f566756b0be, []int{15} return fileDescriptor_892c7f566756b0be, []int{14}
} }
func (m *File) XXX_Unmarshal(b []byte) error { func (m *File) XXX_Unmarshal(b []byte) error {
@@ -959,7 +912,7 @@ func (m *ListFilesRequest) Reset() { *m = ListFilesRequest{} }
func (m *ListFilesRequest) String() string { return proto.CompactTextString(m) } func (m *ListFilesRequest) String() string { return proto.CompactTextString(m) }
func (*ListFilesRequest) ProtoMessage() {} func (*ListFilesRequest) ProtoMessage() {}
func (*ListFilesRequest) Descriptor() ([]byte, []int) { func (*ListFilesRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_892c7f566756b0be, []int{16} return fileDescriptor_892c7f566756b0be, []int{15}
} }
func (m *ListFilesRequest) XXX_Unmarshal(b []byte) error { func (m *ListFilesRequest) XXX_Unmarshal(b []byte) error {
@@ -1013,7 +966,7 @@ func (m *ListFilesResponse) Reset() { *m = ListFilesResponse{} }
func (m *ListFilesResponse) String() string { return proto.CompactTextString(m) } func (m *ListFilesResponse) String() string { return proto.CompactTextString(m) }
func (*ListFilesResponse) ProtoMessage() {} func (*ListFilesResponse) ProtoMessage() {}
func (*ListFilesResponse) Descriptor() ([]byte, []int) { func (*ListFilesResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_892c7f566756b0be, []int{17} return fileDescriptor_892c7f566756b0be, []int{16}
} }
func (m *ListFilesResponse) XXX_Unmarshal(b []byte) error { func (m *ListFilesResponse) XXX_Unmarshal(b []byte) error {
@@ -1060,7 +1013,7 @@ func (m *Statistics) Reset() { *m = Statistics{} }
func (m *Statistics) String() string { return proto.CompactTextString(m) } func (m *Statistics) String() string { return proto.CompactTextString(m) }
func (*Statistics) ProtoMessage() {} func (*Statistics) ProtoMessage() {}
func (*Statistics) Descriptor() ([]byte, []int) { func (*Statistics) Descriptor() ([]byte, []int) {
return fileDescriptor_892c7f566756b0be, []int{18} return fileDescriptor_892c7f566756b0be, []int{17}
} }
func (m *Statistics) XXX_Unmarshal(b []byte) error { func (m *Statistics) XXX_Unmarshal(b []byte) error {
@@ -1108,7 +1061,7 @@ func (m *AddWorkflowExecutionStatisticRequest) Reset() { *m = AddWorkflo
func (m *AddWorkflowExecutionStatisticRequest) String() string { return proto.CompactTextString(m) } func (m *AddWorkflowExecutionStatisticRequest) String() string { return proto.CompactTextString(m) }
func (*AddWorkflowExecutionStatisticRequest) ProtoMessage() {} func (*AddWorkflowExecutionStatisticRequest) ProtoMessage() {}
func (*AddWorkflowExecutionStatisticRequest) Descriptor() ([]byte, []int) { func (*AddWorkflowExecutionStatisticRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_892c7f566756b0be, []int{19} return fileDescriptor_892c7f566756b0be, []int{18}
} }
func (m *AddWorkflowExecutionStatisticRequest) XXX_Unmarshal(b []byte) error { func (m *AddWorkflowExecutionStatisticRequest) XXX_Unmarshal(b []byte) error {
@@ -1167,7 +1120,7 @@ func (m *CronStartWorkflowExecutionStatisticRequest) String() string {
} }
func (*CronStartWorkflowExecutionStatisticRequest) ProtoMessage() {} func (*CronStartWorkflowExecutionStatisticRequest) ProtoMessage() {}
func (*CronStartWorkflowExecutionStatisticRequest) Descriptor() ([]byte, []int) { func (*CronStartWorkflowExecutionStatisticRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_892c7f566756b0be, []int{20} return fileDescriptor_892c7f566756b0be, []int{19}
} }
func (m *CronStartWorkflowExecutionStatisticRequest) XXX_Unmarshal(b []byte) error { func (m *CronStartWorkflowExecutionStatisticRequest) XXX_Unmarshal(b []byte) error {
@@ -1223,7 +1176,6 @@ func init() {
proto.RegisterType((*ListWorkflowExecutionsResponse)(nil), "api.ListWorkflowExecutionsResponse") proto.RegisterType((*ListWorkflowExecutionsResponse)(nil), "api.ListWorkflowExecutionsResponse")
proto.RegisterType((*LogEntry)(nil), "api.LogEntry") proto.RegisterType((*LogEntry)(nil), "api.LogEntry")
proto.RegisterType((*WorkflowExecution)(nil), "api.WorkflowExecution") proto.RegisterType((*WorkflowExecution)(nil), "api.WorkflowExecution")
proto.RegisterType((*WorkflowExecutionParameter)(nil), "api.WorkflowExecutionParameter")
proto.RegisterType((*ArtifactResponse)(nil), "api.ArtifactResponse") proto.RegisterType((*ArtifactResponse)(nil), "api.ArtifactResponse")
proto.RegisterType((*File)(nil), "api.File") proto.RegisterType((*File)(nil), "api.File")
proto.RegisterType((*ListFilesRequest)(nil), "api.ListFilesRequest") proto.RegisterType((*ListFilesRequest)(nil), "api.ListFilesRequest")
@@ -1236,93 +1188,92 @@ func init() {
func init() { proto.RegisterFile("workflow.proto", fileDescriptor_892c7f566756b0be) } func init() { proto.RegisterFile("workflow.proto", fileDescriptor_892c7f566756b0be) }
var fileDescriptor_892c7f566756b0be = []byte{ var fileDescriptor_892c7f566756b0be = []byte{
// 1371 bytes of a gzipped FileDescriptorProto // 1357 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x57, 0xcd, 0x73, 0xd4, 0xc6, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x57, 0x4b, 0x6f, 0x1c, 0x45,
0x12, 0xaf, 0xf1, 0xda, 0xe0, 0xed, 0x85, 0x87, 0x99, 0x07, 0xf6, 0x3e, 0x01, 0xc6, 0x6f, 0x0c, 0x10, 0xd6, 0x78, 0xed, 0xc4, 0xae, 0xcd, 0xc3, 0x29, 0x12, 0x7b, 0xd9, 0x24, 0x8e, 0x69, 0x27,
0x3c, 0x3f, 0xaa, 0xb2, 0x02, 0xe7, 0xa3, 0x52, 0x14, 0x84, 0x18, 0xb0, 0x09, 0xc1, 0x04, 0x22, 0xc1, 0x44, 0x62, 0x27, 0x31, 0x0f, 0xa1, 0x28, 0x21, 0x38, 0x89, 0x1d, 0x42, 0x1c, 0x12, 0xc6,
0x9b, 0x8f, 0x53, 0xa8, 0xb1, 0x76, 0xd6, 0x56, 0x79, 0x57, 0x52, 0x34, 0xb3, 0x98, 0x8d, 0xcb, 0xce, 0xe3, 0x44, 0xd4, 0x9e, 0xed, 0xb5, 0x47, 0xde, 0x9d, 0x19, 0xa6, 0x7b, 0xe3, 0x2c, 0x96,
0x97, 0x54, 0x0e, 0xc9, 0x25, 0x39, 0x70, 0x49, 0xe5, 0x94, 0x54, 0xe5, 0x8f, 0xc8, 0x29, 0xa7, 0x2f, 0x88, 0x03, 0x5c, 0xe0, 0x90, 0x0b, 0xe2, 0x04, 0x12, 0x3f, 0x82, 0x13, 0x27, 0x90, 0x38,
0xa4, 0x2a, 0xa7, 0x5c, 0x72, 0xca, 0x3d, 0x7f, 0x41, 0x6e, 0xb9, 0xa5, 0xa6, 0x35, 0xd2, 0xca, 0x71, 0xe1, 0xc4, 0x11, 0x89, 0x3f, 0xc1, 0x0d, 0x75, 0x4d, 0xcf, 0xec, 0xd8, 0xbb, 0xb3, 0x71,
0x5e, 0x69, 0x31, 0x0a, 0xa9, 0xca, 0x49, 0x9a, 0xee, 0x99, 0xee, 0x5f, 0x7f, 0x4d, 0xf7, 0xc0, 0x86, 0x20, 0x71, 0x9a, 0xee, 0xaa, 0x9e, 0xaa, 0xaf, 0xaa, 0xba, 0x1e, 0x0d, 0x87, 0x36, 0x83,
0xbf, 0xb6, 0x82, 0x68, 0xb3, 0xd5, 0x0e, 0xb6, 0x1a, 0x61, 0x14, 0xa8, 0x80, 0x56, 0x78, 0xe8, 0x68, 0xa3, 0xd1, 0x0c, 0x36, 0x6b, 0x61, 0x14, 0xa8, 0x00, 0x4b, 0x3c, 0xf4, 0xaa, 0x27, 0xd6,
0x59, 0x27, 0xd7, 0x83, 0x60, 0xbd, 0x2d, 0x6c, 0x1e, 0x7a, 0x36, 0xf7, 0xfd, 0x40, 0x71, 0xe5, 0x82, 0x60, 0xad, 0x29, 0x6c, 0x1e, 0x7a, 0x36, 0xf7, 0xfd, 0x40, 0x71, 0xe5, 0x05, 0xbe, 0x8c,
0x05, 0xbe, 0x8c, 0xb7, 0x58, 0x27, 0x0c, 0x17, 0x57, 0x6b, 0xdd, 0x96, 0x2d, 0x3a, 0xa1, 0xea, 0x8f, 0x54, 0x8f, 0x1b, 0x2e, 0xed, 0x56, 0xdb, 0x0d, 0x5b, 0xb4, 0x42, 0xd5, 0x31, 0xcc, 0xc9,
0x19, 0xe6, 0x54, 0x22, 0xef, 0xb1, 0x12, 0x9d, 0xb0, 0xcd, 0x95, 0x30, 0x8c, 0x43, 0x1d, 0xa1, 0x44, 0xde, 0x23, 0x25, 0x5a, 0x61, 0x93, 0x2b, 0x61, 0x18, 0x07, 0x5a, 0x42, 0x45, 0x9e, 0x6b,
0x22, 0xcf, 0x35, 0xab, 0x5a, 0x9b, 0xaf, 0x89, 0x76, 0xbc, 0x60, 0x9f, 0x10, 0x98, 0xbe, 0x1e, 0x76, 0xe5, 0x26, 0x5f, 0x15, 0xcd, 0x84, 0xe5, 0x06, 0xad, 0x56, 0xe0, 0xc7, 0x3b, 0xf6, 0xb9,
0x09, 0xae, 0xc4, 0x43, 0x73, 0x78, 0xf1, 0xa9, 0x70, 0xbb, 0x5a, 0xa7, 0x23, 0x3e, 0xec, 0x0a, 0x05, 0x53, 0xd7, 0x22, 0xc1, 0x95, 0x78, 0x60, 0x44, 0x2d, 0x3c, 0x11, 0x6e, 0x5b, 0x23, 0x70,
0xa9, 0xe8, 0x49, 0xa8, 0xfa, 0xbc, 0x23, 0x64, 0xc8, 0x5d, 0x51, 0x27, 0x33, 0x64, 0xae, 0xea, 0xc4, 0x27, 0x6d, 0x21, 0x15, 0x9e, 0x80, 0x31, 0x9f, 0xb7, 0x84, 0x0c, 0xb9, 0x2b, 0x2a, 0xd6,
0xf4, 0x09, 0xf4, 0x06, 0x1c, 0xdd, 0xda, 0x7b, 0xb2, 0x3e, 0x32, 0x43, 0xe6, 0x6a, 0xf3, 0x93, 0xb4, 0x35, 0x3b, 0xe6, 0x74, 0x09, 0x78, 0x1d, 0x8e, 0x6c, 0xee, 0xfe, 0xb3, 0x32, 0x34, 0x6d,
0x0d, 0x1e, 0x7a, 0x8d, 0x41, 0xb9, 0x83, 0x07, 0xd8, 0x5d, 0x38, 0x71, 0x53, 0xa8, 0x92, 0x10, 0xcd, 0x96, 0xe7, 0x26, 0x6a, 0x3c, 0xf4, 0x6a, 0xbd, 0x72, 0x7b, 0x7f, 0x60, 0x77, 0xe0, 0xf8,
0x28, 0x8c, 0xea, 0x05, 0x6a, 0xad, 0x3a, 0xf8, 0xcf, 0x1e, 0x01, 0xbd, 0x29, 0xd4, 0x42, 0xa4, 0x0d, 0xa1, 0x0a, 0x42, 0x40, 0x18, 0xd6, 0x1b, 0xd2, 0x3a, 0xe6, 0xd0, 0x9a, 0x3d, 0x04, 0xbc,
0xbc, 0x16, 0x77, 0x55, 0x69, 0x39, 0x74, 0x02, 0x2a, 0x9b, 0xa2, 0x57, 0xaf, 0x20, 0x49, 0xff, 0x21, 0xd4, 0x7c, 0xa4, 0xbc, 0x06, 0x77, 0x55, 0x61, 0x39, 0x38, 0x0e, 0xa5, 0x0d, 0xd1, 0xa9,
0xb2, 0xf7, 0xe1, 0xd4, 0x43, 0xae, 0xdc, 0x8d, 0x97, 0x08, 0x76, 0x15, 0x66, 0x1c, 0x21, 0xbb, 0x94, 0x88, 0xa4, 0x97, 0xec, 0x23, 0x38, 0xf9, 0x80, 0x2b, 0x77, 0xfd, 0x05, 0x82, 0x5d, 0x81,
0x6b, 0x1d, 0xef, 0x65, 0xba, 0xe0, 0x3e, 0xfc, 0x77, 0x55, 0x44, 0x1d, 0xcf, 0x2f, 0x1f, 0xdc, 0x69, 0x47, 0xc8, 0xf6, 0x6a, 0xcb, 0x7b, 0x91, 0x2e, 0xb8, 0x07, 0xaf, 0xac, 0x88, 0xa8, 0xe5,
0x3c, 0xb1, 0xcf, 0x08, 0x9c, 0xce, 0x8b, 0xd5, 0x72, 0xb0, 0x2e, 0xcb, 0xfb, 0xb9, 0x0e, 0x07, 0xf9, 0xc5, 0x83, 0xdb, 0x4f, 0xec, 0x53, 0x0b, 0x4e, 0xf5, 0x8b, 0xd5, 0x52, 0xb0, 0x26, 0x8b,
0xc3, 0xa0, 0xf9, 0x9e, 0x26, 0xc7, 0xbe, 0x4e, 0x96, 0xf4, 0x0c, 0x1c, 0x76, 0x03, 0x5f, 0x71, 0xfb, 0xb9, 0x02, 0xfb, 0xc3, 0xa0, 0xfe, 0xa1, 0x26, 0xc7, 0xbe, 0x4e, 0xb6, 0x78, 0x1a, 0x0e,
0xcf, 0x17, 0x11, 0xf2, 0x47, 0x91, 0xbf, 0x9b, 0xc8, 0x42, 0x60, 0x79, 0xa0, 0xee, 0x60, 0xe2, 0xba, 0x81, 0xaf, 0xb8, 0xe7, 0x8b, 0x88, 0xf8, 0xc3, 0xc4, 0xdf, 0x49, 0x64, 0x21, 0xb0, 0x7e,
0xff, 0x1d, 0xb8, 0xd8, 0x32, 0xcc, 0x0e, 0xd5, 0x28, 0xc3, 0xc0, 0x97, 0x82, 0x9e, 0x85, 0x83, 0xa0, 0x6e, 0x53, 0x1a, 0xfc, 0x17, 0xb8, 0xd8, 0x12, 0xcc, 0x0c, 0xd4, 0x28, 0xc3, 0xc0, 0x97,
0x71, 0xf5, 0xc9, 0x3a, 0x99, 0xa9, 0xcc, 0xd5, 0xe6, 0x6b, 0x58, 0x15, 0xf1, 0x36, 0x27, 0xe1, 0x02, 0xcf, 0xc0, 0xfe, 0x38, 0x17, 0x65, 0xc5, 0x9a, 0x2e, 0xcd, 0x96, 0xe7, 0xca, 0x94, 0x15,
0xb1, 0x5f, 0x09, 0x9c, 0x5a, 0xf6, 0xe4, 0xa0, 0xbc, 0x7d, 0x62, 0xbf, 0x00, 0xff, 0x4e, 0xaa, 0xf1, 0x31, 0x27, 0xe1, 0xb1, 0x3f, 0x2c, 0x38, 0xb9, 0xe4, 0xc9, 0x5e, 0x79, 0x7b, 0xc4, 0x7e,
0x6a, 0xd5, 0x14, 0xff, 0x7d, 0xaf, 0x69, 0x4c, 0xc9, 0x63, 0xd1, 0x37, 0x61, 0x6a, 0x2f, 0xf9, 0x1e, 0x5e, 0x4a, 0xb2, 0x6a, 0xc5, 0x94, 0x82, 0x7b, 0x5e, 0xdd, 0x98, 0xd2, 0x8f, 0x85, 0xef,
0x81, 0x88, 0xa4, 0x2e, 0xdf, 0xd8, 0xd2, 0x22, 0x36, 0xb5, 0x60, 0x3c, 0xe4, 0xeb, 0x62, 0xc5, 0xc0, 0xe4, 0x6e, 0xf2, 0x7d, 0x11, 0x49, 0x9d, 0xbe, 0xb1, 0xa5, 0x79, 0x6c, 0xac, 0xc2, 0x68,
0xfb, 0x28, 0x0e, 0xc6, 0x98, 0x93, 0xae, 0xb5, 0x0f, 0xf5, 0x7f, 0x7d, 0x0c, 0xe9, 0xf8, 0xcf, 0xc8, 0xd7, 0xc4, 0xb2, 0xf7, 0x69, 0x1c, 0x8c, 0x11, 0x27, 0xdd, 0x6b, 0x1f, 0xea, 0x75, 0x65,
0x7e, 0x22, 0x30, 0x5d, 0x64, 0x9b, 0xf1, 0xd2, 0x31, 0x18, 0x73, 0x83, 0xae, 0xaf, 0xd0, 0xb0, 0x84, 0xe8, 0xb4, 0x66, 0xbf, 0x5a, 0x30, 0x95, 0x67, 0x9b, 0xf1, 0xd2, 0x51, 0x18, 0x71, 0x83,
0x31, 0x27, 0x5e, 0xd0, 0x25, 0xa0, 0x03, 0x57, 0x85, 0xac, 0x8f, 0xa0, 0x1b, 0x8b, 0x2e, 0x97, 0xb6, 0xaf, 0xc8, 0xb0, 0x11, 0x27, 0xde, 0xe0, 0x22, 0x60, 0x4f, 0xa9, 0x90, 0x95, 0x21, 0x72,
0x9c, 0x13, 0x29, 0xa8, 0x4a, 0x1f, 0x94, 0xd6, 0xa8, 0xbf, 0xd2, 0x58, 0x10, 0x2f, 0xe8, 0x34, 0x63, 0x5e, 0x71, 0xe9, 0xf3, 0x47, 0x0a, 0xaa, 0xd4, 0x05, 0xa5, 0x35, 0xea, 0xaf, 0x34, 0x16,
0x80, 0x0a, 0x14, 0x6f, 0x5f, 0x47, 0x30, 0xb1, 0x11, 0x19, 0x0a, 0xbb, 0x06, 0xe3, 0xcb, 0xc1, 0xc4, 0x1b, 0x9c, 0x02, 0x50, 0x81, 0xe2, 0xcd, 0x6b, 0x04, 0x26, 0x36, 0x22, 0x43, 0x61, 0x57,
0xfa, 0xa2, 0xaf, 0xa2, 0x9e, 0x0e, 0x88, 0xf2, 0x3a, 0x42, 0x2a, 0xde, 0x09, 0x93, 0x80, 0xa4, 0x61, 0x74, 0x29, 0x58, 0x5b, 0xf0, 0x55, 0xd4, 0xd1, 0x01, 0x51, 0x5e, 0x4b, 0x48, 0xc5, 0x5b,
0x04, 0x9d, 0x38, 0x3a, 0x43, 0x85, 0xaf, 0x4c, 0x10, 0x92, 0x25, 0xfb, 0x7d, 0x04, 0x8e, 0x0e, 0x61, 0x12, 0x90, 0x94, 0xa0, 0x2f, 0x8e, 0xbe, 0xa1, 0xc2, 0x57, 0x26, 0x08, 0xc9, 0x96, 0xfd,
0xe0, 0xd6, 0xd2, 0x5c, 0xbc, 0x87, 0x9b, 0x0b, 0x2a, 0x91, 0x96, 0x12, 0xf4, 0x35, 0xd4, 0x4d, 0x39, 0x04, 0x47, 0x7a, 0x70, 0x6b, 0x69, 0x2e, 0xd5, 0xe1, 0xfa, 0xbc, 0x4a, 0xa4, 0xa5, 0x04,
0xc3, 0xa9, 0x7f, 0xd3, 0x64, 0xad, 0x64, 0x92, 0x55, 0xdb, 0xb4, 0xc1, 0x65, 0x52, 0x22, 0xf1, 0x5d, 0x86, 0xda, 0x69, 0x38, 0xf5, 0x32, 0xbd, 0xac, 0xa5, 0xcc, 0x65, 0xd5, 0x36, 0xad, 0x73,
0x42, 0x4b, 0x96, 0x8a, 0x47, 0xb1, 0xe4, 0xb1, 0x58, 0x72, 0x4a, 0xd0, 0x16, 0xb7, 0x3c, 0xdf, 0x99, 0xa4, 0x48, 0xbc, 0xd1, 0x92, 0xa5, 0xe2, 0x51, 0x2c, 0x79, 0x24, 0x96, 0x9c, 0x12, 0xb4,
0x93, 0x1b, 0xc8, 0x3e, 0x80, 0xec, 0x0c, 0x45, 0x07, 0xbb, 0xc3, 0x7d, 0xaf, 0x25, 0xa4, 0xaa, 0xc5, 0x0d, 0xcf, 0xf7, 0xe4, 0x3a, 0xb1, 0xf7, 0x11, 0x3b, 0x43, 0xd1, 0xc1, 0x6e, 0x71, 0xdf,
0x1f, 0x44, 0x6e, 0xba, 0xa6, 0x57, 0x01, 0x42, 0x1e, 0xf1, 0x8e, 0x50, 0x22, 0x92, 0xf5, 0x71, 0x6b, 0x08, 0xa9, 0x2a, 0xfb, 0x89, 0x9b, 0xee, 0xb1, 0x06, 0x10, 0xf2, 0x88, 0xb7, 0x84, 0x12,
0x8c, 0xcb, 0xe9, 0xfc, 0xb8, 0xdc, 0x4b, 0xf6, 0x39, 0x99, 0x23, 0x74, 0x01, 0x26, 0xf6, 0x26, 0x91, 0xac, 0x8c, 0x52, 0x5c, 0x0e, 0x51, 0x5c, 0xee, 0x26, 0x64, 0x27, 0x73, 0x02, 0xe7, 0x61,
0x59, 0xbd, 0x8a, 0xbd, 0xe3, 0xf8, 0x2e, 0x31, 0x09, 0xd3, 0x19, 0xd8, 0x4e, 0xcf, 0xc2, 0x01, 0x7c, 0xf7, 0x9d, 0xaa, 0x8c, 0x51, 0xab, 0x38, 0xb6, 0x23, 0x9a, 0x09, 0xd3, 0xe9, 0x39, 0x8e,
0xec, 0x67, 0xb2, 0x0e, 0xa8, 0xff, 0x30, 0x1e, 0xbc, 0x2d, 0x7a, 0x0f, 0x78, 0xbb, 0x2b, 0x1c, 0x67, 0x60, 0x1f, 0x35, 0x33, 0x59, 0x01, 0x52, 0x77, 0x90, 0x7e, 0xbc, 0x25, 0x3a, 0xf7, 0x79,
0xc3, 0x64, 0x4b, 0x60, 0x15, 0x63, 0x4a, 0x9d, 0x49, 0x76, 0x3b, 0xf3, 0x89, 0x16, 0x61, 0x9c, 0xb3, 0x2d, 0x1c, 0xc3, 0x64, 0x67, 0x61, 0xbc, 0x5b, 0xfb, 0xcd, 0x1d, 0x43, 0x18, 0xae, 0x73,
0x1e, 0x2f, 0xd8, 0x39, 0x98, 0xe8, 0x37, 0x15, 0x93, 0xbc, 0x14, 0x46, 0x9b, 0x5c, 0x71, 0x3c, 0xc5, 0xc9, 0xb9, 0x07, 0x1c, 0x5a, 0xb3, 0x9f, 0x2d, 0x18, 0x5e, 0xf4, 0x9a, 0xe6, 0xde, 0xaa,
0x7d, 0xc8, 0xc1, 0x7f, 0xf6, 0x03, 0x81, 0xd1, 0x25, 0xaf, 0x6d, 0x0a, 0x42, 0x6d, 0x24, 0xa2, 0x75, 0xe3, 0x79, 0x5a, 0xf7, 0xad, 0x07, 0x27, 0x60, 0x4c, 0x3c, 0x51, 0xc2, 0xcf, 0xe4, 0x49,
0xf5, 0x7f, 0xee, 0x45, 0x73, 0x12, 0xaa, 0xe2, 0xa9, 0x12, 0x7e, 0xa6, 0x00, 0xfb, 0x04, 0x7d, 0x97, 0xa0, 0xff, 0x90, 0x49, 0x56, 0x94, 0x1c, 0x5a, 0xe3, 0x34, 0x94, 0x4d, 0xe4, 0x57, 0x3a,
0x42, 0x26, 0xe5, 0x56, 0x71, 0xf0, 0x9f, 0xce, 0x40, 0xcd, 0xa4, 0xd4, 0x6a, 0x2f, 0x14, 0x26, 0xa1, 0x30, 0x01, 0xc8, 0x92, 0x90, 0xc1, 0x81, 0x26, 0x97, 0xea, 0x76, 0x50, 0xf7, 0x1a, 0x9e,
0xb2, 0x59, 0x12, 0x65, 0x70, 0xa8, 0xcd, 0xa5, 0xba, 0x13, 0x34, 0xbd, 0x96, 0x27, 0x9a, 0x26, 0xa8, 0x9b, 0x20, 0xec, 0xa0, 0x69, 0xbd, 0x75, 0x2f, 0x12, 0xae, 0x0a, 0xa2, 0x0e, 0xc5, 0x61,
0xba, 0xbb, 0x68, 0x5a, 0x6f, 0xd3, 0x8b, 0x84, 0xab, 0x82, 0xa8, 0x87, 0x01, 0x1e, 0x77, 0xfa, 0xd4, 0xe9, 0x12, 0xd8, 0x43, 0x18, 0xd7, 0x09, 0xa6, 0x2d, 0xf9, 0x17, 0xb5, 0x2e, 0xf1, 0x41,
0x04, 0xf6, 0x08, 0x26, 0x74, 0xe5, 0x6a, 0x4b, 0xfe, 0xc2, 0x25, 0x9a, 0xf8, 0xa0, 0xd2, 0xf7, 0xa9, 0xeb, 0x03, 0xb6, 0x02, 0x47, 0x32, 0x92, 0x8d, 0x27, 0x4f, 0xc1, 0x48, 0x43, 0x13, 0x4c,
0x01, 0x5b, 0x85, 0xa3, 0x19, 0xc9, 0xc6, 0x93, 0xa7, 0x61, 0xac, 0xa5, 0x09, 0xe6, 0xaa, 0xac, 0x45, 0x1b, 0xa3, 0x18, 0xe8, 0x23, 0x4e, 0x4c, 0xd7, 0x97, 0x2a, 0xe4, 0x91, 0xf0, 0xd5, 0x5d,
0x62, 0x2c, 0xf5, 0x16, 0x27, 0xa6, 0xeb, 0x6c, 0x0d, 0x79, 0x24, 0x7c, 0x75, 0x4f, 0xcb, 0x8b, 0x2d, 0x2f, 0xd6, 0x91, 0xa1, 0xb0, 0x3a, 0xc0, 0xb2, 0x1e, 0x73, 0xa4, 0xf2, 0x5c, 0x89, 0x67,
0x75, 0x64, 0x28, 0xac, 0x09, 0xb0, 0xa2, 0x27, 0x26, 0xa9, 0x3c, 0x57, 0xd2, 0x73, 0xfd, 0x11, 0xbb, 0x73, 0x91, 0xa6, 0xb6, 0xa5, 0x81, 0xbb, 0x8b, 0x8a, 0xb5, 0x6e, 0x39, 0x48, 0xee, 0xc3,
0x4b, 0x53, 0xbb, 0xd2, 0xc0, 0xdd, 0x43, 0xa5, 0x8d, 0xfe, 0x3d, 0x93, 0xe4, 0xd5, 0xad, 0xb8, 0xcd, 0x38, 0x27, 0x4a, 0x4e, 0x1f, 0x0e, 0xfb, 0xd2, 0x82, 0xd3, 0xf3, 0xf5, 0x7a, 0x4f, 0xae,
0xd8, 0x2a, 0x4e, 0x0e, 0x87, 0x7d, 0x46, 0xe0, 0xcc, 0x42, 0xb3, 0x39, 0x90, 0x50, 0xa9, 0xea, 0xa5, 0xaa, 0x8b, 0xbb, 0xca, 0x06, 0x90, 0xa9, 0x01, 0xe4, 0xb0, 0xf2, 0xdc, 0x61, 0x72, 0x43,
0xf2, 0xae, 0xb2, 0x01, 0x64, 0x6a, 0x00, 0x3a, 0xac, 0x36, 0x7f, 0x04, 0xdd, 0xd0, 0xb7, 0xcb, 0xd7, 0x2e, 0x27, 0x73, 0x84, 0x7d, 0x6d, 0xc1, 0xb9, 0x6b, 0x11, 0xe9, 0x8e, 0xd4, 0xff, 0x01,
0xc9, 0x6c, 0x61, 0x5f, 0x10, 0x38, 0x7f, 0x3d, 0x42, 0xdd, 0x91, 0xfa, 0x27, 0x20, 0x9a, 0xff, 0xd1, 0xdc, 0xdf, 0x87, 0xe1, 0x70, 0x02, 0x64, 0x59, 0x44, 0x8f, 0x3d, 0x57, 0xe0, 0x77, 0x16,
0xe3, 0x08, 0x1c, 0x49, 0x80, 0xac, 0x88, 0xe8, 0x89, 0xe7, 0x0a, 0xfa, 0x35, 0x81, 0xa9, 0x82, 0x4c, 0xe6, 0x4c, 0x83, 0x38, 0x43, 0xc2, 0x06, 0xcf, 0x8a, 0xd5, 0x9c, 0xaa, 0xcc, 0xde, 0xff,
0x31, 0x93, 0xce, 0xa2, 0xb0, 0xe1, 0x43, 0xa8, 0x55, 0x70, 0xdd, 0xb3, 0x77, 0x3e, 0xfe, 0xe5, 0xec, 0xf7, 0xbf, 0x9e, 0x0e, 0x5d, 0x65, 0xaf, 0xeb, 0x29, 0x57, 0xda, 0x8f, 0x2f, 0xac, 0x0a,
0xb7, 0x67, 0x23, 0xd7, 0xd8, 0x2b, 0x7a, 0x60, 0x96, 0xf6, 0x93, 0x8b, 0x6b, 0x42, 0xf1, 0x8b, 0xc5, 0x2f, 0xd8, 0x5b, 0xa9, 0x4d, 0xdb, 0x76, 0x3a, 0xca, 0x8a, 0xb4, 0x70, 0x5f, 0xec, 0x9d,
0xf6, 0x76, 0x6a, 0xd3, 0x8e, 0x9d, 0x4e, 0xc5, 0x22, 0xed, 0x08, 0x97, 0x06, 0x47, 0x50, 0xfa, 0x14, 0xf1, 0x2b, 0x0b, 0x8e, 0xf6, 0xeb, 0xbb, 0x38, 0x4d, 0xaa, 0x07, 0x4c, 0x91, 0xb9, 0xe0,
0x39, 0x81, 0x63, 0x79, 0x0d, 0x9d, 0xce, 0xa0, 0xea, 0x21, 0xe3, 0x69, 0x21, 0xb8, 0xcb, 0x08, 0x2e, 0x11, 0xb8, 0xb7, 0xf1, 0xcd, 0xe7, 0x02, 0x17, 0xf3, 0xb7, 0xf1, 0x1b, 0x0b, 0x26, 0xfa,
0xee, 0x0d, 0xfa, 0xda, 0x0b, 0x81, 0x8b, 0xf9, 0x3b, 0xf4, 0x4b, 0x02, 0x93, 0xf9, 0x6d, 0x93, 0x77, 0x37, 0x64, 0xa4, 0x70, 0x60, 0x5b, 0xaf, 0xce, 0x0c, 0x3c, 0x13, 0x27, 0x1c, 0x7b, 0x8b,
0x32, 0x54, 0x38, 0x74, 0x5e, 0xb0, 0x66, 0x87, 0xee, 0x89, 0x0b, 0x8e, 0xbd, 0x8e, 0x08, 0x6d, 0x10, 0xda, 0xf8, 0x7c, 0xee, 0xc3, 0x6f, 0x2d, 0x98, 0xe8, 0x3f, 0xab, 0x1a, 0x68, 0x03, 0x07,
0xfa, 0x62, 0xee, 0xa3, 0x5f, 0x11, 0x98, 0xcc, 0x1f, 0x82, 0x0d, 0xb4, 0xa1, 0x13, 0x72, 0xa1, 0xd9, 0x5c, 0x7f, 0x5d, 0x25, 0x34, 0x97, 0xf0, 0x62, 0x11, 0x7f, 0xd9, 0x9b, 0x5a, 0xe7, 0x79,
0xbf, 0xae, 0x21, 0x9a, 0xcb, 0xf4, 0x52, 0x19, 0x7f, 0xd9, 0x5b, 0x5a, 0xe7, 0x05, 0x42, 0xbf, 0x0b, 0x7f, 0xb2, 0xa0, 0x92, 0x37, 0x47, 0xe2, 0xe9, 0xdc, 0x60, 0x66, 0xc6, 0xcc, 0x6a, 0x5c,
0x27, 0x50, 0x2f, 0x1a, 0x50, 0xe9, 0x99, 0xc2, 0x60, 0x66, 0xe6, 0x57, 0x2b, 0x6e, 0x22, 0x49, 0xfc, 0x93, 0x86, 0xcc, 0x36, 0x08, 0x97, 0x40, 0xb7, 0x10, 0xae, 0x30, 0xa8, 0x4b, 0x7b, 0xcb,
0xa7, 0x67, 0x9b, 0x88, 0x4b, 0x50, 0xb7, 0x14, 0xae, 0x30, 0x68, 0x4a, 0x7b, 0xdb, 0x8c, 0x8d, 0x4c, 0x77, 0xdb, 0x76, 0x3a, 0x5e, 0x4a, 0x7b, 0x6b, 0xc7, 0xa8, 0xb9, 0x6d, 0x37, 0x83, 0x35,
0x3b, 0x76, 0x3a, 0xb7, 0x4a, 0x7b, 0x7b, 0xd7, 0x0c, 0xbb, 0x63, 0xb7, 0x83, 0x75, 0x79, 0x81, 0x79, 0xde, 0xc2, 0x5f, 0xac, 0xfe, 0x8f, 0x16, 0x33, 0x01, 0xe2, 0xab, 0xb9, 0x36, 0xec, 0x9c,
0xd0, 0x1f, 0x49, 0xfe, 0x6b, 0xc8, 0x8c, 0x96, 0xf4, 0x7f, 0x85, 0x36, 0xec, 0x1e, 0x77, 0xad, 0x4a, 0xab, 0xb3, 0xcf, 0x3e, 0x68, 0xee, 0xc1, 0x32, 0x59, 0x78, 0x1b, 0x6f, 0xbd, 0x08, 0x0b,
0xb9, 0xe7, 0x6f, 0x34, 0x79, 0xb0, 0x82, 0x16, 0xde, 0xa1, 0xb7, 0x5f, 0x86, 0x85, 0x66, 0xa6, 0xcd, 0xe8, 0x89, 0xdf, 0x5b, 0xf0, 0x72, 0xee, 0xf3, 0x03, 0xcf, 0x10, 0xb8, 0x67, 0x3d, 0x4f,
0xa5, 0xdf, 0x10, 0xf8, 0x4f, 0xe1, 0xbb, 0x86, 0x9e, 0x45, 0x70, 0xcf, 0x7b, 0xf7, 0x14, 0xe6, 0x72, 0xef, 0xca, 0x02, 0x21, 0xbe, 0x52, 0xbd, 0x5c, 0x08, 0x71, 0x64, 0xd4, 0xe2, 0x0f, 0x16,
0xca, 0x22, 0x22, 0xbe, 0x6a, 0x5d, 0x29, 0x85, 0x38, 0x32, 0x6a, 0xe9, 0xb7, 0x04, 0xac, 0xe2, 0x54, 0xf3, 0x1f, 0x33, 0x78, 0x96, 0xb4, 0x3f, 0xf3, 0xb5, 0x53, 0x9d, 0xa8, 0xc5, 0xaf, 0xe9,
0x57, 0x12, 0x3d, 0x87, 0xda, 0x9f, 0xfb, 0x8c, 0xb2, 0x26, 0x1b, 0xf1, 0xc3, 0xbc, 0x91, 0x3c, 0x5a, 0xf2, 0x9a, 0xae, 0x2d, 0xe8, 0xd7, 0x34, 0x5b, 0x24, 0x94, 0xef, 0x55, 0xdf, 0x2d, 0x84,
0xcc, 0x1b, 0x8b, 0xfa, 0x61, 0xce, 0x96, 0x10, 0xe5, 0xdb, 0xd6, 0x5b, 0xa5, 0x50, 0xaa, 0x44, 0x52, 0x25, 0x7a, 0x75, 0x71, 0x2a, 0x67, 0x9e, 0x9d, 0x38, 0x99, 0x44, 0x76, 0xd7, 0x43, 0xb4,
0xaf, 0xbe, 0x9c, 0x6a, 0x99, 0xf7, 0x2c, 0x9d, 0x4a, 0x22, 0xbb, 0xe7, 0x85, 0x6b, 0xc5, 0x73, 0x1a, 0xcf, 0x3b, 0xbb, 0x47, 0x14, 0x76, 0x87, 0x70, 0xdc, 0xc4, 0x1b, 0x85, 0x70, 0x70, 0x23,
0xd3, 0xde, 0x11, 0x85, 0xdd, 0x45, 0x1c, 0xb7, 0xe8, 0xcd, 0x52, 0x38, 0xb8, 0x11, 0x27, 0xed, 0x4e, 0xda, 0x5b, 0x1b, 0xa2, 0x73, 0xf9, 0xdc, 0xb9, 0x6d, 0xfc, 0xc2, 0x82, 0xb1, 0xb4, 0x7f,
0xed, 0x4d, 0xd1, 0xbb, 0x72, 0xfe, 0xfc, 0x0e, 0xfd, 0x94, 0x40, 0x35, 0xed, 0xdf, 0xf4, 0x78, 0xe3, 0xb1, 0xb4, 0xd6, 0x64, 0x27, 0x05, 0x13, 0xbb, 0x9e, 0x36, 0xcf, 0x96, 0x08, 0xcd, 0x22,
0x7a, 0xd7, 0x64, 0x27, 0x05, 0x13, 0xbb, 0x81, 0x36, 0xcf, 0x96, 0x11, 0xcd, 0x12, 0xbd, 0x51, 0x5e, 0x2f, 0x84, 0x86, 0x26, 0x01, 0x7b, 0x4b, 0x4f, 0x11, 0x04, 0xe5, 0x47, 0x0b, 0xa6, 0x06,
0x0a, 0x0d, 0x4e, 0x02, 0xf6, 0xb6, 0x9e, 0x22, 0x10, 0xca, 0x77, 0x04, 0xa6, 0x87, 0x76, 0x63, 0x76, 0x63, 0x89, 0xaf, 0xc5, 0x5e, 0xd9, 0x43, 0xcb, 0xce, 0x8d, 0xa4, 0xc9, 0x10, 0x76, 0xa5,
0x49, 0xff, 0x1f, 0x7b, 0x65, 0x1f, 0x2d, 0xbb, 0x30, 0x92, 0xa6, 0x42, 0xd8, 0xd5, 0x52, 0x98, 0x10, 0xe6, 0x6e, 0x7b, 0xbc, 0x98, 0x69, 0x95, 0xf8, 0x9b, 0x05, 0x33, 0x7b, 0x68, 0xde, 0x68,
0xfb, 0xed, 0xf1, 0x52, 0xa6, 0x55, 0xd2, 0x9f, 0x09, 0xcc, 0xee, 0xa3, 0x79, 0x53, 0xdb, 0xb4, 0x9b, 0x16, 0xb9, 0xd7, 0x36, 0x9f, 0x6b, 0xc5, 0xc7, 0x64, 0xc5, 0x43, 0xf6, 0x41, 0x21, 0x2b,
0xc8, 0xfd, 0xb6, 0xf9, 0x42, 0x2b, 0x3e, 0x40, 0x2b, 0x1e, 0xb1, 0x77, 0x4b, 0x59, 0xe1, 0x46, 0xdc, 0x28, 0xf0, 0x1f, 0xd1, 0x84, 0xff, 0xa8, 0xbf, 0x41, 0xab, 0xfb, 0x48, 0xdf, 0x1b, 0xff,
0x81, 0xff, 0x18, 0x9f, 0x0e, 0x8f, 0xf3, 0x0d, 0x5a, 0x3b, 0x80, 0xfa, 0x5e, 0xfd, 0x33, 0x00, 0x04, 0x00, 0x00, 0xff, 0xff, 0x72, 0xb1, 0x57, 0x27, 0x90, 0x12, 0x00, 0x00,
0x00, 0xff, 0xff, 0x61, 0xc5, 0x94, 0x20, 0xdb, 0x12, 0x00, 0x00,
} }
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.

View File

@@ -7,6 +7,7 @@ import "google/protobuf/empty.proto";
import "workflow_template.proto"; import "workflow_template.proto";
import "metric.proto"; import "metric.proto";
import "label.proto"; import "label.proto";
import "common.proto";
service WorkflowService { service WorkflowService {
// Creates a Workflow // Creates a Workflow
@@ -165,17 +166,14 @@ message WorkflowExecution {
string finishedAt = 6; string finishedAt = 6;
string manifest = 7; string manifest = 7;
repeated WorkflowExecutionParameter parameters = 8; repeated Parameter parameters = 8;
WorkflowTemplate workflowTemplate = 9; WorkflowTemplate workflowTemplate = 9;
repeated KeyValue labels = 10; repeated KeyValue labels = 10;
} }
message WorkflowExecutionParameter {
string name = 1;
string value = 2;
}
message ArtifactResponse { message ArtifactResponse {
bytes data = 1; bytes data = 1;

264
api/workspace.pb.go Normal file
View File

@@ -0,0 +1,264 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: workspace.proto
package api
import (
context "context"
fmt "fmt"
proto "github.com/golang/protobuf/proto"
_ "google.golang.org/genproto/googleapis/api/annotations"
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 Workspace struct {
Uid string `protobuf:"bytes,1,opt,name=uid,proto3" json:"uid,omitempty"`
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"`
Version int64 `protobuf:"varint,3,opt,name=version,proto3" json:"version,omitempty"`
CreatedAt string `protobuf:"bytes,4,opt,name=createdAt,proto3" json:"createdAt,omitempty"`
Parameters []*Parameter `protobuf:"bytes,5,rep,name=parameters,proto3" json:"parameters,omitempty"`
WorkspaceTemplate *WorkspaceTemplate `protobuf:"bytes,6,opt,name=workspaceTemplate,proto3" json:"workspaceTemplate,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *Workspace) Reset() { *m = Workspace{} }
func (m *Workspace) String() string { return proto.CompactTextString(m) }
func (*Workspace) ProtoMessage() {}
func (*Workspace) Descriptor() ([]byte, []int) {
return fileDescriptor_dac718ecaafc2333, []int{0}
}
func (m *Workspace) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_Workspace.Unmarshal(m, b)
}
func (m *Workspace) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_Workspace.Marshal(b, m, deterministic)
}
func (m *Workspace) XXX_Merge(src proto.Message) {
xxx_messageInfo_Workspace.Merge(m, src)
}
func (m *Workspace) XXX_Size() int {
return xxx_messageInfo_Workspace.Size(m)
}
func (m *Workspace) XXX_DiscardUnknown() {
xxx_messageInfo_Workspace.DiscardUnknown(m)
}
var xxx_messageInfo_Workspace proto.InternalMessageInfo
func (m *Workspace) GetUid() string {
if m != nil {
return m.Uid
}
return ""
}
func (m *Workspace) GetName() string {
if m != nil {
return m.Name
}
return ""
}
func (m *Workspace) GetVersion() int64 {
if m != nil {
return m.Version
}
return 0
}
func (m *Workspace) GetCreatedAt() string {
if m != nil {
return m.CreatedAt
}
return ""
}
func (m *Workspace) GetParameters() []*Parameter {
if m != nil {
return m.Parameters
}
return nil
}
func (m *Workspace) GetWorkspaceTemplate() *WorkspaceTemplate {
if m != nil {
return m.WorkspaceTemplate
}
return nil
}
type CreateWorkspaceRequest struct {
Namespace string `protobuf:"bytes,1,opt,name=namespace,proto3" json:"namespace,omitempty"`
Workspace *Workspace `protobuf:"bytes,3,opt,name=workspace,proto3" json:"workspace,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *CreateWorkspaceRequest) Reset() { *m = CreateWorkspaceRequest{} }
func (m *CreateWorkspaceRequest) String() string { return proto.CompactTextString(m) }
func (*CreateWorkspaceRequest) ProtoMessage() {}
func (*CreateWorkspaceRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_dac718ecaafc2333, []int{1}
}
func (m *CreateWorkspaceRequest) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_CreateWorkspaceRequest.Unmarshal(m, b)
}
func (m *CreateWorkspaceRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_CreateWorkspaceRequest.Marshal(b, m, deterministic)
}
func (m *CreateWorkspaceRequest) XXX_Merge(src proto.Message) {
xxx_messageInfo_CreateWorkspaceRequest.Merge(m, src)
}
func (m *CreateWorkspaceRequest) XXX_Size() int {
return xxx_messageInfo_CreateWorkspaceRequest.Size(m)
}
func (m *CreateWorkspaceRequest) XXX_DiscardUnknown() {
xxx_messageInfo_CreateWorkspaceRequest.DiscardUnknown(m)
}
var xxx_messageInfo_CreateWorkspaceRequest proto.InternalMessageInfo
func (m *CreateWorkspaceRequest) GetNamespace() string {
if m != nil {
return m.Namespace
}
return ""
}
func (m *CreateWorkspaceRequest) GetWorkspace() *Workspace {
if m != nil {
return m.Workspace
}
return nil
}
func init() {
proto.RegisterType((*Workspace)(nil), "api.Workspace")
proto.RegisterType((*CreateWorkspaceRequest)(nil), "api.CreateWorkspaceRequest")
}
func init() { proto.RegisterFile("workspace.proto", fileDescriptor_dac718ecaafc2333) }
var fileDescriptor_dac718ecaafc2333 = []byte{
// 332 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x51, 0xb1, 0x4e, 0xeb, 0x30,
0x14, 0x55, 0x9a, 0xbe, 0x3e, 0xe5, 0xf6, 0xe9, 0xb5, 0x78, 0xa8, 0xac, 0xd0, 0x21, 0x8a, 0x18,
0x32, 0xa0, 0x44, 0x2d, 0x03, 0x12, 0x1b, 0x82, 0x0f, 0x40, 0x01, 0xa9, 0x23, 0x72, 0xd3, 0xab,
0xca, 0xa2, 0x89, 0x8d, 0xed, 0xb6, 0x03, 0x62, 0x61, 0x65, 0xe4, 0xd3, 0xf8, 0x00, 0x16, 0x3e,
0x04, 0xc5, 0x6d, 0x1c, 0x54, 0xd8, 0x7c, 0xcf, 0x3d, 0xe7, 0xf8, 0x1c, 0x5d, 0x18, 0x6c, 0x85,
0x7a, 0xd0, 0x92, 0x15, 0x98, 0x4a, 0x25, 0x8c, 0x20, 0x3e, 0x93, 0x3c, 0x1c, 0x2f, 0x85, 0x58,
0xae, 0x30, 0x63, 0x92, 0x67, 0xac, 0xaa, 0x84, 0x61, 0x86, 0x8b, 0x4a, 0xef, 0x28, 0x21, 0x75,
0x9a, 0x7b, 0x83, 0xa5, 0x5c, 0x31, 0xb3, 0x17, 0x87, 0xff, 0x0a, 0x51, 0x96, 0xa2, 0xda, 0x4d,
0xf1, 0x87, 0x07, 0xc1, 0xac, 0xa1, 0x92, 0x21, 0xf8, 0x6b, 0xbe, 0xa0, 0x5e, 0xe4, 0x25, 0x41,
0x5e, 0x3f, 0x09, 0x81, 0x6e, 0xc5, 0x4a, 0xa4, 0x1d, 0x0b, 0xd9, 0x37, 0xa1, 0xf0, 0x77, 0x83,
0x4a, 0x73, 0x51, 0x51, 0x3f, 0xf2, 0x12, 0x3f, 0x6f, 0x46, 0x32, 0x86, 0xa0, 0x50, 0xc8, 0x0c,
0x2e, 0x2e, 0x0d, 0xed, 0x5a, 0x49, 0x0b, 0x90, 0x14, 0x40, 0x32, 0xc5, 0x4a, 0x34, 0xa8, 0x34,
0xfd, 0x13, 0xf9, 0x49, 0x7f, 0xfa, 0x3f, 0x65, 0x92, 0xa7, 0x37, 0x0d, 0x9c, 0x7f, 0x63, 0x90,
0x6b, 0x38, 0x72, 0x2d, 0xee, 0xf6, 0x25, 0x68, 0x2f, 0xf2, 0x92, 0xfe, 0x74, 0x64, 0x65, 0xb3,
0xc3, 0x6d, 0xfe, 0x53, 0x10, 0x2f, 0x60, 0x74, 0x65, 0x23, 0x38, 0x76, 0x8e, 0x8f, 0x6b, 0xd4,
0xa6, 0x4e, 0x5b, 0xf7, 0xb1, 0xd8, 0xbe, 0x73, 0x0b, 0x90, 0x53, 0x08, 0x9c, 0x99, 0xed, 0xd9,
0x84, 0x6d, 0x7d, 0x5a, 0xc2, 0xf4, 0xd5, 0x83, 0xa1, 0x5b, 0xdc, 0xa2, 0xda, 0xf0, 0x02, 0xc9,
0x16, 0x06, 0x07, 0x5f, 0x93, 0x63, 0x6b, 0xf1, 0x7b, 0xa0, 0xf0, 0xc0, 0x3f, 0x3e, 0x7f, 0x79,
0xff, 0x7c, 0xeb, 0x4c, 0xe2, 0x93, 0xfa, 0xc8, 0x3a, 0xdb, 0x4c, 0xe6, 0x68, 0xd8, 0x24, 0x7b,
0x72, 0x21, 0x9f, 0x33, 0x97, 0x40, 0x5f, 0xb4, 0x69, 0xe6, 0x3d, 0x7b, 0xdc, 0xb3, 0xaf, 0x00,
0x00, 0x00, 0xff, 0xff, 0xb6, 0x9e, 0x1f, 0xcf, 0x3a, 0x02, 0x00, 0x00,
}
// 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
// WorkspaceServiceClient is the client API for WorkspaceService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type WorkspaceServiceClient interface {
CreateWorkspace(ctx context.Context, in *CreateWorkspaceRequest, opts ...grpc.CallOption) (*Workspace, error)
}
type workspaceServiceClient struct {
cc *grpc.ClientConn
}
func NewWorkspaceServiceClient(cc *grpc.ClientConn) WorkspaceServiceClient {
return &workspaceServiceClient{cc}
}
func (c *workspaceServiceClient) CreateWorkspace(ctx context.Context, in *CreateWorkspaceRequest, opts ...grpc.CallOption) (*Workspace, error) {
out := new(Workspace)
err := c.cc.Invoke(ctx, "/api.WorkspaceService/CreateWorkspace", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// WorkspaceServiceServer is the server API for WorkspaceService service.
type WorkspaceServiceServer interface {
CreateWorkspace(context.Context, *CreateWorkspaceRequest) (*Workspace, error)
}
// UnimplementedWorkspaceServiceServer can be embedded to have forward compatible implementations.
type UnimplementedWorkspaceServiceServer struct {
}
func (*UnimplementedWorkspaceServiceServer) CreateWorkspace(ctx context.Context, req *CreateWorkspaceRequest) (*Workspace, error) {
return nil, status.Errorf(codes.Unimplemented, "method CreateWorkspace not implemented")
}
func RegisterWorkspaceServiceServer(s *grpc.Server, srv WorkspaceServiceServer) {
s.RegisterService(&_WorkspaceService_serviceDesc, srv)
}
func _WorkspaceService_CreateWorkspace_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(CreateWorkspaceRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(WorkspaceServiceServer).CreateWorkspace(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/api.WorkspaceService/CreateWorkspace",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(WorkspaceServiceServer).CreateWorkspace(ctx, req.(*CreateWorkspaceRequest))
}
return interceptor(ctx, in, info, handler)
}
var _WorkspaceService_serviceDesc = grpc.ServiceDesc{
ServiceName: "api.WorkspaceService",
HandlerType: (*WorkspaceServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "CreateWorkspace",
Handler: _WorkspaceService_CreateWorkspace_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "workspace.proto",
}

199
api/workspace.pb.gw.go Normal file
View File

@@ -0,0 +1,199 @@
// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
// source: workspace.proto
/*
Package api is a reverse proxy.
It translates gRPC into RESTful JSON APIs.
*/
package api
import (
"context"
"io"
"net/http"
"github.com/golang/protobuf/descriptor"
"github.com/golang/protobuf/proto"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
"github.com/grpc-ecosystem/grpc-gateway/utilities"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/status"
)
// Suppress "imported and not used" errors
var _ codes.Code
var _ io.Reader
var _ status.Status
var _ = runtime.String
var _ = utilities.NewDoubleArray
var _ = descriptor.ForMessage
func request_WorkspaceService_CreateWorkspace_0(ctx context.Context, marshaler runtime.Marshaler, client WorkspaceServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq CreateWorkspaceRequest
var metadata runtime.ServerMetadata
newReader, berr := utilities.IOReaderFactory(req.Body)
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Workspace); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["namespace"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "namespace")
}
protoReq.Namespace, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "namespace", err)
}
msg, err := client.CreateWorkspace(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_WorkspaceService_CreateWorkspace_0(ctx context.Context, marshaler runtime.Marshaler, server WorkspaceServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq CreateWorkspaceRequest
var metadata runtime.ServerMetadata
newReader, berr := utilities.IOReaderFactory(req.Body)
if berr != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
}
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq.Workspace); err != nil && err != io.EOF {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["namespace"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "namespace")
}
protoReq.Namespace, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "namespace", err)
}
msg, err := server.CreateWorkspace(ctx, &protoReq)
return msg, metadata, err
}
// RegisterWorkspaceServiceHandlerServer registers the http handlers for service WorkspaceService to "mux".
// UnaryRPC :call WorkspaceServiceServer directly.
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
func RegisterWorkspaceServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server WorkspaceServiceServer) error {
mux.Handle("POST", pattern_WorkspaceService_CreateWorkspace_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_WorkspaceService_CreateWorkspace_0(rctx, inboundMarshaler, server, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_WorkspaceService_CreateWorkspace_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
// RegisterWorkspaceServiceHandlerFromEndpoint is same as RegisterWorkspaceServiceHandler but
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
func RegisterWorkspaceServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
conn, err := grpc.Dial(endpoint, opts...)
if err != nil {
return err
}
defer func() {
if err != nil {
if cerr := conn.Close(); cerr != nil {
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
}
return
}
go func() {
<-ctx.Done()
if cerr := conn.Close(); cerr != nil {
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
}
}()
}()
return RegisterWorkspaceServiceHandler(ctx, mux, conn)
}
// RegisterWorkspaceServiceHandler registers the http handlers for service WorkspaceService to "mux".
// The handlers forward requests to the grpc endpoint over "conn".
func RegisterWorkspaceServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
return RegisterWorkspaceServiceHandlerClient(ctx, mux, NewWorkspaceServiceClient(conn))
}
// RegisterWorkspaceServiceHandlerClient registers the http handlers for service WorkspaceService
// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "WorkspaceServiceClient".
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "WorkspaceServiceClient"
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
// "WorkspaceServiceClient" to call the correct interceptors.
func RegisterWorkspaceServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client WorkspaceServiceClient) error {
mux.Handle("POST", pattern_WorkspaceService_CreateWorkspace_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_WorkspaceService_CreateWorkspace_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_WorkspaceService_CreateWorkspace_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
var (
pattern_WorkspaceService_CreateWorkspace_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3}, []string{"apis", "v1beta1", "namespace", "workspaces"}, "", runtime.AssumeColonVerbOpt(true)))
)
var (
forward_WorkspaceService_CreateWorkspace_0 = runtime.ForwardResponseMessage
)

30
api/workspace.proto Normal file
View File

@@ -0,0 +1,30 @@
syntax = "proto3";
package api;
import "google/api/annotations.proto";
import "workspace_template.proto";
import "common.proto";
service WorkspaceService {
rpc CreateWorkspace (CreateWorkspaceRequest) returns (Workspace) {
option (google.api.http) = {
post: "/apis/v1beta1/{namespace}/workspaces"
body: "workspace"
};
}
}
message Workspace {
string uid = 1;
string name = 2;
int64 version = 3;
string createdAt = 4;
repeated Parameter parameters = 5;
WorkspaceTemplate workspaceTemplate = 6;
}
message CreateWorkspaceRequest {
string namespace = 1;
Workspace workspace = 3;
}

1
go.mod
View File

@@ -8,6 +8,7 @@ require (
github.com/Masterminds/squirrel v1.1.0 github.com/Masterminds/squirrel v1.1.0
github.com/argoproj/argo v0.0.0-20200331233432-4d1175eb68f6 github.com/argoproj/argo v0.0.0-20200331233432-4d1175eb68f6
github.com/argoproj/pkg v0.0.0-20200318225345-d3be5f29b1a8 github.com/argoproj/pkg v0.0.0-20200318225345-d3be5f29b1a8
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535
github.com/elazarl/goproxy v0.0.0-20191011121108-aa519ddbe484 // indirect github.com/elazarl/goproxy v0.0.0-20191011121108-aa519ddbe484 // indirect
github.com/evanphx/json-patch v4.5.0+incompatible // indirect github.com/evanphx/json-patch v4.5.0+incompatible // indirect
github.com/ghodss/yaml v1.0.0 github.com/ghodss/yaml v1.0.0

2
go.sum
View File

@@ -71,6 +71,8 @@ github.com/argoproj/pkg v0.0.0-20200318225345-d3be5f29b1a8 h1:RMfnXz1F/mOr2bBwMp
github.com/argoproj/pkg v0.0.0-20200318225345-d3be5f29b1a8/go.mod h1:2EZ44RG/CcgtPTwrRR0apOc7oU6UIw8GjCUJWZ8X3bM= github.com/argoproj/pkg v0.0.0-20200318225345-d3be5f29b1a8/go.mod h1:2EZ44RG/CcgtPTwrRR0apOc7oU6UIw8GjCUJWZ8X3bM=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 h1:4daAzAu0S6Vi7/lbWECcX0j45yZReDZ56BQsrVBOEEY=
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
github.com/aws/aws-sdk-go v1.27.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.27.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc= github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=

View File

@@ -98,8 +98,9 @@ func startRPCServer(db *v1.DB, kubeConfig *v1.Config) {
api.RegisterSecretServiceServer(s, server.NewSecretServer()) api.RegisterSecretServiceServer(s, server.NewSecretServer())
api.RegisterNamespaceServiceServer(s, server.NewNamespaceServer()) api.RegisterNamespaceServiceServer(s, server.NewNamespaceServer())
api.RegisterAuthServiceServer(s, server.NewAuthServer()) api.RegisterAuthServiceServer(s, server.NewAuthServer())
api.RegisterWorkspaceTemplateServiceServer(s, server.NewWorkspaceTemplateServer())
api.RegisterLabelServiceServer(s, server.NewLabelServer()) api.RegisterLabelServiceServer(s, server.NewLabelServer())
api.RegisterWorkspaceTemplateServiceServer(s, server.NewWorkspaceTemplateServer())
api.RegisterWorkspaceServiceServer(s, server.NewWorkspaceServer())
if err := s.Serve(lis); err != nil { if err := s.Serve(lis); err != nil {
log.Fatalf("Failed to serve RPC server: %v", err) log.Fatalf("Failed to serve RPC server: %v", err)
@@ -123,8 +124,9 @@ func startHTTPProxy() {
registerHandler(api.RegisterSecretServiceHandlerFromEndpoint, ctx, mux, endpoint, opts) registerHandler(api.RegisterSecretServiceHandlerFromEndpoint, ctx, mux, endpoint, opts)
registerHandler(api.RegisterNamespaceServiceHandlerFromEndpoint, ctx, mux, endpoint, opts) registerHandler(api.RegisterNamespaceServiceHandlerFromEndpoint, ctx, mux, endpoint, opts)
registerHandler(api.RegisterAuthServiceHandlerFromEndpoint, ctx, mux, endpoint, opts) registerHandler(api.RegisterAuthServiceHandlerFromEndpoint, ctx, mux, endpoint, opts)
registerHandler(api.RegisterWorkspaceTemplateServiceHandlerFromEndpoint, ctx, mux, endpoint, opts)
registerHandler(api.RegisterLabelServiceHandlerFromEndpoint, ctx, mux, endpoint, opts) registerHandler(api.RegisterLabelServiceHandlerFromEndpoint, ctx, mux, endpoint, opts)
registerHandler(api.RegisterWorkspaceTemplateServiceHandlerFromEndpoint, ctx, mux, endpoint, opts)
registerHandler(api.RegisterWorkspaceServiceHandlerFromEndpoint, ctx, mux, endpoint, opts)
log.Printf("Starting HTTP proxy on port %v", *httpPort) log.Printf("Starting HTTP proxy on port %v", *httpPort)

View File

@@ -42,7 +42,7 @@ func (c *Client) UpdateCronWorkflow(namespace string, name string, cronWorkflow
re, _ := regexp.Compile(`[^a-zA-Z0-9-]{1,}`) re, _ := regexp.Compile(`[^a-zA-Z0-9-]{1,}`)
opts.GenerateName = strings.ToLower(re.ReplaceAllString(workflowTemplate.Name, `-`)) + "-" opts.GenerateName = strings.ToLower(re.ReplaceAllString(workflowTemplate.Name, `-`)) + "-"
for _, param := range workflow.Parameters { for _, param := range workflow.Parameters {
opts.Parameters = append(opts.Parameters, WorkflowExecutionParameter{ opts.Parameters = append(opts.Parameters, Parameter{
Name: param.Name, Name: param.Name,
Value: param.Value, Value: param.Value,
}) })
@@ -164,7 +164,7 @@ func (c *Client) CreateCronWorkflow(namespace string, cronWorkflow *CronWorkflow
re, _ := regexp.Compile(`[^a-zA-Z0-9-]{1,}`) re, _ := regexp.Compile(`[^a-zA-Z0-9-]{1,}`)
opts.GenerateName = strings.ToLower(re.ReplaceAllString(workflowTemplate.Name, `-`)) + "-" opts.GenerateName = strings.ToLower(re.ReplaceAllString(workflowTemplate.Name, `-`)) + "-"
for _, param := range workflow.Parameters { for _, param := range workflow.Parameters {
opts.Parameters = append(opts.Parameters, WorkflowExecutionParameter{ opts.Parameters = append(opts.Parameters, Parameter{
Name: param.Name, Name: param.Name,
Value: param.Value, Value: param.Value,
}) })

View File

@@ -2,7 +2,6 @@ package v1
import ( import (
"encoding/json" "encoding/json"
v1 "github.com/onepanelio/core/pkg/apis/core/v1"
"github.com/onepanelio/core/pkg/util/mapping" "github.com/onepanelio/core/pkg/util/mapping"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"gopkg.in/yaml.v2" "gopkg.in/yaml.v2"
@@ -76,8 +75,8 @@ type CronWorkflow struct {
Manifest string Manifest string
} }
func (cw *CronWorkflow) GetParametersFromWorkflowSpec() ([]WorkflowExecutionParameter, error) { func (cw *CronWorkflow) GetParametersFromWorkflowSpec() ([]Parameter, error) {
var parameters []WorkflowExecutionParameter var parameters []Parameter
mappedData := make(map[string]interface{}) mappedData := make(map[string]interface{})
@@ -107,7 +106,7 @@ func (cw *CronWorkflow) GetParametersFromWorkflowSpec() ([]WorkflowExecutionPara
name := paramMap["name"].(string) name := paramMap["name"].(string)
value := paramMap["value"].(string) value := paramMap["value"].(string)
workflowParameter := WorkflowExecutionParameter{ workflowParameter := Parameter{
Name: name, Name: name,
Value: &value, Value: &value,
} }
@@ -273,7 +272,7 @@ func (wt *WorkflowTemplate) GenerateUID() (string, error) {
return wt.UID, nil return wt.UID, nil
} }
func (wt *WorkflowTemplate) UpdateManifestParameters(params []WorkflowExecutionParameter) error { func (wt *WorkflowTemplate) UpdateManifestParameters(params []Parameter) error {
manifestMap, err := mapping.NewFromYamlString(wt.Manifest) manifestMap, err := mapping.NewFromYamlString(wt.Manifest)
if err != nil { if err != nil {
return err return err
@@ -427,7 +426,7 @@ type WorkflowExecution struct {
UID string UID string
Name string Name string
GenerateName string GenerateName string
Parameters []WorkflowExecutionParameter Parameters []Parameter
Manifest string Manifest string
Phase wfv1.NodePhase Phase wfv1.NodePhase
StartedAt *time.Time `db:"started_at"` StartedAt *time.Time `db:"started_at"`
@@ -436,9 +435,6 @@ type WorkflowExecution struct {
Labels map[string]string Labels map[string]string
} }
// TODO: Using an alias so we can refactor out WorkflowExecutionParameter
type WorkflowExecutionParameter = v1.Parameter
type ListOptions = metav1.ListOptions type ListOptions = metav1.ListOptions
type PodGCStrategy = wfv1.PodGCStrategy type PodGCStrategy = wfv1.PodGCStrategy
@@ -447,7 +443,7 @@ type WorkflowExecutionOptions struct {
Name string Name string
GenerateName string GenerateName string
Entrypoint string Entrypoint string
Parameters []WorkflowExecutionParameter Parameters []Parameter
ServiceAccount string ServiceAccount string
Labels *map[string]string Labels *map[string]string
ListOptions *ListOptions ListOptions *ListOptions
@@ -593,24 +589,3 @@ func CronWorkflowsToIds(resources []*CronWorkflow) (ids []uint64) {
return return
} }
type WorkspaceTemplate struct {
ID uint64
UID string
Name string
Version int64
Manifest string
IsLatest bool
CreatedAt time.Time `db:"created_at"`
WorkflowTemplate *WorkflowTemplate
}
func (wt *WorkspaceTemplate) GenerateUID() (string, error) {
uid, err := uuid.NewRandom()
if err != nil {
return "", err
}
wt.UID = uid.String()
return wt.UID, nil
}

View File

@@ -0,0 +1,14 @@
package validate
import (
"github.com/asaskevich/govalidator"
"strings"
)
func IsDNSHost(str string) bool {
if str == "" || len(strings.Replace(str, ".", "", -1)) > 63 {
// constraints already violated
return false
}
return govalidator.IsDNSName(str)
}

View File

@@ -141,14 +141,14 @@ func (c *Client) injectAutomatedFields(namespace string, wf *wfv1.Workflow, opts
}) })
// Always add output artifacts for metrics but make them optional // Always add output artifacts for metrics but make them optional
wf.Spec.Templates[i].Outputs.Artifacts = append(template.Outputs.Artifacts, wfv1.Artifact{ //wf.Spec.Templates[i].Outputs.Artifacts = append(template.Outputs.Artifacts, wfv1.Artifact{
Name: "sys-metrics", // Name: "sys-metrics",
Path: "/tmp/sys-metrics.json", // Path: "/tmp/sys-metrics.json",
Optional: true, // Optional: true,
Archive: &wfv1.ArchiveStrategy{ // Archive: &wfv1.ArchiveStrategy{
None: &wfv1.NoneStrategy{}, // None: &wfv1.NoneStrategy{},
}, // },
}) //})
if !addSecretValsToTemplate { if !addSecretValsToTemplate {
continue continue
@@ -310,7 +310,7 @@ func (c *Client) CreateWorkflowExecution(namespace string, workflow *WorkflowExe
re, _ := regexp.Compile(`[^a-zA-Z0-9-]{1,}`) re, _ := regexp.Compile(`[^a-zA-Z0-9-]{1,}`)
opts.GenerateName = strings.ToLower(re.ReplaceAllString(workflowTemplate.Name, `-`)) + "-" opts.GenerateName = strings.ToLower(re.ReplaceAllString(workflowTemplate.Name, `-`)) + "-"
for _, param := range workflow.Parameters { for _, param := range workflow.Parameters {
opts.Parameters = append(opts.Parameters, WorkflowExecutionParameter{ opts.Parameters = append(opts.Parameters, Parameter{
Name: param.Name, Name: param.Name,
Value: param.Value, Value: param.Value,
}) })
@@ -1059,7 +1059,7 @@ func filterOutCustomTypesFromManifest(manifest []byte) (result []byte, err error
// If the parameter does not have a value, skip it so argo doesn't try to process it and fail. // If the parameter does not have a value, skip it so argo doesn't try to process it and fail.
if _, hasValue := paramMap["value"]; !hasValue { if _, hasValue := paramMap["value"]; !hasValue {
continue paramMap["value"] = "<value>"
} }
parametersToKeep = append(parametersToKeep, parameter) parametersToKeep = append(parametersToKeep, parameter)

View File

@@ -339,23 +339,31 @@ func (c *Client) archiveWorkflowTemplate(namespace, uid string) (bool, error) {
return true, nil return true, nil
} }
func (c *Client) CreateWorkflowTemplate(namespace string, workflowTemplate *WorkflowTemplate) (*WorkflowTemplate, error) { func (c *Client) validateWorkflowTemplate(namespace string, workflowTemplate *WorkflowTemplate) (err error) {
// validate workflow template // validate workflow template
finalBytes, err := workflowTemplate.WrapSpec() finalBytes, err := workflowTemplate.WrapSpec()
if err != nil { if err != nil {
return nil, util.NewUserError(codes.InvalidArgument, err.Error()) return
} }
err = c.ValidateWorkflowExecution(namespace, finalBytes)
if err := c.ValidateWorkflowExecution(namespace, finalBytes); err != nil { if err != nil {
log.WithFields(log.Fields{ log.WithFields(log.Fields{
"Namespace": namespace, "Namespace": namespace,
"WorkflowTemplate": workflowTemplate, "WorkflowTemplate": workflowTemplate,
"Error": err.Error(), "Error": err.Error(),
}).Error("Workflow could not be validated.") }).Error("Workflow could not be validated.")
}
return
}
func (c *Client) CreateWorkflowTemplate(namespace string, workflowTemplate *WorkflowTemplate) (*WorkflowTemplate, error) {
// validate workflow template
if err := c.validateWorkflowTemplate(namespace, workflowTemplate); err != nil {
return nil, util.NewUserError(codes.InvalidArgument, err.Error()) return nil, util.NewUserError(codes.InvalidArgument, err.Error())
} }
workflowTemplate, err = c.createWorkflowTemplate(namespace, workflowTemplate) workflowTemplate, err := c.createWorkflowTemplate(namespace, workflowTemplate)
if err != nil { if err != nil {
log.WithFields(log.Fields{ log.WithFields(log.Fields{
"Namespace": namespace, "Namespace": namespace,
@@ -370,17 +378,7 @@ func (c *Client) CreateWorkflowTemplate(namespace string, workflowTemplate *Work
func (c *Client) CreateWorkflowTemplateVersion(namespace string, workflowTemplate *WorkflowTemplate) (*WorkflowTemplate, error) { func (c *Client) CreateWorkflowTemplateVersion(namespace string, workflowTemplate *WorkflowTemplate) (*WorkflowTemplate, error) {
// validate workflow template // validate workflow template
finalBytes, err := workflowTemplate.WrapSpec() if err := c.validateWorkflowTemplate(namespace, workflowTemplate); err != nil {
if err != nil {
return nil, util.NewUserError(codes.InvalidArgument, err.Error())
}
if err := c.ValidateWorkflowExecution(namespace, finalBytes); err != nil {
log.WithFields(log.Fields{
"Namespace": namespace,
"WorkflowTemplate": workflowTemplate,
"Error": err.Error(),
}).Error("Workflow could not be validated.")
return nil, util.NewUserError(codes.InvalidArgument, err.Error()) return nil, util.NewUserError(codes.InvalidArgument, err.Error())
} }

54
pkg/workspace.go Normal file
View File

@@ -0,0 +1,54 @@
package v1
import (
"github.com/onepanelio/core/pkg/util"
"github.com/onepanelio/core/pkg/util/ptr"
"github.com/onepanelio/core/pkg/util/validate"
"google.golang.org/grpc/codes"
)
func injectWorkspaceParameterValues(workspace *Workspace, workspaceAction, resourceAction string) (err error) {
for _, p := range workspace.Parameters {
if p.Name == "sys-name" {
// TODO: These if statements can be removed when we have validation on param level
if p.Value == nil {
return util.NewUserError(codes.InvalidArgument, "Workspace name is required.")
}
if !validate.IsDNSHost(*p.Value) {
return util.NewUserError(codes.InvalidArgument, "Workspace name is not valid.")
}
workspace.Name = *p.Value
}
}
workspace.Parameters = append(workspace.Parameters, Parameter{
Name: "sys-workspace-action",
Value: ptr.String(workspaceAction),
}, Parameter{
Name: "sys-resource-action",
Value: ptr.String(resourceAction),
})
return
}
// CreateWorkspace creates a workspace by triggering the corresponding workflow
func (c *Client) CreateWorkspace(namespace string, workspace *Workspace) (*Workspace, error) {
if err := injectWorkspaceParameterValues(workspace, "create", "apply"); err != nil {
return nil, err
}
workflowTemplate, err := c.getWorkspaceTemplateWorkflowTemplate(namespace,
workspace.WorkspaceTemplate.UID, workspace.WorkspaceTemplate.Version)
if err != nil {
return nil, util.NewUserError(codes.NotFound, "Workspace template not found.")
}
workflowExecution, err := c.CreateWorkflowExecution(namespace, &WorkflowExecution{
Parameters: workspace.Parameters,
WorkflowTemplate: workflowTemplate,
})
workspace.UID = workflowExecution.UID
return workspace, nil
}

View File

@@ -5,7 +5,6 @@ import (
"fmt" "fmt"
sq "github.com/Masterminds/squirrel" sq "github.com/Masterminds/squirrel"
wfv1 "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1" wfv1 "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1"
v1 "github.com/onepanelio/core/pkg/apis/core/v1"
"github.com/onepanelio/core/pkg/util" "github.com/onepanelio/core/pkg/util"
"github.com/onepanelio/core/pkg/util/pagination" "github.com/onepanelio/core/pkg/util/pagination"
"github.com/onepanelio/core/pkg/util/ptr" "github.com/onepanelio/core/pkg/util/ptr"
@@ -16,48 +15,49 @@ import (
"sigs.k8s.io/yaml" "sigs.k8s.io/yaml"
) )
func parseWorkspaceSpec(template string) (spec *v1.WorkspaceSpec, err error) { func parseWorkspaceSpec(template string) (spec *WorkspaceSpec, err error) {
err = yaml.UnmarshalStrict([]byte(template), &spec) err = yaml.UnmarshalStrict([]byte(template), &spec)
return return
} }
func generateArguments(spec *v1.WorkspaceSpec, config map[string]string) (err error) { func generateArguments(spec *WorkspaceSpec, config map[string]string) (err error) {
if spec.Arguments == nil { if spec.Arguments == nil {
spec.Arguments = &v1.Arguments{ spec.Arguments = &Arguments{
Parameters: []v1.Parameter{}, Parameters: []Parameter{},
} }
} }
// Resource action parameter // Resource action parameter
spec.Arguments.Parameters = append(spec.Arguments.Parameters, v1.Parameter{ spec.Arguments.Parameters = append(spec.Arguments.Parameters, Parameter{
Name: "sys-name", Name: "sys-name",
Type: "input.text", Type: "input.text",
Value: ptr.String("name"), Value: ptr.String("name"),
DisplayName: ptr.String("Workspace name"), DisplayName: ptr.String("Workspace name"),
Hint: ptr.String("Must be less than 63 characters, contain only alphanumeric or `-` characters"),
Required: true, Required: true,
}) })
// Resource action parameter // Resource action parameter
spec.Arguments.Parameters = append(spec.Arguments.Parameters, v1.Parameter{ spec.Arguments.Parameters = append(spec.Arguments.Parameters, Parameter{
Name: "sys-resource-action", Name: "sys-resource-action",
Value: ptr.String("apply"), Value: ptr.String("apply"),
Type: "input.hidden", Type: "input.hidden",
}) })
// Workspace action // Workspace action
spec.Arguments.Parameters = append(spec.Arguments.Parameters, v1.Parameter{ spec.Arguments.Parameters = append(spec.Arguments.Parameters, Parameter{
Name: "sys-workspace-action", Name: "sys-workspace-action",
Value: ptr.String("create"), Value: ptr.String("create"),
Type: "input.hidden", Type: "input.hidden",
}) })
// Node pool parameter and options // Node pool parameter and options
var options []*v1.ParameterOption var options []*ParameterOption
if err = yaml.Unmarshal([]byte(config["applicationNodePoolOptions"]), &options); err != nil { if err = yaml.Unmarshal([]byte(config["applicationNodePoolOptions"]), &options); err != nil {
return return
} }
spec.Arguments.Parameters = append(spec.Arguments.Parameters, v1.Parameter{ spec.Arguments.Parameters = append(spec.Arguments.Parameters, Parameter{
Name: "sys-node-pool", Name: "sys-node-pool",
Value: ptr.String(options[0].Value), Value: ptr.String(options[0].Value),
Type: "select.select", Type: "select.select",
@@ -75,7 +75,7 @@ func generateArguments(spec *v1.WorkspaceSpec, config map[string]string) (err er
continue continue
} }
spec.Arguments.Parameters = append(spec.Arguments.Parameters, v1.Parameter{ spec.Arguments.Parameters = append(spec.Arguments.Parameters, Parameter{
Name: fmt.Sprintf("sys-%v-volume-size", v.Name), Name: fmt.Sprintf("sys-%v-volume-size", v.Name),
Type: "input.number", Type: "input.number",
Value: ptr.String("20480"), Value: ptr.String("20480"),
@@ -91,7 +91,7 @@ func generateArguments(spec *v1.WorkspaceSpec, config map[string]string) (err er
return return
} }
func createServiceManifest(spec *v1.WorkspaceSpec) (serviceManifest string, err error) { func createServiceManifest(spec *WorkspaceSpec) (serviceManifest string, err error) {
service := corev1.Service{ service := corev1.Service{
TypeMeta: metav1.TypeMeta{ TypeMeta: metav1.TypeMeta{
APIVersion: "v1", APIVersion: "v1",
@@ -116,7 +116,7 @@ func createServiceManifest(spec *v1.WorkspaceSpec) (serviceManifest string, err
return return
} }
func createVirtualServiceManifest(spec *v1.WorkspaceSpec, config map[string]string) (virtualServiceManifest string, err error) { func createVirtualServiceManifest(spec *WorkspaceSpec, config map[string]string) (virtualServiceManifest string, err error) {
for _, h := range spec.Routes { for _, h := range spec.Routes {
for _, r := range h.Route { for _, r := range h.Route {
r.Destination.Host = "{{workflow.parameters.sys-name}}" r.Destination.Host = "{{workflow.parameters.sys-name}}"
@@ -131,7 +131,7 @@ func createVirtualServiceManifest(spec *v1.WorkspaceSpec, config map[string]stri
"spec": networking.VirtualService{ "spec": networking.VirtualService{
Http: spec.Routes, Http: spec.Routes,
Gateways: []string{"istio-system/ingressgateway"}, Gateways: []string{"istio-system/ingressgateway"},
Hosts: []string{fmt.Sprintf("{{workflow.parameters.sys-name}}-{{workflow.namespace}}.%v", config["ONEPANEL_DOMAIN"])}, Hosts: []string{fmt.Sprintf("{{workflow.parameters.sys-name}}--{{workflow.namespace}}.%v", config["ONEPANEL_DOMAIN"])},
}, },
} }
virtualServiceManifestBytes, err := yaml.Marshal(virtualService) virtualServiceManifestBytes, err := yaml.Marshal(virtualService)
@@ -143,7 +143,7 @@ func createVirtualServiceManifest(spec *v1.WorkspaceSpec, config map[string]stri
return return
} }
func createStatefulSetManifest(workspaceSpec *v1.WorkspaceSpec, config map[string]string) (statefulSetManifest string, err error) { func createStatefulSetManifest(workspaceSpec *WorkspaceSpec, config map[string]string) (statefulSetManifest string, err error) {
var volumeClaims []map[string]interface{} var volumeClaims []map[string]interface{}
volumeClaimsMapped := make(map[string]bool) volumeClaimsMapped := make(map[string]bool)
for _, c := range workspaceSpec.Containers { for _, c := range workspaceSpec.Containers {
@@ -212,7 +212,7 @@ func createStatefulSetManifest(workspaceSpec *v1.WorkspaceSpec, config map[strin
return return
} }
func unmarshalWorkflowTemplate(spec *v1.WorkspaceSpec, serviceManifest, virtualServiceManifest, containersManifest string) (workflowTemplateSpecManifest string, err error) { func unmarshalWorkflowTemplate(spec *WorkspaceSpec, serviceManifest, virtualServiceManifest, containersManifest string) (workflowTemplateSpecManifest string, err error) {
var volumeClaimItems []wfv1.Item var volumeClaimItems []wfv1.Item
volumeClaimsMapped := make(map[string]bool) volumeClaimsMapped := make(map[string]bool)
for _, c := range spec.Containers { for _, c := range spec.Containers {
@@ -427,6 +427,30 @@ func (c *Client) getWorkspaceTemplateByName(namespace, name string) (workspaceTe
return return
} }
func (c *Client) getWorkspaceTemplateWorkflowTemplate(namespace, uid string, version int64) (workflowTemplate *WorkflowTemplate, err error) {
workflowTemplate = &WorkflowTemplate{}
query, args, err := sb.Select("wft.uid").
From("workspace_templates wt").
Join("workflow_templates wft ON wft.id = wt.workflow_template_id").
Where(sq.Eq{
"wt.uid": uid,
"wt.namespace": namespace,
}).
Limit(1).ToSql()
if err != nil {
return
}
if err = c.DB.Get(workflowTemplate, query, args...); err == sql.ErrNoRows {
return
}
workflowTemplate, err = c.getWorkflowTemplate(namespace, workflowTemplate.UID, version)
return
}
func (c *Client) generateWorkspaceTemplateWorkflowTemplate(workspaceTemplate *WorkspaceTemplate) (workflowTemplate *WorkflowTemplate, err error) { func (c *Client) generateWorkspaceTemplateWorkflowTemplate(workspaceTemplate *WorkspaceTemplate) (workflowTemplate *WorkflowTemplate, err error) {
if workspaceTemplate == nil { if workspaceTemplate == nil {
return nil, nil return nil, nil

View File

@@ -65,11 +65,3 @@ func TestParseWorkspaceSpec(t *testing.T) {
assert.Equal(t, workspaceSpec.Containers[0].Ports[0].ContainerPort, int32(80)) assert.Equal(t, workspaceSpec.Containers[0].Ports[0].ContainerPort, int32(80))
assert.Equal(t, workspaceSpec.Containers[1].Ports[0].ContainerPort, int32(443)) assert.Equal(t, workspaceSpec.Containers[1].Ports[0].ContainerPort, int32(443))
} }
func TestCreateWorkspaceTemplate(t *testing.T) {
c := NewTestClient(mockSystemSecret, mockSystemConfigMap)
if err := c.CreateWorkspaceTemplate("rush", workspaceTemplate); err != nil {
t.Error(err)
}
}

View File

@@ -0,0 +1,27 @@
package v1
import (
"github.com/google/uuid"
"time"
)
type WorkspaceTemplate struct {
ID uint64
UID string
Name string
Version int64
Manifest string
IsLatest bool
CreatedAt time.Time `db:"created_at"`
WorkflowTemplate *WorkflowTemplate
}
func (wt *WorkspaceTemplate) GenerateUID() (string, error) {
uid, err := uuid.NewRandom()
if err != nil {
return "", err
}
wt.UID = uid.String()
return wt.UID, nil
}

View File

@@ -4,16 +4,22 @@ import (
wfv1 "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1" wfv1 "github.com/argoproj/argo/pkg/apis/workflow/v1alpha1"
networking "istio.io/api/networking/v1alpha3" networking "istio.io/api/networking/v1alpha3"
corev1 "k8s.io/api/core/v1" corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "time"
) )
// +genclient // +genclient
// +genclient:noStatus // +genclient:noStatus
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object // +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
type Workspace struct { type Workspace struct {
metav1.TypeMeta `json:",inline"` ID uint64
metav1.ObjectMeta `json:"metadata,omitempty" protobuf:"bytes,1,opt,name=metadata"` UID string
Spec WorkspaceSpec `json:"spec" protobuf:"bytes,2,opt,name=spec"` Name string
Labels map[string]string
Parameters []Parameter
CreatedAt time.Time `db:"created_at"`
StartedAt *time.Time `db:"started_at"`
PausedAt *time.Time `db:"paused_at"`
WorkspaceTemplate *WorkspaceTemplate
} }
type WorkspaceSpec struct { type WorkspaceSpec struct {

View File

@@ -31,7 +31,7 @@ func apiCronWorkflow(cwf *v1.CronWorkflow) (cronWorkflow *api.CronWorkflow) {
if cwf.WorkflowExecution != nil { if cwf.WorkflowExecution != nil {
cronWorkflow.WorkflowExecution = GenApiWorkflowExecution(cwf.WorkflowExecution) cronWorkflow.WorkflowExecution = GenApiWorkflowExecution(cwf.WorkflowExecution)
for _, param := range cwf.WorkflowExecution.Parameters { for _, param := range cwf.WorkflowExecution.Parameters {
convertedParam := &api.WorkflowExecutionParameter{ convertedParam := &api.Parameter{
Name: param.Name, Name: param.Name,
Value: *param.Value, Value: *param.Value,
} }
@@ -56,7 +56,7 @@ func (c *CronWorkflowServer) CreateCronWorkflow(ctx context.Context, req *api.Cr
}, },
} }
for _, param := range req.CronWorkflow.WorkflowExecution.Parameters { for _, param := range req.CronWorkflow.WorkflowExecution.Parameters {
workflow.Parameters = append(workflow.Parameters, v1.WorkflowExecutionParameter{ workflow.Parameters = append(workflow.Parameters, v1.Parameter{
Name: param.Name, Name: param.Name,
Value: ptr.String(param.Value), Value: ptr.String(param.Value),
}) })
@@ -89,7 +89,7 @@ func (c *CronWorkflowServer) UpdateCronWorkflow(ctx context.Context, req *api.Up
}, },
} }
for _, param := range req.CronWorkflow.WorkflowExecution.Parameters { for _, param := range req.CronWorkflow.WorkflowExecution.Parameters {
workflow.Parameters = append(workflow.Parameters, v1.WorkflowExecutionParameter{ workflow.Parameters = append(workflow.Parameters, v1.Parameter{
Name: param.Name, Name: param.Name,
Value: ptr.String(param.Value), Value: ptr.String(param.Value),
}) })

View File

@@ -67,7 +67,7 @@ func (s *WorkflowServer) CreateWorkflowExecution(ctx context.Context, req *api.C
}, },
} }
for _, param := range req.WorkflowExecution.Parameters { for _, param := range req.WorkflowExecution.Parameters {
workflow.Parameters = append(workflow.Parameters, v1.WorkflowExecutionParameter{ workflow.Parameters = append(workflow.Parameters, v1.Parameter{
Name: param.Name, Name: param.Name,
Value: ptr.String(param.Value), Value: ptr.String(param.Value),
}) })

View File

@@ -0,0 +1,59 @@
package server
import (
"context"
"github.com/onepanelio/core/api"
v1 "github.com/onepanelio/core/pkg"
"github.com/onepanelio/core/pkg/util/ptr"
"github.com/onepanelio/core/server/auth"
"time"
)
type WorkspaceServer struct{}
func apiWorkspace(wt *v1.Workspace) *api.Workspace {
res := &api.Workspace{
Uid: wt.UID,
Name: wt.Name,
CreatedAt: wt.CreatedAt.UTC().Format(time.RFC3339),
}
if wt.WorkspaceTemplate != nil {
res.WorkspaceTemplate = apiWorkspaceTemplate(wt.WorkspaceTemplate)
}
return res
}
func NewWorkspaceServer() *WorkspaceServer {
return &WorkspaceServer{}
}
func (s *WorkspaceServer) CreateWorkspace(ctx context.Context, req *api.CreateWorkspaceRequest) (*api.Workspace, error) {
client := ctx.Value("kubeClient").(*v1.Client)
allowed, err := auth.IsAuthorized(client, req.Namespace, "create", "apps/v1", "statefulsets", "")
if err != nil || !allowed {
return nil, err
}
workspace := &v1.Workspace{
WorkspaceTemplate: &v1.WorkspaceTemplate{
UID: req.Workspace.WorkspaceTemplate.Uid,
Version: req.Workspace.WorkspaceTemplate.Version,
},
}
for _, param := range req.Workspace.Parameters {
workspace.Parameters = append(workspace.Parameters, v1.Parameter{
Name: param.Name,
Value: ptr.String(param.Value),
})
}
workspace, err = client.CreateWorkspace(req.Namespace, workspace)
if err != nil {
return nil, err
}
req.Workspace = apiWorkspace(workspace)
return req.Workspace, nil
}