Skip to content

Commit

Permalink
feat: search archived wf by startat. Closes argoproj#2436 (argoproj#2473
Browse files Browse the repository at this point in the history
)
  • Loading branch information
whynowy authored Mar 19, 2020
1 parent 23d230b commit 315dc16
Show file tree
Hide file tree
Showing 14 changed files with 413 additions and 41 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ require (
github.com/go-openapi/spec v0.19.2
github.com/go-sql-driver/mysql v1.4.1
github.com/gogo/protobuf v1.3.1
github.com/golang/protobuf v1.3.3
github.com/golang/protobuf v1.3.5
github.com/google/go-querystring v1.0.0 // indirect
github.com/googleapis/gnostic v0.3.1 // indirect
github.com/gophercloud/gophercloud v0.7.0 // indirect
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,8 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.5 h1:F768QJ1E9tib+q5Sc8MkdJi1RxLTbRcTf8LJV56aRls=
github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=
github.com/google/btree v0.0.0-20160524151835-7d79101e329e/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
Expand Down
16 changes: 9 additions & 7 deletions persist/sqldb/mocks/WorkflowArchive.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion persist/sqldb/null_workflow_archive.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package sqldb

import (
"fmt"
"time"

"k8s.io/apimachinery/pkg/labels"

Expand All @@ -17,7 +18,7 @@ func (r *nullWorkflowArchive) ArchiveWorkflow(*wfv1.Workflow) error {
return nil
}

func (r *nullWorkflowArchive) ListWorkflows(string, labels.Requirements, int, int) (wfv1.Workflows, error) {
func (r *nullWorkflowArchive) ListWorkflows(string, time.Time, time.Time, labels.Requirements, int, int) (wfv1.Workflows, error) {
return wfv1.Workflows{}, nil
}

Expand Down
16 changes: 14 additions & 2 deletions persist/sqldb/workflow_archive.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ type archivedWorkflowLabelRecord struct {

type WorkflowArchive interface {
ArchiveWorkflow(wf *wfv1.Workflow) error
ListWorkflows(namespace string, labelRequirements labels.Requirements, limit, offset int) (wfv1.Workflows, error)
ListWorkflows(namespace string, minStartAt, maxStartAt time.Time, labelRequirements labels.Requirements, limit, offset int) (wfv1.Workflows, error)
GetWorkflow(uid string) (*wfv1.Workflow, error)
DeleteWorkflow(uid string) error
}
Expand Down Expand Up @@ -113,7 +113,7 @@ func (r *workflowArchive) ArchiveWorkflow(wf *wfv1.Workflow) error {
})
}

func (r *workflowArchive) ListWorkflows(namespace string, labelRequirements labels.Requirements, limit int, offset int) (wfv1.Workflows, error) {
func (r *workflowArchive) ListWorkflows(namespace string, minStartedAt, maxStartedAt time.Time, labelRequirements labels.Requirements, limit int, offset int) (wfv1.Workflows, error) {
var archivedWfs []archivedWorkflowMetadata
clause, err := labelsClause(r.dbType, labelRequirements)
if err != nil {
Expand All @@ -125,6 +125,7 @@ func (r *workflowArchive) ListWorkflows(namespace string, labelRequirements labe
Where(db.Cond{"clustername": r.clusterName}).
And(db.Cond{"instanceid": r.instanceID}).
And(namespaceEqual(namespace)).
And(startedAtClause(minStartedAt, maxStartedAt)).
And(clause).
OrderBy("-startedat").
Limit(limit).
Expand Down Expand Up @@ -152,6 +153,17 @@ func (r *workflowArchive) ListWorkflows(namespace string, labelRequirements labe
return wfs, nil
}

func startedAtClause(from, to time.Time) db.Compound {
var conds []db.Compound
if !from.IsZero() {
conds = append(conds, db.Cond{"startedat > ": from})
}
if !to.IsZero() {
conds = append(conds, db.Cond{"startedat < ": to})
}
return db.And(conds...)
}

func namespaceEqual(namespace string) db.Cond {
if namespace == "" {
return db.Cond{}
Expand Down
30 changes: 27 additions & 3 deletions server/workflowarchive/archived_workflow_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"sort"
"strconv"
"strings"
"time"

"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
Expand Down Expand Up @@ -47,9 +48,32 @@ func (w *archivedWorkflowServer) ListArchivedWorkflows(ctx context.Context, req
if offset < 0 {
return nil, status.Error(codes.InvalidArgument, "listOptions.continue must >= 0")
}

namespace := ""
if strings.HasPrefix(options.FieldSelector, "metadata.namespace=") {
namespace = strings.TrimPrefix(options.FieldSelector, "metadata.namespace=")
minStartedAt := time.Time{}
maxStartedAt := time.Time{}
selectors := strings.Split(options.FieldSelector, ",")
for _, selector := range selectors {
if len(selector) == 0 {
continue
}
if strings.HasPrefix(selector, "metadata.namespace=") {
namespace = strings.TrimPrefix(selector, "metadata.namespace=")
} else if strings.HasPrefix(selector, "spec.startedAt>") {
minStartedAtStr := strings.TrimPrefix(selector, "spec.startedAt>")
minStartedAt, err = time.Parse(time.RFC3339, minStartedAtStr)
if err != nil {
return nil, err
}
} else if strings.HasPrefix(selector, "spec.startedAt<") {
maxStartedAtStr := strings.TrimPrefix(selector, "spec.startedAt<")
maxStartedAt, err = time.Parse(time.RFC3339, maxStartedAtStr)
if err != nil {
return nil, err
}
} else {
return nil, fmt.Errorf("unsupported requirement %s", selector)
}
}

requirements, err := labels.ParseToRequirements(options.LabelSelector)
Expand All @@ -62,7 +86,7 @@ func (w *archivedWorkflowServer) ListArchivedWorkflows(ctx context.Context, req
hasMore := true
// keep trying until we have enough
for len(items) < limit {
moreItems, err := w.wfArchive.ListWorkflows(namespace, requirements, limit+1, offset)
moreItems, err := w.wfArchive.ListWorkflows(namespace, minStartedAt, maxStartedAt, requirements, limit+1, offset)
if err != nil {
return nil, err
}
Expand Down
13 changes: 11 additions & 2 deletions server/workflowarchive/archived_workflow_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package workflowarchive
import (
"context"
"testing"
"time"

"github.com/stretchr/testify/assert"
"google.golang.org/grpc/codes"
Expand Down Expand Up @@ -45,8 +46,11 @@ func Test_archivedWorkflowServer(t *testing.T) {
}, nil
})
// two pages of results for limit 1
repo.On("ListWorkflows", "", labels.Requirements(nil), 2, 0).Return(wfv1.Workflows{{}, {}}, nil)
repo.On("ListWorkflows", "", labels.Requirements(nil), 2, 1).Return(wfv1.Workflows{{}}, nil)
repo.On("ListWorkflows", "", time.Time{}, time.Time{}, labels.Requirements(nil), 2, 0).Return(wfv1.Workflows{{}, {}}, nil)
repo.On("ListWorkflows", "", time.Time{}, time.Time{}, labels.Requirements(nil), 2, 1).Return(wfv1.Workflows{{}}, nil)
minStartAt, _ := time.Parse(time.RFC3339, "2020-01-01T00:00:00Z")
maxStartAt, _ := time.Parse(time.RFC3339, "2020-01-02T00:00:00Z")
repo.On("ListWorkflows", "", minStartAt, maxStartAt, labels.Requirements(nil), 2, 0).Return(wfv1.Workflows{{}}, nil)
repo.On("GetWorkflow", "").Return(nil, nil)
repo.On("GetWorkflow", "my-uid").Return(&wfv1.Workflow{
ObjectMeta: metav1.ObjectMeta{Name: "my-name"},
Expand Down Expand Up @@ -82,6 +86,11 @@ func Test_archivedWorkflowServer(t *testing.T) {
assert.Len(t, resp.Items, 1)
assert.Empty(t, resp.Continue)
}
resp, err = w.ListArchivedWorkflows(ctx, &workflowarchivepkg.ListArchivedWorkflowsRequest{ListOptions: &metav1.ListOptions{FieldSelector: "spec.startedAt>2020-01-01T00:00:00Z,spec.startedAt<2020-01-02T00:00:00Z", Limit: 1}})
if assert.NoError(t, err) {
assert.Len(t, resp.Items, 1)
assert.Empty(t, resp.Continue)
}
})
t.Run("GetArchivedWorkflow", func(t *testing.T) {
allowed = false
Expand Down
28 changes: 28 additions & 0 deletions test/e2e/argo_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -920,6 +920,34 @@ spec:
Equal("1")
})

s.Run("ListWithMinStartedAtGood", func() {
fieldSelector := "spec.startedAt>" + time.Now().Add(-1*time.Hour).Format(time.RFC3339) + ",spec.startedAt<" + time.Now().Add(1*time.Hour).Format(time.RFC3339)
j := s.e(s.T()).GET("/api/v1/archived-workflows").
WithQuery("listOptions.labelSelector", "argo-e2e").
WithQuery("listOptions.fieldSelector", fieldSelector).
WithQuery("listOptions.limit", 2).
Expect().
Status(200).
JSON()
j.
Path("$.items").
Array().
Length().
Equal(2)
})

s.Run("ListWithMinStartedAtBad", func() {
j := s.e(s.T()).GET("/api/v1/archived-workflows").
WithQuery("listOptions.labelSelector", "argo-e2e").
WithQuery("listOptions.fieldSelector", "spec.startedAt>"+time.Now().Add(1*time.Hour).Format(time.RFC3339)).
WithQuery("listOptions.limit", 2).
Expect().
Status(200).
JSON()
j.
Path("$.items").Null()
})

s.Run("Get", func() {
s.e(s.T()).GET("/api/v1/archived-workflows/not-found").
Expect().
Expand Down
4 changes: 3 additions & 1 deletion ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
"moment": "^2.24.0",
"prop-types": "^15.7.2",
"react": "^16.8.3",
"react-datepicker": "^2.14.0",
"react-dom": "^16.8.3",
"react-form": "2.16.0",
"react-moment": "^0.9.7",
Expand All @@ -32,7 +33,7 @@
"superagent-promise": "^1.1.0",
"ts-loader": "^6.0.4",
"typescript": "^2.8.3",
"webpack-cli": "^3.3.5"
"webpack-cli": "^3.3.11"
},
"devDependencies": {
"@types/classnames": "^2.2.3",
Expand All @@ -42,6 +43,7 @@
"@types/js-yaml": "^3.12.1",
"@types/prop-types": "^15.5.2",
"@types/react": "^16.8.5",
"@types/react-datepicker": "^2.11.0",
"@types/react-dom": "^16.8.2",
"@types/react-router-dom": "^4.2.3",
"@types/superagent": "^3.5.7",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
@import 'node_modules/argo-ui/src/styles/config';

.wf-filters-container {
overflow: visible;
position: relative;
border-radius: 5px;
box-shadow: 1px 1px 3px #8fa4b1;
padding: 0 1em 0.75em 1em;
margin: 12px 0;
background-color: white;
}

.wf-filters-container p {
margin: 0;
margin-top: 1em;
color: #6d7f8b;
text-transform: uppercase;
}

.wf-filters-container__title {
position: relative;
width: 100%;
max-width: 100%;
padding: 8px 0;
font-size: 15px;
background-color: transparent;
border: 0;
}
Loading

0 comments on commit 315dc16

Please sign in to comment.