Skip to content

Commit

Permalink
add label selector
Browse files Browse the repository at this point in the history
  • Loading branch information
zc2638 committed Dec 20, 2023
1 parent 6ee5e9e commit 5f8e6c1
Show file tree
Hide file tree
Showing 15 changed files with 224 additions and 32 deletions.
14 changes: 6 additions & 8 deletions core/clients/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,13 @@ type ServerV1 interface {
SecretUpdate(ctx context.Context, data *v1.Secret) error
SecretDelete(ctx context.Context, namespace, name string) error

WorkflowList(ctx context.Context, namespace string, page v1.Pagination) ([]*v1.Workflow, *v1.Pagination, error)
WorkflowList(ctx context.Context, namespace string, opt v1.ListOption) ([]*v1.Workflow, *v1.Pagination, error)
WorkflowInfo(ctx context.Context, namespace, name string) (*v1.Workflow, error)
WorkflowCreate(ctx context.Context, data *v1.Workflow) error
WorkflowUpdate(ctx context.Context, data *v1.Workflow) error
WorkflowDelete(ctx context.Context, namespace, name string) error

BoxList(ctx context.Context, namespace string, page v1.Pagination) ([]*v1.Box, *v1.Pagination, error)
BoxList(ctx context.Context, namespace string, opt v1.ListOption) ([]*v1.Box, *v1.Pagination, error)
BoxInfo(ctx context.Context, namespace, name string) (*v1.Box, error)
BoxCreate(ctx context.Context, data *v1.Box) error
BoxUpdate(ctx context.Context, data *v1.Box) error
Expand Down Expand Up @@ -134,16 +134,15 @@ func (c *serverV1) SecretDelete(ctx context.Context, namespace, name string) err
return handleClientError(resp, err)
}

func (c *serverV1) WorkflowList(ctx context.Context, namespace string, page v1.Pagination) ([]*v1.Workflow, *v1.Pagination, error) {
func (c *serverV1) WorkflowList(ctx context.Context, namespace string, opt v1.ListOption) ([]*v1.Workflow, *v1.Pagination, error) {
type resultT struct {
v1.Pagination
Items []*v1.Workflow `json:"items"`
}

var result resultT
vs := page.ToValues()
req := c.R(ctx).
SetQueryParamsFromValues(vs).
SetQueryParamsFromValues(opt.ToValues()).
SetPathParam("namespace", namespace).
SetResult(&result)
resp, err := req.Get("/workflow/{namespace}")
Expand Down Expand Up @@ -189,16 +188,15 @@ func (c *serverV1) WorkflowDelete(ctx context.Context, namespace, name string) e
return handleClientError(resp, err)
}

func (c *serverV1) BoxList(ctx context.Context, namespace string, page v1.Pagination) ([]*v1.Box, *v1.Pagination, error) {
func (c *serverV1) BoxList(ctx context.Context, namespace string, opt v1.ListOption) ([]*v1.Box, *v1.Pagination, error) {
type resultT struct {
v1.Pagination
Items []*v1.Box `json:"items"`
}

var result resultT
vs := page.ToValues()
req := c.R(ctx).
SetQueryParamsFromValues(vs).
SetQueryParamsFromValues(opt.ToValues()).
SetPathParam("namespace", namespace).
SetResult(&result)
resp, err := req.Get("/box/{namespace}")
Expand Down
10 changes: 8 additions & 2 deletions core/command/ctl.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,10 @@ func workflowList(cmd *cobra.Command, _ []string) error {
if err != nil {
return err
}
result, _, err := sc.WorkflowList(context.Background(), v1.AllNamespace, *getPage(cmd))
opt := v1.ListOption{
Pagination: *getPage(cmd),
}
result, _, err := sc.WorkflowList(context.Background(), v1.AllNamespace, opt)
if err != nil {
return err
}
Expand Down Expand Up @@ -209,7 +212,10 @@ func boxList(cmd *cobra.Command, _ []string) error {
if err != nil {
return err
}
result, _, err := sc.BoxList(context.Background(), v1.AllNamespace, *getPage(cmd))
opt := v1.ListOption{
Pagination: *getPage(cmd),
}
result, _, err := sc.BoxList(context.Background(), v1.AllNamespace, opt)
if err != nil {
return err
}
Expand Down
6 changes: 4 additions & 2 deletions core/handler/server/box.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@ func boxList(boxSrv service.Box) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
namespace := wrapper.URLParam(r, "namespace")
page := v1.GetPagination(r)

result, err := boxSrv.List(r.Context(), namespace, page)
result, err := boxSrv.List(r.Context(), namespace, v1.ListOption{
Pagination: *page,
LabelSelector: r.URL.Query().Get("labelSelector"),
})
if err != nil {
wrapper.InternalError(w, err)
return
Expand Down
5 changes: 4 additions & 1 deletion core/handler/server/workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@ func workflowList(workflowSrv service.Workflow) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
namespace := wrapper.URLParam(r, "namespace")
page := v1.GetPagination(r)
result, err := workflowSrv.List(r.Context(), namespace, page)
result, err := workflowSrv.List(r.Context(), namespace, v1.ListOption{
Pagination: *page,
LabelSelector: r.URL.Query().Get("labelSelector"),
})
if err != nil {
wrapper.InternalError(w, err)
return
Expand Down
24 changes: 16 additions & 8 deletions core/service/box/box.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (

"github.com/zc2638/ink/core/constant"
"github.com/zc2638/ink/core/service"
"github.com/zc2638/ink/core/service/common"
v1 "github.com/zc2638/ink/pkg/api/core/v1"
storageV1 "github.com/zc2638/ink/pkg/api/storage/v1"
"github.com/zc2638/ink/pkg/database"
Expand All @@ -30,21 +31,28 @@ func New() service.Box {

type srv struct{}

func (s *srv) List(ctx context.Context, namespace string, page *v1.Pagination) ([]*v1.Box, error) {
func (s *srv) List(ctx context.Context, namespace string, opt v1.ListOption) ([]*v1.Box, error) {
db := database.FromContext(ctx)

var (
list []storageV1.Box
total int64
)
labels := opt.Labels()
if len(labels) > 0 {
names, err := common.SelectNamesByLabels(ctx, v1.KindBox, namespace, labels)
if err != nil {
return nil, err
}
if len(names) == 0 {
return nil, nil
}
db = db.Where("name in (?)", names)
}
if len(namespace) > 0 {
db = db.Where("namespace = ?", namespace)
}
if err := db.Model(&storageV1.Box{}).Count(&total).Error; err != nil {
if err := db.Model(&storageV1.Box{}).Count(&opt.Pagination.Total).Error; err != nil {
return nil, err
}
page.SetTotal(total)
if err := db.Scopes(page.Scope).Find(&list).Error; err != nil {
var list []storageV1.Box
if err := db.Scopes(opt.Pagination.Scope).Find(&list).Error; err != nil {
return nil, err
}

Expand Down
58 changes: 58 additions & 0 deletions core/service/common/label.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright © 2023 zc2638 <[email protected]>.
//
// 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 common

import (
"context"
"fmt"

"github.com/99nil/gopkg/sets"

storageV1 "github.com/zc2638/ink/pkg/api/storage/v1"
"github.com/zc2638/ink/pkg/database"
)

func SelectNamesByLabels(ctx context.Context, kind, namespace string, labels map[string]string) ([]string, error) {
if len(labels) == 0 {
return nil, nil
}

db := database.FromContext(ctx)
db = db.Where(&storageV1.Label{Namespace: namespace, Kind: kind})

var start bool
nameSet := sets.New[string]()
for k, v := range labels {
var selectNames []string
if err := db.Where("key = ?", k).Where("value = ?", v).Pluck("name", &selectNames).Error; err != nil {
return nil, fmt.Errorf("select label(%s=%s) failed: %v", k, v, err)
}

if !start {
start = true
nameSet.Add(selectNames...)
continue
}
for _, sn := range selectNames {
if !nameSet.Has(sn) {
nameSet.Remove(sn)
}
}
if nameSet.Len() == 0 {
return nil, nil
}
}
return nameSet.List(), nil
}
4 changes: 2 additions & 2 deletions core/service/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ import (

type (
Workflow interface {
List(ctx context.Context, namespace string, page *v1.Pagination) ([]*v1.Workflow, error)
List(ctx context.Context, namespace string, opt v1.ListOption) ([]*v1.Workflow, error)
Info(ctx context.Context, namespace, name string) (*v1.Workflow, error)
Create(ctx context.Context, data *v1.Workflow) error
Update(ctx context.Context, data *v1.Workflow) error
Delete(ctx context.Context, namespace, name string) error
}

Box interface {
List(ctx context.Context, namespace string, page *v1.Pagination) ([]*v1.Box, error)
List(ctx context.Context, namespace string, opt v1.ListOption) ([]*v1.Box, error)
Info(ctx context.Context, namespace, name string) (*v1.Box, error)
Create(ctx context.Context, data *v1.Box) error
Update(ctx context.Context, data *v1.Box) error
Expand Down
24 changes: 16 additions & 8 deletions core/service/workflow/workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (

"github.com/zc2638/ink/core/constant"
"github.com/zc2638/ink/core/service"
"github.com/zc2638/ink/core/service/common"
v1 "github.com/zc2638/ink/pkg/api/core/v1"
storageV1 "github.com/zc2638/ink/pkg/api/storage/v1"
"github.com/zc2638/ink/pkg/database"
Expand All @@ -30,22 +31,29 @@ func New() service.Workflow {

type srv struct{}

func (s *srv) List(ctx context.Context, namespace string, page *v1.Pagination) ([]*v1.Workflow, error) {
func (s *srv) List(ctx context.Context, namespace string, opt v1.ListOption) ([]*v1.Workflow, error) {
db := database.FromContext(ctx)

var (
list []storageV1.Workflow
total int64
)
labels := opt.Labels()
if len(labels) > 0 {
names, err := common.SelectNamesByLabels(ctx, v1.KindWorkflow, namespace, labels)
if err != nil {
return nil, err
}
if len(names) == 0 {
return nil, nil
}
db = db.Where("name in (?)", names)
}
if len(namespace) > 0 {
db = db.Where("namespace = ?", namespace)
}
if err := db.Model(&storageV1.Workflow{}).Count(&total).Error; err != nil {
if err := db.Model(&storageV1.Workflow{}).Count(&opt.Pagination.Total).Error; err != nil {
return nil, err
}
page.SetTotal(total)

if err := db.Scopes(page.Scope).Find(&list).Error; err != nil {
var list []storageV1.Workflow
if err := db.Scopes(opt.Pagination.Scope).Find(&list).Error; err != nil {
return nil, err
}

Expand Down
67 changes: 67 additions & 0 deletions pkg/api/core/v1/option.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
// Copyright © 2023 zc2638 <[email protected]>.
//
// 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 v1

import (
"net/url"
"strings"
)

type ListOption struct {
Pagination Pagination
LabelSelector string
}

func (o *ListOption) ToValues() url.Values {
result := url.Values{}
for k, v := range o.Pagination.ToValues() {
result[k] = v
}
if len(o.LabelSelector) > 0 {
result.Set("labelSelector", o.LabelSelector)
}
return result
}

func (o *ListOption) SetLabels(labels map[string]string) {
var sb strings.Builder
for k, v := range labels {
sb.WriteString(k)
sb.WriteString("=")
sb.WriteString(v)
sb.WriteString(",")
}
s := sb.String()
s = strings.TrimSuffix(s, ",")
o.LabelSelector = s
}

func (o *ListOption) Labels() map[string]string {
selector := strings.TrimSpace(o.LabelSelector)
if len(selector) == 0 {
return nil
}

labels := make(map[string]string)
parts := strings.Split(o.LabelSelector, ",")
for _, part := range parts {
kv := strings.Split(part, "=")
if len(kv) != 2 {
continue
}
labels[kv[0]] = kv[1]
}
return labels
}
2 changes: 1 addition & 1 deletion pkg/api/core/v1/workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func (w *Workflow) Worker() *Worker {
type WorkflowSpec struct {
Steps []Flow `json:"steps" yaml:"steps"`
WorkingDir string `json:"workingDir,omitempty" yaml:"workingDir,omitempty"`
Concurrency int `json:"concurrency,omitempty" yaml:"concurrency,omitempty"`
Concurrency int `json:"concurrency,omitempty" yaml:"concurrency,5omitempty"`
Volumes []Volume `json:"volumes,omitempty" yaml:"volumes,omitempty"`
DependsOn []string `json:"dependsOn,omitempty" yaml:"dependsOn,omitempty"`
ImagePullSecrets []string `json:"imagePullSecrets,omitempty" yaml:"imagePullSecrets,omitempty"`
Expand Down
15 changes: 15 additions & 0 deletions pkg/api/storage/v1/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,21 @@ func (m *Model) GetID() uint64 {
return m.ID
}

type Label struct {
ID int
Namespace string
Name string
Kind string
Key string
Value string

CreatedAt time.Time
}

func (Label) TableName() string {
return "labels"
}

type Secret struct {
Model

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DROP TABLE IF EXISTS `labels`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
CREATE TABLE IF NOT EXISTS `labels`
(
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`namespace` VARCHAR(255) NOT NULL,
`name` VARCHAR(255) NOT NULL,
`kind` VARCHAR(255) NOT NULL,
`key` VARCHAR(255) NOT NULL,
`value` VARCHAR(255),

`created_at` DATETIME DEFAULT CURRENT_TIMESTAMP
);
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
DROP TABLE IF EXISTS `labels`;
Loading

0 comments on commit 5f8e6c1

Please sign in to comment.