Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion pkg/app/api/grpcapi/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,6 @@ func (a *API) AddApplication(ctx context.Context, req *apiservice.AddApplication
Kind: req.Kind,
CloudProvider: req.CloudProvider,
Description: req.Description,
Tags: req.Tags,
}
err = a.applicationStore.AddApplication(ctx, &app)
if errors.Is(err, datastore.ErrAlreadyExists) {
Expand Down
21 changes: 11 additions & 10 deletions pkg/app/api/grpcapi/web_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -637,7 +637,6 @@ func (a *WebAPI) AddApplication(ctx context.Context, req *webservice.AddApplicat
Kind: req.Kind,
CloudProvider: req.CloudProvider,
Description: req.Description,
Tags: req.Tags,
}
err = a.applicationStore.AddApplication(ctx, &app)
if errors.Is(err, datastore.ErrAlreadyExists) {
Expand All @@ -647,6 +646,7 @@ func (a *WebAPI) AddApplication(ctx context.Context, req *webservice.AddApplicat
a.logger.Error("failed to create application", zap.Error(err))
return nil, status.Error(codes.Internal, "Failed to create application")
}
// TODO: Create a command to send an application information defined in the application config

return &webservice.AddApplicationResponse{
ApplicationId: app.Id,
Expand All @@ -660,7 +660,6 @@ func (a *WebAPI) UpdateApplication(ctx context.Context, req *webservice.UpdateAp
app.PipedId = req.PipedId
app.Kind = req.Kind
app.CloudProvider = req.CloudProvider
app.Tags = req.Tags
return nil
}

Expand Down Expand Up @@ -861,15 +860,16 @@ func (a *WebAPI) ListApplications(ctx context.Context, req *webservice.ListAppli
return nil, status.Error(codes.Internal, "Failed to get applications")
}

if len(req.Options.Tags) == 0 {
if len(req.Options.Labels) == 0 {
return &webservice.ListApplicationsResponse{
Applications: apps,
}, nil
}

// NOTE: Filtering by labels is done by the application-side because we need to create composite indexes for every combination in the filter.
filtered := make([]*model.Application, 0, len(apps))
for _, a := range apps {
if a.ContainTags(req.Options.Tags) {
if a.ContainLabels(req.Options.Labels) {
filtered = append(filtered, a)
}
}
Expand Down Expand Up @@ -1071,20 +1071,21 @@ func (a *WebAPI) ListDeployments(ctx context.Context, req *webservice.ListDeploy
a.logger.Error("failed to get deployments", zap.Error(err))
return nil, status.Error(codes.Internal, "Failed to get deployments")
}
tags := req.Options.Tags
if len(tags) == 0 || len(deployments) == 0 {
labels := req.Options.Labels
if len(labels) == 0 || len(deployments) == 0 {
return &webservice.ListDeploymentsResponse{
Deployments: deployments,
Cursor: cursor,
}, nil
}

// Start filtering them by tags.
// NOTE: For document-oriented databases, it's hard to look for deployments that have all the tags we specified.
// Start filtering them by labels.
//
// NOTE: Filtering by labels is done by the application-side because we need to create composite indexes for every combination in the filter.
// We don't want to depend on any other search engine, that's why it filters here.
filtered := make([]*model.Deployment, 0, len(deployments))
for _, d := range deployments {
if d.ContainTags(tags) {
if d.ContainLabels(labels) {
filtered = append(filtered, d)
}
}
Expand All @@ -1109,7 +1110,7 @@ func (a *WebAPI) ListDeployments(ctx context.Context, req *webservice.ListDeploy
break
}
for _, d := range deployments {
if d.ContainTags(tags) {
if d.ContainLabels(labels) {
filtered = append(filtered, d)
}
}
Expand Down
3 changes: 1 addition & 2 deletions pkg/app/api/service/apiservice/service.proto
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ message AddApplicationRequest {
model.ApplicationKind kind = 5 [(validate.rules).enum.defined_only = true];
string cloud_provider = 6 [(validate.rules).string.min_len = 1];
string description = 7;
repeated string tags = 8;
}

message AddApplicationResponse {
Expand Down Expand Up @@ -84,7 +83,7 @@ message ListApplicationsRequest {
string env_id = 3;
bool disabled = 4;
string env_name = 5;
// TODO: Enable to filter by tags
// TODO: Enable to filter by labels
string cursor = 10;
}

Expand Down
2 changes: 2 additions & 0 deletions pkg/app/api/service/pipedservice/service.proto
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ service PipedService {

// GetDesiredVersion returns the desired version of the given Piped.
rpc GetDesiredVersion(GetDesiredVersionRequest) returns (GetDesiredVersionResponse) {}

// TODO: Add an rpc to update application info based on one defined in the application config
}

enum ListOrder {
Expand Down
6 changes: 2 additions & 4 deletions pkg/app/api/service/webservice/service.proto
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,6 @@ message AddApplicationRequest {
model.ApplicationKind kind = 5 [(validate.rules).enum.defined_only = true];
string cloud_provider = 6 [(validate.rules).string.min_len = 1];
string description = 7;
repeated string tags = 8;
}

message AddApplicationResponse {
Expand All @@ -241,7 +240,6 @@ message UpdateApplicationRequest {
string piped_id = 4 [(validate.rules).string.min_len = 1];
model.ApplicationKind kind = 6 [(validate.rules).enum.defined_only = true];
string cloud_provider = 7 [(validate.rules).string.min_len = 1];
repeated string tags = 8;
}

message UpdateApplicationResponse {
Expand Down Expand Up @@ -283,7 +281,7 @@ message ListApplicationsRequest {
repeated model.ApplicationSyncStatus sync_statuses = 3;
repeated string env_ids = 4;
string name = 5;
repeated string tags = 6;
map<string, string> labels = 6;
}
Options options = 1;
}
Expand Down Expand Up @@ -327,7 +325,7 @@ message ListDeploymentsRequest {
repeated string application_ids = 3;
repeated string env_ids = 4;
string application_name = 5;
repeated string tags = 6;
map<string, string> labels = 6;
}
Options options = 1;
int32 page_size = 2;
Expand Down
1 change: 0 additions & 1 deletion pkg/app/pipectl/cmd/application/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ type add struct {
pipedID string
cloudProvider string
description string
tags []string

repoID string
appDir string
Expand Down
2 changes: 1 addition & 1 deletion pkg/app/piped/trigger/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ func buildDeployment(
},
GitPath: app.GitPath,
CloudProvider: app.CloudProvider,
Tags: app.Tags,
Labels: app.Labels,
Status: model.DeploymentStatus_DEPLOYMENT_PENDING,
StatusReason: "The deployment is waiting to be planned",
Metadata: metadata,
Expand Down
2 changes: 1 addition & 1 deletion pkg/app/web/src/__fixtures__/dummy-application.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export const dummyApplication: Application.AsObject = {
pipedId: dummyPiped.id,
projectId: "project-1",
description: "",
tagsList: [],
labelsMap: [],
mostRecentlySuccessfulDeployment: {
deploymentId: "deployment-1",
completedAt: 0,
Expand Down
2 changes: 1 addition & 1 deletion pkg/app/web/src/__fixtures__/dummy-deployment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const dummyDeployment: Deployment.AsObject = {
trigger: dummyTrigger,
version: "0.0.0",
cloudProvider: "kube-1",
tagsList: [],
labelsMap: [],
createdAt: createdAt.unix(),
updatedAt: completedAt.unix(),
completedAt: completedAt.unix(),
Expand Down
2 changes: 0 additions & 2 deletions pkg/app/web/src/components/application-form/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,6 @@ export interface ApplicationFormValue {
remote: string;
branch: string;
};
tagsList: string[],
}

export type ApplicationFormProps = FormikProps<ApplicationFormValue> & {
Expand All @@ -178,7 +177,6 @@ export const emptyFormValues: ApplicationFormValue = {
remote: "",
branch: "",
},
tagsList: [],
};

export const ApplicationForm: FC<ApplicationFormProps> = memo(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ describe("AddApplicationDrawer", () => {
remote: "[email protected]:pipe-cd/debug.git",
},
repoPath: "path",
tagsList: [],
},
}),
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ export const EditApplicationDrawer: FC<EditApplicationDrawerProps> = memo(
repo: app.gitPath?.repo || { id: "", remote: "", branch: "" },
configFilename: app.gitPath?.configFilename || "",
cloudProvider: app.cloudProvider,
tagsList: app.tagsList,
}
: emptyFormValues,
validationSchema,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const fakeDeployment: Deployment.AsObject = {
},
version: "0.0.1",
cloudProvider: "",
tagsList: [],
labelsMap: [],
trigger: {
commit: {
hash: "3808585b46f1e90196d7ffe8dd04c807a251febc",
Expand Down
6 changes: 2 additions & 4 deletions pkg/app/web/src/modules/applications/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export const fetchApplications = createAsyncThunk<
enabled: options.activeStatus
? { value: options.activeStatus === "enabled" }
: undefined,
tagsList: [], // TODO: Specify tags for ListApplications
labelsMap: [], // TODO: Specify labels for ListApplications
},
});
return applicationsList as Application.AsObject[];
Expand All @@ -71,7 +71,7 @@ export const fetchApplicationsByEnv = createAsyncThunk<
kindsList: [],
name: "",
syncStatusesList: [],
tagsList: [],
labelsMap: [],
},
});
return applicationsList as Application.AsObject[];
Expand Down Expand Up @@ -108,7 +108,6 @@ export const addApplication = createAsyncThunk<
configFilename?: string;
kind: ApplicationKind;
cloudProvider: string;
tagsList: string[];
}
>(`${MODULE_NAME}/add`, async (props) => {
const { applicationId } = await applicationsAPI.addApplication({
Expand All @@ -125,7 +124,6 @@ export const addApplication = createAsyncThunk<
cloudProvider: props.cloudProvider,
kind: props.kind,
description: "",
tagsList: props.tagsList,
});

return applicationId;
Expand Down
2 changes: 1 addition & 1 deletion pkg/app/web/src/modules/deployments/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ const convertFilterOptions = (
statusesList: options.status
? [parseInt(options.status, 10) as DeploymentStatus]
: [],
tagsList: [], // TODO: Specify tags for ListDeployments
labelsMap: [], // TODO: Specify labels for ListDeployments
};
};

Expand Down
2 changes: 0 additions & 2 deletions pkg/app/web/src/modules/update-application/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ export const updateApplication = createAsyncThunk<
configFilename?: string;
kind: ApplicationKind;
cloudProvider: string;
tagsList: string[];
}
>(`${MODULE_NAME}/update`, async (values) => {
await applicationAPI.updateApplication({
Expand All @@ -38,7 +37,6 @@ export const updateApplication = createAsyncThunk<
pipedId: values.pipedId,
cloudProvider: values.cloudProvider,
kind: values.kind,
tagsList: values.tagsList,
});
});

Expand Down
19 changes: 10 additions & 9 deletions pkg/model/application.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,17 +50,18 @@ func MakeApplicationURL(baseURL, applicationID string) string {
return fmt.Sprintf("%s/applications/%s", strings.TrimSuffix(baseURL, "/"), applicationID)
}

// ContainTags checks if it has all the given tags.
func (d *Application) ContainTags(tags []string) bool {
if len(d.Tags) < len(tags) {
// ContainLabels checks if it has all the given labels.
func (a *Application) ContainLabels(labels map[string]string) bool {
if len(a.Labels) < len(labels) {
return false
}
tagMap := make(map[string]struct{}, len(d.Tags))
for i := range d.Tags {
tagMap[d.Tags[i]] = struct{}{}
}
for _, tag := range tags {
if _, ok := tagMap[tag]; !ok {

for k, v := range labels {
value, ok := a.Labels[k]
if !ok {
return false
}
if value != v {
return false
}
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/model/application.proto
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ message Application {
string cloud_provider = 8 [(validate.rules).string.min_len = 1];
// Additional description about application.
string description = 9;
// Custom attributes for filtering.
repeated string tags = 10;
// Custom attributes to identify applications.
map<string, string> labels = 10;

// Basic information about the most recently successful deployment.
// This also shows information about current running workloads.
Expand Down
42 changes: 29 additions & 13 deletions pkg/model/application_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,35 +48,51 @@ func TestMakeApplicationURL(t *testing.T) {
}
}

func TestApplication_ContainTags(t *testing.T) {
func TestApplication_ContainLabels(t *testing.T) {
testcases := []struct {
name string
app *Application
tags []string
want bool
name string
app *Application
labels map[string]string
want bool
}{
{
name: "all given tags aren't contained",
app: &Application{Tags: []string{"foo"}},
tags: []string{"foo", "bar"},
app: &Application{Labels: map[string]string{"key1": "value1"}},
labels: map[string]string{
"key1": "value1",
"key2": "value2",
},
want: false,
},
{
name: "a tag is contained",
app: &Application{Tags: []string{"foo", "bar"}},
tags: []string{"foo"},
name: "a label is contained",
app: &Application{Labels: map[string]string{
"key1": "value1",
"key2": "value2",
}},
labels: map[string]string{
"key1": "value1",
},
want: true,
},
{
name: "all tags are contained",
app: &Application{Tags: []string{"foo", "bar", "baz"}},
tags: []string{"baz", "foo", "bar"},
app: &Application{Labels: map[string]string{
"key1": "value1",
"key2": "value2",
"key3": "value3",
}},
labels: map[string]string{
"key1": "value1",
"key2": "value2",
"key3": "value3",
},
want: true,
},
}
for _, tc := range testcases {
t.Run(tc.name, func(t *testing.T) {
got := tc.app.ContainTags(tc.tags)
got := tc.app.ContainLabels(tc.labels)
assert.Equal(t, tc.want, got)
})
}
Expand Down
Loading