diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json index 3f1d76264bff..e129d92e9e97 100644 --- a/api/openapi-spec/swagger.json +++ b/api/openapi-spec/swagger.json @@ -2497,6 +2497,11 @@ "in": "path", "required": true }, + { + "type": "string", + "name": "namePattern", + "in": "query" + }, { "type": "string", "description": "A selector to restrict the list of returned objects by their labels.\nDefaults to everything.\n+optional.", diff --git a/pkg/apiclient/workflowtemplate/workflow-template.pb.go b/pkg/apiclient/workflowtemplate/workflow-template.pb.go index 6440d96b66d0..42f2bcfc43d6 100644 --- a/pkg/apiclient/workflowtemplate/workflow-template.pb.go +++ b/pkg/apiclient/workflowtemplate/workflow-template.pb.go @@ -161,7 +161,8 @@ func (m *WorkflowTemplateGetRequest) GetGetOptions() *v1.GetOptions { type WorkflowTemplateListRequest struct { Namespace string `protobuf:"bytes,1,opt,name=namespace,proto3" json:"namespace,omitempty"` - ListOptions *v1.ListOptions `protobuf:"bytes,2,opt,name=listOptions,proto3" json:"listOptions,omitempty"` + NamePattern string `protobuf:"bytes,2,opt,name=namePattern,proto3" json:"namePattern,omitempty"` + ListOptions *v1.ListOptions `protobuf:"bytes,3,opt,name=listOptions,proto3" json:"listOptions,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -207,6 +208,13 @@ func (m *WorkflowTemplateListRequest) GetNamespace() string { return "" } +func (m *WorkflowTemplateListRequest) GetNamePattern() string { + if m != nil { + return m.NamePattern + } + return "" +} + func (m *WorkflowTemplateListRequest) GetListOptions() *v1.ListOptions { if m != nil { return m.ListOptions @@ -459,51 +467,51 @@ func init() { } var fileDescriptor_215375a0ab97a62a = []byte{ - // 689 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x56, 0x4f, 0x4f, 0x14, 0x3f, - 0x18, 0x4e, 0x97, 0x5f, 0x7e, 0x91, 0x12, 0x12, 0x53, 0x75, 0xdd, 0x8c, 0xb8, 0x21, 0x73, 0x30, - 0x04, 0xdc, 0x96, 0x05, 0x25, 0x84, 0x9b, 0x40, 0xc2, 0x05, 0x83, 0x19, 0xfc, 0x13, 0xbc, 0x98, - 0x32, 0xd4, 0x61, 0xdc, 0xd9, 0x76, 0x9c, 0x96, 0x21, 0xc6, 0x70, 0xf1, 0x60, 0x3c, 0x9a, 0xf8, - 0x05, 0xfc, 0x00, 0x9e, 0xfc, 0x0e, 0x26, 0x9e, 0x0c, 0xc6, 0x83, 0x57, 0x43, 0xfc, 0x02, 0x7e, - 0x03, 0x33, 0x9d, 0xff, 0xb3, 0x20, 0x03, 0x71, 0x4f, 0xde, 0x9a, 0x6e, 0xdf, 0xf7, 0x7d, 0x9e, - 0xa7, 0xcf, 0x3e, 0x53, 0xb8, 0xe0, 0xf7, 0x1c, 0x42, 0x7d, 0xd7, 0xf6, 0x5c, 0xc6, 0x15, 0xd9, - 0x17, 0x41, 0xef, 0xa9, 0x27, 0xf6, 0x15, 0xeb, 0xfb, 0x1e, 0x55, 0x2c, 0xdb, 0xe8, 0xa4, 0x3b, - 0xd8, 0x0f, 0x84, 0x12, 0xe8, 0x62, 0xf5, 0xa4, 0x31, 0xe1, 0x08, 0xe1, 0x78, 0x2c, 0x6a, 0x46, - 0x28, 0xe7, 0x42, 0x51, 0xe5, 0x0a, 0x2e, 0xe3, 0xf3, 0xc6, 0xad, 0xde, 0xa2, 0xc4, 0xae, 0x88, - 0x7e, 0xed, 0x53, 0x7b, 0xd7, 0xe5, 0x2c, 0x78, 0x41, 0x92, 0xd9, 0x92, 0xf4, 0x99, 0xa2, 0x24, - 0xec, 0x12, 0x87, 0x71, 0x16, 0x50, 0xc5, 0x76, 0x92, 0xaa, 0xbb, 0x8e, 0xab, 0x76, 0xf7, 0xb6, - 0xb1, 0x2d, 0xfa, 0x84, 0x06, 0x8e, 0xf0, 0x03, 0xf1, 0x4c, 0x2f, 0x3a, 0xe9, 0x78, 0x99, 0x37, - 0x49, 0xb7, 0x48, 0xd8, 0xa5, 0x9e, 0xbf, 0x4b, 0x07, 0xda, 0x99, 0x6f, 0x1a, 0xf0, 0xfa, 0xa3, - 0xe4, 0xd4, 0xfd, 0x04, 0xf7, 0x4a, 0xc0, 0xa8, 0x62, 0x16, 0x7b, 0xbe, 0xc7, 0xa4, 0x42, 0x13, - 0x70, 0x94, 0xd3, 0x3e, 0x93, 0x3e, 0xb5, 0x59, 0x0b, 0x4c, 0x82, 0xa9, 0x51, 0x2b, 0xdf, 0x40, - 0x1c, 0x5e, 0x48, 0xe9, 0xb6, 0x1a, 0x93, 0x60, 0x6a, 0x6c, 0xce, 0xc2, 0x39, 0x42, 0x9c, 0x22, - 0xd4, 0x8b, 0x27, 0x19, 0x42, 0x1c, 0xce, 0x63, 0xbf, 0xe7, 0xe0, 0x08, 0x24, 0x4e, 0x77, 0x71, - 0x0a, 0x12, 0x57, 0x01, 0x59, 0xd9, 0x0c, 0xb4, 0x05, 0xc7, 0x6d, 0x0d, 0x6f, 0xc3, 0xd7, 0x5a, - 0xb6, 0x46, 0xf4, 0xd0, 0x79, 0x1c, 0x8b, 0x89, 0x8b, 0x62, 0xe6, 0x23, 0x22, 0x31, 0x71, 0xd8, - 0xc5, 0x2b, 0xc5, 0x52, 0xab, 0xdc, 0xc9, 0x7c, 0x0f, 0xa0, 0x51, 0x9d, 0xbc, 0xc6, 0x54, 0xaa, - 0x03, 0x82, 0xff, 0x45, 0xb4, 0x13, 0x09, 0xf4, 0xba, 0xac, 0x4d, 0xa3, 0xaa, 0xcd, 0x3d, 0x08, - 0x1d, 0xa6, 0xca, 0x40, 0x67, 0xeb, 0x01, 0x5d, 0xcb, 0xea, 0xac, 0x42, 0x0f, 0xf3, 0x2d, 0x80, - 0xd7, 0xaa, 0x10, 0xd7, 0x5d, 0xa9, 0xea, 0xdd, 0xd5, 0x26, 0x1c, 0xf3, 0x5c, 0x99, 0x01, 0x8a, - 0xaf, 0xab, 0x5b, 0x0f, 0xd0, 0x7a, 0x5e, 0x68, 0x15, 0xbb, 0x98, 0x9f, 0xc0, 0xa0, 0x81, 0x1e, - 0xf8, 0x3b, 0x05, 0x03, 0x35, 0x8b, 0xc2, 0x2d, 0x37, 0x5a, 0xa0, 0x96, 0x78, 0x45, 0x63, 0x8d, - 0x0c, 0xdf, 0x58, 0xe6, 0x87, 0x63, 0x78, 0xac, 0x32, 0x8f, 0xe5, 0x3c, 0xce, 0x6e, 0x80, 0x2d, - 0x38, 0xbe, 0xa3, 0x5b, 0x9c, 0xcb, 0xac, 0xab, 0xc5, 0x52, 0xab, 0xdc, 0xc9, 0x9c, 0x84, 0xed, - 0x93, 0xd0, 0x4a, 0x5f, 0x70, 0xc9, 0xcc, 0xd7, 0x8d, 0xe3, 0xbc, 0xc2, 0xd5, 0xbf, 0xf6, 0xbf, - 0x9e, 0xfb, 0x35, 0x0a, 0xaf, 0x56, 0x27, 0x6f, 0xb2, 0x20, 0x74, 0x6d, 0x86, 0x0e, 0x01, 0x6c, - 0xc6, 0xc5, 0xd5, 0x13, 0x88, 0xe0, 0x6a, 0x9e, 0xe3, 0x3f, 0x06, 0xa5, 0x31, 0x04, 0x81, 0xcc, - 0xee, 0xab, 0x6f, 0x3f, 0xdf, 0x35, 0x66, 0xcc, 0x1b, 0xfa, 0x1b, 0x12, 0x76, 0x07, 0x3f, 0x3e, - 0x92, 0xbc, 0xcc, 0x6e, 0xed, 0x60, 0x09, 0x4c, 0xa3, 0x2f, 0x00, 0x5e, 0x5a, 0x63, 0x6a, 0x80, - 0xcf, 0xcd, 0xd3, 0xf9, 0xe4, 0x69, 0x37, 0x14, 0x32, 0xb7, 0x35, 0x19, 0x82, 0x3a, 0xf5, 0xc8, - 0xc4, 0xeb, 0x83, 0x88, 0xd0, 0x95, 0x28, 0x7e, 0xaa, 0xfd, 0x24, 0xea, 0x9c, 0x4e, 0xa9, 0x90, - 0x8e, 0xc6, 0xc3, 0xbf, 0xcf, 0x29, 0x6a, 0x6f, 0x62, 0xcd, 0x6b, 0x0a, 0xd5, 0xbc, 0x24, 0xf4, - 0x1d, 0xc0, 0x66, 0x1c, 0x91, 0xe7, 0x31, 0x5d, 0x29, 0x5c, 0x87, 0x72, 0x4f, 0x8b, 0x9a, 0xcf, - 0x9c, 0x71, 0xb6, 0x7b, 0x8a, 0xbc, 0xf7, 0x11, 0xc0, 0x66, 0x1c, 0x43, 0xe7, 0x61, 0x56, 0x8a, - 0x5b, 0x63, 0xb6, 0x7e, 0x41, 0x92, 0x78, 0x89, 0xbf, 0xa6, 0xcf, 0xe8, 0xaf, 0xaf, 0x00, 0x5e, - 0x8e, 0x82, 0x71, 0x00, 0x72, 0x2d, 0x7b, 0xf1, 0xa1, 0xfe, 0x65, 0x16, 0x34, 0xa5, 0x59, 0x73, - 0xa6, 0x26, 0x25, 0xcf, 0xe5, 0x6a, 0x09, 0x4c, 0x2f, 0x6f, 0x7c, 0x3e, 0x6a, 0x83, 0xc3, 0xa3, - 0x36, 0xf8, 0x71, 0xd4, 0x06, 0x8f, 0xef, 0xd4, 0x7f, 0x33, 0x9e, 0xf0, 0xe8, 0xdd, 0xfe, 0x5f, - 0x3f, 0x17, 0xe7, 0x7f, 0x07, 0x00, 0x00, 0xff, 0xff, 0xc2, 0x65, 0x92, 0x47, 0x1d, 0x0b, 0x00, - 0x00, + // 700 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x56, 0xcf, 0x4e, 0x13, 0x41, + 0x1c, 0xce, 0x14, 0x63, 0x64, 0x08, 0x89, 0x19, 0xb5, 0x36, 0x2b, 0x36, 0xcd, 0x1e, 0x0c, 0x01, + 0x3b, 0x43, 0x41, 0x09, 0xe1, 0x26, 0x90, 0x70, 0xc1, 0x40, 0x16, 0xff, 0x04, 0x2f, 0x66, 0x28, + 0x3f, 0x97, 0xb5, 0xdb, 0x99, 0x75, 0x67, 0x28, 0x31, 0x86, 0x8b, 0x07, 0xe3, 0xdd, 0x17, 0xf0, + 0x01, 0x3c, 0xf1, 0x0e, 0x26, 0x9e, 0x0c, 0xc6, 0x83, 0x57, 0x43, 0x7c, 0x01, 0xdf, 0xc0, 0xec, + 0x74, 0xb7, 0xbb, 0xdd, 0x82, 0x2c, 0xc4, 0x9e, 0xbc, 0x4d, 0xa7, 0xf3, 0xfb, 0xfd, 0xbe, 0xef, + 0x9b, 0x6f, 0xbf, 0x5d, 0x3c, 0x1f, 0xb4, 0x5c, 0xc6, 0x03, 0xaf, 0xe9, 0x7b, 0x20, 0x34, 0xdb, + 0x97, 0x61, 0xeb, 0x85, 0x2f, 0xf7, 0x35, 0xb4, 0x03, 0x9f, 0x6b, 0xe8, 0x6d, 0xd4, 0x93, 0x1d, + 0x1a, 0x84, 0x52, 0x4b, 0x72, 0x35, 0x7f, 0xd2, 0x9a, 0x70, 0xa5, 0x74, 0x7d, 0x88, 0x9a, 0x31, + 0x2e, 0x84, 0xd4, 0x5c, 0x7b, 0x52, 0xa8, 0xee, 0x79, 0xeb, 0x5e, 0x6b, 0x41, 0x51, 0x4f, 0x46, + 0xff, 0xb6, 0x79, 0x73, 0xd7, 0x13, 0x10, 0xbe, 0x66, 0xf1, 0x6c, 0xc5, 0xda, 0xa0, 0x39, 0xeb, + 0x34, 0x98, 0x0b, 0x02, 0x42, 0xae, 0x61, 0x27, 0xae, 0x7a, 0xe8, 0x7a, 0x7a, 0x77, 0x6f, 0x9b, + 0x36, 0x65, 0x9b, 0xf1, 0xd0, 0x95, 0x41, 0x28, 0x5f, 0x9a, 0x45, 0x3d, 0x19, 0xaf, 0xd2, 0x26, + 0xc9, 0x16, 0xeb, 0x34, 0xb8, 0x1f, 0xec, 0xf2, 0x81, 0x76, 0xf6, 0xfb, 0x12, 0xbe, 0xfd, 0x34, + 0x3e, 0xf5, 0x28, 0xc6, 0xbd, 0x1c, 0x02, 0xd7, 0xe0, 0xc0, 0xab, 0x3d, 0x50, 0x9a, 0x4c, 0xe0, + 0x51, 0xc1, 0xdb, 0xa0, 0x02, 0xde, 0x84, 0x0a, 0xaa, 0xa1, 0xc9, 0x51, 0x27, 0xdd, 0x20, 0x02, + 0x5f, 0x49, 0xe8, 0x56, 0x4a, 0x35, 0x34, 0x39, 0x36, 0xeb, 0xd0, 0x14, 0x21, 0x4d, 0x10, 0x9a, + 0xc5, 0xf3, 0x1e, 0x42, 0xda, 0x99, 0xa3, 0x41, 0xcb, 0xa5, 0x11, 0x48, 0x9a, 0xec, 0xd2, 0x04, + 0x24, 0xcd, 0x03, 0x72, 0x7a, 0x33, 0xc8, 0x16, 0x1e, 0x6f, 0x1a, 0x78, 0xeb, 0x81, 0xd1, 0xb2, + 0x32, 0x62, 0x86, 0xce, 0xd1, 0xae, 0x98, 0x34, 0x2b, 0x66, 0x3a, 0x22, 0x12, 0x93, 0x76, 0x1a, + 0x74, 0x39, 0x5b, 0xea, 0xf4, 0x77, 0xb2, 0x3f, 0x22, 0x6c, 0xe5, 0x27, 0xaf, 0x82, 0x4e, 0x74, + 0x20, 0xf8, 0x52, 0x44, 0x3b, 0x96, 0xc0, 0xac, 0xfb, 0xb5, 0x29, 0xe5, 0xb5, 0xd9, 0xc0, 0xd8, + 0x05, 0xdd, 0x0f, 0x74, 0xa6, 0x18, 0xd0, 0xd5, 0x5e, 0x9d, 0x93, 0xe9, 0x61, 0x1f, 0x22, 0x7c, + 0x2b, 0x0f, 0x71, 0xcd, 0x53, 0xba, 0xd8, 0x5d, 0xd5, 0xf0, 0x58, 0xf4, 0x63, 0x83, 0x6b, 0x0d, + 0xa1, 0x88, 0xf1, 0x66, 0xb7, 0xc8, 0x26, 0x1e, 0xf3, 0x3d, 0x95, 0x83, 0xdc, 0x28, 0x06, 0x79, + 0x2d, 0x2d, 0x74, 0xb2, 0x5d, 0xec, 0xcf, 0x68, 0xd0, 0x62, 0x8f, 0x83, 0x9d, 0x8c, 0xc5, 0xca, + 0x59, 0x69, 0x97, 0x4a, 0x15, 0x54, 0x48, 0xde, 0xac, 0xf5, 0x46, 0x86, 0x6f, 0x3d, 0xfb, 0xd3, + 0x09, 0x3c, 0x56, 0xc0, 0x87, 0x94, 0xc7, 0xf9, 0x2d, 0xb2, 0x85, 0xc7, 0x77, 0x4c, 0x8b, 0x0b, + 0xd9, 0x79, 0x25, 0x5b, 0xea, 0xf4, 0x77, 0xb2, 0x6b, 0xb8, 0x7a, 0x1a, 0x5a, 0x15, 0x48, 0xa1, + 0xc0, 0x7e, 0x57, 0x3a, 0xc9, 0x4d, 0x42, 0xff, 0x6f, 0x4f, 0xfe, 0xec, 0xef, 0x51, 0x7c, 0x33, + 0x3f, 0x79, 0x13, 0xc2, 0x8e, 0xd7, 0x04, 0x72, 0x84, 0x70, 0xb9, 0x5b, 0x9c, 0x3f, 0x41, 0x18, + 0xcd, 0x27, 0x3e, 0xfd, 0x6b, 0x94, 0x5a, 0x43, 0x10, 0xc8, 0x6e, 0xbc, 0xfd, 0xfe, 0xeb, 0x43, + 0x69, 0xda, 0xbe, 0x63, 0xde, 0x32, 0x9d, 0xc6, 0xe0, 0xeb, 0x49, 0xb1, 0x37, 0xbd, 0x5b, 0x3b, + 0x58, 0x44, 0x53, 0xe4, 0x2b, 0xc2, 0xd7, 0x56, 0x41, 0x0f, 0xf0, 0xb9, 0x7b, 0x36, 0x9f, 0x34, + 0x0f, 0x87, 0x42, 0xe6, 0xbe, 0x21, 0xc3, 0x48, 0xbd, 0x18, 0x99, 0xee, 0xfa, 0x20, 0x22, 0x74, + 0x23, 0x8a, 0x9f, 0x7c, 0x3f, 0x45, 0xea, 0x67, 0x53, 0xca, 0xe4, 0xa7, 0xf5, 0xe4, 0xdf, 0x73, + 0x8a, 0xda, 0xdb, 0xd4, 0xf0, 0x9a, 0x24, 0x05, 0x2f, 0x89, 0xfc, 0x40, 0xb8, 0xdc, 0x8d, 0xc8, + 0x8b, 0x98, 0xae, 0x2f, 0x5c, 0x87, 0x72, 0x4f, 0x0b, 0x86, 0xcf, 0xac, 0x75, 0xbe, 0x7b, 0x8a, + 0xbc, 0x77, 0x88, 0x70, 0xb9, 0x1b, 0x43, 0x17, 0x61, 0xd6, 0x17, 0xb7, 0xd6, 0x4c, 0xf1, 0x82, + 0x38, 0xf1, 0x62, 0x7f, 0x4d, 0x9d, 0xd3, 0x5f, 0xdf, 0x10, 0xbe, 0x1e, 0x05, 0xe3, 0x00, 0xe4, + 0x42, 0xf6, 0x12, 0x43, 0x7d, 0x64, 0xe6, 0x0d, 0xa5, 0x19, 0x7b, 0xba, 0x20, 0x25, 0xdf, 0x13, + 0x7a, 0x11, 0x4d, 0x2d, 0xad, 0x7f, 0x39, 0xae, 0xa2, 0xa3, 0xe3, 0x2a, 0xfa, 0x79, 0x5c, 0x45, + 0xcf, 0x1e, 0x14, 0xff, 0xaa, 0x3c, 0xe5, 0xb3, 0x78, 0xfb, 0xb2, 0xf9, 0xa0, 0x9c, 0xfb, 0x13, + 0x00, 0x00, 0xff, 0xff, 0xa4, 0xd4, 0xed, 0x3d, 0x3f, 0x0b, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -911,6 +919,13 @@ func (m *WorkflowTemplateListRequest) MarshalToSizedBuffer(dAtA []byte) (int, er i = encodeVarintWorkflowTemplate(dAtA, i, uint64(size)) } i-- + dAtA[i] = 0x1a + } + if len(m.NamePattern) > 0 { + i -= len(m.NamePattern) + copy(dAtA[i:], m.NamePattern) + i = encodeVarintWorkflowTemplate(dAtA, i, uint64(len(m.NamePattern))) + i-- dAtA[i] = 0x12 } if len(m.Namespace) > 0 { @@ -1183,6 +1198,10 @@ func (m *WorkflowTemplateListRequest) Size() (n int) { if l > 0 { n += 1 + l + sovWorkflowTemplate(uint64(l)) } + l = len(m.NamePattern) + if l > 0 { + n += 1 + l + sovWorkflowTemplate(uint64(l)) + } if m.ListOptions != nil { l = m.ListOptions.Size() n += 1 + l + sovWorkflowTemplate(uint64(l)) @@ -1651,6 +1670,38 @@ func (m *WorkflowTemplateListRequest) Unmarshal(dAtA []byte) error { m.Namespace = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NamePattern", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWorkflowTemplate + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthWorkflowTemplate + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthWorkflowTemplate + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.NamePattern = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ListOptions", wireType) } diff --git a/pkg/apiclient/workflowtemplate/workflow-template.proto b/pkg/apiclient/workflowtemplate/workflow-template.proto index f8301303f2ff..1050546cd446 100644 --- a/pkg/apiclient/workflowtemplate/workflow-template.proto +++ b/pkg/apiclient/workflowtemplate/workflow-template.proto @@ -24,7 +24,8 @@ message WorkflowTemplateGetRequest { message WorkflowTemplateListRequest { string namespace = 1; - k8s.io.apimachinery.pkg.apis.meta.v1.ListOptions listOptions = 2; + string namePattern = 2; + k8s.io.apimachinery.pkg.apis.meta.v1.ListOptions listOptions = 3; } message WorkflowTemplateUpdateRequest { diff --git a/sdks/java/client/docs/WorkflowTemplateServiceApi.md b/sdks/java/client/docs/WorkflowTemplateServiceApi.md index e7e12328d57b..e9b1d9611bed 100644 --- a/sdks/java/client/docs/WorkflowTemplateServiceApi.md +++ b/sdks/java/client/docs/WorkflowTemplateServiceApi.md @@ -308,7 +308,7 @@ Name | Type | Description | Notes # **workflowTemplateServiceListWorkflowTemplates** -> IoArgoprojWorkflowV1alpha1WorkflowTemplateList workflowTemplateServiceListWorkflowTemplates(namespace, listOptionsLabelSelector, listOptionsFieldSelector, listOptionsWatch, listOptionsAllowWatchBookmarks, listOptionsResourceVersion, listOptionsResourceVersionMatch, listOptionsTimeoutSeconds, listOptionsLimit, listOptionsContinue) +> IoArgoprojWorkflowV1alpha1WorkflowTemplateList workflowTemplateServiceListWorkflowTemplates(namespace, namePattern, listOptionsLabelSelector, listOptionsFieldSelector, listOptionsWatch, listOptionsAllowWatchBookmarks, listOptionsResourceVersion, listOptionsResourceVersionMatch, listOptionsTimeoutSeconds, listOptionsLimit, listOptionsContinue) @@ -335,6 +335,7 @@ public class Example { WorkflowTemplateServiceApi apiInstance = new WorkflowTemplateServiceApi(defaultClient); String namespace = "namespace_example"; // String | + String namePattern = "namePattern_example"; // String | String listOptionsLabelSelector = "listOptionsLabelSelector_example"; // String | A selector to restrict the list of returned objects by their labels. Defaults to everything. +optional. String listOptionsFieldSelector = "listOptionsFieldSelector_example"; // String | A selector to restrict the list of returned objects by their fields. Defaults to everything. +optional. Boolean listOptionsWatch = true; // Boolean | Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion. +optional. @@ -345,7 +346,7 @@ public class Example { String listOptionsLimit = "listOptionsLimit_example"; // String | limit is a maximum number of responses to return for a list call. If more items exist, the server will set the `continue` field on the list metadata to a value that can be used with the same initial query to retrieve the next set of results. Setting a limit may return fewer than the requested amount of items (up to zero items) in the event all requested objects are filtered out and clients should only use the presence of the continue field to determine whether more results are available. Servers may choose not to support the limit argument and will return all of the available results. If limit is specified and the continue field is empty, clients may assume that no more results are available. This field is not supported if watch is true. The server guarantees that the objects returned when using continue will be identical to issuing a single list call without a limit - that is, no objects created, modified, or deleted after the first request is issued will be included in any subsequent continued requests. This is sometimes referred to as a consistent snapshot, and ensures that a client that is using limit to receive smaller chunks of a very large result can ensure they see all possible objects. If objects are updated during a chunked list the version of the object that was present at the time the first list result was calculated is returned. String listOptionsContinue = "listOptionsContinue_example"; // String | The continue option should be set when retrieving more results from the server. Since this value is server defined, clients may only use the continue value from a previous query result with identical query parameters (except for the value of continue) and the server may reject a continue value it does not recognize. If the specified continue value is no longer valid whether due to expiration (generally five to fifteen minutes) or a configuration change on the server, the server will respond with a 410 ResourceExpired error together with a continue token. If the client needs a consistent list, it must restart their list without the continue field. Otherwise, the client may send another list request with the token received with the 410 error, the server will respond with a list starting from the next key, but from the latest snapshot, which is inconsistent from the previous list results - objects that are created, modified, or deleted after the first list request will be included in the response, as long as their keys are after the \"next key\". This field is not supported when watch is true. Clients may start a watch from the last resourceVersion value returned by the server and not miss any modifications. try { - IoArgoprojWorkflowV1alpha1WorkflowTemplateList result = apiInstance.workflowTemplateServiceListWorkflowTemplates(namespace, listOptionsLabelSelector, listOptionsFieldSelector, listOptionsWatch, listOptionsAllowWatchBookmarks, listOptionsResourceVersion, listOptionsResourceVersionMatch, listOptionsTimeoutSeconds, listOptionsLimit, listOptionsContinue); + IoArgoprojWorkflowV1alpha1WorkflowTemplateList result = apiInstance.workflowTemplateServiceListWorkflowTemplates(namespace, namePattern, listOptionsLabelSelector, listOptionsFieldSelector, listOptionsWatch, listOptionsAllowWatchBookmarks, listOptionsResourceVersion, listOptionsResourceVersionMatch, listOptionsTimeoutSeconds, listOptionsLimit, listOptionsContinue); System.out.println(result); } catch (ApiException e) { System.err.println("Exception when calling WorkflowTemplateServiceApi#workflowTemplateServiceListWorkflowTemplates"); @@ -363,6 +364,7 @@ public class Example { Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **namespace** | **String**| | + **namePattern** | **String**| | [optional] **listOptionsLabelSelector** | **String**| A selector to restrict the list of returned objects by their labels. Defaults to everything. +optional. | [optional] **listOptionsFieldSelector** | **String**| A selector to restrict the list of returned objects by their fields. Defaults to everything. +optional. | [optional] **listOptionsWatch** | **Boolean**| Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion. +optional. | [optional] diff --git a/sdks/python/client/argo_workflows/api/workflow_template_service_api.py b/sdks/python/client/argo_workflows/api/workflow_template_service_api.py index ff914179378c..51fc58f6d2cf 100644 --- a/sdks/python/client/argo_workflows/api/workflow_template_service_api.py +++ b/sdks/python/client/argo_workflows/api/workflow_template_service_api.py @@ -320,6 +320,7 @@ def __init__(self, api_client=None): params_map={ 'all': [ 'namespace', + 'name_pattern', 'list_options_label_selector', 'list_options_field_selector', 'list_options_watch', @@ -348,6 +349,8 @@ def __init__(self, api_client=None): 'openapi_types': { 'namespace': (str,), + 'name_pattern': + (str,), 'list_options_label_selector': (str,), 'list_options_field_selector': @@ -369,6 +372,7 @@ def __init__(self, api_client=None): }, 'attribute_map': { 'namespace': 'namespace', + 'name_pattern': 'namePattern', 'list_options_label_selector': 'listOptions.labelSelector', 'list_options_field_selector': 'listOptions.fieldSelector', 'list_options_watch': 'listOptions.watch', @@ -381,6 +385,7 @@ def __init__(self, api_client=None): }, 'location_map': { 'namespace': 'path', + 'name_pattern': 'query', 'list_options_label_selector': 'query', 'list_options_field_selector': 'query', 'list_options_watch': 'query', @@ -815,6 +820,7 @@ def list_workflow_templates( namespace (str): Keyword Args: + name_pattern (str): [optional] list_options_label_selector (str): A selector to restrict the list of returned objects by their labels. Defaults to everything. +optional.. [optional] list_options_field_selector (str): A selector to restrict the list of returned objects by their fields. Defaults to everything. +optional.. [optional] list_options_watch (bool): Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion. +optional.. [optional] diff --git a/sdks/python/client/docs/WorkflowTemplateServiceApi.md b/sdks/python/client/docs/WorkflowTemplateServiceApi.md index 332d942c45cc..8f9032d97d57 100644 --- a/sdks/python/client/docs/WorkflowTemplateServiceApi.md +++ b/sdks/python/client/docs/WorkflowTemplateServiceApi.md @@ -21743,6 +21743,7 @@ with argo_workflows.ApiClient(configuration) as api_client: # Create an instance of the API class api_instance = workflow_template_service_api.WorkflowTemplateServiceApi(api_client) namespace = "namespace_example" # str | + name_pattern = "namePattern_example" # str | (optional) list_options_label_selector = "listOptions.labelSelector_example" # str | A selector to restrict the list of returned objects by their labels. Defaults to everything. +optional. (optional) list_options_field_selector = "listOptions.fieldSelector_example" # str | A selector to restrict the list of returned objects by their fields. Defaults to everything. +optional. (optional) list_options_watch = True # bool | Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion. +optional. (optional) @@ -21763,7 +21764,7 @@ with argo_workflows.ApiClient(configuration) as api_client: # example passing only required values which don't have defaults set # and optional values try: - api_response = api_instance.list_workflow_templates(namespace, list_options_label_selector=list_options_label_selector, list_options_field_selector=list_options_field_selector, list_options_watch=list_options_watch, list_options_allow_watch_bookmarks=list_options_allow_watch_bookmarks, list_options_resource_version=list_options_resource_version, list_options_resource_version_match=list_options_resource_version_match, list_options_timeout_seconds=list_options_timeout_seconds, list_options_limit=list_options_limit, list_options_continue=list_options_continue) + api_response = api_instance.list_workflow_templates(namespace, name_pattern=name_pattern, list_options_label_selector=list_options_label_selector, list_options_field_selector=list_options_field_selector, list_options_watch=list_options_watch, list_options_allow_watch_bookmarks=list_options_allow_watch_bookmarks, list_options_resource_version=list_options_resource_version, list_options_resource_version_match=list_options_resource_version_match, list_options_timeout_seconds=list_options_timeout_seconds, list_options_limit=list_options_limit, list_options_continue=list_options_continue) pprint(api_response) except argo_workflows.ApiException as e: print("Exception when calling WorkflowTemplateServiceApi->list_workflow_templates: %s\n" % e) @@ -21775,6 +21776,7 @@ with argo_workflows.ApiClient(configuration) as api_client: Name | Type | Description | Notes ------------- | ------------- | ------------- | ------------- **namespace** | **str**| | + **name_pattern** | **str**| | [optional] **list_options_label_selector** | **str**| A selector to restrict the list of returned objects by their labels. Defaults to everything. +optional. | [optional] **list_options_field_selector** | **str**| A selector to restrict the list of returned objects by their fields. Defaults to everything. +optional. | [optional] **list_options_watch** | **bool**| Watch for changes to the described resources and return them as a stream of add, update, and remove notifications. Specify resourceVersion. +optional. | [optional] diff --git a/server/workflowtemplate/workflow_template_server.go b/server/workflowtemplate/workflow_template_server.go index 9006839f192e..90fe7040f2f6 100644 --- a/server/workflowtemplate/workflow_template_server.go +++ b/server/workflowtemplate/workflow_template_server.go @@ -4,6 +4,8 @@ import ( "context" "fmt" "sort" + "strconv" + "strings" "google.golang.org/grpc/codes" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -67,17 +69,87 @@ func (wts *WorkflowTemplateServer) getTemplateAndValidate(ctx context.Context, n return wfTmpl, nil } +func cursorPaginationByResourceVersion(items []v1alpha1.WorkflowTemplate, resourceVersion string, limit int64, wfList *v1alpha1.WorkflowTemplateList) { + // Sort the workflow list in descending order by resourceVersion. + sort.Slice(items, func(i, j int) bool { + itemIRV, _ := strconv.Atoi(items[i].ResourceVersion) + itemJRV, _ := strconv.Atoi(items[j].ResourceVersion) + return itemIRV > itemJRV + }) + + // resourceVersion: unique value to identify the version of the object by Kubernetes. It is used for pagination in workflows. + // receivedRV: resourceVersion value used for previous pagination + // Due to the descending sorting above, the items are filtered to have a resourceVersion smaller than receivedRV. + // The data with values smaller than the receivedRV on the current page will be used for the next page. + if resourceVersion != "" { + var newItems []v1alpha1.WorkflowTemplate + for _, item := range items { + targetRV, _ := strconv.Atoi(item.ResourceVersion) + receivedRV, _ := strconv.Atoi(resourceVersion) + if targetRV < receivedRV { + newItems = append(newItems, item) + } + items = newItems + } + } + + // Indexing list by limit count + if limit != 0 { + endIndex := int(limit) + if endIndex > len(items) || limit == 0 { + endIndex = len(items) + } + wfList.Items = items[0:endIndex] + } else { + wfList.Items = items + } + + // Calculate new offset for next page + // For the next pagination, the resourceVersion of the last item is set in the Continue field. + if limit != 0 && len(wfList.Items) == int(limit) { + lastIndex := len(wfList.Items) - 1 + wfList.ListMeta.Continue = wfList.Items[lastIndex].ResourceVersion + } +} + func (wts *WorkflowTemplateServer) ListWorkflowTemplates(ctx context.Context, req *workflowtemplatepkg.WorkflowTemplateListRequest) (*v1alpha1.WorkflowTemplateList, error) { wfClient := auth.GetWfClient(ctx) - options := &v1.ListOptions{} + k8sOptions := &v1.ListOptions{} + if req.ListOptions != nil { - options = req.ListOptions + k8sOptions = req.ListOptions + } + + // Save the original Continue and Limit for custom filtering. + resourceVersion := k8sOptions.Continue + limit := k8sOptions.Limit + + if req.NamePattern != "" { + // Search whole with Limit 0. + // Reset the Continue "" to prevent Kubernetes native pagination. + // Kubernetes api will search for all results without limit and pagination. + k8sOptions.Continue = "" + k8sOptions.Limit = 0 } - wts.instanceIDService.With(options) - wfList, err := wfClient.ArgoprojV1alpha1().WorkflowTemplates(req.Namespace).List(ctx, *options) + + wts.instanceIDService.With(k8sOptions) + wfList, err := wfClient.ArgoprojV1alpha1().WorkflowTemplates(req.Namespace).List(ctx, *k8sOptions) if err != nil { return nil, sutils.ToStatusError(err, codes.Internal) } + + // Enables name-based searching. + // Do name pattern filtering if NamePattern request exist. + var items []v1alpha1.WorkflowTemplate + if req.NamePattern != "" { + for _, item := range wfList.Items { + if strings.Contains(item.ObjectMeta.Name, req.NamePattern) { + items = append(items, item) + } + } + cursorPaginationByResourceVersion(items, resourceVersion, limit, wfList) + } + sort.Sort(wfList.Items) return wfList, nil } diff --git a/ui/src/app/shared/services/workflow-template-service.ts b/ui/src/app/shared/services/workflow-template-service.ts index fe58eeabed6a..ee063fae1115 100644 --- a/ui/src/app/shared/services/workflow-template-service.ts +++ b/ui/src/app/shared/services/workflow-template-service.ts @@ -11,8 +11,10 @@ export const WorkflowTemplateService = { .then(res => res.body as models.WorkflowTemplate); }, - list(namespace: string, labels?: string[], pagination?: Pagination) { - return requests.get(`api/v1/workflow-templates/${namespace}?${Utils.queryParams({labels, pagination}).join('&')}`).then(res => res.body as models.WorkflowTemplateList); + list(namespace: string, labels?: string[], namePattern?: string, pagination?: Pagination) { + return requests + .get(`api/v1/workflow-templates/${namespace}?${Utils.queryParams({labels, namePattern, pagination}).join('&')}`) + .then(res => res.body as models.WorkflowTemplateList); }, get(name: string, namespace: string) { diff --git a/ui/src/app/shared/utils.ts b/ui/src/app/shared/utils.ts index f9a113b090e1..534c3499d512 100644 --- a/ui/src/app/shared/utils.ts +++ b/ui/src/app/shared/utils.ts @@ -125,6 +125,7 @@ export const Utils = { namespace?: string; name?: string; namePrefix?: string; + namePattern?: string; phases?: Array; labels?: Array; minStartedAt?: Date; @@ -152,6 +153,9 @@ export const Utils = { if (filter.namePrefix) { queryParams.push(`namePrefix=${filter.namePrefix}`); } + if (filter.namePattern) { + queryParams.push(`namePattern=${filter.namePattern}`); + } if (filter.resourceVersion) { queryParams.push(`listOptions.resourceVersion=${filter.resourceVersion}`); } diff --git a/ui/src/app/workflow-templates/components/workflow-template-filters/workflow-template-filters.tsx b/ui/src/app/workflow-templates/components/workflow-template-filters/workflow-template-filters.tsx index a4e5d484829c..0c3259e23a28 100644 --- a/ui/src/app/workflow-templates/components/workflow-template-filters/workflow-template-filters.tsx +++ b/ui/src/app/workflow-templates/components/workflow-template-filters/workflow-template-filters.tsx @@ -1,6 +1,7 @@ import * as React from 'react'; import {useEffect, useState} from 'react'; import * as models from '../../../../models'; +import {InputFilter} from '../../../shared/components/input-filter'; import {NamespaceFilter} from '../../../shared/components/namespace-filter'; import {TagsInput} from '../../../shared/components/tags-input/tags-input'; @@ -9,11 +10,12 @@ require('./workflow-template-filters.scss'); interface WorkflowFilterProps { templates: models.WorkflowTemplate[]; namespace: string; + namePattern: string; labels: string[]; - onChange: (namespace: string, labels: string[]) => void; + onChange: (namespace: string, namePattern: string, labels: string[]) => void; } -export function WorkflowTemplateFilters({templates, namespace, labels, onChange}: WorkflowFilterProps) { +export function WorkflowTemplateFilters({templates, namespace, namePattern, labels, onChange}: WorkflowFilterProps) { const [labelSuggestion, setLabelSuggestion] = useState([]); useEffect(() => { @@ -40,7 +42,7 @@ export function WorkflowTemplateFilters({templates, namespace, labels, onChange} { - onChange(ns, labels); + onChange(ns, namePattern, labels); }} /> @@ -51,7 +53,17 @@ export function WorkflowTemplateFilters({templates, namespace, labels, onChange} autocomplete={labelSuggestion} tags={labels} onChange={tags => { - onChange(namespace, tags); + onChange(namespace, namePattern, tags); + }} + /> + +
+

Name Pattern

+ { + onChange(namespace, wfnamePattern, labels); }} />
diff --git a/ui/src/app/workflow-templates/components/workflow-template-list/workflow-template-list.tsx b/ui/src/app/workflow-templates/components/workflow-template-list/workflow-template-list.tsx index 201f3206435a..6e646506dfe4 100644 --- a/ui/src/app/workflow-templates/components/workflow-template-list/workflow-template-list.tsx +++ b/ui/src/app/workflow-templates/components/workflow-template-list/workflow-template-list.tsx @@ -38,7 +38,7 @@ export function WorkflowTemplateList({match, location, history}: RouteComponentP // state for URL and query parameters const [namespace, setNamespace] = useState(Utils.getNamespace(match.params.namespace) || ''); const [sidePanel, setSidePanel] = useState(queryParams.get('sidePanel') === 'true'); - + const [namePattern, setNamePattern] = useState(''); const [labels, setLabels] = useState([]); const [pagination, setPagination] = useState({ offset: queryParams.get('offset'), @@ -68,14 +68,14 @@ export function WorkflowTemplateList({match, location, history}: RouteComponentP const [templates, setTemplates] = useState(); useEffect(() => { services.workflowTemplate - .list(namespace, labels, pagination) + .list(namespace, labels, namePattern, pagination) .then(list => { setPagination({...pagination, nextOffset: list.metadata.continue}); setTemplates(list.items || []); }) .then(() => setError(null)) .catch(setError); - }, [namespace, labels, pagination.offset, pagination.limit]); + }, [namespace, namePattern, labels, pagination.offset, pagination.limit]); useEffect(() => { storage.setItem('paginationLimit', pagination.limit, 0); }, [pagination.limit, labels]); @@ -106,10 +106,13 @@ export function WorkflowTemplateList({match, location, history}: RouteComponentP { + onChange={(namespaceValue: string, namePatternValue: string, labelsValue: string[]) => { setNamespace(namespaceValue); + setNamePattern(namePatternValue); setLabels(labelsValue); + setPagination({...pagination, offset: ''}); }} />