diff --git a/backend/api/go_client/pipeline_spec.pb.go b/backend/api/go_client/pipeline_spec.pb.go index 560d859e0ac..5eeccfd7566 100644 --- a/backend/api/go_client/pipeline_spec.pb.go +++ b/backend/api/go_client/pipeline_spec.pb.go @@ -51,8 +51,10 @@ type PipelineSpec struct { PipelineManifest string `protobuf:"bytes,3,opt,name=pipeline_manifest,json=pipelineManifest,proto3" json:"pipeline_manifest,omitempty"` // The parameter user provide to inject to the pipeline JSON. // If a default value of a parameter exist in the JSON, - // the value user provided here will replace. + // the value user provided here will replace. V1 only Parameters []*Parameter `protobuf:"bytes,4,rep,name=parameters,proto3" json:"parameters,omitempty"` + // Runtime config of the pipeline. V2 only + RuntimeConfig *PipelineSpec_RuntimeConfig `protobuf:"bytes,6,opt,name=runtime_config,json=runtimeConfig,proto3" json:"runtime_config,omitempty"` } func (x *PipelineSpec) Reset() { @@ -122,6 +124,173 @@ func (x *PipelineSpec) GetParameters() []*Parameter { return nil } +func (x *PipelineSpec) GetRuntimeConfig() *PipelineSpec_RuntimeConfig { + if x != nil { + return x.RuntimeConfig + } + return nil +} + +// Value is the value of the field. +type Value struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Value: + // *Value_IntValue + // *Value_DoubleValue + // *Value_StringValue + Value isValue_Value `protobuf_oneof:"value"` +} + +func (x *Value) Reset() { + *x = Value{} + if protoimpl.UnsafeEnabled { + mi := &file_backend_api_pipeline_spec_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Value) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Value) ProtoMessage() {} + +func (x *Value) ProtoReflect() protoreflect.Message { + mi := &file_backend_api_pipeline_spec_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Value.ProtoReflect.Descriptor instead. +func (*Value) Descriptor() ([]byte, []int) { + return file_backend_api_pipeline_spec_proto_rawDescGZIP(), []int{1} +} + +func (m *Value) GetValue() isValue_Value { + if m != nil { + return m.Value + } + return nil +} + +func (x *Value) GetIntValue() int64 { + if x, ok := x.GetValue().(*Value_IntValue); ok { + return x.IntValue + } + return 0 +} + +func (x *Value) GetDoubleValue() float64 { + if x, ok := x.GetValue().(*Value_DoubleValue); ok { + return x.DoubleValue + } + return 0 +} + +func (x *Value) GetStringValue() string { + if x, ok := x.GetValue().(*Value_StringValue); ok { + return x.StringValue + } + return "" +} + +type isValue_Value interface { + isValue_Value() +} + +type Value_IntValue struct { + // An integer value + IntValue int64 `protobuf:"varint,1,opt,name=int_value,json=intValue,proto3,oneof"` +} + +type Value_DoubleValue struct { + // A double value + DoubleValue float64 `protobuf:"fixed64,2,opt,name=double_value,json=doubleValue,proto3,oneof"` +} + +type Value_StringValue struct { + // A string value + StringValue string `protobuf:"bytes,3,opt,name=string_value,json=stringValue,proto3,oneof"` +} + +func (*Value_IntValue) isValue_Value() {} + +func (*Value_DoubleValue) isValue_Value() {} + +func (*Value_StringValue) isValue_Value() {} + +// The runtime config of a PipelineSpec. +type PipelineSpec_RuntimeConfig struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // The runtime parameters of the PipelineSpec. The parameters will be + // used to replace the placeholders + // at runtime. + Parameters map[string]*Value `protobuf:"bytes,1,rep,name=parameters,proto3" json:"parameters,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // A path in a object store bucket which will be treated as the root + // output directory of the pipeline. It is used by the system to + // generate the paths of output artifacts. Ref:(https://www.kubeflow.org/docs/components/pipelines/pipeline-root/) + PipelineRoot string `protobuf:"bytes,2,opt,name=pipeline_root,json=pipelineRoot,proto3" json:"pipeline_root,omitempty"` +} + +func (x *PipelineSpec_RuntimeConfig) Reset() { + *x = PipelineSpec_RuntimeConfig{} + if protoimpl.UnsafeEnabled { + mi := &file_backend_api_pipeline_spec_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PipelineSpec_RuntimeConfig) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PipelineSpec_RuntimeConfig) ProtoMessage() {} + +func (x *PipelineSpec_RuntimeConfig) ProtoReflect() protoreflect.Message { + mi := &file_backend_api_pipeline_spec_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PipelineSpec_RuntimeConfig.ProtoReflect.Descriptor instead. +func (*PipelineSpec_RuntimeConfig) Descriptor() ([]byte, []int) { + return file_backend_api_pipeline_spec_proto_rawDescGZIP(), []int{0, 0} +} + +func (x *PipelineSpec_RuntimeConfig) GetParameters() map[string]*Value { + if x != nil { + return x.Parameters + } + return nil +} + +func (x *PipelineSpec_RuntimeConfig) GetPipelineRoot() string { + if x != nil { + return x.PipelineRoot + } + return "" +} + var File_backend_api_pipeline_spec_proto protoreflect.FileDescriptor var file_backend_api_pipeline_spec_proto_rawDesc = []byte{ @@ -129,7 +298,7 @@ var file_backend_api_pipeline_spec_proto_rawDesc = []byte{ 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x73, 0x70, 0x65, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x03, 0x61, 0x70, 0x69, 0x1a, 0x1b, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x22, 0xde, 0x01, 0x0a, 0x0c, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, + 0x6f, 0x74, 0x6f, 0x22, 0xf9, 0x03, 0x0a, 0x0c, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x70, 0x65, 0x63, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, @@ -143,11 +312,36 @@ var file_backend_api_pipeline_spec_proto_rawDesc = []byte{ 0x66, 0x65, 0x73, 0x74, 0x12, 0x2e, 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, - 0x74, 0x65, 0x72, 0x73, 0x42, 0x35, 0x5a, 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, - 0x6f, 0x6d, 0x2f, 0x6b, 0x75, 0x62, 0x65, 0x66, 0x6c, 0x6f, 0x77, 0x2f, 0x70, 0x69, 0x70, 0x65, - 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x2f, 0x62, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2f, 0x61, 0x70, - 0x69, 0x2f, 0x67, 0x6f, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x74, 0x65, 0x72, 0x73, 0x12, 0x46, 0x0a, 0x0e, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x5f, + 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1f, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x53, 0x70, 0x65, 0x63, 0x2e, + 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x52, 0x0d, 0x72, + 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x1a, 0xd0, 0x01, 0x0a, + 0x0d, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x4f, + 0x0a, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, 0x01, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x50, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, + 0x65, 0x53, 0x70, 0x65, 0x63, 0x2e, 0x52, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x43, 0x6f, 0x6e, + 0x66, 0x69, 0x67, 0x2e, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, + 0x23, 0x0a, 0x0d, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, + 0x52, 0x6f, 0x6f, 0x74, 0x1a, 0x49, 0x0a, 0x0f, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, + 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x20, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, + 0x79, 0x0a, 0x05, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1d, 0x0a, 0x09, 0x69, 0x6e, 0x74, 0x5f, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x03, 0x48, 0x00, 0x52, 0x08, 0x69, + 0x6e, 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x23, 0x0a, 0x0c, 0x64, 0x6f, 0x75, 0x62, 0x6c, + 0x65, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x01, 0x48, 0x00, 0x52, + 0x0b, 0x64, 0x6f, 0x75, 0x62, 0x6c, 0x65, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x23, 0x0a, 0x0c, + 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x42, 0x07, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x35, 0x5a, 0x33, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6b, 0x75, 0x62, 0x65, 0x66, 0x6c, 0x6f, + 0x77, 0x2f, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x73, 0x2f, 0x62, 0x61, 0x63, 0x6b, + 0x65, 0x6e, 0x64, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x6f, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -162,18 +356,24 @@ func file_backend_api_pipeline_spec_proto_rawDescGZIP() []byte { return file_backend_api_pipeline_spec_proto_rawDescData } -var file_backend_api_pipeline_spec_proto_msgTypes = make([]protoimpl.MessageInfo, 1) +var file_backend_api_pipeline_spec_proto_msgTypes = make([]protoimpl.MessageInfo, 4) var file_backend_api_pipeline_spec_proto_goTypes = []interface{}{ - (*PipelineSpec)(nil), // 0: api.PipelineSpec - (*Parameter)(nil), // 1: api.Parameter + (*PipelineSpec)(nil), // 0: api.PipelineSpec + (*Value)(nil), // 1: api.Value + (*PipelineSpec_RuntimeConfig)(nil), // 2: api.PipelineSpec.RuntimeConfig + nil, // 3: api.PipelineSpec.RuntimeConfig.ParametersEntry + (*Parameter)(nil), // 4: api.Parameter } var file_backend_api_pipeline_spec_proto_depIdxs = []int32{ - 1, // 0: api.PipelineSpec.parameters:type_name -> api.Parameter - 1, // [1:1] is the sub-list for method output_type - 1, // [1:1] is the sub-list for method input_type - 1, // [1:1] is the sub-list for extension type_name - 1, // [1:1] is the sub-list for extension extendee - 0, // [0:1] is the sub-list for field type_name + 4, // 0: api.PipelineSpec.parameters:type_name -> api.Parameter + 2, // 1: api.PipelineSpec.runtime_config:type_name -> api.PipelineSpec.RuntimeConfig + 3, // 2: api.PipelineSpec.RuntimeConfig.parameters:type_name -> api.PipelineSpec.RuntimeConfig.ParametersEntry + 1, // 3: api.PipelineSpec.RuntimeConfig.ParametersEntry.value:type_name -> api.Value + 4, // [4:4] is the sub-list for method output_type + 4, // [4:4] is the sub-list for method input_type + 4, // [4:4] is the sub-list for extension type_name + 4, // [4:4] is the sub-list for extension extendee + 0, // [0:4] is the sub-list for field type_name } func init() { file_backend_api_pipeline_spec_proto_init() } @@ -195,6 +395,35 @@ func file_backend_api_pipeline_spec_proto_init() { return nil } } + file_backend_api_pipeline_spec_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Value); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_backend_api_pipeline_spec_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PipelineSpec_RuntimeConfig); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + file_backend_api_pipeline_spec_proto_msgTypes[1].OneofWrappers = []interface{}{ + (*Value_IntValue)(nil), + (*Value_DoubleValue)(nil), + (*Value_StringValue)(nil), } type x struct{} out := protoimpl.TypeBuilder{ @@ -202,7 +431,7 @@ func file_backend_api_pipeline_spec_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_backend_api_pipeline_spec_proto_rawDesc, NumEnums: 0, - NumMessages: 1, + NumMessages: 4, NumExtensions: 0, NumServices: 0, }, diff --git a/backend/api/go_http_client/job_model/api_pipeline_spec.go b/backend/api/go_http_client/job_model/api_pipeline_spec.go index 66b66c9e298..d6341c7dec1 100644 --- a/backend/api/go_http_client/job_model/api_pipeline_spec.go +++ b/backend/api/go_http_client/job_model/api_pipeline_spec.go @@ -20,7 +20,7 @@ type APIPipelineSpec struct { // The parameter user provide to inject to the pipeline JSON. // If a default value of a parameter exist in the JSON, - // the value user provided here will replace. + // the value user provided here will replace. V1 only Parameters []*APIParameter `json:"parameters"` // Optional input field. The ID of the pipeline user uploaded before. @@ -33,6 +33,9 @@ type APIPipelineSpec struct { // Not empty if the pipeline id is not empty. PipelineName string `json:"pipeline_name,omitempty"` + // Runtime config of the pipeline. V2 only + RuntimeConfig *PipelineSpecRuntimeConfig `json:"runtime_config,omitempty"` + // Optional input field. The marshalled raw argo JSON workflow. // This will be deprecated when pipeline_manifest is in use. WorkflowManifest string `json:"workflow_manifest,omitempty"` @@ -46,6 +49,10 @@ func (m *APIPipelineSpec) Validate(formats strfmt.Registry) error { res = append(res, err) } + if err := m.validateRuntimeConfig(formats); err != nil { + res = append(res, err) + } + if len(res) > 0 { return errors.CompositeValidationError(res...) } @@ -77,6 +84,24 @@ func (m *APIPipelineSpec) validateParameters(formats strfmt.Registry) error { return nil } +func (m *APIPipelineSpec) validateRuntimeConfig(formats strfmt.Registry) error { + + if swag.IsZero(m.RuntimeConfig) { // not required + return nil + } + + if m.RuntimeConfig != nil { + if err := m.RuntimeConfig.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("runtime_config") + } + return err + } + } + + return nil +} + // MarshalBinary interface implementation func (m *APIPipelineSpec) MarshalBinary() ([]byte, error) { if m == nil { diff --git a/backend/api/go_http_client/job_model/api_value.go b/backend/api/go_http_client/job_model/api_value.go new file mode 100644 index 00000000000..62e690fa971 --- /dev/null +++ b/backend/api/go_http_client/job_model/api_value.go @@ -0,0 +1,49 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package job_model + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + strfmt "github.com/go-openapi/strfmt" + + "github.com/go-openapi/swag" +) + +// APIValue Value is the value of the field. +// swagger:model apiValue +type APIValue struct { + + // A double value + DoubleValue float64 `json:"double_value,omitempty"` + + // An integer value + IntValue string `json:"int_value,omitempty"` + + // A string value + StringValue string `json:"string_value,omitempty"` +} + +// Validate validates this api value +func (m *APIValue) Validate(formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *APIValue) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *APIValue) UnmarshalBinary(b []byte) error { + var res APIValue + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/backend/api/go_http_client/job_model/pipeline_spec_runtime_config.go b/backend/api/go_http_client/job_model/pipeline_spec_runtime_config.go new file mode 100644 index 00000000000..3672eb05918 --- /dev/null +++ b/backend/api/go_http_client/job_model/pipeline_spec_runtime_config.go @@ -0,0 +1,83 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package job_model + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + strfmt "github.com/go-openapi/strfmt" + + "github.com/go-openapi/errors" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" +) + +// PipelineSpecRuntimeConfig The runtime config of a PipelineSpec. +// swagger:model PipelineSpecRuntimeConfig +type PipelineSpecRuntimeConfig struct { + + // The runtime parameters of the PipelineSpec. The parameters will be + // used to replace the placeholders + // at runtime. + Parameters map[string]APIValue `json:"parameters,omitempty"` + + // A path in a object store bucket which will be treated as the root + // output directory of the pipeline. It is used by the system to + // generate the paths of output artifacts. Ref:(https://www.kubeflow.org/docs/components/pipelines/pipeline-root/) + PipelineRoot string `json:"pipeline_root,omitempty"` +} + +// Validate validates this pipeline spec runtime config +func (m *PipelineSpecRuntimeConfig) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateParameters(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *PipelineSpecRuntimeConfig) validateParameters(formats strfmt.Registry) error { + + if swag.IsZero(m.Parameters) { // not required + return nil + } + + for k := range m.Parameters { + + if err := validate.Required("parameters"+"."+k, "body", m.Parameters[k]); err != nil { + return err + } + if val, ok := m.Parameters[k]; ok { + if err := val.Validate(formats); err != nil { + return err + } + } + + } + + return nil +} + +// MarshalBinary interface implementation +func (m *PipelineSpecRuntimeConfig) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *PipelineSpecRuntimeConfig) UnmarshalBinary(b []byte) error { + var res PipelineSpecRuntimeConfig + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/backend/api/go_http_client/run_model/api_pipeline_spec.go b/backend/api/go_http_client/run_model/api_pipeline_spec.go index ba829c2291a..49edc9a4d80 100644 --- a/backend/api/go_http_client/run_model/api_pipeline_spec.go +++ b/backend/api/go_http_client/run_model/api_pipeline_spec.go @@ -20,7 +20,7 @@ type APIPipelineSpec struct { // The parameter user provide to inject to the pipeline JSON. // If a default value of a parameter exist in the JSON, - // the value user provided here will replace. + // the value user provided here will replace. V1 only Parameters []*APIParameter `json:"parameters"` // Optional input field. The ID of the pipeline user uploaded before. @@ -33,6 +33,9 @@ type APIPipelineSpec struct { // Not empty if the pipeline id is not empty. PipelineName string `json:"pipeline_name,omitempty"` + // Runtime config of the pipeline. V2 only + RuntimeConfig *PipelineSpecRuntimeConfig `json:"runtime_config,omitempty"` + // Optional input field. The marshalled raw argo JSON workflow. // This will be deprecated when pipeline_manifest is in use. WorkflowManifest string `json:"workflow_manifest,omitempty"` @@ -46,6 +49,10 @@ func (m *APIPipelineSpec) Validate(formats strfmt.Registry) error { res = append(res, err) } + if err := m.validateRuntimeConfig(formats); err != nil { + res = append(res, err) + } + if len(res) > 0 { return errors.CompositeValidationError(res...) } @@ -77,6 +84,24 @@ func (m *APIPipelineSpec) validateParameters(formats strfmt.Registry) error { return nil } +func (m *APIPipelineSpec) validateRuntimeConfig(formats strfmt.Registry) error { + + if swag.IsZero(m.RuntimeConfig) { // not required + return nil + } + + if m.RuntimeConfig != nil { + if err := m.RuntimeConfig.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("runtime_config") + } + return err + } + } + + return nil +} + // MarshalBinary interface implementation func (m *APIPipelineSpec) MarshalBinary() ([]byte, error) { if m == nil { diff --git a/backend/api/go_http_client/run_model/api_value.go b/backend/api/go_http_client/run_model/api_value.go new file mode 100644 index 00000000000..9cc2c14d709 --- /dev/null +++ b/backend/api/go_http_client/run_model/api_value.go @@ -0,0 +1,49 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package run_model + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + strfmt "github.com/go-openapi/strfmt" + + "github.com/go-openapi/swag" +) + +// APIValue Value is the value of the field. +// swagger:model apiValue +type APIValue struct { + + // A double value + DoubleValue float64 `json:"double_value,omitempty"` + + // An integer value + IntValue string `json:"int_value,omitempty"` + + // A string value + StringValue string `json:"string_value,omitempty"` +} + +// Validate validates this api value +func (m *APIValue) Validate(formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *APIValue) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *APIValue) UnmarshalBinary(b []byte) error { + var res APIValue + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/backend/api/go_http_client/run_model/pipeline_spec_runtime_config.go b/backend/api/go_http_client/run_model/pipeline_spec_runtime_config.go new file mode 100644 index 00000000000..eaa49886074 --- /dev/null +++ b/backend/api/go_http_client/run_model/pipeline_spec_runtime_config.go @@ -0,0 +1,83 @@ +// Code generated by go-swagger; DO NOT EDIT. + +package run_model + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + strfmt "github.com/go-openapi/strfmt" + + "github.com/go-openapi/errors" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" +) + +// PipelineSpecRuntimeConfig The runtime config of a PipelineSpec. +// swagger:model PipelineSpecRuntimeConfig +type PipelineSpecRuntimeConfig struct { + + // The runtime parameters of the PipelineSpec. The parameters will be + // used to replace the placeholders + // at runtime. + Parameters map[string]APIValue `json:"parameters,omitempty"` + + // A path in a object store bucket which will be treated as the root + // output directory of the pipeline. It is used by the system to + // generate the paths of output artifacts. Ref:(https://www.kubeflow.org/docs/components/pipelines/pipeline-root/) + PipelineRoot string `json:"pipeline_root,omitempty"` +} + +// Validate validates this pipeline spec runtime config +func (m *PipelineSpecRuntimeConfig) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateParameters(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *PipelineSpecRuntimeConfig) validateParameters(formats strfmt.Registry) error { + + if swag.IsZero(m.Parameters) { // not required + return nil + } + + for k := range m.Parameters { + + if err := validate.Required("parameters"+"."+k, "body", m.Parameters[k]); err != nil { + return err + } + if val, ok := m.Parameters[k]; ok { + if err := val.Validate(formats); err != nil { + return err + } + } + + } + + return nil +} + +// MarshalBinary interface implementation +func (m *PipelineSpecRuntimeConfig) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *PipelineSpecRuntimeConfig) UnmarshalBinary(b []byte) error { + var res PipelineSpecRuntimeConfig + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/backend/api/pipeline_spec.proto b/backend/api/pipeline_spec.proto index e618031f5dd..e32c5adeba5 100644 --- a/backend/api/pipeline_spec.proto +++ b/backend/api/pipeline_spec.proto @@ -36,6 +36,37 @@ message PipelineSpec { // The parameter user provide to inject to the pipeline JSON. // If a default value of a parameter exist in the JSON, - // the value user provided here will replace. + // the value user provided here will replace. V1 only repeated Parameter parameters = 4; + + // The runtime config of a PipelineSpec. + message RuntimeConfig { + // The runtime parameters of the PipelineSpec. The parameters will be + // used to replace the placeholders + // at runtime. + map parameters = 1; + + // A path in a object store bucket which will be treated as the root + // output directory of the pipeline. It is used by the system to + // generate the paths of output artifacts. Ref:(https://www.kubeflow.org/docs/components/pipelines/pipeline-root/) + string pipeline_root = 2; + + } + + // Runtime config of the pipeline. V2 only + RuntimeConfig runtime_config = 6; } + +// Value is the value of the field. +message Value { + oneof value { + // An integer value + int64 int_value = 1; + // A double value + double double_value = 2; + // A string value + string string_value = 3; + } +} + + diff --git a/backend/api/swagger/job.swagger.json b/backend/api/swagger/job.swagger.json index e4c90db0add..731301489ce 100644 --- a/backend/api/swagger/job.swagger.json +++ b/backend/api/swagger/job.swagger.json @@ -262,6 +262,23 @@ "default": "UNKNOWN_MODE", "description": "Required input.\n\n - DISABLED: The job won't schedule any run if disabled." }, + "PipelineSpecRuntimeConfig": { + "type": "object", + "properties": { + "parameters": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/apiValue" + }, + "description": "The runtime parameters of the PipelineSpec. The parameters will be\nused to replace the placeholders\nat runtime." + }, + "pipeline_root": { + "type": "string", + "title": "A path in a object store bucket which will be treated as the root\noutput directory of the pipeline. It is used by the system to\ngenerate the paths of output artifacts. Ref:(https://www.kubeflow.org/docs/components/pipelines/pipeline-root/)" + } + }, + "description": "The runtime config of a PipelineSpec." + }, "apiCronSchedule": { "type": "object", "properties": { @@ -431,7 +448,11 @@ "items": { "$ref": "#/definitions/apiParameter" }, - "description": "The parameter user provide to inject to the pipeline JSON.\nIf a default value of a parameter exist in the JSON,\nthe value user provided here will replace." + "title": "The parameter user provide to inject to the pipeline JSON.\nIf a default value of a parameter exist in the JSON,\nthe value user provided here will replace. V1 only" + }, + "runtime_config": { + "$ref": "#/definitions/PipelineSpecRuntimeConfig", + "title": "Runtime config of the pipeline. V2 only" } } }, @@ -515,6 +536,26 @@ }, "description": "Trigger defines what starts a pipeline run." }, + "apiValue": { + "type": "object", + "properties": { + "int_value": { + "type": "string", + "format": "int64", + "title": "An integer value" + }, + "double_value": { + "type": "number", + "format": "double", + "title": "A double value" + }, + "string_value": { + "type": "string", + "title": "A string value" + } + }, + "description": "Value is the value of the field." + }, "protobufAny": { "type": "object", "properties": { diff --git a/backend/api/swagger/kfp_api_single_file.swagger.json b/backend/api/swagger/kfp_api_single_file.swagger.json index f5a91348d56..a0cb82eefb3 100644 --- a/backend/api/swagger/kfp_api_single_file.swagger.json +++ b/backend/api/swagger/kfp_api_single_file.swagger.json @@ -1454,6 +1454,23 @@ } }, "definitions": { + "PipelineSpecRuntimeConfig": { + "type": "object", + "properties": { + "parameters": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/apiValue" + }, + "description": "The runtime parameters of the PipelineSpec. The parameters will be\nused to replace the placeholders\nat runtime." + }, + "pipeline_root": { + "type": "string", + "title": "A path in a object store bucket which will be treated as the root\noutput directory of the pipeline. It is used by the system to\ngenerate the paths of output artifacts. Ref:(https://www.kubeflow.org/docs/components/pipelines/pipeline-root/)" + } + }, + "description": "The runtime config of a PipelineSpec." + }, "ReportRunMetricsResponseReportRunMetricResult": { "type": "object", "properties": { @@ -1565,7 +1582,11 @@ "items": { "$ref": "#/definitions/apiParameter" }, - "description": "The parameter user provide to inject to the pipeline JSON.\nIf a default value of a parameter exist in the JSON,\nthe value user provided here will replace." + "title": "The parameter user provide to inject to the pipeline JSON.\nIf a default value of a parameter exist in the JSON,\nthe value user provided here will replace. V1 only" + }, + "runtime_config": { + "$ref": "#/definitions/PipelineSpecRuntimeConfig", + "title": "Runtime config of the pipeline. V2 only" } } }, @@ -1781,6 +1802,26 @@ } } }, + "apiValue": { + "type": "object", + "properties": { + "int_value": { + "type": "string", + "format": "int64", + "title": "An integer value" + }, + "double_value": { + "type": "number", + "format": "double", + "title": "A double value" + }, + "string_value": { + "type": "string", + "title": "A string value" + } + }, + "description": "Value is the value of the field." + }, "protobufAny": { "type": "object", "properties": { diff --git a/backend/api/swagger/run.swagger.json b/backend/api/swagger/run.swagger.json index 1fbf2fdb518..754f2cd183d 100644 --- a/backend/api/swagger/run.swagger.json +++ b/backend/api/swagger/run.swagger.json @@ -403,6 +403,23 @@ } }, "definitions": { + "PipelineSpecRuntimeConfig": { + "type": "object", + "properties": { + "parameters": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/apiValue" + }, + "description": "The runtime parameters of the PipelineSpec. The parameters will be\nused to replace the placeholders\nat runtime." + }, + "pipeline_root": { + "type": "string", + "title": "A path in a object store bucket which will be treated as the root\noutput directory of the pipeline. It is used by the system to\ngenerate the paths of output artifacts. Ref:(https://www.kubeflow.org/docs/components/pipelines/pipeline-root/)" + } + }, + "description": "The runtime config of a PipelineSpec." + }, "ReportRunMetricsResponseReportRunMetricResult": { "type": "object", "properties": { @@ -514,7 +531,11 @@ "items": { "$ref": "#/definitions/apiParameter" }, - "description": "The parameter user provide to inject to the pipeline JSON.\nIf a default value of a parameter exist in the JSON,\nthe value user provided here will replace." + "title": "The parameter user provide to inject to the pipeline JSON.\nIf a default value of a parameter exist in the JSON,\nthe value user provided here will replace. V1 only" + }, + "runtime_config": { + "$ref": "#/definitions/PipelineSpecRuntimeConfig", + "title": "Runtime config of the pipeline. V2 only" } } }, @@ -730,6 +751,26 @@ } } }, + "apiValue": { + "type": "object", + "properties": { + "int_value": { + "type": "string", + "format": "int64", + "title": "An integer value" + }, + "double_value": { + "type": "number", + "format": "double", + "title": "A double value" + }, + "string_value": { + "type": "string", + "title": "A string value" + } + }, + "description": "Value is the value of the field." + }, "protobufAny": { "type": "object", "properties": { diff --git a/backend/src/apiserver/common/config.go b/backend/src/apiserver/common/config.go index b35243cdbb4..3bd508810d4 100644 --- a/backend/src/apiserver/common/config.go +++ b/backend/src/apiserver/common/config.go @@ -27,7 +27,6 @@ const ( MultiUserModeSharedReadAccess string = "MULTIUSER_SHARED_READ" PodNamespace string = "POD_NAMESPACE" CacheEnabled string = "CacheEnabled" - DefaultPipelineRunnerServiceAccount string = "DefaultPipelineRunnerServiceAccount" KubeflowUserIDHeader string = "KUBEFLOW_USERID_HEADER" KubeflowUserIDPrefix string = "KUBEFLOW_USERID_PREFIX" UpdatePipelineVersionByDefault string = "AUTO_UPDATE_PIPELINE_DEFAULT_VERSION" diff --git a/backend/src/apiserver/common/util.go b/backend/src/apiserver/common/util.go index aad08416f10..ad6a54b4bfc 100644 --- a/backend/src/apiserver/common/util.go +++ b/backend/src/apiserver/common/util.go @@ -16,7 +16,14 @@ package common import ( api "github.com/kubeflow/pipelines/backend/api/go_client" + "strings" ) +const ( + DefaultPipelineRunnerServiceAccount = "pipeline-runner" + HasDefaultBucketEnvVar = "HAS_DEFAULT_BUCKET" + DefaultBucketNameEnvVar = "BUCKET_NAME" + ProjectIDEnvVar = "PROJECT_ID" + ) func GetNamespaceFromAPIResourceReferences(resourceRefs []*api.ResourceReference) string { namespace := "" @@ -39,3 +46,19 @@ func GetExperimentIDFromAPIResourceReferences(resourceRefs []*api.ResourceRefere } return experimentID } + +// Mutate default values of specified pipeline spec. +// Args: +// text: (part of) pipeline file in string. +func PatchPipelineDefaultParameter(text string) (string, error) { + defaultBucket := GetStringConfig(DefaultBucketNameEnvVar) + projectId := GetStringConfig(ProjectIDEnvVar) + toPatch := map[string]string{ + "{{kfp-default-bucket}}": defaultBucket, + "{{kfp-project-id}}": projectId, + } + for key, value := range toPatch { + text = strings.Replace(text, key, value, -1) + } + return text, nil +} diff --git a/backend/src/apiserver/config/config.json b/backend/src/apiserver/config/config.json index 3897872143f..1fa703b54a1 100644 --- a/backend/src/apiserver/config/config.json +++ b/backend/src/apiserver/config/config.json @@ -18,7 +18,6 @@ "DefaultPipelineRunnerServiceAccount": "pipeline-runner", "CacheEnabled": "true", "CRON_SCHEDULE_TIMEZONE": "UTC", - "CACHE_IMAGE": "gcr.io/google-containers/busybox", + "CACHE_IMAGE": "gcr.io/google-containers/busybox", "CACHE_NODE_RESTRICTIONS": "false" - } diff --git a/backend/src/apiserver/resource/model_converter.go b/backend/src/apiserver/resource/model_converter.go index d16564ae1d9..c246ecf4512 100644 --- a/backend/src/apiserver/resource/model_converter.go +++ b/backend/src/apiserver/resource/model_converter.go @@ -16,6 +16,8 @@ package resource import ( "encoding/json" + "fmt" + "github.com/kubeflow/pipelines/backend/src/apiserver/template" "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" api "github.com/kubeflow/pipelines/backend/api/go_client" @@ -53,13 +55,9 @@ func (r *ResourceManager) ToModelRunMetric(metric *api.RunMetric, runUUID string } } -// The input run might not contain workflowSpecManifest, but instead a pipeline ID. -// The caller would retrieve workflowSpecManifest and pass in. -func (r *ResourceManager) ToModelRunDetail(run *api.Run, runId string, workflow *util.Workflow, workflowSpecManifest string) (*model.RunDetail, error) { - params, err := toModelParameters(run.GetPipelineSpec().GetParameters()) - if err != nil { - return nil, util.Wrap(err, "Unable to parse the parameter.") - } +// The input run might not contain workflowSpecManifest and pipelineSpecManifest, but instead a pipeline ID. +// The caller would retrieve manifest and pass in. +func (r *ResourceManager) ToModelRunDetail(run *api.Run, runId string, workflow *util.Workflow, manifest string, templateType template.TemplateType) (*model.RunDetail, error) { resourceReferences, err := r.toModelResourceReferences(runId, common.Run, run.GetResourceReferences()) if err != nil { return nil, util.Wrap(err, "Unable to convert resource references.") @@ -77,7 +75,7 @@ func (r *ResourceManager) ToModelRunDetail(run *api.Run, runId string, workflow return nil, util.Wrap(err, "Error getting the experiment UUID") } - return &model.RunDetail{ + runDetail := &model.RunDetail{ Run: model.Run{ UUID: runId, ExperimentUUID: experimentUUID, @@ -91,21 +89,35 @@ func (r *ResourceManager) ToModelRunDetail(run *api.Run, runId string, workflow PipelineSpec: model.PipelineSpec{ PipelineId: run.GetPipelineSpec().GetPipelineId(), PipelineName: pipelineName, - WorkflowSpecManifest: workflowSpecManifest, - Parameters: params, }, }, - PipelineRuntime: model.PipelineRuntime{ - WorkflowRuntimeManifest: workflow.ToStringForStore(), - }, - }, nil -} + } -func (r *ResourceManager) ToModelJob(job *api.Job, swf *util.ScheduledWorkflow, workflowSpecManifest string) (*model.Job, error) { - params, err := toModelParameters(job.GetPipelineSpec().GetParameters()) - if err != nil { - return nil, util.Wrap(err, "Error parsing the input job.") + if templateType == template.V1 { + params, err := apiParametersToModelParameters(run.GetPipelineSpec().GetParameters()) + if err != nil { + return nil, util.Wrap(err, "Unable to parse the parameter.") + } + runDetail.Parameters = params + runDetail.WorkflowSpecManifest = manifest + runDetail.WorkflowRuntimeManifest = workflow.ToStringForStore() + return runDetail, nil + + } else if templateType == template.V2 { + params, err := runtimeConfigToModelParameters(run.GetPipelineSpec().GetRuntimeConfig()) + if err != nil { + return nil, util.Wrap(err, "Unable to parse the parameter.") + } + runDetail.Parameters = params + runDetail.PipelineSpecManifest = manifest + return runDetail, nil + + } else { + return nil, fmt.Errorf("failed to generate RunDetail with templateType %s", templateType) } +} + +func (r *ResourceManager) ToModelJob(job *api.Job, swf *util.ScheduledWorkflow, manifest string, templateType template.TemplateType) (*model.Job, error) { resourceReferences, err := r.toModelResourceReferences(string(swf.UID), common.Job, job.GetResourceReferences()) if err != nil { return nil, util.Wrap(err, "Error to convert resource references.") @@ -121,7 +133,7 @@ func (r *ResourceManager) ToModelJob(job *api.Job, swf *util.ScheduledWorkflow, if swf.Spec.Workflow != nil { serviceAccount = swf.Spec.Workflow.Spec.ServiceAccountName } - return &model.Job{ + modelJob := &model.Job{ UUID: string(swf.UID), DisplayName: job.Name, Name: swf.Name, @@ -137,14 +149,33 @@ func (r *ResourceManager) ToModelJob(job *api.Job, swf *util.ScheduledWorkflow, PipelineSpec: model.PipelineSpec{ PipelineId: job.GetPipelineSpec().GetPipelineId(), PipelineName: pipelineName, - WorkflowSpecManifest: workflowSpecManifest, - Parameters: params, - }, - }, nil + }} + + if templateType == template.V1 { + params, err := apiParametersToModelParameters(job.GetPipelineSpec().GetParameters()) + if err != nil { + return nil, util.Wrap(err, "Unable to parse the parameter.") + } + modelJob.Parameters = params + modelJob.WorkflowSpecManifest = manifest + return modelJob, nil + + } else if templateType == template.V2 { + params, err := runtimeConfigToModelParameters(job.GetPipelineSpec().GetRuntimeConfig()) + if err != nil { + return nil, util.Wrap(err, "Unable to parse the parameter.") + } + modelJob.Parameters = params + modelJob.PipelineSpecManifest = manifest + return modelJob, nil + + } else { + return nil, fmt.Errorf("failed to generate ModelJob with templateType %s", templateType) + } } func (r *ResourceManager) ToModelPipelineVersion(version *api.PipelineVersion) (*model.PipelineVersion, error) { - paramStr, err := toModelParameters(version.Parameters) + paramStr, err := apiParametersToModelParameters(version.Parameters) if err != nil { return nil, err } @@ -196,7 +227,7 @@ func toModelTrigger(trigger *api.Trigger) model.Trigger { return modelTrigger } -func toModelParameters(apiParams []*api.Parameter) (string, error) { +func apiParametersToModelParameters(apiParams []*api.Parameter) (string, error) { if apiParams == nil || len(apiParams) == 0 { return "", nil } @@ -215,6 +246,35 @@ func toModelParameters(apiParams []*api.Parameter) (string, error) { return string(paramsBytes), nil } +func runtimeConfigToModelParameters(runtimeConfig *api.PipelineSpec_RuntimeConfig) (string, error) { + if runtimeConfig == nil { + return "", nil + } + var params []v1alpha1.Parameter + for k, v := range runtimeConfig.GetParameters() { + param := v1alpha1.Parameter{ + Name: k, + } + switch t := v.Value.(type) { + case *api.Value_StringValue: + param.Value = v1alpha1.AnyStringPtr(v.GetStringValue()) + case *api.Value_DoubleValue: + param.Value = v1alpha1.AnyStringPtr(v.GetDoubleValue()) + case *api.Value_IntValue: + param.Value = v1alpha1.AnyStringPtr(v.GetIntValue()) + default: + return "", fmt.Errorf("unknown property type in pipelineSpec runtimeConfig Parameters: %T", t) + } + + params = append(params, param) + } + paramsBytes, err := json.Marshal(params) + if err != nil { + return "", util.NewInternalServerError(err, "Failed to stream API parameter as string.") + } + return string(paramsBytes), nil +} + func (r *ResourceManager) toModelResourceReferences( resourceId string, resourceType model.ResourceType, apiRefs []*api.ResourceReference) ([]*model.ResourceReference, error) { var modelRefs []*model.ResourceReference diff --git a/backend/src/apiserver/resource/model_converter_test.go b/backend/src/apiserver/resource/model_converter_test.go index 0caab6b1171..6ab93429b48 100644 --- a/backend/src/apiserver/resource/model_converter_test.go +++ b/backend/src/apiserver/resource/model_converter_test.go @@ -15,10 +15,11 @@ package resource import ( + "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" + "github.com/kubeflow/pipelines/backend/src/apiserver/template" "strings" "testing" - "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" "github.com/golang/protobuf/ptypes/timestamp" "github.com/google/go-cmp/cmp" api "github.com/kubeflow/pipelines/backend/api/go_client" @@ -150,115 +151,265 @@ func TestToModelRunDetail(t *testing.T) { store, manager, experiment := initWithExperiment(t) defer store.Close() - apiRun := &api.Run{ - Id: "run1", - Name: "name1", - Description: "this is a run", - PipelineSpec: &api.PipelineSpec{ - Parameters: []*api.Parameter{{Name: "param2", Value: "world"}}, - }, - ResourceReferences: []*api.ResourceReference{ - {Key: &api.ResourceKey{Type: api.ResourceType_EXPERIMENT, Id: experiment.UUID}, Relationship: api.Relationship_OWNER}, - }, - } - workflow := util.NewWorkflow(&v1alpha1.Workflow{ - ObjectMeta: v1.ObjectMeta{Name: "workflow-name", UID: "123"}, - Status: v1alpha1.WorkflowStatus{Phase: "running"}, - }) - modelRunDetail, err := manager.ToModelRunDetail(apiRun, "123", workflow, "workflow spec") - assert.Nil(t, err) - - expectedModelRunDetail := &model.RunDetail{ - Run: model.Run{ - UUID: "123", - ExperimentUUID: experiment.UUID, - DisplayName: "name1", - Name: "workflow-name", - Conditions: "running", - Description: "this is a run", - PipelineSpec: model.PipelineSpec{ - WorkflowSpecManifest: "workflow spec", - Parameters: `[{"name":"param2","value":"world"}]`, + tests := []struct { + name string + apiRun *api.Run + workflow *util.Workflow + manifest string + templateType template.TemplateType + expectedModelRunDetail *model.RunDetail + }{ + { name : "v1", + apiRun: &api.Run{ + Id: "run1", + Name: "name1", + Description: "this is a run", + PipelineSpec: &api.PipelineSpec{ + Parameters: []*api.Parameter{{Name: "param2", Value: "world"}}, + }, + ResourceReferences: []*api.ResourceReference{ + { + Key: &api.ResourceKey{Type: api.ResourceType_EXPERIMENT, Id: experiment.UUID}, + Relationship: api.Relationship_OWNER}}, }, - ResourceReferences: []*model.ResourceReference{ - { - ResourceUUID: "123", - ResourceType: common.Run, - ReferenceUUID: experiment.UUID, - ReferenceName: experiment.Name, - ReferenceType: common.Experiment, - Relationship: common.Owner}, + workflow: util.NewWorkflow(&v1alpha1.Workflow{ + ObjectMeta: v1.ObjectMeta{Name: "workflow-name", UID: "123"}, + Status: v1alpha1.WorkflowStatus{Phase: "running"}, + }), + manifest: "workflow spec", + templateType: template.V1, + expectedModelRunDetail: &model.RunDetail{ + Run: model.Run{ + UUID: "123", + ExperimentUUID: experiment.UUID, + DisplayName: "name1", + Name: "workflow-name", + Conditions: "running", + Description: "this is a run", + PipelineSpec: model.PipelineSpec{ + WorkflowSpecManifest: "workflow spec", + Parameters: `[{"name":"param2","value":"world"}]`, + }, + ResourceReferences: []*model.ResourceReference{ + { + ResourceUUID: "123", + ResourceType: common.Run, + ReferenceUUID: experiment.UUID, + ReferenceName: experiment.Name, + ReferenceType: common.Experiment, + Relationship: common.Owner}, + }, + }, + PipelineRuntime: model.PipelineRuntime{ + WorkflowRuntimeManifest: util.NewWorkflow(&v1alpha1.Workflow{ + ObjectMeta: v1.ObjectMeta{Name: "workflow-name", UID: "123"}, + Status: v1alpha1.WorkflowStatus{Phase: "running"}, + }).ToStringForStore(), + }, }, }, - PipelineRuntime: model.PipelineRuntime{ - WorkflowRuntimeManifest: workflow.ToStringForStore(), + { name : "v2", + apiRun: &api.Run{ + Id: "run1", + Name: "name1", + Description: "this is a run", + PipelineSpec: &api.PipelineSpec{RuntimeConfig: &api.PipelineSpec_RuntimeConfig{Parameters: map[string]*api.Value{ + "param2": { + Value: &api.Value_StringValue{ + StringValue: "world", + }, + }, + }}}, + ResourceReferences: []*api.ResourceReference{ + { + Key: &api.ResourceKey{Type: api.ResourceType_EXPERIMENT, Id: experiment.UUID}, + Relationship: api.Relationship_OWNER}}, + }, + workflow: util.NewWorkflow(&v1alpha1.Workflow{ + ObjectMeta: v1.ObjectMeta{Name: "workflow-name", UID: "123"}, + Status: v1alpha1.WorkflowStatus{Phase: "running"}, + }), + manifest: "pipeline spec", + templateType: template.V2, + expectedModelRunDetail: &model.RunDetail{ + Run: model.Run{ + UUID: "123", + ExperimentUUID: experiment.UUID, + DisplayName: "name1", + Name: "workflow-name", + Conditions: "running", + Description: "this is a run", + PipelineSpec: model.PipelineSpec{ + PipelineSpecManifest: "pipeline spec", + Parameters: `[{"name":"param2","value":"world"}]`, + }, + ResourceReferences: []*model.ResourceReference{ + { + ResourceUUID: "123", + ResourceType: common.Run, + ReferenceUUID: experiment.UUID, + ReferenceName: experiment.Name, + ReferenceType: common.Experiment, + Relationship: common.Owner}, + }, + }, + }, }, } - assert.Equal(t, expectedModelRunDetail, modelRunDetail) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + modelRunDetail, err := manager.ToModelRunDetail(tt.apiRun, "123", tt.workflow, tt.manifest, tt.templateType) + assert.Nil(t, err) + assert.Equal(t, tt.expectedModelRunDetail, modelRunDetail) + }) + } + } func TestToModelJob(t *testing.T) { store, manager, experiment, pipeline := initWithExperimentAndPipeline(t) defer store.Close() - apiJob := &api.Job{ - Name: "name1", - Enabled: true, - MaxConcurrency: 1, - NoCatchup: true, - Trigger: &api.Trigger{ - Trigger: &api.Trigger_CronSchedule{CronSchedule: &api.CronSchedule{ - StartTime: ×tamp.Timestamp{Seconds: 1}, - Cron: "1 * * * *", - }}}, - ResourceReferences: []*api.ResourceReference{ - {Key: &api.ResourceKey{Type: api.ResourceType_EXPERIMENT, Id: experiment.UUID}, Relationship: api.Relationship_OWNER}, - }, - PipelineSpec: &api.PipelineSpec{PipelineId: pipeline.UUID, Parameters: []*api.Parameter{{Name: "param2", Value: "world"}}}, - } - swf := util.NewScheduledWorkflow(&swfapi.ScheduledWorkflow{ - ObjectMeta: v1.ObjectMeta{ - Name: "swf_name", - Namespace: "swf_namespace", - UID: "swf_123", - }, - Status: swfapi.ScheduledWorkflowStatus{ - Conditions: []swfapi.ScheduledWorkflowCondition{{Type: swfapi.ScheduledWorkflowEnabled}}}, - }) - modelJob, err := manager.ToModelJob(apiJob, swf, "workflow spec") - assert.Nil(t, err) - expectedModelJob := &model.Job{ - UUID: "swf_123", - Name: "swf_name", - Namespace: "swf_namespace", - Conditions: "Enabled", - DisplayName: "name1", - Enabled: true, - Trigger: model.Trigger{ - CronSchedule: model.CronSchedule{ - CronScheduleStartTimeInSec: util.Int64Pointer(1), - Cron: util.StringPointer("1 * * * *"), + tests := []struct { + name string + apiJob *api.Job + swf *util.ScheduledWorkflow + manifest string + templateType template.TemplateType + expectedModelJob *model.Job + }{ + {name: "v1", + apiJob: &api.Job{ + Name: "name1", + Enabled: true, + MaxConcurrency: 1, + NoCatchup: true, + Trigger: &api.Trigger{ + Trigger: &api.Trigger_CronSchedule{CronSchedule: &api.CronSchedule{ + StartTime: ×tamp.Timestamp{Seconds: 1}, + Cron: "1 * * * *", + }}}, + ResourceReferences: []*api.ResourceReference{ + {Key: &api.ResourceKey{Type: api.ResourceType_EXPERIMENT, Id: experiment.UUID}, Relationship: api.Relationship_OWNER}, + }, + PipelineSpec: &api.PipelineSpec{PipelineId: pipeline.UUID, Parameters: []*api.Parameter{{Name: "param2", Value: "world"}}}, + }, + swf: util.NewScheduledWorkflow(&swfapi.ScheduledWorkflow{ + ObjectMeta: v1.ObjectMeta{ + Name: "swf_name", + Namespace: "swf_namespace", + UID: "swf_123", + }, + Status: swfapi.ScheduledWorkflowStatus{ + Conditions: []swfapi.ScheduledWorkflowCondition{{Type: swfapi.ScheduledWorkflowEnabled}}}, + }), + manifest: "workflow spec", + templateType: template.V1, + expectedModelJob: &model.Job{ + UUID: "swf_123", + Name: "swf_name", + Namespace: "swf_namespace", + Conditions: "Enabled", + DisplayName: "name1", + Enabled: true, + Trigger: model.Trigger{ + CronSchedule: model.CronSchedule{ + CronScheduleStartTimeInSec: util.Int64Pointer(1), + Cron: util.StringPointer("1 * * * *"), + }, + }, + MaxConcurrency: 1, + NoCatchup: true, + PipelineSpec: model.PipelineSpec{ + PipelineId: pipeline.UUID, + PipelineName: pipeline.Name, + WorkflowSpecManifest: "workflow spec", + Parameters: `[{"name":"param2","value":"world"}]`, + }, + ResourceReferences: []*model.ResourceReference{ + { + ResourceUUID: "swf_123", + ResourceType: common.Job, + ReferenceUUID: experiment.UUID, + ReferenceName: experiment.Name, + ReferenceType: common.Experiment, + Relationship: common.Owner}, + }, }, }, - MaxConcurrency: 1, - NoCatchup: true, - PipelineSpec: model.PipelineSpec{ - PipelineId: pipeline.UUID, - PipelineName: pipeline.Name, - WorkflowSpecManifest: "workflow spec", - Parameters: `[{"name":"param2","value":"world"}]`, - }, - ResourceReferences: []*model.ResourceReference{ - { - ResourceUUID: "swf_123", - ResourceType: common.Job, - ReferenceUUID: experiment.UUID, - ReferenceName: experiment.Name, - ReferenceType: common.Experiment, - Relationship: common.Owner}, + {name: "v2", + apiJob: &api.Job{ + Name: "name1", + Enabled: true, + MaxConcurrency: 1, + NoCatchup: true, + Trigger: &api.Trigger{ + Trigger: &api.Trigger_CronSchedule{CronSchedule: &api.CronSchedule{ + StartTime: ×tamp.Timestamp{Seconds: 1}, + Cron: "1 * * * *", + }}}, + ResourceReferences: []*api.ResourceReference{ + {Key: &api.ResourceKey{Type: api.ResourceType_EXPERIMENT, Id: experiment.UUID}, Relationship: api.Relationship_OWNER}, + }, + PipelineSpec: &api.PipelineSpec{PipelineId: pipeline.UUID, RuntimeConfig: &api.PipelineSpec_RuntimeConfig{Parameters: map[string]*api.Value{ + "param2": { + Value: &api.Value_StringValue{ + StringValue: "world", + }, + }, + }}}, + }, + swf: util.NewScheduledWorkflow(&swfapi.ScheduledWorkflow{ + ObjectMeta: v1.ObjectMeta{ + Name: "swf_name", + Namespace: "swf_namespace", + UID: "swf_123", + }, + Status: swfapi.ScheduledWorkflowStatus{ + Conditions: []swfapi.ScheduledWorkflowCondition{{Type: swfapi.ScheduledWorkflowEnabled}}}, + }), + manifest: "pipeline spec", + templateType: template.V2, + expectedModelJob: &model.Job{ + UUID: "swf_123", + Name: "swf_name", + Namespace: "swf_namespace", + Conditions: "Enabled", + DisplayName: "name1", + Enabled: true, + Trigger: model.Trigger{ + CronSchedule: model.CronSchedule{ + CronScheduleStartTimeInSec: util.Int64Pointer(1), + Cron: util.StringPointer("1 * * * *"), + }, + }, + MaxConcurrency: 1, + NoCatchup: true, + PipelineSpec: model.PipelineSpec{ + PipelineId: pipeline.UUID, + PipelineName: pipeline.Name, + PipelineSpecManifest: "pipeline spec", + Parameters: `[{"name":"param2","value":"world"}]`, + }, + ResourceReferences: []*model.ResourceReference{ + { + ResourceUUID: "swf_123", + ResourceType: common.Job, + ReferenceUUID: experiment.UUID, + ReferenceName: experiment.Name, + ReferenceType: common.Experiment, + Relationship: common.Owner}, + }, + }, }, } - assert.Equal(t, expectedModelJob, modelJob) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + modelJob, err := manager.ToModelJob(tt.apiJob, tt.swf, tt.manifest, tt.templateType) + assert.Nil(t, err) + assert.Equal(t, tt.expectedModelJob, modelJob) + }) + } } func TestToModelResourceReferences(t *testing.T) { diff --git a/backend/src/apiserver/resource/resource_manager.go b/backend/src/apiserver/resource/resource_manager.go index f2dcbb0d4af..6d3200beb34 100644 --- a/backend/src/apiserver/resource/resource_manager.go +++ b/backend/src/apiserver/resource/resource_manager.go @@ -18,6 +18,7 @@ import ( "context" "encoding/json" "fmt" + "github.com/kubeflow/pipelines/backend/src/apiserver/template" "io" "strconv" @@ -36,7 +37,6 @@ import ( "github.com/kubeflow/pipelines/backend/src/apiserver/model" "github.com/kubeflow/pipelines/backend/src/apiserver/storage" "github.com/kubeflow/pipelines/backend/src/common/util" - scheduledworkflow "github.com/kubeflow/pipelines/backend/src/crd/pkg/apis/scheduledworkflow/v1beta1" scheduledworkflowclient "github.com/kubeflow/pipelines/backend/src/crd/pkg/client/clientset/versioned/typed/scheduledworkflow/v1beta1" "github.com/pkg/errors" "github.com/prometheus/client_golang/prometheus" @@ -50,13 +50,6 @@ import ( utilerrors "k8s.io/apimachinery/pkg/util/errors" ) -const ( - defaultPipelineRunnerServiceAccount = "pipeline-runner" - HasDefaultBucketEnvVar = "HAS_DEFAULT_BUCKET" - ProjectIDEnvVar = "PROJECT_ID" - DefaultBucketNameEnvVar = "BUCKET_NAME" -) - // Metric variables. Please prefix the metric names with resource_manager_. var ( // Count the removed workflows due to garbage collection. @@ -262,7 +255,7 @@ func (r *ResourceManager) UpdatePipelineDefaultVersion(pipelineId string, versio } func (r *ResourceManager) CreatePipeline(name string, description string, namespace string, pipelineFile []byte) (*model.Pipeline, error) { - tmpl, err := util.NewTemplate(pipelineFile) + tmpl, err := template.New(pipelineFile) if err != nil { return nil, util.Wrap(err, "Create pipeline failed") } @@ -338,83 +331,35 @@ func (r *ResourceManager) GetPipelineTemplate(pipelineId string) ([]byte, error) } func (r *ResourceManager) CreateRun(ctx context.Context, apiRun *api.Run) (*model.RunDetail, error) { - // Get workflow from either of the two places: - // (1) raw pipeline manifest in pipeline_spec + // Get manifest from either of the two places: + // (1) raw manifest in pipeline_spec // (2) pipeline version in resource_references - // And the latter takes priority over the former when the pipeline manifest is from pipeline_spec.pipeline_id - // workflow manifest and pipeline id/version will not exist at the same time, guaranteed by the validation phase - workflowSpecManifestBytes, err := getWorkflowSpecManifestBytes(apiRun.PipelineSpec, &apiRun.ResourceReferences, r) + // And the latter takes priority over the former when the manifest is from pipeline_spec.pipeline_id + // workflow/pipeline manifest and pipeline id/version will not exist at the same time, guaranteed by the validation phase + manifestBytes, err := getManifestBytes(apiRun.PipelineSpec, &apiRun.ResourceReferences, r) if err != nil { return nil, err } + uuid, err := r.uuid.NewRandom() if err != nil { return nil, util.NewInternalServerError(err, "Failed to generate run ID.") } runId := uuid.String() - runAt := r.time.Now().Unix() - var workflow util.Workflow - if err = json.Unmarshal(workflowSpecManifestBytes, &workflow); err != nil { - return nil, util.NewInternalServerError(err, - "Failed to unmarshal workflow spec manifest. Workflow bytes: %s", string(workflowSpecManifestBytes)) - } - if workflow.Workflow == nil { - return nil, util.Wrap( - util.NewResourceNotFoundError("WorkflowSpecManifest", apiRun.GetName()), - "Failed to fetch workflow spec manifest.") - } - - parameters := toParametersMap(apiRun.GetPipelineSpec().GetParameters()) - // Verify no additional parameter provided - if err = workflow.VerifyParameters(parameters); err != nil { - return nil, util.Wrap(err, "Failed to verify parameters.") - } - // Append provided parameter - workflow.OverrideParameters(parameters) - - // Replace macros - formatter := util.NewRunParameterFormatter(uuid.String(), runAt) - formattedParams := formatter.FormatWorkflowParameters(workflow.GetWorkflowParametersAsMap()) - workflow.OverrideParameters(formattedParams) - - r.setDefaultServiceAccount(&workflow, apiRun.GetServiceAccount()) - - // Disable istio sidecar injection if not specified - workflow.SetAnnotationsToAllTemplatesIfKeyNotExist(util.AnnotationKeyIstioSidecarInject, util.AnnotationValueIstioSidecarInjectDisabled) - // Add a KFP specific label for cache service filtering. The cache_enabled flag here is a global control for whether cache server will - // receive targeting pods. Since cache server only receives pods in step level, the resource manager here will set this global label flag - // on every single step/pod so the cache server can understand. - // TODO: Add run_level flag with similar logic by reading flag value from create_run api. - workflow.SetLabelsToAllTemplates(util.LabelKeyCacheEnabled, common.IsCacheEnabled()) - - err = OverrideParameterWithSystemDefault(workflow, apiRun) + tmpl, err := template.New(manifestBytes) if err != nil { return nil, err } - - // Add label to the workflow so it can be persisted by persistent agent later. - workflow.SetLabels(util.LabelKeyWorkflowRunId, runId) - // Add run name annotation to the workflow so that it can be logged by the Metadata Writer. - workflow.SetAnnotations(util.AnnotationKeyRunName, apiRun.Name) - // Replace {{workflow.uid}} with runId - err = workflow.ReplaceUID(runId) - if err != nil { - return nil, util.NewInternalServerError(err, "Failed to replace workflow ID") + runWorkflowOptions := template.RunWorkflowOptions{ + RunId: runId, + RunAt: runAt, } - workflow.SetPodMetadataLabels(util.LabelKeyWorkflowRunId, runId) - - // Marking auto-added artifacts as optional. Otherwise most older workflows will start failing after upgrade to Argo 2.3. - // TODO: Fix the components to explicitly declare the artifacts they really output. - for templateIdx, template := range workflow.Workflow.Spec.Templates { - for artIdx, artifact := range template.Outputs.Artifacts { - if artifact.Name == "mlpipeline-ui-metadata" || artifact.Name == "mlpipeline-metrics" { - workflow.Workflow.Spec.Templates[templateIdx].Outputs.Artifacts[artIdx].Optional = true - } - } + workflow, err := tmpl.RunWorkflow(apiRun, runWorkflowOptions) + if err != nil { + return nil, util.NewInternalServerError(err, "failed to generate the workflow.") } - // Add a reference to the default experiment if run does not already have a containing experiment ref, err := r.getDefaultExperimentIfNoExperiment(apiRun.GetResourceReferences()) if err != nil { @@ -443,8 +388,19 @@ func (r *ResourceManager) CreateRun(ctx context.Context, apiRun *api.Run) (*mode return nil, util.NewInternalServerError(err, "Failed to create a workflow for (%s)", workflow.Name) } + // Patched the default value to apiRun + if common.GetBoolConfigWithDefault(common.HasDefaultBucketEnvVar, false) { + for _, param := range apiRun.PipelineSpec.Parameters { + var err error + param.Value, err = common.PatchPipelineDefaultParameter(param.Value) + if err != nil { + return nil, fmt.Errorf("failed to patch default value to pipeline. Error: %v", err) + } + } + } + // Store run metadata into database - runDetail, err := r.ToModelRunDetail(apiRun, runId, util.NewWorkflow(newWorkflow), string(workflowSpecManifestBytes)) + runDetail, err := r.ToModelRunDetail(apiRun, runId, util.NewWorkflow(newWorkflow), string(manifestBytes), tmpl.GetTemplateType()) if err != nil { return nil, util.Wrap(err, "Failed to convert run model") } @@ -577,9 +533,12 @@ func (r *ResourceManager) RetryRun(ctx context.Context, runId string) error { return util.Wrap(err, "Retry run failed") } - if runDetail.WorkflowRuntimeManifest == "" { + if runDetail.WorkflowSpecManifest != "" && runDetail.WorkflowRuntimeManifest == "" { return util.NewBadRequestError(errors.New("workflow cannot be retried"), "Workflow must be Failed/Error to retry") } + if runDetail.PipelineSpecManifest != "" { + return util.NewBadRequestError(errors.New("workflow cannot be retried"), "Workflow must be with v1 mode to retry") + } var workflow util.Workflow if err := json.Unmarshal([]byte(runDetail.WorkflowRuntimeManifest), &workflow); err != nil { return util.NewInternalServerError(err, "Failed to retrieve the runtime pipeline spec from the run") @@ -712,62 +671,20 @@ func (r *ResourceManager) CreateJob(ctx context.Context, apiJob *api.Job) (*mode // (2) pipeline version in resource_references // And the latter takes priority over the former when the pipeline manifest is from pipeline_spec.pipeline_id // workflow manifest and pipeline id/version will not exist at the same time, guaranteed by the validation phase - workflowSpecManifestBytes, err := getWorkflowSpecManifestBytes(apiJob.PipelineSpec, &apiJob.ResourceReferences, r) + manifestBytes, err := getManifestBytes(apiJob.PipelineSpec, &apiJob.ResourceReferences, r) if err != nil { return nil, err } - var workflow util.Workflow - err = json.Unmarshal(workflowSpecManifestBytes, &workflow) + tmpl, err := template.New(manifestBytes) if err != nil { - return nil, util.NewInternalServerError(err, - "Failed to unmarshal workflow spec manifest. Workflow bytes: %s", string(workflowSpecManifestBytes)) - } - if workflow.Workflow == nil { - return nil, util.Wrap( - util.NewResourceNotFoundError("WorkflowSpecManifest", apiJob.GetName()), - "Failed to fetch workflow spec manifest.") - } - - // Verify no additional parameter provided - err = workflow.VerifyParameters(toParametersMap(apiJob.GetPipelineSpec().GetParameters())) - if err != nil { - return nil, util.Wrap(err, "Create job failed") + return nil, err } - r.setDefaultServiceAccount(&workflow, apiJob.GetServiceAccount()) - - // Disable istio sidecar injection if not specified - workflow.SetAnnotationsToAllTemplatesIfKeyNotExist(util.AnnotationKeyIstioSidecarInject, util.AnnotationValueIstioSidecarInjectDisabled) - - swfGeneratedName, err := toSWFCRDResourceGeneratedName(apiJob.Name) + scheduledWorkflow, err := tmpl.ScheduledWorkflow(apiJob) if err != nil { - return nil, util.Wrap(err, "Create job failed") - } - scheduledWorkflow := &scheduledworkflow.ScheduledWorkflow{ - ObjectMeta: v1.ObjectMeta{GenerateName: swfGeneratedName}, - Spec: scheduledworkflow.ScheduledWorkflowSpec{ - Enabled: apiJob.Enabled, - MaxConcurrency: &apiJob.MaxConcurrency, - Trigger: *toCRDTrigger(apiJob.Trigger), - Workflow: &scheduledworkflow.WorkflowResource{ - Parameters: toCRDParameter(apiJob.GetPipelineSpec().GetParameters()), - Spec: workflow.Spec, - }, - NoCatchup: util.BoolPointer(apiJob.NoCatchup), - }, + return nil, util.Wrap(err, "failed to generate the scheduledWorkflow.") } - - // Marking auto-added artifacts as optional. Otherwise most older workflows will start failing after upgrade to Argo 2.3. - // TODO: Fix the components to explicitly declare the artifacts they really output. - for templateIdx, template := range scheduledWorkflow.Spec.Workflow.Spec.Templates { - for artIdx, artifact := range template.Outputs.Artifacts { - if artifact.Name == "mlpipeline-ui-metadata" || artifact.Name == "mlpipeline-metrics" { - scheduledWorkflow.Spec.Workflow.Spec.Templates[templateIdx].Outputs.Artifacts[artIdx].Optional = true - } - } - } - // Add a reference to the default experiment if run does not already have a containing experiment ref, err := r.getDefaultExperimentIfNoExperiment(apiJob.GetResourceReferences()) if err != nil { @@ -787,7 +704,7 @@ func (r *ResourceManager) CreateJob(ctx context.Context, apiJob *api.Job) (*mode return nil, util.NewInternalServerError(err, "Failed to create a scheduled workflow for (%s)", scheduledWorkflow.Name) } - job, err := r.ToModelJob(apiJob, util.NewScheduledWorkflow(newScheduledWorkflow), string(workflowSpecManifestBytes)) + job, err := r.ToModelJob(apiJob, util.NewScheduledWorkflow(newScheduledWorkflow), string(manifestBytes), tmpl.GetTemplateType()) if err != nil { return nil, util.Wrap(err, "Create job failed") } @@ -1055,7 +972,7 @@ func (r *ResourceManager) getWorkflowSpecBytesFromPipelineSpec(spec *api.Pipelin return nil, util.NewInvalidInputError("Please provide a valid pipeline spec") } -func (r *ResourceManager) getWorkflowSpecBytesFromPipelineVersion(references []*api.ResourceReference) ([]byte, error) { +func (r *ResourceManager) getManifestBytesFromPipelineVersion(references []*api.ResourceReference) ([]byte, error) { var pipelineVersionId = "" for _, reference := range references { if reference.Key.Type == api.ResourceType_PIPELINE_VERSION && reference.Relationship == api.Relationship_CREATOR { @@ -1065,30 +982,31 @@ func (r *ResourceManager) getWorkflowSpecBytesFromPipelineVersion(references []* if len(pipelineVersionId) == 0 { return nil, util.NewInvalidInputError("No pipeline version.") } - var workflow util.Workflow - err := r.objectStore.GetFromYamlFile(&workflow, r.objectStore.GetPipelineKey(pipelineVersionId)) + manifestBytes, err := r.objectStore.GetFile(r.objectStore.GetPipelineKey(pipelineVersionId)) if err != nil { - return nil, util.Wrap(err, "Get pipeline YAML failed.") + return nil, util.Wrap(err, "Get manifest bytes from PipelineVersion failed.") } - return []byte(workflow.ToStringForStore()), nil + return manifestBytes, nil } -func getWorkflowSpecManifestBytes(pipelineSpec *api.PipelineSpec, resourceReferences *[]*api.ResourceReference, r *ResourceManager) ([]byte, error) { - var workflowSpecManifestBytes []byte +func getManifestBytes(pipelineSpec *api.PipelineSpec, resourceReferences *[]*api.ResourceReference, r *ResourceManager) ([]byte, error) { + var manifestBytes []byte if pipelineSpec.GetWorkflowManifest() != "" { - workflowSpecManifestBytes = []byte(pipelineSpec.GetWorkflowManifest()) + manifestBytes = []byte(pipelineSpec.GetWorkflowManifest()) + } else if pipelineSpec.GetPipelineManifest() != "" { + manifestBytes = []byte(pipelineSpec.GetPipelineManifest()) } else { err := convertPipelineIdToDefaultPipelineVersion(pipelineSpec, resourceReferences, r) if err != nil { return nil, util.Wrap(err, "Failed to find default version to create run with pipeline id.") } - workflowSpecManifestBytes, err = r.getWorkflowSpecBytesFromPipelineVersion(*resourceReferences) + manifestBytes, err = r.getManifestBytesFromPipelineVersion(*resourceReferences) if err != nil { - return nil, util.Wrap(err, "Failed to fetch workflow spec.") + return nil, util.Wrap(err, "Failed to fetch manifest bytes.") } } - return workflowSpecManifestBytes, nil + return manifestBytes, nil } // Used to initialize the Experiment database with a default to be used for runs @@ -1174,6 +1092,9 @@ func (r *ResourceManager) ReadArtifact(runID string, nodeID string, artifactName if err != nil { return nil, err } + if run.WorkflowRuntimeManifest == "" { + return nil, util.NewInvalidInputError("read artifact from run with v2 IR spec is not supported") + } var storageWorkflow workflowapi.Workflow err = json.Unmarshal([]byte(run.WorkflowRuntimeManifest), &storageWorkflow) if err != nil { @@ -1206,10 +1127,6 @@ func (r *ResourceManager) MarkSampleLoaded() error { return r.dBStatusStore.MarkSampleLoaded() } -func (r *ResourceManager) getDefaultSA() string { - return common.GetStringConfigWithDefault(common.DefaultPipelineRunnerServiceAccount, defaultPipelineRunnerServiceAccount) -} - func (r *ResourceManager) CreatePipelineVersion(apiVersion *api.PipelineVersion, pipelineFile []byte, updateDefaultVersion bool) (*model.PipelineVersion, error) { // Extract pipeline id var pipelineId = "" @@ -1221,7 +1138,7 @@ func (r *ResourceManager) CreatePipelineVersion(apiVersion *api.PipelineVersion, if len(pipelineId) == 0 { return nil, util.NewInvalidInputError("Create pipeline version failed due to missing pipeline id") } - tmpl, err := util.NewTemplate(pipelineFile) + tmpl, err := template.New(pipelineFile) if err != nil { return nil, util.Wrap(err, "Create pipeline version failed") } @@ -1405,19 +1322,6 @@ func (r *ResourceManager) GetNamespaceFromPipelineVersion(versionId string) (str return r.GetNamespaceFromPipelineID(pipelineVersion.PipelineId) } -func (r *ResourceManager) setDefaultServiceAccount(workflow *util.Workflow, serviceAccount string) { - if len(serviceAccount) > 0 { - workflow.SetServiceAccount(serviceAccount) - return - } - workflowServiceAccount := workflow.Spec.ServiceAccountName - if len(workflowServiceAccount) == 0 || workflowServiceAccount == defaultPipelineRunnerServiceAccount { - // To reserve SDK backward compatibility, the backend only replaces - // serviceaccount when it is empty or equal to default value set by SDK. - workflow.SetServiceAccount(r.getDefaultSA()) - } -} - func (r *ResourceManager) getNamespaceFromExperiment(references []*api.ResourceReference) (string, error) { experimentID := common.GetExperimentIDFromAPIResourceReferences(references) experiment, err := r.GetExperiment(experimentID) diff --git a/backend/src/apiserver/resource/resource_manager_test.go b/backend/src/apiserver/resource/resource_manager_test.go index 077e3c5b03e..b7497dbe3e1 100644 --- a/backend/src/apiserver/resource/resource_manager_test.go +++ b/backend/src/apiserver/resource/resource_manager_test.go @@ -18,6 +18,7 @@ import ( "context" "encoding/json" "fmt" + "github.com/kubeflow/pipelines/backend/src/apiserver/template" "strings" "testing" "time" @@ -183,6 +184,26 @@ func initWithJob(t *testing.T) (*FakeClientManager, *ResourceManager, *model.Job return store, manager, j } +// Util function to create an initial state with pipeline uploaded +func initWithJobV2(t *testing.T) (*FakeClientManager, *ResourceManager, *model.Job) { + store, manager, exp := initWithExperiment(t) + job := &api.Job{ + Name: "j1", + Enabled: true, + PipelineSpec: &api.PipelineSpec{PipelineManifest: v2SpecHelloWorld}, + ResourceReferences: []*api.ResourceReference{ + { + Key: &api.ResourceKey{Type: api.ResourceType_EXPERIMENT, Id: exp.UUID}, + Relationship: api.Relationship_OWNER, + }, + }, + } + j, err := manager.CreateJob(context.Background(), job) + assert.Nil(t, err) + + return store, manager, j +} + func initWithOneTimeRun(t *testing.T) (*FakeClientManager, *ResourceManager, *model.RunDetail) { store, manager, exp := initWithExperiment(t) apiRun := &api.Run{ @@ -205,6 +226,25 @@ func initWithOneTimeRun(t *testing.T) (*FakeClientManager, *ResourceManager, *mo return store, manager, runDetail } +func initWithOneTimeRunV2(t *testing.T) (*FakeClientManager, *ResourceManager, *model.RunDetail) { + store, manager, exp := initWithExperiment(t) + apiRun := &api.Run{ + Name: "run1", + PipelineSpec: &api.PipelineSpec{ + PipelineManifest: v2SpecHelloWorld, + }, + ResourceReferences: []*api.ResourceReference{ + { + Key: &api.ResourceKey{Type: api.ResourceType_EXPERIMENT, Id: exp.UUID}, + Relationship: api.Relationship_OWNER, + }, + }, + } + runDetail, err := manager.CreateRun(context.Background(), apiRun) + assert.Nil(t, err) + return store, manager, runDetail +} + func initWithPatchedRun(t *testing.T) (*FakeClientManager, *ResourceManager, *model.RunDetail) { store, manager, exp := initWithExperiment(t) apiRun := &api.Run{ @@ -384,7 +424,7 @@ func TestCreatePipeline(t *testing.T) { msg: "InvalidTemplate", template: "I am invalid yaml", errorCode: codes.InvalidArgument, - errorIs: util.ErrorInvalidPipelineSpec, + errorIs: template.ErrorInvalidPipelineSpec, }, { msg: "BadDB", @@ -489,6 +529,7 @@ func TestGetPipelineTemplate_PipelineFileNotFound(t *testing.T) { assert.Contains(t, err.Error(), "object not found") } +// TODO: use table driven test to test CreateRun api func TestCreateRun_ThroughPipelineID(t *testing.T) { store, manager, p := initWithPipeline(t) defer store.Close() @@ -539,7 +580,7 @@ func TestCreateRun_ThroughPipelineID(t *testing.T) { expectedRuntimeWorkflow.Labels = map[string]string{util.LabelKeyWorkflowRunId: "123e4567-e89b-12d3-a456-426655440000"} expectedRuntimeWorkflow.Annotations = map[string]string{util.AnnotationKeyRunName: "run1"} expectedRuntimeWorkflow.Spec.Arguments.Parameters = []v1alpha1.Parameter{{Name: "param1", Value: v1alpha1.AnyStringPtr("world")}} - expectedRuntimeWorkflow.Spec.ServiceAccountName = defaultPipelineRunnerServiceAccount + expectedRuntimeWorkflow.Spec.ServiceAccountName = common.DefaultPipelineRunnerServiceAccount expectedRuntimeWorkflow.Spec.PodMetadata = &v1alpha1.Metadata{ Labels: map[string]string{ util.LabelKeyWorkflowRunId: DefaultFakeUUID, @@ -592,6 +633,42 @@ func TestCreateRun_ThroughPipelineID(t *testing.T) { assert.Equal(t, expectedRunDetail, runDetail, "CreateRun stored invalid data in database") } +func TestCreateRun_ThroughWorkflowSpecV2(t *testing.T) { + store, manager, runDetail := initWithOneTimeRunV2(t) + expectedExperimentUUID := runDetail.ExperimentUUID + + expectedRunDetail := &model.RunDetail{ + Run: model.Run{ + UUID: "123e4567-e89b-12d3-a456-426655440000", + ExperimentUUID: expectedExperimentUUID, + DisplayName: "run1", + Name: "hello-world-0", + ServiceAccount: "pipeline-runner", + StorageState: api.Run_STORAGESTATE_AVAILABLE.String(), + CreatedAtInSec: 2, + PipelineSpec: model.PipelineSpec{ + PipelineSpecManifest: v2SpecHelloWorld, + }, + ResourceReferences: []*model.ResourceReference{ + { + ResourceUUID: "123e4567-e89b-12d3-a456-426655440000", + ResourceType: common.Run, + ReferenceUUID: DefaultFakeUUID, + ReferenceName: "e1", + ReferenceType: common.Experiment, + Relationship: common.Owner, + }, + }, + }, + } + assert.Equal(t, expectedRunDetail, runDetail, "The CreateRun return has unexpected value.") + assert.Equal(t, 1, store.ArgoClientFake.GetWorkflowCount(), "Workflow CRD is not created.") + runDetail, err := manager.GetRun(runDetail.UUID) + assert.Nil(t, err) + assert.Equal(t, expectedRunDetail, runDetail, "CreateRun stored invalid data in database") +} + + func TestCreateRun_ThroughWorkflowSpec(t *testing.T) { store, manager, runDetail := initWithOneTimeRun(t) expectedExperimentUUID := runDetail.ExperimentUUID @@ -600,7 +677,7 @@ func TestCreateRun_ThroughWorkflowSpec(t *testing.T) { expectedRuntimeWorkflow.Labels = map[string]string{util.LabelKeyWorkflowRunId: "123e4567-e89b-12d3-a456-426655440000"} expectedRuntimeWorkflow.Annotations = map[string]string{util.AnnotationKeyRunName: "run1"} expectedRuntimeWorkflow.Spec.Arguments.Parameters = []v1alpha1.Parameter{{Name: "param1", Value: v1alpha1.AnyStringPtr("world")}} - expectedRuntimeWorkflow.Spec.ServiceAccountName = defaultPipelineRunnerServiceAccount + expectedRuntimeWorkflow.Spec.ServiceAccountName = common.DefaultPipelineRunnerServiceAccount expectedRuntimeWorkflow.Spec.PodMetadata = &v1alpha1.Metadata{ Labels: map[string]string{ util.LabelKeyWorkflowRunId: DefaultFakeUUID, @@ -645,9 +722,9 @@ func TestCreateRun_ThroughWorkflowSpec(t *testing.T) { } func TestCreateRun_ThroughWorkflowSpecWithPatch(t *testing.T) { - viper.Set(HasDefaultBucketEnvVar, "true") - viper.Set(ProjectIDEnvVar, "test-project-id") - viper.Set(DefaultBucketNameEnvVar, "test-default-bucket") + viper.Set(common.HasDefaultBucketEnvVar, "true") + viper.Set(common.ProjectIDEnvVar, "test-project-id") + viper.Set(common.DefaultBucketNameEnvVar, "test-default-bucket") store, manager, runDetail := initWithPatchedRun(t) expectedExperimentUUID := runDetail.ExperimentUUID expectedRuntimeWorkflow := testWorkflow.DeepCopy() @@ -655,7 +732,7 @@ func TestCreateRun_ThroughWorkflowSpecWithPatch(t *testing.T) { expectedRuntimeWorkflow.Labels = map[string]string{util.LabelKeyWorkflowRunId: "123e4567-e89b-12d3-a456-426655440000"} expectedRuntimeWorkflow.Annotations = map[string]string{util.AnnotationKeyRunName: "run1"} expectedRuntimeWorkflow.Spec.Arguments.Parameters = []v1alpha1.Parameter{{Name: "param1", Value: v1alpha1.AnyStringPtr("test-default-bucket")}} - expectedRuntimeWorkflow.Spec.ServiceAccountName = defaultPipelineRunnerServiceAccount + expectedRuntimeWorkflow.Spec.ServiceAccountName = common.DefaultPipelineRunnerServiceAccount expectedRuntimeWorkflow.Spec.PodMetadata = &v1alpha1.Metadata{ Labels: map[string]string{ util.LabelKeyWorkflowRunId: DefaultFakeUUID, @@ -952,7 +1029,7 @@ func TestCreateRun_EmptyPipelineSpec(t *testing.T) { } _, err := manager.CreateRun(context.Background(), apiRun) assert.NotNil(t, err) - assert.Contains(t, err.Error(), "Failed to fetch workflow spec") + assert.Contains(t, err.Error(), "Failed to fetch manifest bytes") } func TestCreateRun_InvalidWorkflowSpec(t *testing.T) { @@ -970,7 +1047,7 @@ func TestCreateRun_InvalidWorkflowSpec(t *testing.T) { } _, err := manager.CreateRun(context.Background(), apiRun) assert.NotNil(t, err) - assert.Contains(t, err.Error(), "Failed to unmarshal workflow spec manifest") + assert.Contains(t, err.Error(), "unknown template format") } func TestCreateRun_NullWorkflowSpec(t *testing.T) { @@ -988,7 +1065,7 @@ func TestCreateRun_NullWorkflowSpec(t *testing.T) { } _, err := manager.CreateRun(context.Background(), apiRun) assert.NotNil(t, err) - assert.Contains(t, err.Error(), "Failed to fetch workflow spec manifest.: ResourceNotFoundError: WorkflowSpecManifest run1 not found.") + assert.Contains(t, err.Error(), "unknown template format") } func TestCreateRun_OverrideParametersError(t *testing.T) { @@ -1252,6 +1329,7 @@ func TestRetryRun_UpdateAndCreateFailed(t *testing.T) { assert.Contains(t, err.Error(), "Failed to create or update the run") } +// TODO Use table driven to write UT to test CreateJob func TestCreateJob_ThroughWorkflowSpec(t *testing.T) { store, _, job := initWithJob(t) defer store.Close() @@ -1282,6 +1360,39 @@ func TestCreateJob_ThroughWorkflowSpec(t *testing.T) { assert.Equal(t, expectedJob, job) } +func TestCreateJob_ThroughWorkflowSpecV2(t *testing.T) { + store, manager, job := initWithJobV2(t) + defer store.Close() + expectedJob := &model.Job{ + UUID: "123e4567-e89b-12d3-a456-426655440000", + DisplayName: "j1", + Name: "j1", + Namespace: "ns1", + ServiceAccount: "pipeline-runner", + Enabled: true, + CreatedAtInSec: 2, + UpdatedAtInSec: 2, + Conditions: "NO_STATUS", + PipelineSpec: model.PipelineSpec{ + PipelineSpecManifest: v2SpecHelloWorld, + }, + ResourceReferences: []*model.ResourceReference{ + { + ResourceUUID: "123e4567-e89b-12d3-a456-426655440000", + ResourceType: common.Job, + ReferenceUUID: DefaultFakeUUID, + ReferenceName: "e1", + ReferenceType: common.Experiment, + Relationship: common.Owner, + }, + }, + } + assert.Equal(t, expectedJob, job) + fetchedJob, err := manager.GetJob(job.UUID) + assert.Nil(t, err) + assert.Equal(t, expectedJob, fetchedJob, "CreateJob stored invalid data in database") +} + func TestCreateJob_ThroughPipelineID(t *testing.T) { store, manager, pipeline := initWithPipeline(t) defer store.Close() @@ -1538,7 +1649,7 @@ func TestCreateJob_EmptyPipelineSpec(t *testing.T) { } _, err := manager.CreateJob(context.Background(), job) assert.NotNil(t, err) - assert.Contains(t, err.Error(), "Failed to fetch workflow spec") + assert.Contains(t, err.Error(), "Failed to fetch manifest bytes") } func TestCreateJob_InvalidWorkflowSpec(t *testing.T) { @@ -1557,7 +1668,7 @@ func TestCreateJob_InvalidWorkflowSpec(t *testing.T) { } _, err := manager.CreateJob(context.Background(), job) assert.NotNil(t, err) - assert.Contains(t, err.Error(), "Failed to unmarshal workflow spec manifest") + assert.Contains(t, err.Error(), "unknown template format") } func TestCreateJob_NullWorkflowSpec(t *testing.T) { @@ -1576,7 +1687,7 @@ func TestCreateJob_NullWorkflowSpec(t *testing.T) { } _, err := manager.CreateJob(context.Background(), job) assert.NotNil(t, err) - assert.Contains(t, err.Error(), "Failed to fetch workflow spec manifest.: ResourceNotFoundError: WorkflowSpecManifest pp 1 not found.") + assert.Contains(t, err.Error(), "unknown template format") } func TestCreateJob_ExtraInputParameterError(t *testing.T) { @@ -2942,7 +3053,7 @@ func TestCreatePipelineVersion(t *testing.T) { msg: "InvalidTemplate", template: "I am invalid yaml", errorCode: codes.InvalidArgument, - errorIs: util.ErrorInvalidPipelineSpec, + errorIs: template.ErrorInvalidPipelineSpec, }, { msg: "BadDB", @@ -3055,7 +3166,7 @@ func TestCreatePipelineOrVersion_V2PipelineName(t *testing.T) { require.Nil(t, err) bytes, err := manager.GetPipelineTemplate(createdPipeline.UUID) require.Nil(t, err) - tmpl, err := util.NewTemplate(bytes) + tmpl, err := template.New(bytes) require.Nil(t, err) assert.Equal(t, test.pipelineName, tmpl.V2PipelineName()) @@ -3075,7 +3186,7 @@ func TestCreatePipelineOrVersion_V2PipelineName(t *testing.T) { require.Nil(t, err) bytes, err = manager.GetPipelineVersionTemplate(version.UUID) require.Nil(t, err) - tmpl, err = util.NewTemplate(bytes) + tmpl, err = template.New(bytes) require.Nil(t, err) assert.Equal(t, test.pipelineName, tmpl.V2PipelineName()) }) diff --git a/backend/src/apiserver/resource/resource_manager_util.go b/backend/src/apiserver/resource/resource_manager_util.go index 102a373bfde..859efa02da2 100644 --- a/backend/src/apiserver/resource/resource_manager_util.go +++ b/backend/src/apiserver/resource/resource_manager_util.go @@ -17,109 +17,17 @@ package resource import ( "context" "errors" - "fmt" - "regexp" - "strings" - "time" - wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" "github.com/argoproj/argo-workflows/v3/workflow/common" api "github.com/kubeflow/pipelines/backend/api/go_client" "github.com/kubeflow/pipelines/backend/src/apiserver/client" - servercommon "github.com/kubeflow/pipelines/backend/src/apiserver/common" "github.com/kubeflow/pipelines/backend/src/apiserver/model" "github.com/kubeflow/pipelines/backend/src/common/util" - scheduledworkflow "github.com/kubeflow/pipelines/backend/src/crd/pkg/apis/scheduledworkflow/v1beta1" apierr "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "strings" ) -func toCRDTrigger(apiTrigger *api.Trigger) *scheduledworkflow.Trigger { - var crdTrigger scheduledworkflow.Trigger - if apiTrigger.GetCronSchedule() != nil { - crdTrigger.CronSchedule = toCRDCronSchedule(apiTrigger.GetCronSchedule()) - } - if apiTrigger.GetPeriodicSchedule() != nil { - crdTrigger.PeriodicSchedule = toCRDPeriodicSchedule(apiTrigger.GetPeriodicSchedule()) - } - return &crdTrigger -} - -func toCRDCronSchedule(cronSchedule *api.CronSchedule) *scheduledworkflow.CronSchedule { - if cronSchedule == nil || cronSchedule.Cron == "" { - return nil - } - crdCronSchedule := scheduledworkflow.CronSchedule{} - crdCronSchedule.Cron = cronSchedule.Cron - - if cronSchedule.StartTime != nil { - startTime := v1.NewTime(time.Unix(cronSchedule.StartTime.Seconds, 0)) - crdCronSchedule.StartTime = &startTime - } - if cronSchedule.EndTime != nil { - endTime := v1.NewTime(time.Unix(cronSchedule.EndTime.Seconds, 0)) - crdCronSchedule.EndTime = &endTime - } - return &crdCronSchedule -} - -func toCRDPeriodicSchedule(periodicSchedule *api.PeriodicSchedule) *scheduledworkflow.PeriodicSchedule { - if periodicSchedule == nil || periodicSchedule.IntervalSecond == 0 { - return nil - } - crdPeriodicSchedule := scheduledworkflow.PeriodicSchedule{} - crdPeriodicSchedule.IntervalSecond = periodicSchedule.IntervalSecond - if periodicSchedule.StartTime != nil { - startTime := v1.NewTime(time.Unix(periodicSchedule.StartTime.Seconds, 0)) - crdPeriodicSchedule.StartTime = &startTime - } - if periodicSchedule.EndTime != nil { - endTime := v1.NewTime(time.Unix(periodicSchedule.EndTime.Seconds, 0)) - crdPeriodicSchedule.EndTime = &endTime - } - return &crdPeriodicSchedule -} - -func toCRDParameter(apiParams []*api.Parameter) []scheduledworkflow.Parameter { - var swParams []scheduledworkflow.Parameter - for _, apiParam := range apiParams { - swParam := scheduledworkflow.Parameter{ - Name: apiParam.Name, - Value: apiParam.Value, - } - swParams = append(swParams, swParam) - } - return swParams -} - -// Process the job name to remove special char, prepend with "job-" prefix if empty, and -// truncate size to <=25 -func toSWFCRDResourceGeneratedName(displayName string) (string, error) { - const ( - // K8s resource name only allow lower case alphabetic char, number and - - swfCompatibleNameRegx = "[^a-z0-9-]+" - ) - reg, err := regexp.Compile(swfCompatibleNameRegx) - if err != nil { - return "", util.NewInternalServerError(err, "Failed to compile ScheduledWorkflow name replacer Regex.") - } - processedName := reg.ReplaceAllString(strings.ToLower(displayName), "") - if processedName == "" { - processedName = "job-" - } - return util.Truncate(processedName, 25), nil -} - -func toParametersMap(apiParams []*api.Parameter) map[string]string { - // Preprocess workflow by appending parameter and add pipeline specific labels - desiredParamsMap := make(map[string]string) - for _, param := range apiParams { - desiredParamsMap[param.Name] = param.Value - } - return desiredParamsMap -} - func formulateRetryWorkflow(wf *util.Workflow) (*util.Workflow, []string, error) { switch wf.Status.Phase { case wfv1.WorkflowFailed, wfv1.WorkflowError: @@ -186,62 +94,6 @@ func deletePods(ctx context.Context, k8sCoreClient client.KubernetesCoreInterfac return nil } -// Mutate default values of specified pipeline spec. -// Args: -// text: (part of) pipeline file in string. -func PatchPipelineDefaultParameter(text string) (string, error) { - defaultBucket := servercommon.GetStringConfig(DefaultBucketNameEnvVar) - projectId := servercommon.GetStringConfig(ProjectIDEnvVar) - toPatch := map[string]string{ - "{{kfp-default-bucket}}": defaultBucket, - "{{kfp-project-id}}": projectId, - } - for key, value := range toPatch { - text = strings.Replace(text, key, value, -1) - } - return text, nil -} - -// Patch the system-specified default parameters if available. -func OverrideParameterWithSystemDefault(workflow util.Workflow, apiRun *api.Run) error { - // Patch the default value to workflow spec. - if servercommon.GetBoolConfigWithDefault(HasDefaultBucketEnvVar, false) { - patchedSlice := make([]wfv1.Parameter, 0) - for _, currentParam := range workflow.Spec.Arguments.Parameters { - if currentParam.Value != nil { - desiredValue, err := PatchPipelineDefaultParameter(currentParam.Value.String()) - if err != nil { - return fmt.Errorf("failed to patch default value to pipeline. Error: %v", err) - } - patchedSlice = append(patchedSlice, wfv1.Parameter{ - Name: currentParam.Name, - Value: wfv1.AnyStringPtr(desiredValue), - }) - } else if currentParam.Default != nil { - desiredValue, err := PatchPipelineDefaultParameter(currentParam.Default.String()) - if err != nil { - return fmt.Errorf("failed to patch default value to pipeline. Error: %v", err) - } - patchedSlice = append(patchedSlice, wfv1.Parameter{ - Name: currentParam.Name, - Value: wfv1.AnyStringPtr(desiredValue), - }) - } - } - workflow.Spec.Arguments.Parameters = patchedSlice - - // Patched the default value to apiRun - for _, param := range apiRun.PipelineSpec.Parameters { - var err error - param.Value, err = PatchPipelineDefaultParameter(param.Value) - if err != nil { - return fmt.Errorf("failed to patch default value to pipeline. Error: %v", err) - } - } - } - return nil -} - // Convert PipelineId in PipelineSpec to the pipeline's default pipeline version. // This is for legacy usage of pipeline id to create run. The standard way to // create run is by specifying the pipeline version. diff --git a/backend/src/apiserver/resource/resource_manager_util_test.go b/backend/src/apiserver/resource/resource_manager_util_test.go index f68d606f012..188e3aa066a 100644 --- a/backend/src/apiserver/resource/resource_manager_util_test.go +++ b/backend/src/apiserver/resource/resource_manager_util_test.go @@ -15,137 +15,15 @@ package resource import ( - "testing" - "time" - "github.com/ghodss/yaml" + api "github.com/kubeflow/pipelines/backend/api/go_client" "github.com/kubeflow/pipelines/backend/src/apiserver/storage" "github.com/kubeflow/pipelines/backend/src/common/util" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - "github.com/golang/protobuf/ptypes/timestamp" - api "github.com/kubeflow/pipelines/backend/api/go_client" - scheduledworkflow "github.com/kubeflow/pipelines/backend/src/crd/pkg/apis/scheduledworkflow/v1beta1" "github.com/stretchr/testify/assert" + "testing" ) -func TestToSwfCRDResourceGeneratedName_SpecialCharsAndSpace(t *testing.T) { - name, err := toSWFCRDResourceGeneratedName("! HaVe ä £unky name") - assert.Nil(t, err) - assert.Equal(t, name, "haveunkyname") -} - -func TestToSwfCRDResourceGeneratedName_TruncateLongName(t *testing.T) { - name, err := toSWFCRDResourceGeneratedName("AloooooooooooooooooongName") - assert.Nil(t, err) - assert.Equal(t, name, "aloooooooooooooooooongnam") -} - -func TestToSwfCRDResourceGeneratedName_EmptyName(t *testing.T) { - name, err := toSWFCRDResourceGeneratedName("") - assert.Nil(t, err) - assert.Equal(t, name, "job-") -} - -func TestToCrdParameter(t *testing.T) { - assert.Equal(t, - toCRDParameter([]*api.Parameter{{Name: "param2", Value: "world"}, {Name: "param1", Value: "hello"}}), - []scheduledworkflow.Parameter{{Name: "param2", Value: "world"}, {Name: "param1", Value: "hello"}}) -} -func TestToCrdCronSchedule(t *testing.T) { - actualCronSchedule := toCRDCronSchedule(&api.CronSchedule{ - Cron: "123", - StartTime: ×tamp.Timestamp{Seconds: 123}, - EndTime: ×tamp.Timestamp{Seconds: 456}, - }) - startTime := v1.NewTime(time.Unix(123, 0)) - endTime := v1.NewTime(time.Unix(456, 0)) - assert.Equal(t, actualCronSchedule, &scheduledworkflow.CronSchedule{ - Cron: "123", - StartTime: &startTime, - EndTime: &endTime, - }) -} - -func TestToCrdCronSchedule_NilCron(t *testing.T) { - actualCronSchedule := toCRDCronSchedule(&api.CronSchedule{ - StartTime: ×tamp.Timestamp{Seconds: 123}, - EndTime: ×tamp.Timestamp{Seconds: 456}, - }) - assert.Nil(t, actualCronSchedule) -} - -func TestToCrdCronSchedule_NilStartTime(t *testing.T) { - actualCronSchedule := toCRDCronSchedule(&api.CronSchedule{ - Cron: "123", - EndTime: ×tamp.Timestamp{Seconds: 456}, - }) - endTime := v1.NewTime(time.Unix(456, 0)) - assert.Equal(t, actualCronSchedule, &scheduledworkflow.CronSchedule{ - Cron: "123", - EndTime: &endTime, - }) -} - -func TestToCrdCronSchedule_NilEndTime(t *testing.T) { - actualCronSchedule := toCRDCronSchedule(&api.CronSchedule{ - Cron: "123", - StartTime: ×tamp.Timestamp{Seconds: 123}, - }) - startTime := v1.NewTime(time.Unix(123, 0)) - assert.Equal(t, actualCronSchedule, &scheduledworkflow.CronSchedule{ - Cron: "123", - StartTime: &startTime, - }) -} - -func TestToCrdPeriodicSchedule(t *testing.T) { - actualPeriodicSchedule := toCRDPeriodicSchedule(&api.PeriodicSchedule{ - IntervalSecond: 123, - StartTime: ×tamp.Timestamp{Seconds: 1}, - EndTime: ×tamp.Timestamp{Seconds: 2}, - }) - startTime := v1.NewTime(time.Unix(1, 0)) - endTime := v1.NewTime(time.Unix(2, 0)) - assert.Equal(t, actualPeriodicSchedule, &scheduledworkflow.PeriodicSchedule{ - IntervalSecond: 123, - StartTime: &startTime, - EndTime: &endTime, - }) -} - -func TestToCrdPeriodicSchedule_NilInterval(t *testing.T) { - actualPeriodicSchedule := toCRDPeriodicSchedule(&api.PeriodicSchedule{ - StartTime: ×tamp.Timestamp{Seconds: 1}, - EndTime: ×tamp.Timestamp{Seconds: 2}, - }) - assert.Nil(t, actualPeriodicSchedule) -} - -func TestToCrdPeriodicSchedule_NilStartTime(t *testing.T) { - actualPeriodicSchedule := toCRDPeriodicSchedule(&api.PeriodicSchedule{ - IntervalSecond: 123, - EndTime: ×tamp.Timestamp{Seconds: 2}, - }) - endTime := v1.NewTime(time.Unix(2, 0)) - assert.Equal(t, actualPeriodicSchedule, &scheduledworkflow.PeriodicSchedule{ - IntervalSecond: 123, - EndTime: &endTime, - }) -} - -func TestToCrdPeriodicSchedule_NilEndTime(t *testing.T) { - actualPeriodicSchedule := toCRDPeriodicSchedule(&api.PeriodicSchedule{ - IntervalSecond: 123, - StartTime: ×tamp.Timestamp{Seconds: 1}, - }) - startTime := v1.NewTime(time.Unix(1, 0)) - assert.Equal(t, actualPeriodicSchedule, &scheduledworkflow.PeriodicSchedule{ - IntervalSecond: 123, - StartTime: &startTime, - }) -} func TestRetryWorkflowWith(t *testing.T) { wf := ` diff --git a/backend/src/apiserver/server/api_converter.go b/backend/src/apiserver/server/api_converter.go index ee4e87ac2d8..02e51781ed5 100644 --- a/backend/src/apiserver/server/api_converter.go +++ b/backend/src/apiserver/server/api_converter.go @@ -19,6 +19,7 @@ import ( api "github.com/kubeflow/pipelines/backend/api/go_client" "github.com/kubeflow/pipelines/backend/src/apiserver/common" "github.com/kubeflow/pipelines/backend/src/apiserver/model" + "github.com/kubeflow/pipelines/backend/src/apiserver/template" "github.com/kubeflow/pipelines/backend/src/common/util" ) @@ -129,7 +130,7 @@ func toApiParameters(paramsString string) ([]*api.Parameter, error) { if paramsString == "" { return nil, nil } - params, err := util.UnmarshalParameters(paramsString) + params, err := template.UnmarshalParameters(paramsString) if err != nil { return nil, util.NewInternalServerError(err, "Parameter with wrong format is stored") } diff --git a/backend/src/apiserver/server/job_server_test.go b/backend/src/apiserver/server/job_server_test.go index c881ed3baa0..26de4dd0a62 100644 --- a/backend/src/apiserver/server/job_server_test.go +++ b/backend/src/apiserver/server/job_server_test.go @@ -160,7 +160,7 @@ func TestValidateApiJob_NoValidPipelineSpecOrPipelineVersion(t *testing.T) { err := server.validateCreateJobRequest(&api.CreateJobRequest{Job: apiJob}) assert.Equal(t, codes.InvalidArgument, err.(*util.UserError).ExternalStatusCode()) assert.NotNil(t, err) - assert.Contains(t, err.Error(), "Please specify a pipeline by providing a (workflow manifest) or (pipeline id or/and pipeline version).") + assert.Contains(t, err.Error(), "Please specify a pipeline by providing a (workflow manifest or pipeline manifest) or (pipeline id or/and pipeline version).") } func TestValidateApiJob_WorkflowManifestAndPipelineVersion(t *testing.T) { @@ -185,7 +185,7 @@ func TestValidateApiJob_WorkflowManifestAndPipelineVersion(t *testing.T) { err := server.validateCreateJobRequest(&api.CreateJobRequest{Job: apiJob}) assert.Equal(t, codes.InvalidArgument, err.(*util.UserError).ExternalStatusCode()) assert.NotNil(t, err) - assert.Contains(t, err.Error(), "Please don't specify a pipeline version or pipeline ID when you specify a workflow manifest.") + assert.Contains(t, err.Error(), "Please don't specify a pipeline version or pipeline ID when you specify a workflow manifest or pipeline manifest.") } func TestValidateApiJob_ValidatePipelineSpecFailed(t *testing.T) { diff --git a/backend/src/apiserver/server/run_server_test.go b/backend/src/apiserver/server/run_server_test.go index 53b79394e5b..5079180c00e 100644 --- a/backend/src/apiserver/server/run_server_test.go +++ b/backend/src/apiserver/server/run_server_test.go @@ -531,7 +531,7 @@ func TestValidateCreateRunRequest_NilPipelineSpecAndEmptyPipelineVersion(t *test } err := server.validateCreateRunRequest(&api.CreateRunRequest{Run: run}) assert.NotNil(t, err) - assert.Contains(t, err.Error(), "Please specify a pipeline by providing a (workflow manifest) or (pipeline id or/and pipeline version).") + assert.Contains(t, err.Error(), "Please specify a pipeline by providing a (workflow manifest or pipeline manifest) or (pipeline id or/and pipeline version).") } func TestValidateCreateRunRequest_WorkflowManifestAndPipelineVersion(t *testing.T) { @@ -548,7 +548,7 @@ func TestValidateCreateRunRequest_WorkflowManifestAndPipelineVersion(t *testing. } err := server.validateCreateRunRequest(&api.CreateRunRequest{Run: run}) assert.NotNil(t, err) - assert.Contains(t, err.Error(), "Please don't specify a pipeline version or pipeline ID when you specify a workflow manifest.") + assert.Contains(t, err.Error(), "Please don't specify a pipeline version or pipeline ID when you specify a workflow manifest or pipeline manifest.") } func TestValidateCreateRunRequest_InvalidPipelineSpec(t *testing.T) { @@ -566,7 +566,7 @@ func TestValidateCreateRunRequest_InvalidPipelineSpec(t *testing.T) { } err := server.validateCreateRunRequest(&api.CreateRunRequest{Run: run}) assert.NotNil(t, err) - assert.Contains(t, err.Error(), "Please don't specify a pipeline version or pipeline ID when you specify a workflow manifest.") + assert.Contains(t, err.Error(), "Please don't specify a pipeline version or pipeline ID when you specify a workflow manifest or pipeline manifest.") } func TestValidateCreateRunRequest_TooMuchParameters(t *testing.T) { diff --git a/backend/src/apiserver/server/util.go b/backend/src/apiserver/server/util.go index ba4232a6ace..52a72984073 100644 --- a/backend/src/apiserver/server/util.go +++ b/backend/src/apiserver/server/util.go @@ -8,6 +8,8 @@ import ( "compress/gzip" "context" "encoding/json" + "github.com/golang/protobuf/jsonpb" + "github.com/kubeflow/pipelines/api/v2alpha1/go/pipelinespec" "io" "io/ioutil" "net/url" @@ -219,18 +221,25 @@ func ValidateExperimentResourceReference(resourceManager *resource.ResourceManag func ValidatePipelineSpecAndResourceReferences(resourceManager *resource.ResourceManager, spec *api.PipelineSpec, resourceReferences []*api.ResourceReference) error { pipelineId := spec.GetPipelineId() workflowManifest := spec.GetWorkflowManifest() + pipelineManifest := spec.GetPipelineManifest() pipelineVersionId := getPipelineVersionIdFromResourceReferences(resourceManager, resourceReferences) - if workflowManifest != "" { + if workflowManifest != "" || pipelineManifest != ""{ + if workflowManifest != "" && pipelineManifest != "" { + return util.NewInvalidInputError("Please don't specify both workflow manifest and pipeline manifest.") + } if pipelineId != "" || pipelineVersionId != "" { - return util.NewInvalidInputError("Please don't specify a pipeline version or pipeline ID when you specify a workflow manifest.") + return util.NewInvalidInputError("Please don't specify a pipeline version or pipeline ID when you specify a workflow manifest or pipeline manifest.") + } + if err := validateWorkflowManifest(workflowManifest); err != nil { + return err } - if err := validateWorkflowManifest(spec.GetWorkflowManifest()); err != nil { + if err := validatePipelineManifest(pipelineManifest); err != nil { return err } } else { if pipelineId == "" && pipelineVersionId == "" { - return util.NewInvalidInputError("Please specify a pipeline by providing a (workflow manifest) or (pipeline id or/and pipeline version).") + return util.NewInvalidInputError("Please specify a pipeline by providing a (workflow manifest or pipeline manifest) or (pipeline id or/and pipeline version).") } if err := validatePipelineId(resourceManager, pipelineId); err != nil { return err @@ -247,7 +256,16 @@ func ValidatePipelineSpecAndResourceReferences(resourceManager *resource.Resourc } } } - return validateParameters(spec.GetParameters()) + if spec.GetParameters() != nil && spec.GetRuntimeConfig() != nil { + return util.NewInvalidInputError("Please don't specify both parameters and runtime config.") + } + if err := validateParameters(spec.GetParameters()); err != nil { + return err + } + if err := validateRuntimeConfig(spec.GetRuntimeConfig()); err != nil { + return err + } + return nil } func validateParameters(parameters []*api.Parameter) error { if parameters != nil { @@ -264,6 +282,21 @@ func validateParameters(parameters []*api.Parameter) error { return nil } +func validateRuntimeConfig(runtimeConfig *api.PipelineSpec_RuntimeConfig) error { + if runtimeConfig.GetParameters() != nil { + paramsBytes, err := json.Marshal(runtimeConfig.GetParameters()) + if err != nil { + return util.NewInternalServerError(err, + "Failed to Marshall the runtime config parameters into bytes.") + } + if len(paramsBytes) > util.MaxParameterBytes { + return util.NewInvalidInputError("The input parameter length exceed maximum size of %v.", util.MaxParameterBytes) + } + } + return nil +} + + func validatePipelineId(resourceManager *resource.ResourceManager, pipelineId string) error { if pipelineId != "" { // Verify pipeline exist @@ -286,6 +319,18 @@ func validateWorkflowManifest(workflowManifest string) error { return nil } +func validatePipelineManifest(pipelineManifest string) error { + if pipelineManifest != "" { + // Verify valid IR spec + spec := &pipelinespec.PipelineSpec{} + if err := jsonpb.UnmarshalString(pipelineManifest, spec); err != nil { + return util.NewInvalidInputErrorWithDetails(err, + "Invalid IR spec format.") + } + } + return nil +} + func getPipelineVersionIdFromResourceReferences(resourceManager *resource.ResourceManager, resourceReferences []*api.ResourceReference) string { var pipelineVersionId = "" for _, resourceReference := range resourceReferences { diff --git a/backend/src/apiserver/server/util_test.go b/backend/src/apiserver/server/util_test.go index 0249eaccf78..5ba0961768c 100644 --- a/backend/src/apiserver/server/util_test.go +++ b/backend/src/apiserver/server/util_test.go @@ -284,7 +284,7 @@ func TestValidatePipelineSpecAndResourceReferences_WorkflowManifestAndPipelineVe WorkflowManifest: testWorkflow.ToStringForStore()} err := ValidatePipelineSpecAndResourceReferences(manager, spec, validReferencesOfExperimentAndPipelineVersion) assert.NotNil(t, err) - assert.Contains(t, err.Error(), "Please don't specify a pipeline version or pipeline ID when you specify a workflow manifest.") + assert.Contains(t, err.Error(), "Please don't specify a pipeline version or pipeline ID when you specify a workflow manifest or pipeline manifest.") } func TestValidatePipelineSpecAndResourceReferences_WorkflowManifestAndPipelineID(t *testing.T) { @@ -295,7 +295,7 @@ func TestValidatePipelineSpecAndResourceReferences_WorkflowManifestAndPipelineID WorkflowManifest: testWorkflow.ToStringForStore()} err := ValidatePipelineSpecAndResourceReferences(manager, spec, validReference) assert.NotNil(t, err) - assert.Contains(t, err.Error(), "Please don't specify a pipeline version or pipeline ID when you specify a workflow manifest.") + assert.Contains(t, err.Error(), "Please don't specify a pipeline version or pipeline ID when you specify a workflow manifest or pipeline manifest.") } func TestValidatePipelineSpecAndResourceReferences_InvalidWorkflowManifest(t *testing.T) { @@ -312,7 +312,7 @@ func TestValidatePipelineSpecAndResourceReferences_NilPipelineSpecAndEmptyPipeli defer clients.Close() err := ValidatePipelineSpecAndResourceReferences(manager, nil, validReference) assert.NotNil(t, err) - assert.Contains(t, err.Error(), "Please specify a pipeline by providing a (workflow manifest) or (pipeline id or/and pipeline version).") + assert.Contains(t, err.Error(), "Please specify a pipeline by providing a (workflow manifest or pipeline manifest) or (pipeline id or/and pipeline version).") } func TestValidatePipelineSpecAndResourceReferences_EmptyPipelineSpecAndEmptyPipelineVersion(t *testing.T) { @@ -321,7 +321,7 @@ func TestValidatePipelineSpecAndResourceReferences_EmptyPipelineSpecAndEmptyPipe spec := &api.PipelineSpec{} err := ValidatePipelineSpecAndResourceReferences(manager, spec, validReference) assert.NotNil(t, err) - assert.Contains(t, err.Error(), "Please specify a pipeline by providing a (workflow manifest) or (pipeline id or/and pipeline version).") + assert.Contains(t, err.Error(), "Please specify a pipeline by providing a (workflow manifest or pipeline manifest) or (pipeline id or/and pipeline version).") } func TestValidatePipelineSpecAndResourceReferences_InvalidPipelineId(t *testing.T) { diff --git a/backend/src/apiserver/storage/run_store.go b/backend/src/apiserver/storage/run_store.go index c65cc753c25..b2abb39bc3a 100644 --- a/backend/src/apiserver/storage/run_store.go +++ b/backend/src/apiserver/storage/run_store.go @@ -207,7 +207,7 @@ func (s *RunStore) GetRun(runId string) (*model.RunDetail, error) { if len(runs) == 0 { return nil, util.NewResourceNotFoundError("Run", fmt.Sprint(runId)) } - if runs[0].WorkflowRuntimeManifest == "" { + if runs[0].WorkflowRuntimeManifest == "" && runs[0].WorkflowSpecManifest != ""{ // This can only happen when workflow reporting is failed. return nil, util.NewResourceNotFoundError("Failed to get run: %s", runId) } @@ -316,7 +316,7 @@ func (s *RunStore) scanRowsToRunDetails(rows *sql.Rows) ([]*model.RunDetail, err PipelineSpec: model.PipelineSpec{ PipelineId: pipelineId, PipelineName: pipelineName, - PipelineSpecManifest: pipelineRuntimeManifest, + PipelineSpecManifest: pipelineSpecManifest, WorkflowSpecManifest: workflowSpecManifest, Parameters: parameters, }, diff --git a/backend/src/apiserver/template/argo_template.go b/backend/src/apiserver/template/argo_template.go new file mode 100644 index 00000000000..90c1954faaf --- /dev/null +++ b/backend/src/apiserver/template/argo_template.go @@ -0,0 +1,203 @@ +package template + +import ( + "fmt" + workflowapi "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" + "github.com/argoproj/argo-workflows/v3/workflow/validate" + "github.com/ghodss/yaml" + + api "github.com/kubeflow/pipelines/backend/api/go_client" + "github.com/kubeflow/pipelines/backend/src/apiserver/common" + "github.com/kubeflow/pipelines/backend/src/common/util" + scheduledworkflow "github.com/kubeflow/pipelines/backend/src/crd/pkg/apis/scheduledworkflow/v1beta1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func (t *Argo) RunWorkflow(apiRun *api.Run, options RunWorkflowOptions) (*util.Workflow, error) { + workflow := util.NewWorkflow(t.wf.Workflow.DeepCopy()) + + // Add a KFP specific label for cache service filtering. The cache_enabled flag here is a global control for whether cache server will + // receive targeting pods. Since cache server only receives pods in step level, the resource manager here will set this global label flag + // on every single step/pod so the cache server can understand. + // TODO: Add run_level flag with similar logic by reading flag value from create_run api. + workflow.SetLabelsToAllTemplates(util.LabelKeyCacheEnabled, common.IsCacheEnabled()) + parameters := toParametersMap(apiRun.GetPipelineSpec().GetParameters()) + // Verify no additional parameter provided + if err := workflow.VerifyParameters(parameters); err != nil { + return nil, util.Wrap(err, "Failed to verify parameters.") + } + // Append provided parameter + workflow.OverrideParameters(parameters) + + // Replace macros + formatter := util.NewRunParameterFormatter(options.RunId, options.RunAt) + formattedParams := formatter.FormatWorkflowParameters(workflow.GetWorkflowParametersAsMap()) + workflow.OverrideParameters(formattedParams) + + setDefaultServiceAccount(workflow, apiRun.GetServiceAccount()) + + // Disable istio sidecar injection if not specified + workflow.SetAnnotationsToAllTemplatesIfKeyNotExist(util.AnnotationKeyIstioSidecarInject, util.AnnotationValueIstioSidecarInjectDisabled) + + err := OverrideParameterWithSystemDefault(workflow) + if err != nil { + return nil, err + } + + // Add label to the workflow so it can be persisted by persistent agent later. + workflow.SetLabels(util.LabelKeyWorkflowRunId, options.RunId) + // Add run name annotation to the workflow so that it can be logged by the Metadata Writer. + workflow.SetAnnotations(util.AnnotationKeyRunName, apiRun.Name) + // Replace {{workflow.uid}} with runId + err = workflow.ReplaceUID(options.RunId) + if err != nil { + return nil, util.NewInternalServerError(err, "Failed to replace workflow ID") + } + workflow.SetPodMetadataLabels(util.LabelKeyWorkflowRunId, options.RunId) + + // Marking auto-added artifacts as optional. Otherwise most older workflows will start failing after upgrade to Argo 2.3. + // TODO: Fix the components to explicitly declare the artifacts they really output. + for templateIdx, template := range workflow.Workflow.Spec.Templates { + for artIdx, artifact := range template.Outputs.Artifacts { + if artifact.Name == "mlpipeline-ui-metadata" || artifact.Name == "mlpipeline-metrics" { + workflow.Workflow.Spec.Templates[templateIdx].Outputs.Artifacts[artIdx].Optional = true + } + } + } + return workflow, nil + +} + +type Argo struct { + wf *util.Workflow +} + +func (t *Argo) ScheduledWorkflow(apiJob *api.Job) (*scheduledworkflow.ScheduledWorkflow, error) { + workflow := util.NewWorkflow(t.wf.Workflow.DeepCopy()) + + parameters := toParametersMap(apiJob.GetPipelineSpec().GetParameters()) + // Verify no additional parameter provided + if err := workflow.VerifyParameters(parameters); err != nil { + return nil, util.Wrap(err, "Failed to verify parameters.") + } + // Append provided parameter + workflow.OverrideParameters(parameters) + setDefaultServiceAccount(workflow, apiJob.GetServiceAccount()) + // Disable istio sidecar injection if not specified + workflow.SetAnnotationsToAllTemplatesIfKeyNotExist(util.AnnotationKeyIstioSidecarInject, util.AnnotationValueIstioSidecarInjectDisabled) + swfGeneratedName, err := toSWFCRDResourceGeneratedName(apiJob.Name) + if err != nil { + return nil, util.Wrap(err, "Create job failed") + } + scheduledWorkflow := &scheduledworkflow.ScheduledWorkflow{ + ObjectMeta: metav1.ObjectMeta{GenerateName: swfGeneratedName}, + Spec: scheduledworkflow.ScheduledWorkflowSpec{ + Enabled: apiJob.Enabled, + MaxConcurrency: &apiJob.MaxConcurrency, + Trigger: *toCRDTrigger(apiJob.Trigger), + Workflow: &scheduledworkflow.WorkflowResource{ + Parameters: toCRDParameter(apiJob.GetPipelineSpec().GetParameters()), + Spec: workflow.Spec, + }, + NoCatchup: util.BoolPointer(apiJob.NoCatchup), + }, + } + + // Marking auto-added artifacts as optional. Otherwise most older workflows will start failing after upgrade to Argo 2.3. + // TODO: Fix the components to explicitly declare the artifacts they really output. + for templateIdx, template := range scheduledWorkflow.Spec.Workflow.Spec.Templates { + for artIdx, artifact := range template.Outputs.Artifacts { + if artifact.Name == "mlpipeline-ui-metadata" || artifact.Name == "mlpipeline-metrics" { + scheduledWorkflow.Spec.Workflow.Spec.Templates[templateIdx].Outputs.Artifacts[artIdx].Optional = true + } + } + } + return scheduledWorkflow, nil +} + +func (t *Argo) GetTemplateType() TemplateType { + return V1 +} + +func NewArgoTemplate(bytes []byte) (*Argo, error) { + wf, err := ValidateWorkflow(bytes) + if err != nil { + return nil, err + } + return &Argo{wf}, nil +} + +func (t *Argo) Bytes() []byte { + if t == nil { + return nil + } + return []byte(t.wf.ToStringForStore()) +} + +func (t *Argo) IsV2() bool { + if t == nil { + return false + } + return t.wf.IsV2Compatible() +} + +const ( + paramV2compatPipelineName = "pipeline-name" +) + +func (t *Argo) V2PipelineName() string { + if t == nil { + return "" + } + return t.wf.GetWorkflowParametersAsMap()[paramV2compatPipelineName] +} + +func (t *Argo) OverrideV2PipelineName(name, namespace string) { + if t == nil || !t.wf.IsV2Compatible() { + return + } + var pipelineRef string + if namespace != "" { + pipelineRef = fmt.Sprintf("namespace/%s/pipeline/%s", namespace, name) + } else { + pipelineRef = fmt.Sprintf("pipeline/%s", name) + } + overrides := make(map[string]string) + overrides[paramV2compatPipelineName] = pipelineRef + t.wf.OverrideParameters(overrides) +} + +func (t *Argo) ParametersJSON() (string, error) { + if t == nil { + return "", nil + } + return MarshalParameters(t.wf.Spec.Arguments.Parameters) +} + +func NewArgoTemplateFromWorkflow(wf *workflowapi.Workflow) (*Argo, error) { + return &Argo{wf: &util.Workflow{Workflow: wf}}, nil +} + +func ValidateWorkflow(template []byte) (*util.Workflow, error) { + var wf workflowapi.Workflow + err := yaml.Unmarshal(template, &wf) + if err != nil { + return nil, util.NewInvalidInputErrorWithDetails(err, "Failed to parse the workflow template.") + } + if wf.APIVersion != argoVersion { + return nil, util.NewInvalidInputError("Unsupported argo version. Expected: %v. Received: %v", argoVersion, wf.APIVersion) + } + if wf.Kind != argoK8sResource { + return nil, util.NewInvalidInputError("Unexpected resource type. Expected: %v. Received: %v", argoK8sResource, wf.Kind) + } + _, err = validate.ValidateWorkflow(nil, nil, &wf, validate.ValidateOpts{ + Lint: true, + IgnoreEntrypoint: true, + WorkflowTemplateValidation: false, // not used by kubeflow + }) + if err != nil { + return nil, err + } + return util.NewWorkflow(&wf), nil +} + diff --git a/backend/src/apiserver/template/template.go b/backend/src/apiserver/template/template.go new file mode 100644 index 00000000000..23b6cb0fc1d --- /dev/null +++ b/backend/src/apiserver/template/template.go @@ -0,0 +1,308 @@ +// Copyright 2018 The Kubeflow Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package template + +import ( + "encoding/json" + "fmt" + "github.com/kubeflow/pipelines/api/v2alpha1/go/pipelinespec" + api "github.com/kubeflow/pipelines/backend/api/go_client" + "regexp" + "strings" + "time" + + "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" + wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" + "github.com/ghodss/yaml" + + "github.com/kubeflow/pipelines/backend/src/apiserver/common" + "github.com/kubeflow/pipelines/backend/src/common/util" + scheduledworkflow "github.com/kubeflow/pipelines/backend/src/crd/pkg/apis/scheduledworkflow/v1beta1" + "google.golang.org/protobuf/encoding/protojson" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type TemplateType string + +const ( + V1 TemplateType = "v1Argo" + V2 TemplateType = "v2" + Unknown TemplateType = "Unknown" + + argoGroup = "argoproj.io/" + argoVersion = "argoproj.io/v1alpha1" + argoK8sResource = "Workflow" + +) + +// Unmarshal parameters from JSON encoded string. +func UnmarshalParameters(paramsString string) ([]v1alpha1.Parameter, error) { + if paramsString == "" { + return nil, nil + } + var params []v1alpha1.Parameter + err := json.Unmarshal([]byte(paramsString), ¶ms) + if err != nil { + return nil, util.NewInternalServerError(err, "Parameters have wrong format") + } + return params, nil +} + +// Marshal parameters to JSON encoded string. +// This also checks result is not longer than a limit. +func MarshalParameters(params []v1alpha1.Parameter) (string, error) { + if params == nil { + return "[]", nil + } + paramBytes, err := json.Marshal(params) + if err != nil { + return "", util.NewInvalidInputErrorWithDetails(err, "Failed to marshal the parameter.") + } + if len(paramBytes) > util.MaxParameterBytes { + return "", util.NewInvalidInputError("The input parameter length exceed maximum size of %v.", util.MaxParameterBytes) + } + return string(paramBytes), nil +} + +var ErrorInvalidPipelineSpec = fmt.Errorf("pipeline spec is invalid") + +// inferTemplateFormat infers format from pipeline template. +// There is no guarantee that the template is valid in inferred format, so validation +// is still needed. +func inferTemplateFormat(template []byte) TemplateType { + switch { + case len(template) == 0: + return Unknown + case isArgoWorkflow(template): + return V1 + case isPipelineSpec(template): + return V2 + default: + return Unknown + } +} + +// isArgoWorkflow returns whether template is in argo workflow spec format. +func isArgoWorkflow(template []byte) bool { + var meta metav1.TypeMeta + err := yaml.Unmarshal(template, &meta) + if err != nil { + return false + } + return strings.HasPrefix(meta.APIVersion, argoGroup) && meta.Kind == argoK8sResource +} + +// isPipelineSpec returns whether template is in KFP api/v2alpha1/PipelineSpec format. +func isPipelineSpec(template []byte) bool { + var spec pipelinespec.PipelineSpec + err := protojson.Unmarshal(template, &spec) + return err == nil && spec.GetPipelineInfo().GetName() != "" && spec.GetRoot() != nil +} + +// Pipeline template +type Template interface { + IsV2() bool + // Gets v2 pipeline name. + V2PipelineName() string + // Overrides v2 pipeline name to distinguish shared/namespaced pipelines. + // The name is used as ML Metadata pipeline context name. + OverrideV2PipelineName(name, namespace string) + // Gets parameters in JSON format. + ParametersJSON() (string, error) + // Get bytes content. + Bytes() []byte + GetTemplateType() TemplateType + + //Get workflow + RunWorkflow(apiRun *api.Run, options RunWorkflowOptions) (*util.Workflow, error) + + ScheduledWorkflow(apiJob *api.Job) (*scheduledworkflow.ScheduledWorkflow, error) +} + +type RunWorkflowOptions struct { + RunId string + RunAt int64 +} + +func New(bytes []byte) (Template, error) { + format := inferTemplateFormat(bytes) + switch format { + case V1: + return NewArgoTemplate(bytes) + case V2: + return NewV2SpecTemplate(bytes) + default: + return nil, util.NewInvalidInputErrorWithDetails(ErrorInvalidPipelineSpec, "unknown template format") + } +} + + + + + +func toParametersMap(apiParams []*api.Parameter) map[string]string { + // Preprocess workflow by appending parameter and add pipeline specific labels + desiredParamsMap := make(map[string]string) + for _, param := range apiParams { + desiredParamsMap[param.Name] = param.Value + } + return desiredParamsMap +} + +// Patch the system-specified default parameters if available. +func OverrideParameterWithSystemDefault(workflow *util.Workflow) error { + // Patch the default value to workflow spec. + if common.GetBoolConfigWithDefault(common.HasDefaultBucketEnvVar, false) { + patchedSlice := make([]wfv1.Parameter, 0) + for _, currentParam := range workflow.Spec.Arguments.Parameters { + if currentParam.Value != nil { + desiredValue, err := common.PatchPipelineDefaultParameter(currentParam.Value.String()) + if err != nil { + return fmt.Errorf("failed to patch default value to pipeline. Error: %v", err) + } + patchedSlice = append(patchedSlice, wfv1.Parameter{ + Name: currentParam.Name, + Value: wfv1.AnyStringPtr(desiredValue), + }) + } else if currentParam.Default != nil { + desiredValue, err := common.PatchPipelineDefaultParameter(currentParam.Default.String()) + if err != nil { + return fmt.Errorf("failed to patch default value to pipeline. Error: %v", err) + } + patchedSlice = append(patchedSlice, wfv1.Parameter{ + Name: currentParam.Name, + Value: wfv1.AnyStringPtr(desiredValue), + }) + } + } + workflow.Spec.Arguments.Parameters = patchedSlice + } + return nil +} + +func setDefaultServiceAccount(workflow *util.Workflow, serviceAccount string) { + if len(serviceAccount) > 0 { + workflow.SetServiceAccount(serviceAccount) + return + } + workflowServiceAccount := workflow.Spec.ServiceAccountName + if len(workflowServiceAccount) == 0 || workflowServiceAccount == common.DefaultPipelineRunnerServiceAccount { + // To reserve SDK backward compatibility, the backend only replaces + // serviceaccount when it is empty or equal to default value set by SDK. + workflow.SetServiceAccount(common.GetStringConfigWithDefault(common.DefaultPipelineRunnerServiceAccount, common.DefaultPipelineRunnerServiceAccount)) + } +} + +// Process the job name to remove special char, prepend with "job-" prefix if empty, and +// truncate size to <=25 +func toSWFCRDResourceGeneratedName(displayName string) (string, error) { + const ( + // K8s resource name only allow lower case alphabetic char, number and - + swfCompatibleNameRegx = "[^a-z0-9-]+" + ) + reg, err := regexp.Compile(swfCompatibleNameRegx) + if err != nil { + return "", util.NewInternalServerError(err, "Failed to compile ScheduledWorkflow name replacer Regex.") + } + processedName := reg.ReplaceAllString(strings.ToLower(displayName), "") + if processedName == "" { + processedName = "job-" + } + return util.Truncate(processedName, 25), nil +} + +func toCRDTrigger(apiTrigger *api.Trigger) *scheduledworkflow.Trigger { + var crdTrigger scheduledworkflow.Trigger + if apiTrigger.GetCronSchedule() != nil { + crdTrigger.CronSchedule = toCRDCronSchedule(apiTrigger.GetCronSchedule()) + } + if apiTrigger.GetPeriodicSchedule() != nil { + crdTrigger.PeriodicSchedule = toCRDPeriodicSchedule(apiTrigger.GetPeriodicSchedule()) + } + return &crdTrigger +} + +func toCRDCronSchedule(cronSchedule *api.CronSchedule) *scheduledworkflow.CronSchedule { + if cronSchedule == nil || cronSchedule.Cron == "" { + return nil + } + crdCronSchedule := scheduledworkflow.CronSchedule{} + crdCronSchedule.Cron = cronSchedule.Cron + + if cronSchedule.StartTime != nil { + startTime := metav1.NewTime(time.Unix(cronSchedule.StartTime.Seconds, 0)) + crdCronSchedule.StartTime = &startTime + } + if cronSchedule.EndTime != nil { + endTime := metav1.NewTime(time.Unix(cronSchedule.EndTime.Seconds, 0)) + crdCronSchedule.EndTime = &endTime + } + return &crdCronSchedule +} + +func toCRDPeriodicSchedule(periodicSchedule *api.PeriodicSchedule) *scheduledworkflow.PeriodicSchedule { + if periodicSchedule == nil || periodicSchedule.IntervalSecond == 0 { + return nil + } + crdPeriodicSchedule := scheduledworkflow.PeriodicSchedule{} + crdPeriodicSchedule.IntervalSecond = periodicSchedule.IntervalSecond + if periodicSchedule.StartTime != nil { + startTime := metav1.NewTime(time.Unix(periodicSchedule.StartTime.Seconds, 0)) + crdPeriodicSchedule.StartTime = &startTime + } + if periodicSchedule.EndTime != nil { + endTime := metav1.NewTime(time.Unix(periodicSchedule.EndTime.Seconds, 0)) + crdPeriodicSchedule.EndTime = &endTime + } + return &crdPeriodicSchedule +} + +func toCRDParameter(apiParams []*api.Parameter) []scheduledworkflow.Parameter { + var swParams []scheduledworkflow.Parameter + for _, apiParam := range apiParams { + swParam := scheduledworkflow.Parameter{ + Name: apiParam.Name, + Value: apiParam.Value, + } + swParams = append(swParams, swParam) + } + return swParams +} + +func toPipelineJobRuntimeConfig(apiRuntimeConfig *api.PipelineSpec_RuntimeConfig) (*pipelinespec.PipelineJob_RuntimeConfig, error) { + if apiRuntimeConfig == nil { + return nil, nil + } + runTimeConfig := &pipelinespec.PipelineJob_RuntimeConfig{} + runTimeConfig.Parameters = make(map[string]*pipelinespec.Value) + for k, v := range apiRuntimeConfig.GetParameters() { + value := &pipelinespec.Value{} + switch t := v.Value.(type) { + case *api.Value_StringValue: + value.Value = &pipelinespec.Value_StringValue{StringValue: v.GetStringValue()} + case *api.Value_DoubleValue: + value.Value = &pipelinespec.Value_DoubleValue{DoubleValue: v.GetDoubleValue()} + case *api.Value_IntValue: + value.Value = &pipelinespec.Value_IntValue{IntValue: v.GetIntValue()} + default: + return nil, fmt.Errorf("unknown property type in pipelineSpec runtimeConfig Parameters: %T", t) + } + runTimeConfig.Parameters[k] = value + } + if apiRuntimeConfig.GetPipelineRoot() != "" { + runTimeConfig.GcsOutputDirectory = apiRuntimeConfig.GetPipelineRoot() + } + return runTimeConfig, nil +} diff --git a/backend/src/apiserver/template/template_test.go b/backend/src/apiserver/template/template_test.go new file mode 100644 index 00000000000..582f573febc --- /dev/null +++ b/backend/src/apiserver/template/template_test.go @@ -0,0 +1,336 @@ +// Copyright 2018 The Kubeflow Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package template + +import ( + "github.com/golang/protobuf/ptypes/timestamp" + api "github.com/kubeflow/pipelines/backend/api/go_client" + scheduledworkflow "github.com/kubeflow/pipelines/backend/src/crd/pkg/apis/scheduledworkflow/v1beta1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "testing" + "time" + + "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" + "github.com/ghodss/yaml" + commonutil "github.com/kubeflow/pipelines/backend/src/common/util" + "github.com/stretchr/testify/assert" + "google.golang.org/grpc/codes" +) + +func TestFailValidation(t *testing.T) { + wf := unmarshalWf(emptyName) + wf.Spec.Arguments.Parameters = []v1alpha1.Parameter{{Name: "dup", Value: v1alpha1.AnyStringPtr("value1")}} + templateBytes, _ := yaml.Marshal(wf) + _, err := ValidateWorkflow([]byte(templateBytes)) + if assert.NotNil(t, err) { + assert.Contains(t, err.Error(), "name is required") + } +} + +func TestValidateWorkflow_ParametersTooLong(t *testing.T) { + var params []v1alpha1.Parameter + // Create a long enough parameter string so it exceed the length limit of parameter. + for i := 0; i < 10000; i++ { + params = append(params, v1alpha1.Parameter{Name: "name1", Value: v1alpha1.AnyStringPtr("value1")}) + } + template := v1alpha1.Workflow{Spec: v1alpha1.WorkflowSpec{Arguments: v1alpha1.Arguments{ + Parameters: params}}} + templateBytes, _ := yaml.Marshal(template) + _, err := ValidateWorkflow(templateBytes) + assert.Equal(t, codes.InvalidArgument, err.(*commonutil.UserError).ExternalStatusCode()) +} + +func TestParseSpecFormat(t *testing.T) { + tt := []struct { + template string + templateType TemplateType + }{{ + // standard match + template: ` +apiVersion: argoproj.io/v1alpha1 +kind: Workflow`, + templateType: V1, + }, { // template contains content too + template: template, + templateType: V1, + }, { + // version does not matter + template: ` +apiVersion: argoproj.io/v1alpha2 +kind: Workflow`, + templateType: V1, + }, { + template: v2SpecHelloWorld, + templateType: V2, + }, { + template: "", + templateType: Unknown, + }, { + template: "{}", + templateType: Unknown, + }, { + // group incorrect + template: ` +apiVersion: pipelines.kubeflow.org/v1alpha1 +kind: Workflow`, + templateType: Unknown, + }, { + // kind incorrect + template: ` +apiVersion: argoproj.io/v1alpha1 +kind: CronWorkflow`, + templateType: Unknown, + }, { + template: `{"abc": "def", "b": {"key": 3}}`, + templateType: Unknown, + }} + for _, test := range tt { + format := inferTemplateFormat([]byte(test.template)) + if format != test.templateType { + t.Errorf("InferSpecFormat(%s)=%q, expect %q", test.template, format, test.templateType) + } + } +} + +func unmarshalWf(yamlStr string) *v1alpha1.Workflow { + var wf v1alpha1.Workflow + err := yaml.Unmarshal([]byte(yamlStr), &wf) + if err != nil { + panic(err) + } + return &wf +} + +var template = ` +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: hello-world- +spec: + entrypoint: whalesay + templates: + - name: whalesay + inputs: + parameters: + - name: dup + value: "value1" + container: + image: docker/whalesay:latest` + +var emptyName = ` +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: hello-world- +spec: + entrypoint: whalesay + templates: + - name: whalesay + inputs: + parameters: + - name: "" + value: "value1" + container: + image: docker/whalesay:latest` + +var v2SpecHelloWorld = ` +{ + "components": { + "comp-hello-world": { + "executorLabel": "exec-hello-world", + "inputDefinitions": { + "parameters": { + "text": { + "type": "STRING" + } + } + } + } + }, + "deploymentSpec": { + "executors": { + "exec-hello-world": { + "container": { + "args": [ + "--text", + "{{$.inputs.parameters['text']}}" + ], + "command": [ + "sh", + "-ec", + "program_path=$(mktemp)\nprintf \"%s\" \"$0\" > \"$program_path\"\npython3 -u \"$program_path\" \"$@\"\n", + "def hello_world(text):\n print(text)\n return text\n\nimport argparse\n_parser = argparse.ArgumentParser(prog='Hello world', description='')\n_parser.add_argument(\"--text\", dest=\"text\", type=str, required=True, default=argparse.SUPPRESS)\n_parsed_args = vars(_parser.parse_args())\n\n_outputs = hello_world(**_parsed_args)\n" + ], + "image": "python:3.7" + } + } + } + }, + "pipelineInfo": { + "name": "hello-world" + }, + "root": { + "dag": { + "tasks": { + "hello-world": { + "cachingOptions": { + "enableCache": true + }, + "componentRef": { + "name": "comp-hello-world" + }, + "inputs": { + "parameters": { + "text": { + "componentInputParameter": "text" + } + } + }, + "taskInfo": { + "name": "hello-world" + } + } + } + }, + "inputDefinitions": { + "parameters": { + "text": { + "type": "STRING" + } + } + } + }, + "schemaVersion": "2.0.0", + "sdkVersion": "kfp-1.6.5" +} +` + +func TestToSwfCRDResourceGeneratedName_SpecialCharsAndSpace(t *testing.T) { + name, err := toSWFCRDResourceGeneratedName("! HaVe ä £unky name") + assert.Nil(t, err) + assert.Equal(t, name, "haveunkyname") +} + +func TestToSwfCRDResourceGeneratedName_TruncateLongName(t *testing.T) { + name, err := toSWFCRDResourceGeneratedName("AloooooooooooooooooongName") + assert.Nil(t, err) + assert.Equal(t, name, "aloooooooooooooooooongnam") +} + +func TestToSwfCRDResourceGeneratedName_EmptyName(t *testing.T) { + name, err := toSWFCRDResourceGeneratedName("") + assert.Nil(t, err) + assert.Equal(t, name, "job-") +} + +func TestToCrdParameter(t *testing.T) { + assert.Equal(t, + toCRDParameter([]*api.Parameter{{Name: "param2", Value: "world"}, {Name: "param1", Value: "hello"}}), + []scheduledworkflow.Parameter{{Name: "param2", Value: "world"}, {Name: "param1", Value: "hello"}}) +} + +func TestToCrdCronSchedule(t *testing.T) { + actualCronSchedule := toCRDCronSchedule(&api.CronSchedule{ + Cron: "123", + StartTime: ×tamp.Timestamp{Seconds: 123}, + EndTime: ×tamp.Timestamp{Seconds: 456}, + }) + startTime := metav1.NewTime(time.Unix(123, 0)) + endTime := metav1.NewTime(time.Unix(456, 0)) + assert.Equal(t, actualCronSchedule, &scheduledworkflow.CronSchedule{ + Cron: "123", + StartTime: &startTime, + EndTime: &endTime, + }) +} + +func TestToCrdCronSchedule_NilCron(t *testing.T) { + actualCronSchedule := toCRDCronSchedule(&api.CronSchedule{ + StartTime: ×tamp.Timestamp{Seconds: 123}, + EndTime: ×tamp.Timestamp{Seconds: 456}, + }) + assert.Nil(t, actualCronSchedule) +} + +func TestToCrdCronSchedule_NilStartTime(t *testing.T) { + actualCronSchedule := toCRDCronSchedule(&api.CronSchedule{ + Cron: "123", + EndTime: ×tamp.Timestamp{Seconds: 456}, + }) + endTime := metav1.NewTime(time.Unix(456, 0)) + assert.Equal(t, actualCronSchedule, &scheduledworkflow.CronSchedule{ + Cron: "123", + EndTime: &endTime, + }) +} + +func TestToCrdCronSchedule_NilEndTime(t *testing.T) { + actualCronSchedule := toCRDCronSchedule(&api.CronSchedule{ + Cron: "123", + StartTime: ×tamp.Timestamp{Seconds: 123}, + }) + startTime := metav1.NewTime(time.Unix(123, 0)) + assert.Equal(t, actualCronSchedule, &scheduledworkflow.CronSchedule{ + Cron: "123", + StartTime: &startTime, + }) +} + +func TestToCrdPeriodicSchedule(t *testing.T) { + actualPeriodicSchedule := toCRDPeriodicSchedule(&api.PeriodicSchedule{ + IntervalSecond: 123, + StartTime: ×tamp.Timestamp{Seconds: 1}, + EndTime: ×tamp.Timestamp{Seconds: 2}, + }) + startTime := metav1.NewTime(time.Unix(1, 0)) + endTime := metav1.NewTime(time.Unix(2, 0)) + assert.Equal(t, actualPeriodicSchedule, &scheduledworkflow.PeriodicSchedule{ + IntervalSecond: 123, + StartTime: &startTime, + EndTime: &endTime, + }) +} + +func TestToCrdPeriodicSchedule_NilInterval(t *testing.T) { + actualPeriodicSchedule := toCRDPeriodicSchedule(&api.PeriodicSchedule{ + StartTime: ×tamp.Timestamp{Seconds: 1}, + EndTime: ×tamp.Timestamp{Seconds: 2}, + }) + assert.Nil(t, actualPeriodicSchedule) +} + +func TestToCrdPeriodicSchedule_NilStartTime(t *testing.T) { + actualPeriodicSchedule := toCRDPeriodicSchedule(&api.PeriodicSchedule{ + IntervalSecond: 123, + EndTime: ×tamp.Timestamp{Seconds: 2}, + }) + endTime := metav1.NewTime(time.Unix(2, 0)) + assert.Equal(t, actualPeriodicSchedule, &scheduledworkflow.PeriodicSchedule{ + IntervalSecond: 123, + EndTime: &endTime, + }) +} + +func TestToCrdPeriodicSchedule_NilEndTime(t *testing.T) { + actualPeriodicSchedule := toCRDPeriodicSchedule(&api.PeriodicSchedule{ + IntervalSecond: 123, + StartTime: ×tamp.Timestamp{Seconds: 1}, + }) + startTime := metav1.NewTime(time.Unix(1, 0)) + assert.Equal(t, actualPeriodicSchedule, &scheduledworkflow.PeriodicSchedule{ + IntervalSecond: 123, + StartTime: &startTime, + }) +} diff --git a/backend/src/apiserver/template/v2_template.go b/backend/src/apiserver/template/v2_template.go new file mode 100644 index 00000000000..4e0597200c0 --- /dev/null +++ b/backend/src/apiserver/template/v2_template.go @@ -0,0 +1,158 @@ +package template + +import ( + "fmt" + structpb "github.com/golang/protobuf/ptypes/struct" + + "github.com/kubeflow/pipelines/api/v2alpha1/go/pipelinespec" + api "github.com/kubeflow/pipelines/backend/api/go_client" + "github.com/kubeflow/pipelines/backend/src/common/util" + scheduledworkflow "github.com/kubeflow/pipelines/backend/src/crd/pkg/apis/scheduledworkflow/v1beta1" + "github.com/kubeflow/pipelines/v2/compiler" + "google.golang.org/protobuf/encoding/protojson" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type V2Spec struct { + spec *pipelinespec.PipelineSpec +} + +func (t *V2Spec) ScheduledWorkflow(apiJob *api.Job) (*scheduledworkflow.ScheduledWorkflow, error) { + bytes, err := protojson.Marshal(t.spec) + if err != nil { + return nil, util.Wrap(err, "Failed marshal pipeline spec to json") + } + spec := &structpb.Struct{} + if err := protojson.Unmarshal(bytes, spec); err != nil { + return nil, util.Wrap(err, "Failed to parse pipeline spec") + } + job := &pipelinespec.PipelineJob{PipelineSpec: spec} + jobRuntimeConfig, err := toPipelineJobRuntimeConfig(apiJob.GetPipelineSpec().GetRuntimeConfig()) + if err != nil { + return nil, util.Wrap(err, "Failed to convert to PipelineJob RuntimeConfig") + } + job.RuntimeConfig = jobRuntimeConfig + wf, err := compiler.Compile(job, nil) + if err != nil { + return nil, util.Wrap(err, "Failed to compile job") + } + workflow := util.NewWorkflow(wf) + setDefaultServiceAccount(workflow, apiJob.GetServiceAccount()) + // Disable istio sidecar injection if not specified + workflow.SetAnnotationsToAllTemplatesIfKeyNotExist(util.AnnotationKeyIstioSidecarInject, util.AnnotationValueIstioSidecarInjectDisabled) + swfGeneratedName, err := toSWFCRDResourceGeneratedName(apiJob.Name) + if err != nil { + return nil, util.Wrap(err, "Create job failed") + } + scheduledWorkflow := &scheduledworkflow.ScheduledWorkflow{ + ObjectMeta: metav1.ObjectMeta{GenerateName: swfGeneratedName}, + Spec: scheduledworkflow.ScheduledWorkflowSpec{ + Enabled: apiJob.Enabled, + MaxConcurrency: &apiJob.MaxConcurrency, + Trigger: *toCRDTrigger(apiJob.Trigger), + Workflow: &scheduledworkflow.WorkflowResource{ + Parameters: toCRDParameter(apiJob.GetPipelineSpec().GetParameters()), + Spec: workflow.Spec, + }, + NoCatchup: util.BoolPointer(apiJob.NoCatchup), + }, + } + return scheduledWorkflow, nil +} + +func (t *V2Spec) GetTemplateType() TemplateType { + return V2 +} + +func NewV2SpecTemplate(template []byte) (*V2Spec, error) { + var spec pipelinespec.PipelineSpec + err := protojson.Unmarshal(template, &spec) + if err != nil { + return nil, util.NewInvalidInputErrorWithDetails(ErrorInvalidPipelineSpec, fmt.Sprintf("invalid v2 pipeline spec: %s", err.Error())) + } + if spec.GetPipelineInfo().GetName() == "" { + return nil, util.NewInvalidInputErrorWithDetails(ErrorInvalidPipelineSpec, "invalid v2 pipeline spec: name is empty") + } + if spec.GetRoot() == nil { + return nil, util.NewInvalidInputErrorWithDetails(ErrorInvalidPipelineSpec, "invalid v2 pipeline spec: root component is empty") + } + return &V2Spec{spec: &spec}, nil +} + +func (t *V2Spec) Bytes() []byte { + if t == nil { + return nil + } + bytes, err := protojson.Marshal(t.spec) + if err != nil { + // this is unexpected + return nil + } + return bytes +} + +func (t *V2Spec) IsV2() bool { + return true +} + +func (t *V2Spec) V2PipelineName() string { + if t == nil { + return "" + } + return t.spec.GetPipelineInfo().GetName() +} + +func (t *V2Spec) OverrideV2PipelineName(name, namespace string) { + if t == nil { + return + } + var pipelineRef string + if namespace != "" { + pipelineRef = fmt.Sprintf("namespace/%s/pipeline/%s", namespace, name) + } else { + pipelineRef = fmt.Sprintf("pipeline/%s", name) + } + t.spec.PipelineInfo.Name = pipelineRef +} + +func (t *V2Spec) ParametersJSON() (string, error) { + // TODO(v2): implement this after pipeline spec can contain parameter defaults + return "[]", nil +} + +func (t *V2Spec) RunWorkflow(apiRun *api.Run, options RunWorkflowOptions) (*util.Workflow, error) { + bytes, err := protojson.Marshal(t.spec) + if err != nil { + return nil, util.Wrap(err, "Failed marshal pipeline spec to json") + } + spec := &structpb.Struct{} + if err := protojson.Unmarshal(bytes, spec); err != nil { + return nil, util.Wrap(err, "Failed to parse pipeline spec") + } + job := &pipelinespec.PipelineJob{PipelineSpec: spec} + jobRuntimeConfig, err := toPipelineJobRuntimeConfig(apiRun.GetPipelineSpec().GetRuntimeConfig()) + if err != nil { + return nil, util.Wrap(err, "Failed to convert to PipelineJob RuntimeConfig") + } + job.RuntimeConfig = jobRuntimeConfig + wf, err := compiler.Compile(job, nil) + if err != nil { + return nil, util.Wrap(err, "Failed to compile job") + } + workflow := util.NewWorkflow(wf) + setDefaultServiceAccount(workflow, apiRun.GetServiceAccount()) + // Disable istio sidecar injection if not specified + workflow.SetAnnotationsToAllTemplatesIfKeyNotExist(util.AnnotationKeyIstioSidecarInject, util.AnnotationValueIstioSidecarInjectDisabled) + // Add label to the workflow so it can be persisted by persistent agent later. + workflow.SetLabels(util.LabelKeyWorkflowRunId, options.RunId) + // Add run name annotation to the workflow so that it can be logged by the Metadata Writer. + workflow.SetAnnotations(util.AnnotationKeyRunName, apiRun.Name) + // Replace {{workflow.uid}} with runId + err = workflow.ReplaceUID(options.RunId) + if err != nil { + return nil, util.NewInternalServerError(err, "Failed to replace workflow ID") + } + workflow.SetPodMetadataLabels(util.LabelKeyWorkflowRunId, options.RunId) + return workflow, nil + +} diff --git a/backend/src/common/client/api_server/pipeline_client.go b/backend/src/common/client/api_server/pipeline_client.go index ca12f8e86fa..56e87301d0e 100644 --- a/backend/src/common/client/api_server/pipeline_client.go +++ b/backend/src/common/client/api_server/pipeline_client.go @@ -7,6 +7,7 @@ import ( apiclient "github.com/kubeflow/pipelines/backend/api/go_http_client/pipeline_client" params "github.com/kubeflow/pipelines/backend/api/go_http_client/pipeline_client/pipeline_service" model "github.com/kubeflow/pipelines/backend/api/go_http_client/pipeline_model" + "github.com/kubeflow/pipelines/backend/src/apiserver/template" "github.com/kubeflow/pipelines/backend/src/common/util" "golang.org/x/net/context" _ "k8s.io/client-go/plugin/pkg/client/auth/gcp" @@ -17,7 +18,7 @@ type PipelineInterface interface { Create(params *params.CreatePipelineParams) (*model.APIPipeline, error) Get(params *params.GetPipelineParams) (*model.APIPipeline, error) Delete(params *params.DeletePipelineParams) error - GetTemplate(params *params.GetTemplateParams) (util.Template, error) + GetTemplate(params *params.GetTemplateParams) (template.Template, error) List(params *params.ListPipelinesParams) ([]*model.APIPipeline, int, string, error) ListAll(params *params.ListPipelinesParams, maxResultSize int) ( []*model.APIPipeline, error) @@ -136,7 +137,7 @@ func (c *PipelineClient) Delete(parameters *params.DeletePipelineParams) error { return nil } -func (c *PipelineClient) GetTemplate(parameters *params.GetTemplateParams) (util.Template, error) { +func (c *PipelineClient) GetTemplate(parameters *params.GetTemplateParams) (template.Template, error) { // Create context with timeout ctx, cancel := context.WithTimeout(context.Background(), apiServerDefaultTimeout) defer cancel() @@ -157,7 +158,7 @@ func (c *PipelineClient) GetTemplate(parameters *params.GetTemplateParams) (util } // Unmarshal response - return util.NewTemplate([]byte(response.Payload.Template)) + return template.New([]byte(response.Payload.Template)) } func (c *PipelineClient) List(parameters *params.ListPipelinesParams) ( @@ -286,7 +287,7 @@ func (c *PipelineClient) GetPipelineVersion(parameters *params.GetPipelineVersio } func (c *PipelineClient) GetPipelineVersionTemplate(parameters *params.GetPipelineVersionTemplateParams) ( - util.Template, error) { + template.Template, error) { // Create context with timeout ctx, cancel := context.WithTimeout(context.Background(), apiServerDefaultTimeout) defer cancel() @@ -307,5 +308,5 @@ func (c *PipelineClient) GetPipelineVersionTemplate(parameters *params.GetPipeli } // Unmarshal response - return util.NewTemplate([]byte(response.Payload.Template)) + return template.New([]byte(response.Payload.Template)) } diff --git a/backend/src/common/client/api_server/pipeline_client_fake.go b/backend/src/common/client/api_server/pipeline_client_fake.go index e55e2d427b0..5356310aedc 100644 --- a/backend/src/common/client/api_server/pipeline_client_fake.go +++ b/backend/src/common/client/api_server/pipeline_client_fake.go @@ -2,6 +2,7 @@ package api_server import ( "fmt" + "github.com/kubeflow/pipelines/backend/src/apiserver/template" "path" @@ -10,7 +11,6 @@ import ( params "github.com/kubeflow/pipelines/backend/api/go_http_client/pipeline_client/pipeline_service" pipelineparams "github.com/kubeflow/pipelines/backend/api/go_http_client/pipeline_client/pipeline_service" pipelinemodel "github.com/kubeflow/pipelines/backend/api/go_http_client/pipeline_model" - "github.com/kubeflow/pipelines/backend/src/common/util" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -42,8 +42,8 @@ func getDefaultWorkflow() *workflowapi.Workflow { }} } -func getDefaultTemplate() util.Template { - tmpl, _ := util.NewArgoTemplateFromWorkflow(&workflowapi.Workflow{ +func getDefaultTemplate() template.Template { + tmpl, _ := template.NewArgoTemplateFromWorkflow(&workflowapi.Workflow{ ObjectMeta: metav1.ObjectMeta{ Namespace: "MY_NAMESPACE", Name: "MY_NAME", @@ -92,7 +92,7 @@ func (c *PipelineClientFake) Delete(params *pipelineparams.DeletePipelineParams) } func (c *PipelineClientFake) GetTemplate(params *pipelineparams.GetTemplateParams) ( - util.Template, error) { + template.Template, error) { switch params.ID { case PipelineForClientErrorTest: return nil, fmt.Errorf(ClientErrorString) diff --git a/backend/src/common/util/template_util.go b/backend/src/common/util/template_util.go deleted file mode 100644 index 19f7af96f3d..00000000000 --- a/backend/src/common/util/template_util.go +++ /dev/null @@ -1,277 +0,0 @@ -// Copyright 2018 The Kubeflow Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package util - -import ( - "encoding/json" - "fmt" - "strings" - - "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" - workflowapi "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" - "github.com/argoproj/argo-workflows/v3/workflow/validate" - "github.com/ghodss/yaml" - "github.com/kubeflow/pipelines/api/v2alpha1/go/pipelinespec" - "google.golang.org/protobuf/encoding/protojson" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" -) - -type TemplateType string - -const ( - V1 TemplateType = "v1" - V2 TemplateType = "v2" - Unknown TemplateType = "Unknown" - - argoGroup = "argoproj.io/" - argoVersion = "argoproj.io/v1alpha1" - argoK8sResource = "Workflow" -) - -// Unmarshal parameters from JSON encoded string. -func UnmarshalParameters(paramsString string) ([]v1alpha1.Parameter, error) { - if paramsString == "" { - return nil, nil - } - var params []v1alpha1.Parameter - err := json.Unmarshal([]byte(paramsString), ¶ms) - if err != nil { - return nil, NewInternalServerError(err, "Parameters have wrong format") - } - return params, nil -} - -// Marshal parameters to JSON encoded string. -// This also checks result is not longer than a limit. -func MarshalParameters(params []v1alpha1.Parameter) (string, error) { - if params == nil { - return "[]", nil - } - paramBytes, err := json.Marshal(params) - if err != nil { - return "", NewInvalidInputErrorWithDetails(err, "Failed to marshal the parameter.") - } - if len(paramBytes) > MaxParameterBytes { - return "", NewInvalidInputError("The input parameter length exceed maximum size of %v.", MaxParameterBytes) - } - return string(paramBytes), nil -} - -func ValidateWorkflow(template []byte) (*Workflow, error) { - var wf v1alpha1.Workflow - err := yaml.Unmarshal(template, &wf) - if err != nil { - return nil, NewInvalidInputErrorWithDetails(err, "Failed to parse the workflow template.") - } - if wf.APIVersion != argoVersion { - return nil, NewInvalidInputError("Unsupported argo version. Expected: %v. Received: %v", argoVersion, wf.APIVersion) - } - if wf.Kind != argoK8sResource { - return nil, NewInvalidInputError("Unexpected resource type. Expected: %v. Received: %v", argoK8sResource, wf.Kind) - } - _, err = validate.ValidateWorkflow(nil, nil, &wf, validate.ValidateOpts{ - Lint: true, - IgnoreEntrypoint: true, - WorkflowTemplateValidation: false, // not used by kubeflow - }) - if err != nil { - return nil, err - } - return NewWorkflow(&wf), nil -} - -var ErrorInvalidPipelineSpec = fmt.Errorf("pipeline spec is invalid") - -// InferTemplateFormat infers format from pipeline template. -// There is no guarantee that the template is valid in inferred format, so validation -// is still needed. -func InferTemplateFormat(template []byte) TemplateType { - switch { - case len(template) == 0: - return Unknown - case isArgoWorkflow(template): - return V1 - case isPipelineSpec(template): - return V2 - default: - return Unknown - } -} - -// isArgoWorkflow returns whether template is in argo workflow spec format. -func isArgoWorkflow(template []byte) bool { - var meta metav1.TypeMeta - err := yaml.Unmarshal(template, &meta) - if err != nil { - return false - } - return strings.HasPrefix(meta.APIVersion, argoGroup) && meta.Kind == argoK8sResource -} - -// isPipelineSpec returns whether template is in KFP api/v2alpha1/PipelineSpec format. -func isPipelineSpec(template []byte) bool { - var spec pipelinespec.PipelineSpec - err := protojson.Unmarshal(template, &spec) - return err == nil && spec.GetPipelineInfo().GetName() != "" && spec.GetRoot() != nil -} - -// Pipeline template -type Template interface { - IsV2() bool - // Gets v2 pipeline name. - V2PipelineName() string - // Overrides v2 pipeline name to distinguish shared/namespaced pipelines. - // The name is used as ML Metadata pipeline context name. - OverrideV2PipelineName(name, namespace string) - // Gets parameters in JSON format. - ParametersJSON() (string, error) - // Get bytes content. - Bytes() []byte -} - -func NewTemplate(bytes []byte) (Template, error) { - format := InferTemplateFormat(bytes) - switch format { - case V1: - return NewArgoTemplate(bytes) - case V2: - return NewV2SpecTemplate(bytes) - default: - return nil, NewInvalidInputErrorWithDetails(ErrorInvalidPipelineSpec, "unknown template format") - } -} - -type ArgoTemplate struct { - wf *Workflow -} - -func NewArgoTemplate(bytes []byte) (*ArgoTemplate, error) { - wf, err := ValidateWorkflow(bytes) - if err != nil { - return nil, err - } - return &ArgoTemplate{wf}, nil -} - -func NewArgoTemplateFromWorkflow(wf *workflowapi.Workflow) (*ArgoTemplate, error) { - return &ArgoTemplate{wf: &Workflow{wf}}, nil -} - -func (t *ArgoTemplate) Bytes() []byte { - if t == nil { - return nil - } - return []byte(t.wf.ToStringForStore()) -} - -func (t *ArgoTemplate) IsV2() bool { - if t == nil { - return false - } - return t.wf.IsV2Compatible() -} - -const ( - paramV2compatPipelineName = "pipeline-name" -) - -func (t *ArgoTemplate) V2PipelineName() string { - if t == nil { - return "" - } - return t.wf.GetWorkflowParametersAsMap()[paramV2compatPipelineName] -} - -func (t *ArgoTemplate) OverrideV2PipelineName(name, namespace string) { - if t == nil || !t.wf.IsV2Compatible() { - return - } - var pipelineRef string - if namespace != "" { - pipelineRef = fmt.Sprintf("namespace/%s/pipeline/%s", namespace, name) - } else { - pipelineRef = fmt.Sprintf("pipeline/%s", name) - } - overrides := make(map[string]string) - overrides[paramV2compatPipelineName] = pipelineRef - t.wf.OverrideParameters(overrides) -} - -func (t *ArgoTemplate) ParametersJSON() (string, error) { - if t == nil { - return "", nil - } - return MarshalParameters(t.wf.Spec.Arguments.Parameters) -} - -type V2SpecTemplate struct { - spec *pipelinespec.PipelineSpec -} - -func NewV2SpecTemplate(template []byte) (*V2SpecTemplate, error) { - var spec pipelinespec.PipelineSpec - err := protojson.Unmarshal(template, &spec) - if err != nil { - return nil, NewInvalidInputErrorWithDetails(ErrorInvalidPipelineSpec, fmt.Sprintf("invalid v2 pipeline spec: %s", err.Error())) - } - if spec.GetPipelineInfo().GetName() == "" { - return nil, NewInvalidInputErrorWithDetails(ErrorInvalidPipelineSpec, "invalid v2 pipeline spec: name is empty") - } - if spec.GetRoot() == nil { - return nil, NewInvalidInputErrorWithDetails(ErrorInvalidPipelineSpec, "invalid v2 pipeline spec: root component is empty") - } - return &V2SpecTemplate{spec: &spec}, nil -} - -func (t *V2SpecTemplate) Bytes() []byte { - if t == nil { - return nil - } - bytes, err := protojson.Marshal(t.spec) - if err != nil { - // this is unexpected - return nil - } - return bytes -} - -func (t *V2SpecTemplate) IsV2() bool { - return true -} - -func (t *V2SpecTemplate) V2PipelineName() string { - if t == nil { - return "" - } - return t.spec.GetPipelineInfo().GetName() -} - -func (t *V2SpecTemplate) OverrideV2PipelineName(name, namespace string) { - if t == nil { - return - } - var pipelineRef string - if namespace != "" { - pipelineRef = fmt.Sprintf("namespace/%s/pipeline/%s", namespace, name) - } else { - pipelineRef = fmt.Sprintf("pipeline/%s", name) - } - t.spec.PipelineInfo.Name = pipelineRef -} - -func (t *V2SpecTemplate) ParametersJSON() (string, error) { - // TODO(v2): implement this after pipeline spec can contain parameter defaults - return "[]", nil -} diff --git a/backend/src/common/util/template_util_test.go b/backend/src/common/util/template_util_test.go deleted file mode 100644 index c302da714aa..00000000000 --- a/backend/src/common/util/template_util_test.go +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright 2018 The Kubeflow Authors -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package util - -import ( - "testing" - - "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" - "github.com/ghodss/yaml" - "github.com/stretchr/testify/assert" - "google.golang.org/grpc/codes" -) - -func TestFailValidation(t *testing.T) { - wf := unmarshalWf(emptyName) - wf.Spec.Arguments.Parameters = []v1alpha1.Parameter{{Name: "dup", Value: v1alpha1.AnyStringPtr("value1")}} - templateBytes, _ := yaml.Marshal(wf) - _, err := ValidateWorkflow([]byte(templateBytes)) - if assert.NotNil(t, err) { - assert.Contains(t, err.Error(), "name is required") - } -} - -func TestValidateWorkflow_ParametersTooLong(t *testing.T) { - var params []v1alpha1.Parameter - // Create a long enough parameter string so it exceed the length limit of parameter. - for i := 0; i < 10000; i++ { - params = append(params, v1alpha1.Parameter{Name: "name1", Value: v1alpha1.AnyStringPtr("value1")}) - } - template := v1alpha1.Workflow{Spec: v1alpha1.WorkflowSpec{Arguments: v1alpha1.Arguments{ - Parameters: params}}} - templateBytes, _ := yaml.Marshal(template) - _, err := ValidateWorkflow(templateBytes) - assert.Equal(t, codes.InvalidArgument, err.(*UserError).ExternalStatusCode()) -} - -func unmarshalWf(yamlStr string) *v1alpha1.Workflow { - var wf v1alpha1.Workflow - err := yaml.Unmarshal([]byte(yamlStr), &wf) - if err != nil { - panic(err) - } - return &wf -} - -var template = ` -apiVersion: argoproj.io/v1alpha1 -kind: Workflow -metadata: - generateName: hello-world- -spec: - entrypoint: whalesay - templates: - - name: whalesay - inputs: - parameters: - - name: dup - value: "value1" - container: - image: docker/whalesay:latest` - -var emptyName = ` -apiVersion: argoproj.io/v1alpha1 -kind: Workflow -metadata: - generateName: hello-world- -spec: - entrypoint: whalesay - templates: - - name: whalesay - inputs: - parameters: - - name: "" - value: "value1" - container: - image: docker/whalesay:latest` diff --git a/backend/test/integration/pipeline_api_test.go b/backend/test/integration/pipeline_api_test.go index 3e16b021103..dbe8f328c90 100644 --- a/backend/test/integration/pipeline_api_test.go +++ b/backend/test/integration/pipeline_api_test.go @@ -10,6 +10,7 @@ import ( "github.com/golang/glog" params "github.com/kubeflow/pipelines/backend/api/go_http_client/pipeline_client/pipeline_service" model "github.com/kubeflow/pipelines/backend/api/go_http_client/pipeline_model" + pipelinetemplate "github.com/kubeflow/pipelines/backend/src/apiserver/template" uploadParams "github.com/kubeflow/pipelines/backend/api/go_http_client/pipeline_upload_client/pipeline_upload_service" "github.com/kubeflow/pipelines/backend/src/common/client/api_server" @@ -191,14 +192,14 @@ func (s *PipelineApiTest) TestPipelineAPI() { require.Nil(t, err) bytes, err := ioutil.ReadFile("../resources/arguments-parameters.yaml") require.Nil(t, err) - expected, err := util.NewTemplate(bytes) + expected, err := pipelinetemplate.New(bytes) assert.Equal(t, expected, template) template, err = s.pipelineClient.GetTemplate(¶ms.GetTemplateParams{ID: v2HelloPipeline.ID}) require.Nil(t, err) bytes, err = ioutil.ReadFile("../resources/v2-hello-world.json") require.Nil(t, err) - expected, err = util.NewTemplate(bytes) + expected, err = pipelinetemplate.New(bytes) expected.OverrideV2PipelineName("v2-hello-world.json", "") assert.Equal(t, expected, template) } diff --git a/backend/test/integration/pipeline_version_api_test.go b/backend/test/integration/pipeline_version_api_test.go index 4a6c8d6d552..dd312d2fd81 100644 --- a/backend/test/integration/pipeline_version_api_test.go +++ b/backend/test/integration/pipeline_version_api_test.go @@ -9,6 +9,7 @@ import ( params "github.com/kubeflow/pipelines/backend/api/go_http_client/pipeline_client/pipeline_service" "github.com/kubeflow/pipelines/backend/api/go_http_client/pipeline_model" uploadParams "github.com/kubeflow/pipelines/backend/api/go_http_client/pipeline_upload_client/pipeline_upload_service" + pipelinetemplate "github.com/kubeflow/pipelines/backend/src/apiserver/template" "github.com/kubeflow/pipelines/backend/src/common/client/api_server" "github.com/kubeflow/pipelines/backend/src/common/util" "github.com/kubeflow/pipelines/backend/test" @@ -290,7 +291,7 @@ func (s *PipelineVersionApiTest) TestArgoSpec() { require.Nil(t, err) bytes, err := ioutil.ReadFile("../resources/arguments-parameters.yaml") require.Nil(t, err) - expected, err := util.NewTemplate(bytes) + expected, err := pipelinetemplate.New(bytes) require.Nil(t, err) assert.Equal(t, expected, template) } @@ -323,7 +324,7 @@ func (s *PipelineVersionApiTest) TestV2Spec() { require.Nil(t, err) bytes, err := ioutil.ReadFile("../resources/v2-hello-world.json") require.Nil(t, err) - expected, err := util.NewTemplate(bytes) + expected, err := pipelinetemplate.New(bytes) require.Nil(t, err) expected.OverrideV2PipelineName("test_v2_pipeline", "") assert.Equal(t, expected, template) diff --git a/backend/test/integration/upgrade_test.go b/backend/test/integration/upgrade_test.go index 98245546c20..7cf3d15acc8 100644 --- a/backend/test/integration/upgrade_test.go +++ b/backend/test/integration/upgrade_test.go @@ -20,6 +20,7 @@ import ( uploadParams "github.com/kubeflow/pipelines/backend/api/go_http_client/pipeline_upload_client/pipeline_upload_service" runParams "github.com/kubeflow/pipelines/backend/api/go_http_client/run_client/run_service" "github.com/kubeflow/pipelines/backend/api/go_http_client/run_model" + pipelinetemplate "github.com/kubeflow/pipelines/backend/src/apiserver/template" "github.com/kubeflow/pipelines/backend/src/common/client/api_server" "github.com/kubeflow/pipelines/backend/src/common/util" "github.com/kubeflow/pipelines/backend/test" @@ -232,7 +233,7 @@ func (s *UpgradeTests) VerifyPipelines() { require.Nil(t, err) bytes, err := ioutil.ReadFile("../resources/arguments-parameters.yaml") require.Nil(t, err) - expected, err := util.NewTemplate(bytes) + expected, err := pipelinetemplate.New(bytes) require.Nil(t, err) assert.Equal(t, expected, template) } diff --git a/backend/third_party_licenses/apiserver.csv b/backend/third_party_licenses/apiserver.csv index 492f5f67004..b63e81c8e1c 100644 --- a/backend/third_party_licenses/apiserver.csv +++ b/backend/third_party_licenses/apiserver.csv @@ -17,7 +17,6 @@ github.com/cenkalti/backoff, https://github.com/cenkalti/backoff/blob/v2.2.1/LIC github.com/cespare/xxhash/v2, https://github.com/cespare/xxhash/blob/v2.1.1/LICENSE.txt, MIT github.com/colinmarc/hdfs, https://github.com/colinmarc/hdfs/blob/9746310a4d31/LICENSE.txt, MIT github.com/davecgh/go-spew, https://github.com/davecgh/go-spew/blob/v1.1.1/LICENSE, ISC -github.com/docker/spdystream, https://github.com/docker/spdystream/blob/6480d4af844c/LICENSE, Apache-2.0 github.com/doublerebel/bellows, https://github.com/doublerebel/bellows/blob/f177d92a03d3/LICENSE, MIT github.com/emicklei/go-restful, https://github.com/emicklei/go-restful/blob/v2.15.0/LICENSE, MIT github.com/fsnotify/fsnotify, https://github.com/fsnotify/fsnotify/blob/v1.4.9/LICENSE, BSD-3-Clause @@ -37,6 +36,7 @@ github.com/go-stack/stack, https://github.com/go-stack/stack/blob/v1.8.0/LICENSE github.com/gogo/protobuf, https://github.com/gogo/protobuf/blob/v1.3.2/LICENSE, BSD-3-Clause / BSD-2-Clause github.com/golang/glog, https://github.com/golang/glog/blob/23def4e6c14b/LICENSE, Apache-2.0 github.com/golang/protobuf, https://github.com/golang/protobuf/blob/v1.5.0/LICENSE, BSD-3-Clause +github.com/google/go-cmp, https://github.com/google/go-cmp/blob/v0.5.5/LICENSE, BSD-3-Clause github.com/google/gofuzz, https://github.com/google/gofuzz/blob/v1.1.0/LICENSE, Apache-2.0 github.com/google/uuid, https://github.com/google/uuid/blob/v1.1.2/LICENSE, BSD-3-Clause github.com/googleapis/gnostic, https://github.com/googleapis/gnostic/blob/v0.5.1/LICENSE, Apache-2.0 @@ -62,6 +62,7 @@ github.com/klauspost/compress, https://github.com/klauspost/compress/blob/v1.11. github.com/klauspost/compress, https://github.com/klauspost/compress/blob/v1.11.9/zstd/internal/xxhash/LICENSE.txt, MIT github.com/klauspost/pgzip, https://github.com/klauspost/pgzip/blob/v1.2.5/GO_LICENSE, BSD-3-Clause github.com/klauspost/pgzip, https://github.com/klauspost/pgzip/blob/v1.2.5/LICENSE, MIT +github.com/kubeflow/pipelines/v2, https://github.com/kubeflow/pipelines/blob/2e3fb5efff56/LICENSE, Apache-2.0 github.com/lann/builder, https://github.com/lann/builder/blob/47ae307949d0/LICENSE, MIT github.com/lann/ps, https://github.com/lann/ps/blob/62de8c46ede0/LICENSE, MIT github.com/lestrrat-go/strftime, https://github.com/lestrrat-go/strftime/blob/v1.0.4/LICENSE, MIT @@ -76,6 +77,7 @@ github.com/mitchellh/copystructure, https://github.com/mitchellh/copystructure/b github.com/mitchellh/go-homedir, https://github.com/mitchellh/go-homedir/blob/v1.1.0/LICENSE, MIT github.com/mitchellh/mapstructure, https://github.com/mitchellh/mapstructure/blob/v1.4.1/LICENSE, MIT github.com/mitchellh/reflectwalk, https://github.com/mitchellh/reflectwalk/blob/v1.0.1/LICENSE, MIT +github.com/moby/spdystream, https://github.com/moby/spdystream/blob/v0.2.0/LICENSE, Apache-2.0 github.com/modern-go/concurrent, https://github.com/modern-go/concurrent/blob/bacd9c7ef1dd/LICENSE, Apache-2.0 github.com/modern-go/reflect2, https://github.com/modern-go/reflect2/blob/v1.0.1/LICENSE, Apache-2.0 github.com/oliveagle/jsonpath, https://github.com/oliveagle/jsonpath/blob/2e52cf6e6852/LICENSE, MIT @@ -105,13 +107,13 @@ go.mongodb.org/mongo-driver/., https://github.com/mongodb/mongo-go-driver/blob/v go.mongodb.org/mongo-driver/., https://github.com/mongodb/mongo-go-driver/blob/v1.4.4/THIRD-PARTY-NOTICES#L31-L61, BSD-3-Clause golang.org/x/crypto, https://github.com/golang/crypto/blob/0c34fe9e7dc2/LICENSE, BSD-3-Clause golang.org/x/net, https://github.com/golang/net/blob/6b1517762897/LICENSE, BSD-3-Clause -golang.org/x/oauth2, https://github.com/golang/oauth2/blob/bf48bf16ab8d/LICENSE, BSD-3-Clause -golang.org/x/sys, https://github.com/golang/sys/blob/47abb6519492/LICENSE, BSD-3-Clause +golang.org/x/oauth2, https://github.com/golang/oauth2/blob/0b49973bad19/LICENSE, BSD-3-Clause +golang.org/x/sys, https://github.com/golang/sys/blob/d19ff857e887/LICENSE, BSD-3-Clause golang.org/x/term, https://github.com/golang/term/blob/7de9c90e9dd1/LICENSE, BSD-3-Clause golang.org/x/text, https://github.com/golang/text/blob/v0.3.5/LICENSE, BSD-3-Clause golang.org/x/time, https://github.com/golang/time/blob/3af7569d3a1e/LICENSE, BSD-3-Clause -google.golang.org/genproto, https://github.com/googleapis/go-genproto/blob/86f49bd18e98/LICENSE, Apache-2.0 -google.golang.org/grpc, https://github.com/grpc/grpc-go/blob/v1.34.0/LICENSE, Apache-2.0 +google.golang.org/genproto, https://github.com/googleapis/go-genproto/blob/6486ece9c497/LICENSE, Apache-2.0 +google.golang.org/grpc, https://github.com/grpc/grpc-go/blob/v1.36.0/LICENSE, Apache-2.0 google.golang.org/protobuf, https://github.com/protocolbuffers/protobuf-go/blob/v1.27.1/LICENSE, BSD-3-Clause gopkg.in/inf.v0, https://github.com/go-inf/inf/blob/v0.9.1/LICENSE, BSD-3-Clause gopkg.in/ini.v1, https://github.com/go-ini/ini/blob/v1.57.0/LICENSE, Apache-2.0 @@ -121,15 +123,15 @@ gopkg.in/jcmturner/gokrb5.v5, https://github.com/jcmturner/gokrb5/blob/v5.3.0/LI gopkg.in/jcmturner/rpc.v0, https://github.com/jcmturner/rpc/blob/v0.0.2/LICENSE, Apache-2.0 gopkg.in/yaml.v2, https://github.com/go-yaml/yaml/blob/v2.4.0/LICENSE, Apache-2.0 / MIT gopkg.in/yaml.v3, https://github.com/go-yaml/yaml/blob/496545a6307b/LICENSE, MIT -k8s.io/api, https://github.com/kubernetes/api/blob/v0.19.6/LICENSE, Apache-2.0 -k8s.io/apimachinery, https://github.com/kubernetes/apimachinery/blob/v0.19.6/LICENSE, Apache-2.0 -k8s.io/client-go, https://github.com/kubernetes/client-go/blob/v0.19.6/LICENSE, Apache-2.0 -k8s.io/klog/v2, https://github.com/kubernetes/klog/blob/v2.5.0/LICENSE, Apache-2.0 -k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/d219536bb9fd/LICENSE, Apache-2.0 -k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/d219536bb9fd/pkg/validation/errors/LICENSE, Apache-2.0 -k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/d219536bb9fd/pkg/validation/spec/LICENSE, Apache-2.0 -k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/d219536bb9fd/pkg/validation/strfmt/LICENSE, Apache-2.0 -k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/d219536bb9fd/pkg/validation/validate/LICENSE, Apache-2.0 +k8s.io/api, https://github.com/kubernetes/api/blob/v0.20.4/LICENSE, Apache-2.0 +k8s.io/apimachinery, https://github.com/kubernetes/apimachinery/blob/v0.21.2/LICENSE, Apache-2.0 +k8s.io/client-go, https://github.com/kubernetes/client-go/blob/v0.20.4/LICENSE, Apache-2.0 +k8s.io/klog/v2, https://github.com/kubernetes/klog/blob/v2.8.0/LICENSE, Apache-2.0 +k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/591a79e4bda7/LICENSE, Apache-2.0 +k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/591a79e4bda7/pkg/validation/errors/LICENSE, Apache-2.0 +k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/591a79e4bda7/pkg/validation/spec/LICENSE, Apache-2.0 +k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/591a79e4bda7/pkg/validation/strfmt/LICENSE, Apache-2.0 +k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/591a79e4bda7/pkg/validation/validate/LICENSE, Apache-2.0 k8s.io/kubernetes, https://github.com/kubernetes/kubernetes/blob/v1.11.1/LICENSE, Apache-2.0 k8s.io/kubernetes, https://github.com/kubernetes/kubernetes/blob/v1.11.1/pkg/credentialprovider/azure/azure_acr_helper.go, MIT k8s.io/kubernetes, https://github.com/kubernetes/kubernetes/blob/v1.11.1/third_party/forked/golang/LICENSE, BSD-3-Clause @@ -140,5 +142,5 @@ k8s.io/kubernetes, https://github.com/kubernetes/kubernetes/blob/v1.11.1/third_p k8s.io/utils, https://github.com/kubernetes/utils/blob/67b214c5f920/LICENSE, Apache-2.0 k8s.io/utils, https://github.com/kubernetes/utils/blob/67b214c5f920/inotify/LICENSE, BSD-3-Clause k8s.io/utils, https://github.com/kubernetes/utils/blob/67b214c5f920/third_party/forked/golang/LICENSE, BSD-3-Clause -sigs.k8s.io/structured-merge-diff/v4, https://github.com/kubernetes-sigs/structured-merge-diff/blob/v4.0.2/LICENSE, Apache-2.0 +sigs.k8s.io/structured-merge-diff/v4, https://github.com/kubernetes-sigs/structured-merge-diff/blob/v4.1.0/LICENSE, Apache-2.0 sigs.k8s.io/yaml, https://github.com/kubernetes-sigs/yaml/blob/v1.2.0/LICENSE, MIT / BSD-3-Clause diff --git a/backend/third_party_licenses/cache_server.csv b/backend/third_party_licenses/cache_server.csv index f9b11ebbae8..58b802849b1 100644 --- a/backend/third_party_licenses/cache_server.csv +++ b/backend/third_party_licenses/cache_server.csv @@ -1,24 +1,13 @@ # Generated by https://github.com/google/go-licenses/v2. DO NOT EDIT. github.com/kubeflow/pipelines, https://github.com/kubeflow/pipelines/blob/master/LICENSE, Apache-2.0 github.com/kubeflow/pipelines, https://github.com/kubeflow/pipelines/blob/master/backend/src/apiserver/archive/log.go, Apache-2.0 -github.com/Masterminds/goutils, https://github.com/Masterminds/goutils/blob/v1.1.0/LICENSE.txt, Apache-2.0 -github.com/Masterminds/semver, https://github.com/Masterminds/semver/blob/v1.5.0/LICENSE.txt, MIT -github.com/Masterminds/sprig, https://github.com/Masterminds/sprig/blob/v2.22.0/LICENSE.txt, MIT github.com/PuerkitoBio/purell, https://github.com/PuerkitoBio/purell/blob/v1.1.1/LICENSE, BSD-3-Clause github.com/PuerkitoBio/urlesc, https://github.com/PuerkitoBio/urlesc/blob/de5bf2ad4578/LICENSE, BSD-3-Clause -github.com/antonmedv/expr, https://github.com/antonmedv/expr/blob/v1.8.8/LICENSE, MIT github.com/argoproj/argo-workflows/v3, https://github.com/argoproj/argo-workflows/blob/v3.1.14/LICENSE, Apache-2.0 -github.com/argoproj/pkg, https://github.com/argoproj/pkg/blob/v0.10.1/LICENSE, Apache-2.0 github.com/asaskevich/govalidator, https://github.com/asaskevich/govalidator/blob/7a23bdc65eef/LICENSE, MIT -github.com/beorn7/perks, https://github.com/beorn7/perks/blob/v1.0.1/LICENSE, MIT github.com/cenkalti/backoff, https://github.com/cenkalti/backoff/blob/v2.2.1/LICENSE, MIT -github.com/cespare/xxhash/v2, https://github.com/cespare/xxhash/blob/v2.1.1/LICENSE.txt, MIT -github.com/colinmarc/hdfs, https://github.com/colinmarc/hdfs/blob/9746310a4d31/LICENSE.txt, MIT github.com/davecgh/go-spew, https://github.com/davecgh/go-spew/blob/v1.1.1/LICENSE, ISC -github.com/docker/spdystream, https://github.com/docker/spdystream/blob/6480d4af844c/LICENSE, Apache-2.0 -github.com/doublerebel/bellows, https://github.com/doublerebel/bellows/blob/f177d92a03d3/LICENSE, MIT github.com/emicklei/go-restful, https://github.com/emicklei/go-restful/blob/v2.15.0/LICENSE, MIT -github.com/ghodss/yaml, https://github.com/ghodss/yaml/blob/25d852aebe32/LICENSE, MIT / BSD-3-Clause github.com/go-logr/logr, https://github.com/go-logr/logr/blob/v0.4.0/LICENSE, Apache-2.0 github.com/go-openapi/errors, https://github.com/go-openapi/errors/blob/v0.19.9/LICENSE, Apache-2.0 github.com/go-openapi/jsonpointer, https://github.com/go-openapi/jsonpointer/blob/v0.19.5/LICENSE, Apache-2.0 @@ -33,18 +22,14 @@ github.com/go-stack/stack, https://github.com/go-stack/stack/blob/v1.8.0/LICENSE github.com/gogo/protobuf, https://github.com/gogo/protobuf/blob/v1.3.2/LICENSE, BSD-3-Clause / BSD-2-Clause github.com/golang/glog, https://github.com/golang/glog/blob/23def4e6c14b/LICENSE, Apache-2.0 github.com/golang/protobuf, https://github.com/golang/protobuf/blob/v1.5.0/LICENSE, BSD-3-Clause +github.com/google/go-cmp, https://github.com/google/go-cmp/blob/v0.5.5/LICENSE, BSD-3-Clause github.com/google/gofuzz, https://github.com/google/gofuzz/blob/v1.1.0/LICENSE, Apache-2.0 github.com/google/uuid, https://github.com/google/uuid/blob/v1.1.2/LICENSE, BSD-3-Clause github.com/googleapis/gnostic, https://github.com/googleapis/gnostic/blob/v0.5.1/LICENSE, Apache-2.0 -github.com/gorilla/websocket, https://github.com/gorilla/websocket/blob/v1.4.2/LICENSE, BSD-2-Clause -github.com/gorilla/websocket, https://github.com/gorilla/websocket/blob/v1.4.2/examples/autobahn/server.go, MIT github.com/grpc-ecosystem/grpc-gateway, https://github.com/grpc-ecosystem/grpc-gateway/blob/v1.16.0/LICENSE.txt, BSD-3-Clause github.com/grpc-ecosystem/grpc-gateway, https://github.com/grpc-ecosystem/grpc-gateway/blob/v1.16.0/internal/casing/LICENSE.md, BSD-3-Clause github.com/grpc-ecosystem/grpc-gateway, https://github.com/grpc-ecosystem/grpc-gateway/blob/v1.16.0/third_party/googleapis/LICENSE, Apache-2.0 -github.com/hashicorp/go-uuid, https://github.com/hashicorp/go-uuid/blob/v1.0.2/LICENSE, MPL-2.0 -github.com/huandu/xstrings, https://github.com/huandu/xstrings/blob/v1.3.1/LICENSE, MIT github.com/imdario/mergo, https://github.com/imdario/mergo/blob/v0.3.12/LICENSE, BSD-3-Clause -github.com/jcmturner/gofork, https://github.com/jcmturner/gofork/blob/v1.0.0/LICENSE, BSD-3-Clause github.com/jinzhu/gorm, https://github.com/jinzhu/gorm/blob/v1.9.1/License, MIT github.com/jinzhu/inflection, https://github.com/jinzhu/inflection/blob/04140366298a/LICENSE, MIT github.com/josharian/intern, https://github.com/josharian/intern/blob/v1.0.0/license.md, MIT @@ -54,55 +39,37 @@ github.com/mailru/easyjson, https://github.com/mailru/easyjson/blob/v0.7.6/LICEN github.com/mailru/easyjson, https://github.com/mailru/easyjson/blob/v0.7.6/parser/modulepath.go, BSD-3-Clause github.com/mattn/go-sqlite3, https://github.com/mattn/go-sqlite3/blob/v1.9.0/LICENSE, MIT github.com/mattn/go-sqlite3/., https://github.com/mattn/go-sqlite3/blob/v1.9.0/sqlite3-binding.h#L2-L11, blessing -github.com/matttproud/golang_protobuf_extensions, https://github.com/matttproud/golang_protobuf_extensions/blob/c182affec369/LICENSE, Apache-2.0 -github.com/mitchellh/copystructure, https://github.com/mitchellh/copystructure/blob/v1.0.0/LICENSE, MIT github.com/mitchellh/mapstructure, https://github.com/mitchellh/mapstructure/blob/v1.4.1/LICENSE, MIT -github.com/mitchellh/reflectwalk, https://github.com/mitchellh/reflectwalk/blob/v1.0.1/LICENSE, MIT github.com/modern-go/concurrent, https://github.com/modern-go/concurrent/blob/bacd9c7ef1dd/LICENSE, Apache-2.0 github.com/modern-go/reflect2, https://github.com/modern-go/reflect2/blob/v1.0.1/LICENSE, Apache-2.0 -github.com/oliveagle/jsonpath, https://github.com/oliveagle/jsonpath/blob/2e52cf6e6852/LICENSE, MIT github.com/peterhellberg/duration, https://github.com/peterhellberg/duration/blob/ec6baeebcd10/LICENSE, MIT github.com/pkg/errors, https://github.com/pkg/errors/blob/v0.9.1/LICENSE, BSD-2-Clause -github.com/prometheus/client_golang, https://github.com/prometheus/client_golang/blob/v1.9.0/LICENSE, Apache-2.0 -github.com/prometheus/client_model, https://github.com/prometheus/client_model/blob/v0.2.0/LICENSE, Apache-2.0 -github.com/prometheus/common, https://github.com/prometheus/common/blob/v0.15.0/LICENSE, Apache-2.0 -github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg, https://github.com/prometheus/common/blob/v0.15.0/internal/bitbucket.org/ww/goautoneg/README.txt, BSD-3-Clause -github.com/prometheus/procfs, https://github.com/prometheus/procfs/blob/v0.2.0/LICENSE, Apache-2.0 -github.com/robfig/cron/v3, https://github.com/robfig/cron/blob/v3.0.1/LICENSE, MIT -github.com/sirupsen/logrus, https://github.com/sirupsen/logrus/blob/v1.6.0/LICENSE, MIT -github.com/sirupsen/logrus, https://github.com/sirupsen/logrus/blob/v1.6.0/alt_exit.go, MIT github.com/spf13/pflag, https://github.com/spf13/pflag/blob/v1.0.5/LICENSE, BSD-3-Clause -github.com/valyala/bytebufferpool, https://github.com/valyala/bytebufferpool/blob/v1.0.0/LICENSE, MIT -github.com/valyala/fasttemplate, https://github.com/valyala/fasttemplate/blob/v1.1.0/LICENSE, MIT go.mongodb.org/mongo-driver, https://github.com/mongodb/mongo-go-driver/blob/v1.4.4/LICENSE, Apache-2.0 go.mongodb.org/mongo-driver/., https://github.com/mongodb/mongo-go-driver/blob/v1.4.4/THIRD-PARTY-NOTICES#L1-L29, BSD-2-Clause go.mongodb.org/mongo-driver/., https://github.com/mongodb/mongo-go-driver/blob/v1.4.4/THIRD-PARTY-NOTICES#L31-L61, BSD-3-Clause golang.org/x/crypto, https://github.com/golang/crypto/blob/0c34fe9e7dc2/LICENSE, BSD-3-Clause golang.org/x/net, https://github.com/golang/net/blob/6b1517762897/LICENSE, BSD-3-Clause -golang.org/x/oauth2, https://github.com/golang/oauth2/blob/bf48bf16ab8d/LICENSE, BSD-3-Clause -golang.org/x/sys, https://github.com/golang/sys/blob/47abb6519492/LICENSE, BSD-3-Clause +golang.org/x/oauth2, https://github.com/golang/oauth2/blob/0b49973bad19/LICENSE, BSD-3-Clause +golang.org/x/sys, https://github.com/golang/sys/blob/d19ff857e887/LICENSE, BSD-3-Clause golang.org/x/term, https://github.com/golang/term/blob/7de9c90e9dd1/LICENSE, BSD-3-Clause golang.org/x/text, https://github.com/golang/text/blob/v0.3.5/LICENSE, BSD-3-Clause golang.org/x/time, https://github.com/golang/time/blob/3af7569d3a1e/LICENSE, BSD-3-Clause -google.golang.org/genproto, https://github.com/googleapis/go-genproto/blob/86f49bd18e98/LICENSE, Apache-2.0 -google.golang.org/grpc, https://github.com/grpc/grpc-go/blob/v1.34.0/LICENSE, Apache-2.0 +google.golang.org/genproto, https://github.com/googleapis/go-genproto/blob/6486ece9c497/LICENSE, Apache-2.0 +google.golang.org/grpc, https://github.com/grpc/grpc-go/blob/v1.36.0/LICENSE, Apache-2.0 google.golang.org/protobuf, https://github.com/protocolbuffers/protobuf-go/blob/v1.27.1/LICENSE, BSD-3-Clause gopkg.in/inf.v0, https://github.com/go-inf/inf/blob/v0.9.1/LICENSE, BSD-3-Clause -gopkg.in/jcmturner/aescts.v1, https://github.com/jcmturner/aescts/blob/v1.0.1/LICENSE, Apache-2.0 -gopkg.in/jcmturner/dnsutils.v1, https://github.com/jcmturner/dnsutils/blob/v1.0.1/LICENSE, Apache-2.0 -gopkg.in/jcmturner/gokrb5.v5, https://github.com/jcmturner/gokrb5/blob/v5.3.0/LICENSE, Apache-2.0 -gopkg.in/jcmturner/rpc.v0, https://github.com/jcmturner/rpc/blob/v0.0.2/LICENSE, Apache-2.0 gopkg.in/yaml.v2, https://github.com/go-yaml/yaml/blob/v2.4.0/LICENSE, Apache-2.0 / MIT gopkg.in/yaml.v3, https://github.com/go-yaml/yaml/blob/496545a6307b/LICENSE, MIT -k8s.io/api, https://github.com/kubernetes/api/blob/v0.19.6/LICENSE, Apache-2.0 -k8s.io/apimachinery, https://github.com/kubernetes/apimachinery/blob/v0.19.6/LICENSE, Apache-2.0 -k8s.io/client-go, https://github.com/kubernetes/client-go/blob/v0.19.6/LICENSE, Apache-2.0 -k8s.io/klog/v2, https://github.com/kubernetes/klog/blob/v2.5.0/LICENSE, Apache-2.0 -k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/d219536bb9fd/LICENSE, Apache-2.0 -k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/d219536bb9fd/pkg/validation/errors/LICENSE, Apache-2.0 -k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/d219536bb9fd/pkg/validation/spec/LICENSE, Apache-2.0 -k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/d219536bb9fd/pkg/validation/strfmt/LICENSE, Apache-2.0 -k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/d219536bb9fd/pkg/validation/validate/LICENSE, Apache-2.0 +k8s.io/api, https://github.com/kubernetes/api/blob/v0.20.4/LICENSE, Apache-2.0 +k8s.io/apimachinery, https://github.com/kubernetes/apimachinery/blob/v0.21.2/LICENSE, Apache-2.0 +k8s.io/client-go, https://github.com/kubernetes/client-go/blob/v0.20.4/LICENSE, Apache-2.0 +k8s.io/klog/v2, https://github.com/kubernetes/klog/blob/v2.8.0/LICENSE, Apache-2.0 +k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/591a79e4bda7/LICENSE, Apache-2.0 +k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/591a79e4bda7/pkg/validation/errors/LICENSE, Apache-2.0 +k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/591a79e4bda7/pkg/validation/spec/LICENSE, Apache-2.0 +k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/591a79e4bda7/pkg/validation/strfmt/LICENSE, Apache-2.0 +k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/591a79e4bda7/pkg/validation/validate/LICENSE, Apache-2.0 k8s.io/kubernetes, https://github.com/kubernetes/kubernetes/blob/v1.11.1/LICENSE, Apache-2.0 k8s.io/kubernetes, https://github.com/kubernetes/kubernetes/blob/v1.11.1/pkg/credentialprovider/azure/azure_acr_helper.go, MIT k8s.io/kubernetes, https://github.com/kubernetes/kubernetes/blob/v1.11.1/third_party/forked/golang/LICENSE, BSD-3-Clause @@ -113,5 +80,5 @@ k8s.io/kubernetes, https://github.com/kubernetes/kubernetes/blob/v1.11.1/third_p k8s.io/utils, https://github.com/kubernetes/utils/blob/67b214c5f920/LICENSE, Apache-2.0 k8s.io/utils, https://github.com/kubernetes/utils/blob/67b214c5f920/inotify/LICENSE, BSD-3-Clause k8s.io/utils, https://github.com/kubernetes/utils/blob/67b214c5f920/third_party/forked/golang/LICENSE, BSD-3-Clause -sigs.k8s.io/structured-merge-diff/v4, https://github.com/kubernetes-sigs/structured-merge-diff/blob/v4.0.2/LICENSE, Apache-2.0 +sigs.k8s.io/structured-merge-diff/v4, https://github.com/kubernetes-sigs/structured-merge-diff/blob/v4.1.0/LICENSE, Apache-2.0 sigs.k8s.io/yaml, https://github.com/kubernetes-sigs/yaml/blob/v1.2.0/LICENSE, MIT / BSD-3-Clause diff --git a/backend/third_party_licenses/persistence_agent.csv b/backend/third_party_licenses/persistence_agent.csv index a9dbcae0b54..90fee8e4c60 100644 --- a/backend/third_party_licenses/persistence_agent.csv +++ b/backend/third_party_licenses/persistence_agent.csv @@ -1,26 +1,16 @@ # Generated by https://github.com/google/go-licenses/v2. DO NOT EDIT. github.com/kubeflow/pipelines, https://github.com/kubeflow/pipelines/blob/master/LICENSE, Apache-2.0 github.com/kubeflow/pipelines, https://github.com/kubeflow/pipelines/blob/master/backend/src/apiserver/archive/log.go, Apache-2.0 -cloud.google.com/go, https://github.com/googleapis/google-cloud-go/blob/v0.55.0/LICENSE, Apache-2.0 -cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/elf, https://github.com/googleapis/google-cloud-go/blob/v0.55.0/cmd/go-cloud-debug-agent/internal/debug/elf/elf.go#L1-L43, BSD-2-Clause -github.com/Masterminds/goutils, https://github.com/Masterminds/goutils/blob/v1.1.0/LICENSE.txt, Apache-2.0 -github.com/Masterminds/semver, https://github.com/Masterminds/semver/blob/v1.5.0/LICENSE.txt, MIT -github.com/Masterminds/sprig, https://github.com/Masterminds/sprig/blob/v2.22.0/LICENSE.txt, MIT +cloud.google.com/go, https://github.com/googleapis/google-cloud-go/blob/v0.72.0/LICENSE, Apache-2.0 +cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/elf, https://github.com/googleapis/google-cloud-go/blob/v0.72.0/cmd/go-cloud-debug-agent/internal/debug/elf/elf.go#L1-L43, BSD-2-Clause +cloud.google.com/go/third_party/pkgsite, https://github.com/googleapis/google-cloud-go/blob/v0.72.0/third_party/pkgsite/LICENSE, BSD-3-Clause github.com/PuerkitoBio/purell, https://github.com/PuerkitoBio/purell/blob/v1.1.1/LICENSE, BSD-3-Clause github.com/PuerkitoBio/urlesc, https://github.com/PuerkitoBio/urlesc/blob/de5bf2ad4578/LICENSE, BSD-3-Clause -github.com/antonmedv/expr, https://github.com/antonmedv/expr/blob/v1.8.8/LICENSE, MIT github.com/argoproj/argo-workflows/v3, https://github.com/argoproj/argo-workflows/blob/v3.1.14/LICENSE, Apache-2.0 -github.com/argoproj/pkg, https://github.com/argoproj/pkg/blob/v0.10.1/LICENSE, Apache-2.0 github.com/asaskevich/govalidator, https://github.com/asaskevich/govalidator/blob/7a23bdc65eef/LICENSE, MIT -github.com/beorn7/perks, https://github.com/beorn7/perks/blob/v1.0.1/LICENSE, MIT github.com/cenkalti/backoff, https://github.com/cenkalti/backoff/blob/v2.2.1/LICENSE, MIT -github.com/cespare/xxhash/v2, https://github.com/cespare/xxhash/blob/v2.1.1/LICENSE.txt, MIT -github.com/colinmarc/hdfs, https://github.com/colinmarc/hdfs/blob/9746310a4d31/LICENSE.txt, MIT github.com/davecgh/go-spew, https://github.com/davecgh/go-spew/blob/v1.1.1/LICENSE, ISC -github.com/docker/spdystream, https://github.com/docker/spdystream/blob/6480d4af844c/LICENSE, Apache-2.0 -github.com/doublerebel/bellows, https://github.com/doublerebel/bellows/blob/f177d92a03d3/LICENSE, MIT github.com/emicklei/go-restful, https://github.com/emicklei/go-restful/blob/v2.15.0/LICENSE, MIT -github.com/ghodss/yaml, https://github.com/ghodss/yaml/blob/25d852aebe32/LICENSE, MIT / BSD-3-Clause github.com/go-logr/logr, https://github.com/go-logr/logr/blob/v0.4.0/LICENSE, Apache-2.0 github.com/go-openapi/errors, https://github.com/go-openapi/errors/blob/v0.19.9/LICENSE, Apache-2.0 github.com/go-openapi/jsonpointer, https://github.com/go-openapi/jsonpointer/blob/v0.19.5/LICENSE, Apache-2.0 @@ -38,69 +28,48 @@ github.com/google/go-cmp, https://github.com/google/go-cmp/blob/v0.5.5/LICENSE, github.com/google/gofuzz, https://github.com/google/gofuzz/blob/v1.1.0/LICENSE, Apache-2.0 github.com/google/uuid, https://github.com/google/uuid/blob/v1.1.2/LICENSE, BSD-3-Clause github.com/googleapis/gnostic, https://github.com/googleapis/gnostic/blob/v0.5.1/LICENSE, Apache-2.0 -github.com/gorilla/websocket, https://github.com/gorilla/websocket/blob/v1.4.2/LICENSE, BSD-2-Clause -github.com/gorilla/websocket, https://github.com/gorilla/websocket/blob/v1.4.2/examples/autobahn/server.go, MIT github.com/grpc-ecosystem/grpc-gateway, https://github.com/grpc-ecosystem/grpc-gateway/blob/v1.16.0/LICENSE.txt, BSD-3-Clause github.com/grpc-ecosystem/grpc-gateway, https://github.com/grpc-ecosystem/grpc-gateway/blob/v1.16.0/internal/casing/LICENSE.md, BSD-3-Clause github.com/grpc-ecosystem/grpc-gateway, https://github.com/grpc-ecosystem/grpc-gateway/blob/v1.16.0/third_party/googleapis/LICENSE, Apache-2.0 -github.com/hashicorp/go-uuid, https://github.com/hashicorp/go-uuid/blob/v1.0.2/LICENSE, MPL-2.0 github.com/hashicorp/golang-lru, https://github.com/hashicorp/golang-lru/blob/v0.5.4/LICENSE, MPL-2.0 -github.com/huandu/xstrings, https://github.com/huandu/xstrings/blob/v1.3.1/LICENSE, MIT github.com/imdario/mergo, https://github.com/imdario/mergo/blob/v0.3.12/LICENSE, BSD-3-Clause -github.com/jcmturner/gofork, https://github.com/jcmturner/gofork/blob/v1.0.0/LICENSE, BSD-3-Clause github.com/josharian/intern, https://github.com/josharian/intern/blob/v1.0.0/license.md, MIT github.com/json-iterator/go, https://github.com/json-iterator/go/blob/v1.1.10/LICENSE, MIT github.com/lestrrat-go/strftime, https://github.com/lestrrat-go/strftime/blob/v1.0.4/LICENSE, MIT github.com/mailru/easyjson, https://github.com/mailru/easyjson/blob/v0.7.6/LICENSE, MIT github.com/mailru/easyjson, https://github.com/mailru/easyjson/blob/v0.7.6/parser/modulepath.go, BSD-3-Clause -github.com/matttproud/golang_protobuf_extensions, https://github.com/matttproud/golang_protobuf_extensions/blob/c182affec369/LICENSE, Apache-2.0 -github.com/mitchellh/copystructure, https://github.com/mitchellh/copystructure/blob/v1.0.0/LICENSE, MIT github.com/mitchellh/mapstructure, https://github.com/mitchellh/mapstructure/blob/v1.4.1/LICENSE, MIT -github.com/mitchellh/reflectwalk, https://github.com/mitchellh/reflectwalk/blob/v1.0.1/LICENSE, MIT github.com/modern-go/concurrent, https://github.com/modern-go/concurrent/blob/bacd9c7ef1dd/LICENSE, Apache-2.0 github.com/modern-go/reflect2, https://github.com/modern-go/reflect2/blob/v1.0.1/LICENSE, Apache-2.0 -github.com/oliveagle/jsonpath, https://github.com/oliveagle/jsonpath/blob/2e52cf6e6852/LICENSE, MIT github.com/pkg/errors, https://github.com/pkg/errors/blob/v0.9.1/LICENSE, BSD-2-Clause -github.com/prometheus/client_golang, https://github.com/prometheus/client_golang/blob/v1.9.0/LICENSE, Apache-2.0 -github.com/prometheus/client_model, https://github.com/prometheus/client_model/blob/v0.2.0/LICENSE, Apache-2.0 -github.com/prometheus/common, https://github.com/prometheus/common/blob/v0.15.0/LICENSE, Apache-2.0 -github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg, https://github.com/prometheus/common/blob/v0.15.0/internal/bitbucket.org/ww/goautoneg/README.txt, BSD-3-Clause -github.com/prometheus/procfs, https://github.com/prometheus/procfs/blob/v0.2.0/LICENSE, Apache-2.0 -github.com/robfig/cron/v3, https://github.com/robfig/cron/blob/v3.0.1/LICENSE, MIT github.com/sirupsen/logrus, https://github.com/sirupsen/logrus/blob/v1.6.0/LICENSE, MIT github.com/sirupsen/logrus, https://github.com/sirupsen/logrus/blob/v1.6.0/alt_exit.go, MIT github.com/spf13/pflag, https://github.com/spf13/pflag/blob/v1.0.5/LICENSE, BSD-3-Clause -github.com/valyala/bytebufferpool, https://github.com/valyala/bytebufferpool/blob/v1.0.0/LICENSE, MIT -github.com/valyala/fasttemplate, https://github.com/valyala/fasttemplate/blob/v1.1.0/LICENSE, MIT go.mongodb.org/mongo-driver, https://github.com/mongodb/mongo-go-driver/blob/v1.4.4/LICENSE, Apache-2.0 go.mongodb.org/mongo-driver/., https://github.com/mongodb/mongo-go-driver/blob/v1.4.4/THIRD-PARTY-NOTICES#L1-L29, BSD-2-Clause go.mongodb.org/mongo-driver/., https://github.com/mongodb/mongo-go-driver/blob/v1.4.4/THIRD-PARTY-NOTICES#L31-L61, BSD-3-Clause golang.org/x/crypto, https://github.com/golang/crypto/blob/0c34fe9e7dc2/LICENSE, BSD-3-Clause golang.org/x/net, https://github.com/golang/net/blob/6b1517762897/LICENSE, BSD-3-Clause -golang.org/x/oauth2, https://github.com/golang/oauth2/blob/bf48bf16ab8d/LICENSE, BSD-3-Clause -golang.org/x/sys, https://github.com/golang/sys/blob/47abb6519492/LICENSE, BSD-3-Clause +golang.org/x/oauth2, https://github.com/golang/oauth2/blob/0b49973bad19/LICENSE, BSD-3-Clause +golang.org/x/sys, https://github.com/golang/sys/blob/d19ff857e887/LICENSE, BSD-3-Clause golang.org/x/term, https://github.com/golang/term/blob/7de9c90e9dd1/LICENSE, BSD-3-Clause golang.org/x/text, https://github.com/golang/text/blob/v0.3.5/LICENSE, BSD-3-Clause golang.org/x/time, https://github.com/golang/time/blob/3af7569d3a1e/LICENSE, BSD-3-Clause -google.golang.org/genproto, https://github.com/googleapis/go-genproto/blob/86f49bd18e98/LICENSE, Apache-2.0 -google.golang.org/grpc, https://github.com/grpc/grpc-go/blob/v1.34.0/LICENSE, Apache-2.0 +google.golang.org/genproto, https://github.com/googleapis/go-genproto/blob/6486ece9c497/LICENSE, Apache-2.0 +google.golang.org/grpc, https://github.com/grpc/grpc-go/blob/v1.36.0/LICENSE, Apache-2.0 google.golang.org/protobuf, https://github.com/protocolbuffers/protobuf-go/blob/v1.27.1/LICENSE, BSD-3-Clause gopkg.in/inf.v0, https://github.com/go-inf/inf/blob/v0.9.1/LICENSE, BSD-3-Clause -gopkg.in/jcmturner/aescts.v1, https://github.com/jcmturner/aescts/blob/v1.0.1/LICENSE, Apache-2.0 -gopkg.in/jcmturner/dnsutils.v1, https://github.com/jcmturner/dnsutils/blob/v1.0.1/LICENSE, Apache-2.0 -gopkg.in/jcmturner/gokrb5.v5, https://github.com/jcmturner/gokrb5/blob/v5.3.0/LICENSE, Apache-2.0 -gopkg.in/jcmturner/rpc.v0, https://github.com/jcmturner/rpc/blob/v0.0.2/LICENSE, Apache-2.0 gopkg.in/yaml.v2, https://github.com/go-yaml/yaml/blob/v2.4.0/LICENSE, Apache-2.0 / MIT gopkg.in/yaml.v3, https://github.com/go-yaml/yaml/blob/496545a6307b/LICENSE, MIT -k8s.io/api, https://github.com/kubernetes/api/blob/v0.19.6/LICENSE, Apache-2.0 -k8s.io/apimachinery, https://github.com/kubernetes/apimachinery/blob/v0.19.6/LICENSE, Apache-2.0 -k8s.io/client-go, https://github.com/kubernetes/client-go/blob/v0.19.6/LICENSE, Apache-2.0 -k8s.io/klog/v2, https://github.com/kubernetes/klog/blob/v2.5.0/LICENSE, Apache-2.0 -k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/d219536bb9fd/LICENSE, Apache-2.0 -k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/d219536bb9fd/pkg/validation/errors/LICENSE, Apache-2.0 -k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/d219536bb9fd/pkg/validation/spec/LICENSE, Apache-2.0 -k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/d219536bb9fd/pkg/validation/strfmt/LICENSE, Apache-2.0 -k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/d219536bb9fd/pkg/validation/validate/LICENSE, Apache-2.0 +k8s.io/api, https://github.com/kubernetes/api/blob/v0.20.4/LICENSE, Apache-2.0 +k8s.io/apimachinery, https://github.com/kubernetes/apimachinery/blob/v0.21.2/LICENSE, Apache-2.0 +k8s.io/client-go, https://github.com/kubernetes/client-go/blob/v0.20.4/LICENSE, Apache-2.0 +k8s.io/klog/v2, https://github.com/kubernetes/klog/blob/v2.8.0/LICENSE, Apache-2.0 +k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/591a79e4bda7/LICENSE, Apache-2.0 +k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/591a79e4bda7/pkg/validation/errors/LICENSE, Apache-2.0 +k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/591a79e4bda7/pkg/validation/spec/LICENSE, Apache-2.0 +k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/591a79e4bda7/pkg/validation/strfmt/LICENSE, Apache-2.0 +k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/591a79e4bda7/pkg/validation/validate/LICENSE, Apache-2.0 k8s.io/kubernetes, https://github.com/kubernetes/kubernetes/blob/v1.11.1/LICENSE, Apache-2.0 k8s.io/kubernetes, https://github.com/kubernetes/kubernetes/blob/v1.11.1/pkg/credentialprovider/azure/azure_acr_helper.go, MIT k8s.io/kubernetes, https://github.com/kubernetes/kubernetes/blob/v1.11.1/third_party/forked/golang/LICENSE, BSD-3-Clause @@ -111,5 +80,5 @@ k8s.io/kubernetes, https://github.com/kubernetes/kubernetes/blob/v1.11.1/third_p k8s.io/utils, https://github.com/kubernetes/utils/blob/67b214c5f920/LICENSE, Apache-2.0 k8s.io/utils, https://github.com/kubernetes/utils/blob/67b214c5f920/inotify/LICENSE, BSD-3-Clause k8s.io/utils, https://github.com/kubernetes/utils/blob/67b214c5f920/third_party/forked/golang/LICENSE, BSD-3-Clause -sigs.k8s.io/structured-merge-diff/v4, https://github.com/kubernetes-sigs/structured-merge-diff/blob/v4.0.2/LICENSE, Apache-2.0 +sigs.k8s.io/structured-merge-diff/v4, https://github.com/kubernetes-sigs/structured-merge-diff/blob/v4.1.0/LICENSE, Apache-2.0 sigs.k8s.io/yaml, https://github.com/kubernetes-sigs/yaml/blob/v1.2.0/LICENSE, MIT / BSD-3-Clause diff --git a/backend/third_party_licenses/swf.csv b/backend/third_party_licenses/swf.csv index 9a2b34bfbfc..a1bac36a78d 100644 --- a/backend/third_party_licenses/swf.csv +++ b/backend/third_party_licenses/swf.csv @@ -1,8 +1,9 @@ # Generated by https://github.com/google/go-licenses/v2. DO NOT EDIT. github.com/kubeflow/pipelines, https://github.com/kubeflow/pipelines/blob/master/LICENSE, Apache-2.0 github.com/kubeflow/pipelines, https://github.com/kubeflow/pipelines/blob/master/backend/src/apiserver/archive/log.go, Apache-2.0 -cloud.google.com/go, https://github.com/googleapis/google-cloud-go/blob/v0.55.0/LICENSE, Apache-2.0 -cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/elf, https://github.com/googleapis/google-cloud-go/blob/v0.55.0/cmd/go-cloud-debug-agent/internal/debug/elf/elf.go#L1-L43, BSD-2-Clause +cloud.google.com/go, https://github.com/googleapis/google-cloud-go/blob/v0.72.0/LICENSE, Apache-2.0 +cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/elf, https://github.com/googleapis/google-cloud-go/blob/v0.72.0/cmd/go-cloud-debug-agent/internal/debug/elf/elf.go#L1-L43, BSD-2-Clause +cloud.google.com/go/third_party/pkgsite, https://github.com/googleapis/google-cloud-go/blob/v0.72.0/third_party/pkgsite/LICENSE, BSD-3-Clause github.com/Masterminds/goutils, https://github.com/Masterminds/goutils/blob/v1.1.0/LICENSE.txt, Apache-2.0 github.com/Masterminds/semver, https://github.com/Masterminds/semver/blob/v1.5.0/LICENSE.txt, MIT github.com/Masterminds/sprig, https://github.com/Masterminds/sprig/blob/v2.22.0/LICENSE.txt, MIT @@ -12,16 +13,11 @@ github.com/antonmedv/expr, https://github.com/antonmedv/expr/blob/v1.8.8/LICENSE github.com/argoproj/argo-workflows/v3, https://github.com/argoproj/argo-workflows/blob/v3.1.14/LICENSE, Apache-2.0 github.com/argoproj/pkg, https://github.com/argoproj/pkg/blob/v0.10.1/LICENSE, Apache-2.0 github.com/asaskevich/govalidator, https://github.com/asaskevich/govalidator/blob/7a23bdc65eef/LICENSE, MIT -github.com/beorn7/perks, https://github.com/beorn7/perks/blob/v1.0.1/LICENSE, MIT github.com/cenkalti/backoff, https://github.com/cenkalti/backoff/blob/v2.2.1/LICENSE, MIT -github.com/cespare/xxhash/v2, https://github.com/cespare/xxhash/blob/v2.1.1/LICENSE.txt, MIT -github.com/colinmarc/hdfs, https://github.com/colinmarc/hdfs/blob/9746310a4d31/LICENSE.txt, MIT github.com/davecgh/go-spew, https://github.com/davecgh/go-spew/blob/v1.1.1/LICENSE, ISC -github.com/docker/spdystream, https://github.com/docker/spdystream/blob/6480d4af844c/LICENSE, Apache-2.0 github.com/doublerebel/bellows, https://github.com/doublerebel/bellows/blob/f177d92a03d3/LICENSE, MIT github.com/emicklei/go-restful, https://github.com/emicklei/go-restful/blob/v2.15.0/LICENSE, MIT github.com/fsnotify/fsnotify, https://github.com/fsnotify/fsnotify/blob/v1.4.9/LICENSE, BSD-3-Clause -github.com/ghodss/yaml, https://github.com/ghodss/yaml/blob/25d852aebe32/LICENSE, MIT / BSD-3-Clause github.com/go-logr/logr, https://github.com/go-logr/logr/blob/v0.4.0/LICENSE, Apache-2.0 github.com/go-openapi/errors, https://github.com/go-openapi/errors/blob/v0.19.9/LICENSE, Apache-2.0 github.com/go-openapi/jsonpointer, https://github.com/go-openapi/jsonpointer/blob/v0.19.5/LICENSE, Apache-2.0 @@ -45,34 +41,26 @@ github.com/gorilla/websocket, https://github.com/gorilla/websocket/blob/v1.4.2/e github.com/grpc-ecosystem/grpc-gateway, https://github.com/grpc-ecosystem/grpc-gateway/blob/v1.16.0/LICENSE.txt, BSD-3-Clause github.com/grpc-ecosystem/grpc-gateway, https://github.com/grpc-ecosystem/grpc-gateway/blob/v1.16.0/internal/casing/LICENSE.md, BSD-3-Clause github.com/grpc-ecosystem/grpc-gateway, https://github.com/grpc-ecosystem/grpc-gateway/blob/v1.16.0/third_party/googleapis/LICENSE, Apache-2.0 -github.com/hashicorp/go-uuid, https://github.com/hashicorp/go-uuid/blob/v1.0.2/LICENSE, MPL-2.0 github.com/hashicorp/golang-lru, https://github.com/hashicorp/golang-lru/blob/v0.5.4/LICENSE, MPL-2.0 github.com/hashicorp/hcl, https://github.com/hashicorp/hcl/blob/v1.0.0/LICENSE, MPL-2.0 github.com/huandu/xstrings, https://github.com/huandu/xstrings/blob/v1.3.1/LICENSE, MIT github.com/imdario/mergo, https://github.com/imdario/mergo/blob/v0.3.12/LICENSE, BSD-3-Clause -github.com/jcmturner/gofork, https://github.com/jcmturner/gofork/blob/v1.0.0/LICENSE, BSD-3-Clause github.com/josharian/intern, https://github.com/josharian/intern/blob/v1.0.0/license.md, MIT github.com/json-iterator/go, https://github.com/json-iterator/go/blob/v1.1.10/LICENSE, MIT github.com/lestrrat-go/strftime, https://github.com/lestrrat-go/strftime/blob/v1.0.4/LICENSE, MIT github.com/magiconair/properties, https://github.com/magiconair/properties/blob/v1.8.1/LICENSE, BSD-2-Clause github.com/mailru/easyjson, https://github.com/mailru/easyjson/blob/v0.7.6/LICENSE, MIT github.com/mailru/easyjson, https://github.com/mailru/easyjson/blob/v0.7.6/parser/modulepath.go, BSD-3-Clause -github.com/matttproud/golang_protobuf_extensions, https://github.com/matttproud/golang_protobuf_extensions/blob/c182affec369/LICENSE, Apache-2.0 github.com/mitchellh/copystructure, https://github.com/mitchellh/copystructure/blob/v1.0.0/LICENSE, MIT github.com/mitchellh/mapstructure, https://github.com/mitchellh/mapstructure/blob/v1.4.1/LICENSE, MIT github.com/mitchellh/reflectwalk, https://github.com/mitchellh/reflectwalk/blob/v1.0.1/LICENSE, MIT +github.com/moby/spdystream, https://github.com/moby/spdystream/blob/v0.2.0/LICENSE, Apache-2.0 github.com/modern-go/concurrent, https://github.com/modern-go/concurrent/blob/bacd9c7ef1dd/LICENSE, Apache-2.0 github.com/modern-go/reflect2, https://github.com/modern-go/reflect2/blob/v1.0.1/LICENSE, Apache-2.0 github.com/oliveagle/jsonpath, https://github.com/oliveagle/jsonpath/blob/2e52cf6e6852/LICENSE, MIT github.com/pelletier/go-toml, https://github.com/pelletier/go-toml/blob/v1.8.0/LICENSE, MIT github.com/pkg/errors, https://github.com/pkg/errors/blob/v0.9.1/LICENSE, BSD-2-Clause -github.com/prometheus/client_golang, https://github.com/prometheus/client_golang/blob/v1.9.0/LICENSE, Apache-2.0 -github.com/prometheus/client_model, https://github.com/prometheus/client_model/blob/v0.2.0/LICENSE, Apache-2.0 -github.com/prometheus/common, https://github.com/prometheus/common/blob/v0.15.0/LICENSE, Apache-2.0 -github.com/prometheus/common/internal/bitbucket.org/ww/goautoneg, https://github.com/prometheus/common/blob/v0.15.0/internal/bitbucket.org/ww/goautoneg/README.txt, BSD-3-Clause -github.com/prometheus/procfs, https://github.com/prometheus/procfs/blob/v0.2.0/LICENSE, Apache-2.0 github.com/robfig/cron, https://github.com/robfig/cron/blob/v1.2.0/LICENSE, MIT -github.com/robfig/cron/v3, https://github.com/robfig/cron/blob/v3.0.1/LICENSE, MIT github.com/sirupsen/logrus, https://github.com/sirupsen/logrus/blob/v1.6.0/LICENSE, MIT github.com/sirupsen/logrus, https://github.com/sirupsen/logrus/blob/v1.6.0/alt_exit.go, MIT github.com/spf13/afero, https://github.com/spf13/afero/blob/v1.3.2/LICENSE.txt, Apache-2.0 @@ -88,31 +76,27 @@ go.mongodb.org/mongo-driver/., https://github.com/mongodb/mongo-go-driver/blob/v go.mongodb.org/mongo-driver/., https://github.com/mongodb/mongo-go-driver/blob/v1.4.4/THIRD-PARTY-NOTICES#L31-L61, BSD-3-Clause golang.org/x/crypto, https://github.com/golang/crypto/blob/0c34fe9e7dc2/LICENSE, BSD-3-Clause golang.org/x/net, https://github.com/golang/net/blob/6b1517762897/LICENSE, BSD-3-Clause -golang.org/x/oauth2, https://github.com/golang/oauth2/blob/bf48bf16ab8d/LICENSE, BSD-3-Clause -golang.org/x/sys, https://github.com/golang/sys/blob/47abb6519492/LICENSE, BSD-3-Clause +golang.org/x/oauth2, https://github.com/golang/oauth2/blob/0b49973bad19/LICENSE, BSD-3-Clause +golang.org/x/sys, https://github.com/golang/sys/blob/d19ff857e887/LICENSE, BSD-3-Clause golang.org/x/term, https://github.com/golang/term/blob/7de9c90e9dd1/LICENSE, BSD-3-Clause golang.org/x/text, https://github.com/golang/text/blob/v0.3.5/LICENSE, BSD-3-Clause golang.org/x/time, https://github.com/golang/time/blob/3af7569d3a1e/LICENSE, BSD-3-Clause -google.golang.org/genproto, https://github.com/googleapis/go-genproto/blob/86f49bd18e98/LICENSE, Apache-2.0 -google.golang.org/grpc, https://github.com/grpc/grpc-go/blob/v1.34.0/LICENSE, Apache-2.0 +google.golang.org/genproto, https://github.com/googleapis/go-genproto/blob/6486ece9c497/LICENSE, Apache-2.0 +google.golang.org/grpc, https://github.com/grpc/grpc-go/blob/v1.36.0/LICENSE, Apache-2.0 google.golang.org/protobuf, https://github.com/protocolbuffers/protobuf-go/blob/v1.27.1/LICENSE, BSD-3-Clause gopkg.in/inf.v0, https://github.com/go-inf/inf/blob/v0.9.1/LICENSE, BSD-3-Clause gopkg.in/ini.v1, https://github.com/go-ini/ini/blob/v1.57.0/LICENSE, Apache-2.0 -gopkg.in/jcmturner/aescts.v1, https://github.com/jcmturner/aescts/blob/v1.0.1/LICENSE, Apache-2.0 -gopkg.in/jcmturner/dnsutils.v1, https://github.com/jcmturner/dnsutils/blob/v1.0.1/LICENSE, Apache-2.0 -gopkg.in/jcmturner/gokrb5.v5, https://github.com/jcmturner/gokrb5/blob/v5.3.0/LICENSE, Apache-2.0 -gopkg.in/jcmturner/rpc.v0, https://github.com/jcmturner/rpc/blob/v0.0.2/LICENSE, Apache-2.0 gopkg.in/yaml.v2, https://github.com/go-yaml/yaml/blob/v2.4.0/LICENSE, Apache-2.0 / MIT gopkg.in/yaml.v3, https://github.com/go-yaml/yaml/blob/496545a6307b/LICENSE, MIT -k8s.io/api, https://github.com/kubernetes/api/blob/v0.19.6/LICENSE, Apache-2.0 -k8s.io/apimachinery, https://github.com/kubernetes/apimachinery/blob/v0.19.6/LICENSE, Apache-2.0 -k8s.io/client-go, https://github.com/kubernetes/client-go/blob/v0.19.6/LICENSE, Apache-2.0 -k8s.io/klog/v2, https://github.com/kubernetes/klog/blob/v2.5.0/LICENSE, Apache-2.0 -k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/d219536bb9fd/LICENSE, Apache-2.0 -k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/d219536bb9fd/pkg/validation/errors/LICENSE, Apache-2.0 -k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/d219536bb9fd/pkg/validation/spec/LICENSE, Apache-2.0 -k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/d219536bb9fd/pkg/validation/strfmt/LICENSE, Apache-2.0 -k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/d219536bb9fd/pkg/validation/validate/LICENSE, Apache-2.0 +k8s.io/api, https://github.com/kubernetes/api/blob/v0.20.4/LICENSE, Apache-2.0 +k8s.io/apimachinery, https://github.com/kubernetes/apimachinery/blob/v0.21.2/LICENSE, Apache-2.0 +k8s.io/client-go, https://github.com/kubernetes/client-go/blob/v0.20.4/LICENSE, Apache-2.0 +k8s.io/klog/v2, https://github.com/kubernetes/klog/blob/v2.8.0/LICENSE, Apache-2.0 +k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/591a79e4bda7/LICENSE, Apache-2.0 +k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/591a79e4bda7/pkg/validation/errors/LICENSE, Apache-2.0 +k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/591a79e4bda7/pkg/validation/spec/LICENSE, Apache-2.0 +k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/591a79e4bda7/pkg/validation/strfmt/LICENSE, Apache-2.0 +k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/591a79e4bda7/pkg/validation/validate/LICENSE, Apache-2.0 k8s.io/kubernetes, https://github.com/kubernetes/kubernetes/blob/v1.11.1/LICENSE, Apache-2.0 k8s.io/kubernetes, https://github.com/kubernetes/kubernetes/blob/v1.11.1/pkg/credentialprovider/azure/azure_acr_helper.go, MIT k8s.io/kubernetes, https://github.com/kubernetes/kubernetes/blob/v1.11.1/third_party/forked/golang/LICENSE, BSD-3-Clause @@ -123,5 +107,5 @@ k8s.io/kubernetes, https://github.com/kubernetes/kubernetes/blob/v1.11.1/third_p k8s.io/utils, https://github.com/kubernetes/utils/blob/67b214c5f920/LICENSE, Apache-2.0 k8s.io/utils, https://github.com/kubernetes/utils/blob/67b214c5f920/inotify/LICENSE, BSD-3-Clause k8s.io/utils, https://github.com/kubernetes/utils/blob/67b214c5f920/third_party/forked/golang/LICENSE, BSD-3-Clause -sigs.k8s.io/structured-merge-diff/v4, https://github.com/kubernetes-sigs/structured-merge-diff/blob/v4.0.2/LICENSE, Apache-2.0 +sigs.k8s.io/structured-merge-diff/v4, https://github.com/kubernetes-sigs/structured-merge-diff/blob/v4.1.0/LICENSE, Apache-2.0 sigs.k8s.io/yaml, https://github.com/kubernetes-sigs/yaml/blob/v1.2.0/LICENSE, MIT / BSD-3-Clause diff --git a/backend/third_party_licenses/viewer.csv b/backend/third_party_licenses/viewer.csv index ca922b9c2b4..f209cba213f 100644 --- a/backend/third_party_licenses/viewer.csv +++ b/backend/third_party_licenses/viewer.csv @@ -1,8 +1,9 @@ # Generated by https://github.com/google/go-licenses/v2. DO NOT EDIT. github.com/kubeflow/pipelines, https://github.com/kubeflow/pipelines/blob/master/LICENSE, Apache-2.0 github.com/kubeflow/pipelines, https://github.com/kubeflow/pipelines/blob/master/backend/src/apiserver/archive/log.go, Apache-2.0 -cloud.google.com/go, https://github.com/googleapis/google-cloud-go/blob/v0.55.0/LICENSE, Apache-2.0 -cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/elf, https://github.com/googleapis/google-cloud-go/blob/v0.55.0/cmd/go-cloud-debug-agent/internal/debug/elf/elf.go#L1-L43, BSD-2-Clause +cloud.google.com/go, https://github.com/googleapis/google-cloud-go/blob/v0.72.0/LICENSE, Apache-2.0 +cloud.google.com/go/cmd/go-cloud-debug-agent/internal/debug/elf, https://github.com/googleapis/google-cloud-go/blob/v0.72.0/cmd/go-cloud-debug-agent/internal/debug/elf/elf.go#L1-L43, BSD-2-Clause +cloud.google.com/go/third_party/pkgsite, https://github.com/googleapis/google-cloud-go/blob/v0.72.0/third_party/pkgsite/LICENSE, BSD-3-Clause github.com/beorn7/perks, https://github.com/beorn7/perks/blob/v1.0.1/LICENSE, MIT github.com/cespare/xxhash/v2, https://github.com/cespare/xxhash/blob/v2.1.1/LICENSE.txt, MIT github.com/davecgh/go-spew, https://github.com/davecgh/go-spew/blob/v1.1.1/LICENSE, ISC @@ -32,8 +33,8 @@ github.com/prometheus/procfs, https://github.com/prometheus/procfs/blob/v0.2.0/L github.com/spf13/pflag, https://github.com/spf13/pflag/blob/v1.0.5/LICENSE, BSD-3-Clause golang.org/x/crypto, https://github.com/golang/crypto/blob/0c34fe9e7dc2/LICENSE, BSD-3-Clause golang.org/x/net, https://github.com/golang/net/blob/6b1517762897/LICENSE, BSD-3-Clause -golang.org/x/oauth2, https://github.com/golang/oauth2/blob/bf48bf16ab8d/LICENSE, BSD-3-Clause -golang.org/x/sys, https://github.com/golang/sys/blob/47abb6519492/LICENSE, BSD-3-Clause +golang.org/x/oauth2, https://github.com/golang/oauth2/blob/0b49973bad19/LICENSE, BSD-3-Clause +golang.org/x/sys, https://github.com/golang/sys/blob/d19ff857e887/LICENSE, BSD-3-Clause golang.org/x/term, https://github.com/golang/term/blob/7de9c90e9dd1/LICENSE, BSD-3-Clause golang.org/x/text, https://github.com/golang/text/blob/v0.3.5/LICENSE, BSD-3-Clause golang.org/x/time, https://github.com/golang/time/blob/3af7569d3a1e/LICENSE, BSD-3-Clause @@ -42,20 +43,20 @@ google.golang.org/protobuf, https://github.com/protocolbuffers/protobuf-go/blob/ gopkg.in/inf.v0, https://github.com/go-inf/inf/blob/v0.9.1/LICENSE, BSD-3-Clause gopkg.in/yaml.v2, https://github.com/go-yaml/yaml/blob/v2.4.0/LICENSE, Apache-2.0 / MIT gopkg.in/yaml.v3, https://github.com/go-yaml/yaml/blob/496545a6307b/LICENSE, MIT -k8s.io/api, https://github.com/kubernetes/api/blob/v0.19.6/LICENSE, Apache-2.0 +k8s.io/api, https://github.com/kubernetes/api/blob/v0.20.4/LICENSE, Apache-2.0 k8s.io/apiextensions-apiserver, https://github.com/kubernetes/apiextensions-apiserver/blob/v0.19.2/LICENSE, Apache-2.0 -k8s.io/apimachinery, https://github.com/kubernetes/apimachinery/blob/v0.19.6/LICENSE, Apache-2.0 -k8s.io/client-go, https://github.com/kubernetes/client-go/blob/v0.19.6/LICENSE, Apache-2.0 +k8s.io/apimachinery, https://github.com/kubernetes/apimachinery/blob/v0.21.2/LICENSE, Apache-2.0 +k8s.io/client-go, https://github.com/kubernetes/client-go/blob/v0.20.4/LICENSE, Apache-2.0 k8s.io/component-base, https://github.com/kubernetes/component-base/blob/v0.19.2/LICENSE, Apache-2.0 -k8s.io/klog/v2, https://github.com/kubernetes/klog/blob/v2.5.0/LICENSE, Apache-2.0 -k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/d219536bb9fd/LICENSE, Apache-2.0 -k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/d219536bb9fd/pkg/validation/errors/LICENSE, Apache-2.0 -k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/d219536bb9fd/pkg/validation/spec/LICENSE, Apache-2.0 -k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/d219536bb9fd/pkg/validation/strfmt/LICENSE, Apache-2.0 -k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/d219536bb9fd/pkg/validation/validate/LICENSE, Apache-2.0 +k8s.io/klog/v2, https://github.com/kubernetes/klog/blob/v2.8.0/LICENSE, Apache-2.0 +k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/591a79e4bda7/LICENSE, Apache-2.0 +k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/591a79e4bda7/pkg/validation/errors/LICENSE, Apache-2.0 +k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/591a79e4bda7/pkg/validation/spec/LICENSE, Apache-2.0 +k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/591a79e4bda7/pkg/validation/strfmt/LICENSE, Apache-2.0 +k8s.io/kube-openapi, https://github.com/kubernetes/kube-openapi/blob/591a79e4bda7/pkg/validation/validate/LICENSE, Apache-2.0 k8s.io/utils, https://github.com/kubernetes/utils/blob/67b214c5f920/LICENSE, Apache-2.0 k8s.io/utils, https://github.com/kubernetes/utils/blob/67b214c5f920/inotify/LICENSE, BSD-3-Clause k8s.io/utils, https://github.com/kubernetes/utils/blob/67b214c5f920/third_party/forked/golang/LICENSE, BSD-3-Clause sigs.k8s.io/controller-runtime, https://github.com/kubernetes-sigs/controller-runtime/blob/v0.7.0/LICENSE, Apache-2.0 -sigs.k8s.io/structured-merge-diff/v4, https://github.com/kubernetes-sigs/structured-merge-diff/blob/v4.0.2/LICENSE, Apache-2.0 +sigs.k8s.io/structured-merge-diff/v4, https://github.com/kubernetes-sigs/structured-merge-diff/blob/v4.1.0/LICENSE, Apache-2.0 sigs.k8s.io/yaml, https://github.com/kubernetes-sigs/yaml/blob/v1.2.0/LICENSE, MIT / BSD-3-Clause diff --git a/go-licenses.yaml b/go-licenses.yaml index 9d0a8b042dd..dd3127a57f2 100644 --- a/go-licenses.yaml +++ b/go-licenses.yaml @@ -102,7 +102,7 @@ module: # We do not use UI code here. - third_party/swagger-ui/lib - name: cloud.google.com/go - version: v0.55.0 + version: v0.72.0 license: path: LICENSE spdxId: Apache-2.0 @@ -113,6 +113,10 @@ module: spdxId: BSD-2-Clause lineStart: 1 lineEnd: 43 + - path: third_party/pkgsite + license: + path: LICENSE + spdxId: BSD-3-Clause - name: cloud.google.com/go/storage version: v1.12.0 license: diff --git a/go.mod b/go.mod index 69e68931501..4b4021aaa1a 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,6 @@ require ( github.com/VividCortex/mysqlerr v0.0.0-20170204212430-6c6b55f8796f github.com/argoproj/argo-workflows/v3 v3.1.14 github.com/cenkalti/backoff v2.2.1+incompatible - github.com/denisenkom/go-mssqldb v0.0.0-20181014144952-4e0d7dc8888f // indirect github.com/eapache/go-resiliency v1.2.0 github.com/elazarl/goproxy v0.0.0-20181111060418-2ce16c963a8a // indirect github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 // indirect @@ -28,7 +27,8 @@ require ( github.com/jinzhu/gorm v1.9.1 github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a // indirect github.com/jinzhu/now v0.0.0-20181116074157-8ec929ed50c3 // indirect - github.com/kubeflow/pipelines/api v0.0.0-20211013231727-1e2af8379f62 + github.com/kubeflow/pipelines/api v0.0.0-20211026071850-2e3fb5efff56 + github.com/kubeflow/pipelines/v2 v2.0.0-20211026071850-2e3fb5efff56 github.com/lestrrat-go/strftime v1.0.4 github.com/mattn/go-sqlite3 v1.9.0 github.com/minio/minio-go v6.0.14+incompatible @@ -40,14 +40,14 @@ require ( github.com/spf13/viper v1.7.0 github.com/stretchr/testify v1.7.0 golang.org/x/net v0.0.0-20210326060303-6b1517762897 - google.golang.org/genproto v0.0.0-20200806141610-86f49bd18e98 - google.golang.org/grpc v1.34.0 + google.golang.org/genproto v0.0.0-20201203001206-6486ece9c497 + google.golang.org/grpc v1.36.0 google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 google.golang.org/protobuf v1.27.1 honnef.co/go/tools v0.2.0 // indirect - k8s.io/api v0.19.6 - k8s.io/apimachinery v0.19.6 - k8s.io/client-go v0.19.6 + k8s.io/api v0.20.4 + k8s.io/apimachinery v0.21.2 + k8s.io/client-go v0.20.4 k8s.io/code-generator v0.19.6 k8s.io/kubernetes v0.17.9 sigs.k8s.io/controller-runtime v0.7.0 diff --git a/go.sum b/go.sum index 386336ab954..ef61c586c7a 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,8 @@ +bazil.org/fuse v0.0.0-20180421153158-65cc252bf669/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.39.0/go.mod h1:rVLT6fkc8chs9sfPtFc1SBH6em7n+ZoXaG+87tDISts= cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= @@ -9,30 +11,58 @@ cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6T cloud.google.com/go v0.51.0/go.mod h1:hWtGJ6gnXH+KgDv+V0zFGDvpi07n3z8ZNj3T1RW0Gcw= cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= cloud.google.com/go v0.55.0 h1:eoz/lYxKSL4CNAiaUJ0ZfD1J3bfMYbU5B3rwM1C1EIU= cloud.google.com/go v0.55.0/go.mod h1:ZHmoY+/lIMNkN2+fBmuTiqZ4inFhvQad8ft7MT8IV5Y= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.66.0/go.mod h1:dgqGAjKCDxyhGTtC9dAREQGUJpkceNm1yt590Qno0Ko= +cloud.google.com/go v0.72.0 h1:eWRCuwubtDrCJG0oSUMgnsbD4CmPFQF2ei4OFbXvwww= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/firestore v1.4.0/go.mod h1:NjjGEnxCS3CAKYp+vmALu20QzcqasGodQp48WxJGAYc= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/pubsub v1.9.0/go.mod h1:G3o6/kJvEMIEAN5urdkaP4be49WQsjNiykBIto9LFtY= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/storage v1.12.0/go.mod h1:fFLk2dp2oAhDz8QFKwqrjdJvxSp/W2g7nillojlL5Ho= +contrib.go.opencensus.io/exporter/aws v0.0.0-20200617204711-c478e41e60e9/go.mod h1:uu1P0UCM/6RbsMrgPa98ll8ZcHM858i/AD06a9aLRCA= +contrib.go.opencensus.io/exporter/stackdriver v0.13.4/go.mod h1:aXENhDJ1Y4lIg4EUaVTwzvYETVNZk10Pu26tevFKLUc= +contrib.go.opencensus.io/integrations/ocsql v0.1.7/go.mod h1:8DsSdjz3F+APR+0z0WkU1aRorQCFfRxvqjUUPMbF3fE= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/Azure/azure-amqp-common-go/v3 v3.0.0/go.mod h1:SY08giD/XbhTz07tJdpw1SoxQXHPN30+DI3Z04SYqyg= github.com/Azure/azure-amqp-common-go/v3 v3.0.1/go.mod h1:PBIGdzcO1teYoufTKMcGibdKaYZv4avS+O6LNIp8bq0= github.com/Azure/azure-amqp-common-go/v3 v3.1.0/go.mod h1:PBIGdzcO1teYoufTKMcGibdKaYZv4avS+O6LNIp8bq0= +github.com/Azure/azure-event-hubs-go/v3 v3.3.0/go.mod h1:LSZw8Q6j0iylRjGk4g9BPd+FzS35+Eff5gvs+t37iOM= github.com/Azure/azure-event-hubs-go/v3 v3.3.7/go.mod h1:sszMsQpFy8Au2s2NColbnJY8lRVm1koW0XxBJ3rN5TY= github.com/Azure/azure-pipeline-go v0.1.8/go.mod h1:XA1kFWRVhSK+KNFiOhfv83Fv8L9achrP7OxIzeTn1Yg= github.com/Azure/azure-pipeline-go v0.1.9/go.mod h1:XA1kFWRVhSK+KNFiOhfv83Fv8L9achrP7OxIzeTn1Yg= +github.com/Azure/azure-pipeline-go v0.2.3/go.mod h1:x841ezTBIMG6O3lAcl8ATHnsOPVl2bqk7S3ta6S6u4k= github.com/Azure/azure-sdk-for-go v37.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-sdk-for-go v43.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-sdk-for-go v49.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go v51.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go v52.6.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-service-bus-go v0.10.7/go.mod h1:o5z/3lDG1iT/T/G7vgIwIqVDTx9Qa2wndf5OdzSzpF8= github.com/Azure/azure-storage-blob-go v0.6.0/go.mod h1:oGfmITT1V6x//CswqY2gtAHND+xIP64/qL7a5QJix0Y= +github.com/Azure/azure-storage-blob-go v0.13.0/go.mod h1:pA9kNqtjUeQF2zOSu4s//nUdBD+e64lEuc4sVnuOfNs= +github.com/Azure/go-amqp v0.12.6/go.mod h1:qApuH6OFTSKZFmCOxccvAv5rLizBQf4v8pRmG138DPo= github.com/Azure/go-amqp v0.13.0/go.mod h1:qj+o8xPCz9tMSbQ83Vp8boHahuRDl5mkNHyt1xlxUTs= github.com/Azure/go-amqp v0.13.1/go.mod h1:qj+o8xPCz9tMSbQ83Vp8boHahuRDl5mkNHyt1xlxUTs= github.com/Azure/go-amqp v0.13.6/go.mod h1:wbpCKA8tR5MLgRyIu+bb+S6ECdIDdYJ0NlpFE9xsBPI= @@ -41,16 +71,26 @@ github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSW github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= github.com/Azure/go-autorest/autorest v0.9.3/go.mod h1:GsRuLYvwzLjjjRoWEIyMUaYq8GNUx2nRB378IPt/1p0= github.com/Azure/go-autorest/autorest v0.9.6/go.mod h1:/FALq9T/kS7b5J5qsQ+RSTUdAmGFqi0vUdVNNx8q630= +github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= github.com/Azure/go-autorest/autorest v0.11.3/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= +github.com/Azure/go-autorest/autorest v0.11.7/go.mod h1:V6p3pKZx1KKkJubbxnDWrzNhEIfOy/pTGasLqzHIPHs= +github.com/Azure/go-autorest/autorest v0.11.9/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw= +github.com/Azure/go-autorest/autorest v0.11.12/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw= github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= github.com/Azure/go-autorest/autorest/adal v0.8.1/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q= github.com/Azure/go-autorest/autorest/adal v0.8.2/go.mod h1:ZjhuQClTqx435SRJ2iMlOxPYt3d2C/T/7TiQCVZSn3Q= github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= +github.com/Azure/go-autorest/autorest/adal v0.9.2/go.mod h1:/3SMAM86bP6wC9Ev35peQDUeqFZBMH07vvUOmg4z/fE= +github.com/Azure/go-autorest/autorest/adal v0.9.4/go.mod h1:/3SMAM86bP6wC9Ev35peQDUeqFZBMH07vvUOmg4z/fE= +github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= +github.com/Azure/go-autorest/autorest/adal v0.9.6/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= github.com/Azure/go-autorest/autorest/azure/auth v0.4.2/go.mod h1:90gmfKdlmKgfjUpnCEpOJzsUEjrWDSLwHIG73tSXddM= +github.com/Azure/go-autorest/autorest/azure/auth v0.5.3/go.mod h1:4bJZhUhcq8LB20TruwHbAQsmUs2Xh+QR7utuJpLXX3A= github.com/Azure/go-autorest/autorest/azure/cli v0.3.1/go.mod h1:ZG5p860J94/0kI9mNJVoIoLgXcirM2gF5i2kWloofxw= +github.com/Azure/go-autorest/autorest/azure/cli v0.4.2/go.mod h1:7qkJkT+j6b+hIpzMOwPChJhTqS8VbsqqgULzMNRugoM= github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= @@ -62,6 +102,7 @@ github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935 github.com/Azure/go-autorest/autorest/to v0.3.0/go.mod h1:MgwOyqaIuKdG4TL/2ywSsIWKAfJfgHDo8ObuUk3t5sA= github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE= github.com/Azure/go-autorest/autorest/validation v0.2.0/go.mod h1:3EEqHnBxQGHXRYq3HT1WyXAvT7LLY3tl70hw6tQIbjI= +github.com/Azure/go-autorest/autorest/validation v0.3.0/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E= github.com/Azure/go-autorest/autorest/validation v0.3.1/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E= github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= @@ -73,6 +114,7 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= github.com/DataDog/datadog-go v2.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/GoogleCloudPlatform/cloudsql-proxy v1.19.1/go.mod h1:+yYmuKqcBVkgRePGpUhTA9OEg0XsnFE96eZ6nJ2yCQM= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Masterminds/goutils v1.1.0 h1:zukEsf/1JZwCMgHiK3GZftabmxiCw4apj3a28RPBiVg= github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= @@ -126,9 +168,12 @@ github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/ardielle/ardielle-go v1.5.2/go.mod h1:I4hy1n795cUhaVt/ojz83SNVCYIGsAFAONtv2Dr7HUI= github.com/ardielle/ardielle-tools v1.5.4/go.mod h1:oZN+JRMnqGiIhrzkRN9l26Cej9dEx4jeNG6A+AdkShk= +github.com/argoproj/argo-events v1.2.0/go.mod h1:eY+egQNBLXAz/AF4mqgHsMMa4Aur7frHjUfBg+RpX04= github.com/argoproj/argo-events v1.4.0/go.mod h1:wI5A0U3Wj9ZvfPn3ioL18Dz29+7aibtlyU9pS0Ry+bg= +github.com/argoproj/argo-workflows/v3 v3.1.1/go.mod h1:Z8Wc7uDOGw8TRdhqqREHLFE5SAgS0ENqqwaLakv56MU= github.com/argoproj/argo-workflows/v3 v3.1.14 h1:JTcCK2el7sTWfvbDJw+hcZ/1sCa5igPq6AxIodv7egw= github.com/argoproj/argo-workflows/v3 v3.1.14/go.mod h1:AOj9yCLSNPCCxEF/PT+0dMZCDBDWIGX6EL6PPvqTyMc= +github.com/argoproj/pkg v0.8.1/go.mod h1:ra+bQPmbVAoEL+gYSKesuigt4m49i3Qa3mE/xQcjCiA= github.com/argoproj/pkg v0.9.0/go.mod h1:ra+bQPmbVAoEL+gYSKesuigt4m49i3Qa3mE/xQcjCiA= github.com/argoproj/pkg v0.10.1 h1:B7y7IqEFKNaNGg82U0COeVe/V5uj4Dum027yFe5DxRU= github.com/argoproj/pkg v0.10.1/go.mod h1:ra+bQPmbVAoEL+gYSKesuigt4m49i3Qa3mE/xQcjCiA= @@ -147,9 +192,13 @@ github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef h1:46PFijGL github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= github.com/awalterschulze/gographviz v0.0.0-20200901124122-0eecad45bd71/go.mod h1:/ynarkO/43wP/JM2Okn61e8WFMtdbtA8he7GJxW+SFM= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/aws/aws-sdk-go v1.15.27/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= +github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.30.7/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= github.com/aws/aws-sdk-go v1.33.16/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48= +github.com/aws/aws-sdk-go v1.36.1/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc= github.com/beefsack/go-rate v0.0.0-20180408011153-efa7637bb9b6/go.mod h1:6YNgTHLutezwnBvyneBbwvB8C82y3dcoOj5EQJIdGXA= @@ -169,6 +218,7 @@ github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= @@ -184,6 +234,7 @@ github.com/cloudevents/sdk-go/v2 v2.1.0/go.mod h1:3CTrpB4+u7Iaj6fd7E2Xvm5IxMdRoa github.com/cloudfoundry/jibber_jabber v0.0.0-20151120183258-bcc4c8345a21/go.mod h1:po7NpZ/QiTKzBKyrsEAxwnTamCoh8uDk/egRpQ7siIc= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/colinmarc/hdfs v1.1.4-0.20180802165501-48eb8d6c34a9/go.mod h1:0DumPviB681UcSuJErAbDIOx6SIaJWj463TymfZG02I= @@ -213,12 +264,13 @@ github.com/davecgh/go-spew v0.0.0-20161028175848-04cdfd42973b/go.mod h1:J7Y8YcW2 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/denisenkom/go-mssqldb v0.0.0-20181014144952-4e0d7dc8888f h1:WH0w/R4Yoey+04HhFxqZ6VX6I0d7RMyw5aXQ9UTvQPs= -github.com/denisenkom/go-mssqldb v0.0.0-20181014144952-4e0d7dc8888f/go.mod h1:xN/JuLBIz4bjkxNmByTiV1IbhfnYb6oo99phBn4Eqhc= +github.com/denisenkom/go-mssqldb v0.9.0 h1:RSohk2RsiZqLZ0zCjtfn3S4Gp4exhpBWHyQ7D0yGjAk= +github.com/denisenkom/go-mssqldb v0.9.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= github.com/devigned/tab v0.1.1/go.mod h1:XG9mPq0dFghrYvoBF3xdRrJzSTX1b7IQrvaL9mzjeJY= github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= +github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= github.com/dimfeld/httptreemux v5.0.1+incompatible/go.mod h1:rbUlSV+CCpv/SuqUTP/8Bk2O3LyUV436/yaRGkhP6Z0= github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= @@ -254,6 +306,7 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5 h1:Yzb9+7DPaBjB8zlTR87/ElzFsnQfuHnVUVqpZZIcV5Y= github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0= @@ -283,6 +336,8 @@ github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2H github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32 h1:Mn26/9ZMNWSw9C9ERFA1PUxfmGpolnw2v0bKOREu5ew= github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32/go.mod h1:GIjDIg/heH5DOkXY3YJ/wNhfHsQHoXGjl8G8amsYQ1I= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= github.com/gizak/termui/v3 v3.1.0/go.mod h1:bXQEBkJpzxUAKf0+xq9MSWAvWZlE7c+aidmyFlkYTrY= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= @@ -295,6 +350,7 @@ github.com/go-git/go-git/v5 v5.3.0/go.mod h1:xdX4bWJ48aOrdhnl2XqHYstHbbp6+LFS4r4 github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-ini/ini v1.51.1 h1:/QG3cj23k5V8mOl4JnNzUNhc1kr/jzMiNsNuWKcx8gM= github.com/go-ini/ini v1.51.1/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= @@ -402,6 +458,10 @@ github.com/go-openapi/validate v0.19.12/go.mod h1:Rzou8hA/CBw8donlS6WNEUQupNvUZ0 github.com/go-openapi/validate v0.19.15/go.mod h1:tbn/fdOwYHgrhPBzidZfJC2MIVvs9GA7monOmWBbeCI= github.com/go-openapi/validate v0.20.1 h1:QGQ5CvK74E28t3DkegGweKR+auemUi5IdpMc4x3UW6s= github.com/go-openapi/validate v0.20.1/go.mod h1:b60iJT+xNNLfaQJUqLI7946tYiFEOuE9E4k54HpKcJ0= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-python/gpython v0.0.3/go.mod h1:bmk0l57W/7Cs67MMnz4U28SoYyvz5NTMYyJvUqytJhs= github.com/go-redis/redis v6.15.8+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= github.com/go-resty/resty/v2 v2.3.0/go.mod h1:UpN9CgLZNsv4e9XG50UU8xdI0F43UQ4HmxLBDwaroHU= @@ -439,6 +499,9 @@ github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGt github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= github.com/gobwas/glob v0.2.4-0.20181002190808-e7a84e9525fe/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -447,6 +510,8 @@ github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5 github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -459,13 +524,16 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= @@ -487,28 +555,41 @@ github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5a github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-github/v31 v31.0.0/go.mod h1:NQPZol8/1sMoWYGN2yaALIBytu17gAWfhbweiEed3pM= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/go-replayers/grpcreplay v1.0.0/go.mod h1:8Ig2Idjpr6gifRd6pNVggX6TC1Zw6Jx74AKp7QNH2QE= +github.com/google/go-replayers/httpreplay v0.1.2/go.mod h1:YKZViNhiGgqdBlUbI2MwGpq4pXxNmhJLPHQ7cv2b5no= github.com/google/gofuzz v0.0.0-20161122191042-44d81051d367/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200905233945-acf8798be1f7/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/wire v0.4.0/go.mod h1:ngWDr9Qvq3yZA10YrxfyGELY/AFWGVpy9c1LTRi1EoU= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY= @@ -531,12 +612,14 @@ github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB7 github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.0.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.1.0/go.mod h1:f5nM7jw/oeRSadq3xCzHAvxcr8HZnzsqU6ILg/0NiiE= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= @@ -583,11 +666,13 @@ github.com/hashicorp/raft-boltdb v0.0.0-20171010151810-6e5ba93211ea/go.mod h1:pN github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/hokaccha/go-prettyjson v0.0.0-20190818114111-108c894c2c0e/go.mod h1:pFlLw2CfqZiIBOx6BuCeRLCrfxBJipTY0nIOF/VbGcI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huandu/xstrings v1.3.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/huandu/xstrings v1.3.1 h1:4jgBlKK6tLKFvO8u5pmYjG91cqytmDCDvGh7ECVFfFs= github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/iancoleman/strcase v0.1.1/go.mod h1:SK73tn/9oHe+/Y0h39VT4UCxmurVJkR5NA7kMEAOgSE= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= @@ -611,6 +696,7 @@ github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a h1:eeaG9XMUvRBYX github.com/jinzhu/inflection v0.0.0-20180308033659-04140366298a/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v0.0.0-20181116074157-8ec929ed50c3 h1:xvj06l8iSwiWpYgm8MbPp+naBg+pwfqmdXabzqPCn/8= github.com/jinzhu/now v0.0.0-20181116074157-8ec929ed50c3/go.mod h1:oHTiXerJ20+SfYcrdlBO7rzZRJWGwSTQ0iUY2jI6Gfc= +github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= @@ -626,6 +712,7 @@ github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBv github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= @@ -648,7 +735,9 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.9.5/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.9.8/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.10.8/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.8/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.11.9 h1:5OCMOdde1TCT2sookEuVeEZzA8bmRSFV3AwPDZAG8AA= github.com/klauspost/compress v1.11.9/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= @@ -672,20 +761,26 @@ github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/kubeflow/pipelines/api v0.0.0-20211013231727-1e2af8379f62 h1:7teFwqme7fjyWYltBEM38vPQ8PNBhqoaNLG/B7qE4nA= -github.com/kubeflow/pipelines/api v0.0.0-20211013231727-1e2af8379f62/go.mod h1:ItI8RjFTt0RY6X0g6B3VocSaphuE+DNuNTzAY9NF8EY= +github.com/kubeflow/pipelines/api v0.0.0-20211020193552-20f28631517d/go.mod h1:ItI8RjFTt0RY6X0g6B3VocSaphuE+DNuNTzAY9NF8EY= +github.com/kubeflow/pipelines/api v0.0.0-20211026071850-2e3fb5efff56 h1:hzWxrPYGY6MHKkJKjpBFOAgBO1gjQAoM5C583D/wWxQ= +github.com/kubeflow/pipelines/api v0.0.0-20211026071850-2e3fb5efff56/go.mod h1:ItI8RjFTt0RY6X0g6B3VocSaphuE+DNuNTzAY9NF8EY= +github.com/kubeflow/pipelines/v2 v2.0.0-20211026071850-2e3fb5efff56 h1:e2cnrbByKrPQBcRFwy8qzRALSOqbPksgary85Bx0Tqc= +github.com/kubeflow/pipelines/v2 v2.0.0-20211026071850-2e3fb5efff56/go.mod h1:ytz5OLX4hTyYxBkd/ejS4H3ELqGgXAoJNjyPFEqOlE4= github.com/labstack/echo v3.2.1+incompatible/go.mod h1:0INS7j/VjnFxD4E2wkz67b8cVwCLbBmJyDaka6Cmk1s= github.com/labstack/gommon v0.2.7/go.mod h1:/tj9csK2iPSBvn+3NLM9e52usepMtrd5ilFYA+wQNJ4= github.com/lann/builder v0.0.0-20180802200727-47ae307949d0 h1:SOEGU9fKiNWd/HOJuq6+3iTQz8KNCLtVX6idSoTLdUw= github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o= github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 h1:P6pPBnrTSX3DEVR4fDembhRWSsG5rVo6hYhAB/ADZrk= github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc h1:RKf14vYWi2ttpEmkA4aQ3j4u9dStX2t4M8UM6qqNsG8= github.com/lestrrat-go/envload v0.0.0-20180220234015-a3eb8ddeffcc/go.mod h1:kopuH9ugFRkIXf3YoqHKyrJ9YfUFsckUU9S7B+XP+is= github.com/lestrrat-go/strftime v1.0.4 h1:T1Rb9EPkAhgxKqbcMIPguPq8glqXTA1koF8n9BHElA8= github.com/lestrrat-go/strftime v1.0.4/go.mod h1:E1nN3pCbtMSu1yjSVeyuRFVm/U0xoR76fd03sz+Qz4g= github.com/lib/pq v1.3.0 h1:/qkRGz8zljWiDcFvgpwUpwIAPu3r07TDvs3Rws+o/pU= github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.9.0 h1:L8nSXQQzAYByakOFMTwpjRoHsMJklur4Gi59b6VivR8= +github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/lightstep/tracecontext.go v0.0.0-20181129014701-1757c391b1ac/go.mod h1:Frd2bnT3w5FB5q49ENTfVlztJES+1k/7lyWX2+9gq/M= @@ -710,6 +805,7 @@ github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaO github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-ieproxy v0.0.1/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= @@ -753,6 +849,8 @@ github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/mitchellh/reflectwalk v1.0.1 h1:FVzMWA5RllMAKIdUSC8mdWo3XtwoecrH79BY70sEEpE= github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/moby/spdystream v0.2.0 h1:cjW1zVyyoiM0T7b6UoySUFqzXMoqRckQtXwGPiBhOM8= +github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= @@ -980,11 +1078,13 @@ github.com/stripe/stripe-go v70.15.0+incompatible/go.mod h1:A1dQZmO/QypXmsL0T8ax github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tidwall/gjson v1.6.0/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls= +github.com/tidwall/gjson v1.6.8/go.mod h1:zeFuBCIqD4sN/gmqBzZ4j7Jd6UcA2Fc56x7QFsv+8fI= github.com/tidwall/gjson v1.7.5/go.mod h1:5/xDoumyyDNerp2U36lyolv46b3uF/9Bu6OfyQ9GImk= github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E= github.com/tidwall/match v1.0.3/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tidwall/pretty v1.0.1/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/tidwall/pretty v1.0.2/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tidwall/pretty v1.1.0 h1:K3hMW5epkdAVwibsQEfR/7Zj0Qgt4DxtNumTq/VloO8= github.com/tidwall/pretty v1.1.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tidwall/sjson v1.1.1/go.mod h1:yvVuSnpEQv5cYIrO+AT6kw4QVfd5SDZoGIS7/5+fZFs= @@ -993,7 +1093,9 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1 github.com/toqueteos/webbrowser v1.2.0/go.mod h1:XWoZq4cyp9WeUeak7w7LXRUQf1F1ATJMir8RTqb4ayM= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= @@ -1042,12 +1144,15 @@ go.mongodb.org/mongo-driver v1.3.5/go.mod h1:Ual6Gkco7ZGQw8wE1t4tLnvBsf6yVSM60qW go.mongodb.org/mongo-driver v1.4.3/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc= go.mongodb.org/mongo-driver v1.4.4 h1:bsPHfODES+/yx2PCWzUYMH8xj6PVniPI8DQrsJuSXSs= go.mongodb.org/mongo-driver v1.4.4/go.mod h1:WcMNYLx/IlOxLe6JRJiv2uXuCz6zBLndR4SoGjYphSc= +go.opencensus.io v0.15.0/go.mod h1:UffZAU+4sDEINUGP/B7UfBBkq4fqLu9zXAX7ke6CHW0= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= @@ -1066,6 +1171,7 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.15.0 h1:ZZCA22JRF2gQE5FoNmhmrf7jeJJ2uhqDUNRYKm8dvmM= go.uber.org/zap v1.15.0/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= +gocloud.dev v0.22.0/go.mod h1:z3jKIQ0Es9LALVZFQ3wOvwqAsSLq1R5c/2RdmghDucw= golang.org/x/crypto v0.0.0-20180723164146-c126467f60eb/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180910181607-0e37d006457b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= @@ -1076,6 +1182,7 @@ golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190320223903-b7391e95e576/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= @@ -1096,6 +1203,7 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= @@ -1159,11 +1267,14 @@ golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1171,16 +1282,22 @@ golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226101413-39120d07d75e/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210326060303-6b1517762897 h1:KrsHThm5nFk34YtATK1LsThyGhGbGe1olrte/HInHvs= @@ -1192,6 +1309,10 @@ golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201203001011-0b49973bad19 h1:ZD+2Sd/BnevwJp8PSli8WgGAGzb9IZtxBsv1iZMYeEA= +golang.org/x/oauth2 v0.0.0-20201203001011-0b49973bad19/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1241,6 +1362,7 @@ golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1255,19 +1377,31 @@ golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200317113312-5766fd39f98d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200828194041-157a740278f4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210324051608-47abb6519492 h1:Paq34FxTluEPvVyayQqMPgHm+vTOrIifmcYxFBx9TLg= golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210426230700-d19ff857e887 h1:dXfMednGJh/SUUFjTLsWJz3P+TQt9qnR11GgeI3vWKs= +golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1303,6 +1437,7 @@ golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190422233926-fe54fb35175b/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -1318,6 +1453,7 @@ golang.org/x/tools v0.0.0-20190808195139-e713427fea3f/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1338,11 +1474,30 @@ golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200317043434-63da46f3035e/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200616133436-c1934b75d054/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200717024301-6ddee64345a6/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200828161849-5deb26317202/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20200915173823-2db8f0ff891c/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= +golang.org/x/tools v0.0.0-20200918232735-d647fc253266/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201202200335-bef1c476418a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201203202102-a1a1cbeaa516/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= @@ -1358,30 +1513,46 @@ gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6d gonum.org/v1/netlib v0.0.0-20190331212654-76723241ea4e/go.mod h1:kS+toOQn6AQKjmKJ7gzohV1XkqsFehRA2FbsbkopSuQ= google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.5.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.10.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.15.1/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.31.0/go.mod h1:CL+9IBCa2WWU6gRuBWaKqGWLFFwbEUXkfeMkHLQWYWo= +google.golang.org/api v0.32.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190508193815-b515fa19cec8/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= @@ -1395,11 +1566,31 @@ google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvx google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200317114155-1f3552e48f24/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200806141610-86f49bd18e98 h1:LCO0fg4kb6WwkXQXRQQgUYsFeFb5taTX5WAx5O/Vt28= google.golang.org/genproto v0.0.0-20200806141610-86f49bd18e98/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200831141814-d751682dd103/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200914193844-75d14daec038/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200921151605-7abf4a1a14d5/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201203001206-6486ece9c497 h1:jDYzwXmX9tLnuG4sL85HPmE1ruErXOopALp2i/0AHnI= +google.golang.org/genproto v0.0.0-20201203001206-6486ece9c497/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -1414,11 +1605,18 @@ google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.28.1/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0 h1:raiipEjMOIC/TO2AvyTxP25XFdLxNIBwzDh3FM3XztI= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.36.0 h1:o1bcQ6imQMIOpdrO3SWf2z5RV72WbDwdXuK0MDlc8As= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 h1:M1YKkFIboKNieVO5DLUEVzQfGwJD30Nv2jfUgzb5UcE= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/grpc/examples v0.0.0-20201226181154-53788aa5dcb4/go.mod h1:Ly7ZA/ARzg8fnPU9TyZIxoz33sEUuWX7txiqs8lPTgE= @@ -1505,6 +1703,7 @@ honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.2.0 h1:ws8AfbgTX3oIczLPNPCu5166oBg9ST2vNs0rcht+mDE= honnef.co/go/tools v0.2.0/go.mod h1:lPVVZ2BS5TfnjLyizF7o7hv7j9/L+8cZY2hLyjP9cGY= k8s.io/api v0.17.0/go.mod h1:npsyOePkeP0CPwyGfXDHxvypiYMJxBWAMpQxCaJ4ZxI= @@ -1512,6 +1711,8 @@ k8s.io/api v0.17.8/go.mod h1:N++Llhs8kCixMUoCaXXAyMMPbo8dDVnh+IQ36xZV2/0= k8s.io/api v0.19.2/go.mod h1:IQpK0zFQ1xc5iNIQPqzgoOwuFugaYHK4iCknlAQP9nI= k8s.io/api v0.19.6 h1:F3lfwgpKcKms6F1mMqkQXFzXmme8QqHTJBtBkev3TOg= k8s.io/api v0.19.6/go.mod h1:Plxx44Nh4zVblkJrIgxVPgPre1mvng6tXf1Sj3bs0fU= +k8s.io/api v0.20.4 h1:xZjKidCirayzX6tHONRQyTNDVIR55TYVqgATqo6ZULY= +k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ= k8s.io/apiextensions-apiserver v0.17.0/go.mod h1:XiIFUakZywkUl54fVXa7QTEHcqQz9HG55nHd1DCoHj8= k8s.io/apiextensions-apiserver v0.19.2 h1:oG84UwiDsVDu7dlsGQs5GySmQHCzMhknfhFExJMz9tA= k8s.io/apiextensions-apiserver v0.19.2/go.mod h1:EYNjpqIAvNZe+svXVx9j4uBaVhTB4C94HkY3w058qcg= @@ -1520,6 +1721,9 @@ k8s.io/apimachinery v0.17.8/go.mod h1:Lg8zZ5iC/O8UjCqW6DNhcQG2m4TdjF9kwG3891OWbb k8s.io/apimachinery v0.19.2/go.mod h1:DnPGDnARWFvYa3pMHgSxtbZb7gpzzAZ1pTfaUNDVlmA= k8s.io/apimachinery v0.19.6 h1:kBLzSGuDdY1NdSV2uFzI+FwZ9wtkmG+X3ZVcWXSqNgA= k8s.io/apimachinery v0.19.6/go.mod h1:6sRbGRAVY5DOCuZwB5XkqguBqpqLU6q/kOaOdk29z6Q= +k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= +k8s.io/apimachinery v0.21.2 h1:vezUc/BHqWlQDnZ+XkrpXSmnANSLbpnlpwo0Lhk0gpc= +k8s.io/apimachinery v0.21.2/go.mod h1:CdTY8fU/BlvAbJ2z/8kBwimGki5Zp8/fbVuLY8gJumM= k8s.io/apiserver v0.17.0/go.mod h1:ABM+9x/prjINN6iiffRVNCBR2Wk7uY4z+EtEGZD48cg= k8s.io/apiserver v0.19.2/go.mod h1:FreAq0bJ2vtZFj9Ago/X0oNGC51GfubKK/ViOKfVAOA= k8s.io/client-go v0.17.0/go.mod h1:TYgR6EUHs6k45hb6KWjVD6jFZvJV4gHDikv/It0xz+k= @@ -1527,6 +1731,8 @@ k8s.io/client-go v0.17.8/go.mod h1:SJsDS64AAtt9VZyeaQMb4Ck5etCitZ/FwajWdzua5eY= k8s.io/client-go v0.19.2/go.mod h1:S5wPhCqyDNAlzM9CnEdgTGV4OqhsW3jGO1UM1epwfJA= k8s.io/client-go v0.19.6 h1:vtPb33nP8DBMW+/CyuJ8fiie36c3CM1Ts6L4Tsr+PtU= k8s.io/client-go v0.19.6/go.mod h1:gEiS+efRlXYUEQ9Oz4lmNXlxAl5JZ8y2zbTDGhvXXnk= +k8s.io/client-go v0.20.4 h1:85crgh1IotNkLpKYKZHVNI1JT86nr/iDCvq2iWKsql4= +k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k= k8s.io/code-generator v0.17.0/go.mod h1:DVmfPQgxQENqDIzVR2ddLXMH34qeszkKSdH/N+s+38s= k8s.io/code-generator v0.19.2/go.mod h1:moqLn7w0t9cMs4+5CQyxnfA/HV8MF6aAVENF+WZZhgk= k8s.io/code-generator v0.19.6 h1:N7PlZyX25j5Jl9oIBphWN2qp1AKZOwXdDVfj2Z0V0p8= @@ -1547,13 +1753,18 @@ k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= +k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= k8s.io/klog/v2 v2.5.0 h1:8mOnjf1RmUPW6KRqQCfYSZq/K20Unmp3IhuZUhxl8KI= k8s.io/klog/v2 v2.5.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= +k8s.io/klog/v2 v2.8.0 h1:Q3gmuM9hKEjefWFFYF0Mat+YyFJvsUyYuwyNNJ5C9Ts= +k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E= k8s.io/kube-openapi v0.0.0-20200410145947-bcb3869e6f29/go.mod h1:F+5wygcW0wmRTnM3cOgIqGivxkwSWIWT5YdsDbeAOaU= k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o= k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd h1:sOHNzJIkytDF6qadMNKhhDRpc6ODik8lVC6nOur7B2c= k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= +k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7 h1:vEx13qjvaZ4yfObSSXW7BrMc/KQBBT/Jyee8XtLf4x0= +k8s.io/kube-openapi v0.0.0-20210305001622-591a79e4bda7/go.mod h1:wXW5VT87nVfh/iLV8FpR2uDvrFyomxbtb1KivDbvPTE= k8s.io/kubernetes v1.11.1 h1:wHOPX+teuYaSlUWfL/b24jMH0n7HECbj4Xt8i7kSZIw= k8s.io/kubernetes v1.11.1/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= @@ -1567,6 +1778,7 @@ modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03 modernc.org/strutil v1.0.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs= modernc.org/xc v1.0.0/go.mod h1:mRNCo0bvLjGhHO9WsyuKVU4q0ceiDDDoEeWDJHrNx8I= moul.io/http2curl v1.0.1-0.20190925090545-5cd742060b0e/go.mod h1:nejbQVfXh96n9dSF6cH3Jsk/QI1Z2oEL7sSI2ifXFNA= +nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= @@ -1581,6 +1793,8 @@ sigs.k8s.io/structured-merge-diff/v2 v2.0.1/go.mod h1:Wb7vfKAodbKgf6tn1Kl0VvGj7m sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/structured-merge-diff/v4 v4.0.2 h1:YHQV7Dajm86OuqnIR6zAelnDWBRjo+YhYV9PmGrh1s8= sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= +sigs.k8s.io/structured-merge-diff/v4 v4.1.0 h1:C4r9BgJ98vrKnnVCjwCSXcWjWe0NKcUQkmzDXZXGwH8= +sigs.k8s.io/structured-merge-diff/v4 v4.1.0/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= sigs.k8s.io/yaml v1.2.0 h1:kr/MCeFWJWTwyaHoR9c8EjH9OumOmoF9YGiZd7lFm/Q= sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc=