diff --git a/internal/providers/gitlab/gitlab.go b/internal/providers/gitlab/gitlab.go index baf8a5b01f..c3c6226850 100644 --- a/internal/providers/gitlab/gitlab.go +++ b/internal/providers/gitlab/gitlab.go @@ -116,27 +116,6 @@ func (c *gitlabClient) GetCredential() provifv1.GitLabCredential { return c.cred } -// FetchAllProperties implements the provider interface -// TODO: Implement this -func (_ *gitlabClient) FetchAllProperties( - _ context.Context, _ *properties.Properties, _ minderv1.Entity, _ *properties.Properties, -) (*properties.Properties, error) { - return nil, nil -} - -// FetchProperty implements the provider interface -// TODO: Implement this -func (_ *gitlabClient) FetchProperty( - _ context.Context, _ *properties.Properties, _ minderv1.Entity, _ string) (*properties.Property, error) { - return nil, nil -} - -// GetEntityName implements the provider interface -// TODO: Implement this -func (_ *gitlabClient) GetEntityName(_ minderv1.Entity, _ *properties.Properties) (string, error) { - return "", nil -} - // SupportsEntity implements the Provider interface func (_ *gitlabClient) SupportsEntity(_ minderv1.Entity) bool { // TODO: implement diff --git a/internal/providers/gitlab/properties.go b/internal/providers/gitlab/properties.go new file mode 100644 index 0000000000..65fb7da258 --- /dev/null +++ b/internal/providers/gitlab/properties.go @@ -0,0 +1,83 @@ +// +// Copyright 2024 Stacklok, Inc. +// +// 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 gitlab + +import ( + "context" + "errors" + "fmt" + + "github.com/stacklok/minder/internal/entities/properties" + minderv1 "github.com/stacklok/minder/pkg/api/protobuf/go/minder/v1" +) + +const ( + // RepoPropertyGroupName represents the gitlab group + RepoPropertyGroupName = "gitlab/group_name" + // RepoPropertyProjectName represents the gitlab project + RepoPropertyProjectName = "gitlab/project_name" +) + +// FetchAllProperties implements the provider interface +// TODO: Implement this +func (_ *gitlabClient) FetchAllProperties( + _ context.Context, _ *properties.Properties, _ minderv1.Entity, _ *properties.Properties, +) (*properties.Properties, error) { + return nil, nil +} + +// FetchProperty implements the provider interface +// TODO: Implement this +func (_ *gitlabClient) FetchProperty( + _ context.Context, _ *properties.Properties, _ minderv1.Entity, _ string) (*properties.Property, error) { + return nil, nil +} + +// GetEntityName implements the provider interface +func (_ *gitlabClient) GetEntityName(entityType minderv1.Entity, props *properties.Properties) (string, error) { + if props == nil { + return "", errors.New("properties are nil") + } + + if entityType == minderv1.Entity_ENTITY_REPOSITORIES { + groupName, err := getStringProp(props, RepoPropertyGroupName) + if err != nil { + return "", err + } + + projectName, err := getStringProp(props, RepoPropertyProjectName) + if err != nil { + return "", err + } + + return formatRepoName(groupName, projectName), nil + } + + return "", fmt.Errorf("entity type %s not supported", entityType) +} + +func getStringProp(props *properties.Properties, key string) (string, error) { + value, err := props.GetProperty(key).AsString() + if err != nil { + return "", fmt.Errorf("property %s not found or not a string", key) + } + + return value, nil +} + +func formatRepoName(groupName, projectName string) string { + return groupName + "/" + projectName +} diff --git a/internal/providers/gitlab/properties_test.go b/internal/providers/gitlab/properties_test.go new file mode 100644 index 0000000000..e8dcae334c --- /dev/null +++ b/internal/providers/gitlab/properties_test.go @@ -0,0 +1,116 @@ +// +// Copyright 2024 Stacklok, Inc. +// +// 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 gitlab + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/stacklok/minder/internal/entities/properties" + minderv1 "github.com/stacklok/minder/pkg/api/protobuf/go/minder/v1" +) + +func Test_gitlabClient_GetEntityName(t *testing.T) { + t.Parallel() + + type args struct { + entityType minderv1.Entity + props *properties.Properties + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "nil properties", + args: args{ + entityType: minderv1.Entity_ENTITY_REPOSITORIES, + props: nil, + }, + want: "", + wantErr: true, + }, + { + name: "valid properties for repository succeeds", + args: args{ + entityType: minderv1.Entity_ENTITY_REPOSITORIES, + props: MustNewProperties(map[string]any{ + RepoPropertyGroupName: "group", + RepoPropertyProjectName: "project", + }), + }, + want: "group/project", + wantErr: false, + }, + { + name: "insufficient properties for repository fails (lacks project)", + args: args{ + entityType: minderv1.Entity_ENTITY_REPOSITORIES, + props: MustNewProperties(map[string]any{ + RepoPropertyGroupName: "group", + }), + }, + want: "", + wantErr: true, + }, + { + name: "insufficient properties for repository fails (lacks group)", + args: args{ + entityType: minderv1.Entity_ENTITY_REPOSITORIES, + props: MustNewProperties(map[string]any{ + RepoPropertyProjectName: "project", + }), + }, + want: "", + wantErr: true, + }, + { + name: "unsupported entity type fails", + args: args{ + entityType: minderv1.Entity_ENTITY_UNSPECIFIED, + props: MustNewProperties(map[string]any{}), + }, + want: "", + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + c := &gitlabClient{} + got, err := c.GetEntityName(tt.args.entityType, tt.args.props) + if tt.wantErr { + assert.Error(t, err) + } else { + assert.NoError(t, err) + assert.Equal(t, tt.want, got) + } + }) + } +} + +// MustNewProperties creates Properties from a map or panics +func MustNewProperties(props map[string]any) *properties.Properties { + p, err := properties.NewProperties(props) + if err != nil { + panic(err) + } + return p +}