Skip to content

Commit

Permalink
metadata client and rpaasv2 manager
Browse files Browse the repository at this point in the history
  • Loading branch information
gvicentin committed Jun 5, 2024
1 parent 2c6e24b commit d4adddc
Show file tree
Hide file tree
Showing 8 changed files with 410 additions and 182 deletions.
6 changes: 3 additions & 3 deletions cmd/plugin/rpaasv2/cmd/metadata.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ func createMetadata(meta []string, metaType string, isSet bool) (*types.Metadata
var item types.MetadataItem
if isSet {
if !strings.Contains(kv, "=") {
return nil, fmt.Errorf("invalid NAME=value pair: %v", kv)
return nil, fmt.Errorf("invalid NAME=value pair: %q", kv)
}
item.Name = strings.Split(kv, "=")[0]
item.Value = strings.Split(kv, "=")[1]
Expand All @@ -155,7 +155,7 @@ func runSetMetadata(c *cli.Context) error {
}

if !isValidMetadataType(metaType) {
return fmt.Errorf("invalid metadata type: %v", metaType)
return fmt.Errorf("invalid metadata type: %q", metaType)
}

metadata, err := createMetadata(keyValues, metaType, true)
Expand Down Expand Up @@ -216,7 +216,7 @@ func runUnsetMetadata(c *cli.Context) error {
}

if !isValidMetadataType(metaType) {
return fmt.Errorf("invalid metadata type: %v", metaType)
return fmt.Errorf("invalid metadata type: %q", metaType)
}

metadata, _ := createMetadata(keys, metaType, false)
Expand Down
6 changes: 3 additions & 3 deletions cmd/plugin/rpaasv2/cmd/metadata_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,12 @@ func TestSetMetadata(t *testing.T) {
{
name: "invalid metadata type",
args: []string{"-i", "my-instance", "-t", "invalid", "key=value"},
expectedErr: "invalid metadata type: invalid",
expectedErr: "invalid metadata type: \"invalid\"",
},
{
name: "invalid key value pair",
args: []string{"-i", "my-instance", "-t", "annotation", "key"},
expectedErr: "invalid NAME=value pair: key",
expectedErr: "invalid NAME=value pair: \"key\"",
},
{
name: "valid metadata",
Expand Down Expand Up @@ -161,7 +161,7 @@ func TestUnsetMetadata(t *testing.T) {
{
name: "invalid metadata type",
args: []string{"-i", "my-instance", "-t", "invalid", "key=value"},
expectedErr: "invalid metadata type: invalid",
expectedErr: "invalid metadata type: \"invalid\"",
},
{
name: "valid metadata",
Expand Down
112 changes: 0 additions & 112 deletions internal/pkg/rpaas/k8s.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import (
"net"
"net/url"
"regexp"
"slices"
"sort"
"strings"
"text/template"
Expand Down Expand Up @@ -1643,25 +1642,6 @@ func setLoadBalancerName(instance *v1alpha1.RpaasInstance, lbName string) {
instance.Spec.Service.Annotations[lbNameLabelKey] = lbName
}

func filterMetadata(meta map[string]string) map[string]string {
filterAnnotations := make(map[string]string)
for key, val := range meta {
if !strings.HasPrefix(key, defaultKeyLabelPrefix) {
filterAnnotations[key] = val
}
}
return filterAnnotations
}

func flattenMetadata(meta map[string]string) []string {
var result []string
for k, v := range meta {
result = append(result, fmt.Sprintf("%s=%s", k, v))
}
slices.Sort(result)
return result
}

func (m *k8sRpaasManager) GetInstanceInfo(ctx context.Context, instanceName string) (*clientTypes.InstanceInfo, error) {
instance, err := m.GetInstance(ctx, instanceName)
if err != nil {
Expand Down Expand Up @@ -2468,95 +2448,3 @@ func contains(ss []string, s string) bool {

return false
}

func (m *k8sRpaasManager) GetMetadata(ctx context.Context, instanceName string) (*clientTypes.Metadata, error) {
instance, err := m.GetInstance(ctx, instanceName)
if err != nil {
return nil, err
}

filteredLabels := filterMetadata(instance.Labels)
filteredAnnotations := filterMetadata(instance.Annotations)

metadata := &clientTypes.Metadata{}

for k, v := range filteredLabels {
item := clientTypes.MetadataItem{Name: k, Value: v}
metadata.Labels = append(metadata.Labels, item)
}

for k, v := range filteredAnnotations {
item := clientTypes.MetadataItem{Name: k, Value: v}
metadata.Annotations = append(metadata.Annotations, item)
}

return metadata, nil
}

func validateMetadata(items []clientTypes.MetadataItem) error {
for _, item := range items {
if strings.HasPrefix(item.Name, defaultKeyLabelPrefix) {
return &ValidationError{Msg: fmt.Sprintf("metadata key %q is reserved", item.Name)}
}
}
return nil
}

func (m *k8sRpaasManager) SetMetadata(ctx context.Context, instanceName string, metadata *clientTypes.Metadata) error {
instance, err := m.GetInstance(ctx, instanceName)
if err != nil {
return err
}

if err = validateMetadata(metadata.Labels); err != nil {
return err
}

if err = validateMetadata(metadata.Annotations); err != nil {
return err
}

originalInstance := instance.DeepCopy()

if metadata.Labels != nil {
for _, item := range metadata.Labels {
instance.Labels[item.Name] = item.Value
}
}

if metadata.Annotations != nil {
for _, item := range metadata.Annotations {
instance.Annotations[item.Name] = item.Value
}
}

return m.patchInstance(ctx, originalInstance, instance)
}

func (m *k8sRpaasManager) UnsetMetadata(ctx context.Context, instanceName string, metadata *clientTypes.Metadata) error {
instance, err := m.GetInstance(ctx, instanceName)
if err != nil {
return err
}
originalInstance := instance.DeepCopy()

if metadata.Labels != nil {
for _, item := range metadata.Labels {
if _, ok := instance.Labels[item.Name]; !ok {
return &NotFoundError{Msg: fmt.Sprintf("label %q not found in instance %q", item.Name, instanceName)}
}
delete(instance.Labels, item.Name)
}
}

if metadata.Annotations != nil {
for _, item := range metadata.Annotations {
if _, ok := instance.Annotations[item.Name]; !ok {
return &NotFoundError{Msg: fmt.Sprintf("annotation %q not found in instance %q", item.Name, instanceName)}
}
delete(instance.Annotations, item.Name)
}
}

return m.patchInstance(ctx, originalInstance, instance)
}
36 changes: 0 additions & 36 deletions internal/pkg/rpaas/k8s_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5187,39 +5187,3 @@ func Test_k8sRpaasManager_Debug(t *testing.T) {
}

}

func Test_k8sRpaasManager_GetMetadata(t *testing.T) {
scheme := newScheme()

instance := newEmptyRpaasInstance()
instance.ObjectMeta = metav1.ObjectMeta{
Name: "my-instance",
Namespace: "rpaasv2",
Labels: map[string]string{
"rpaas.extensions.tsuru.io/cluster-name": "my-cluster",
"rpaas.extensions.tsuru.io/instance-name": "my-instance",
"rpaas.extensions.tsuru.io/service-name": "my-service",
"rpaas.extensions.tsuru.io/team-owner": "my-team",
"rpaas_instance": "my-instance",
"rpaas_service": "my-service",
},
Annotations: map[string]string{
"rpaas.extensions.tsuru.io/cluster-name": "my-cluster",
"rpaas.extensions.tsuru.io/description": "my-description",
"rpaas.extensions.tsuru.io/tags": "my-tag=my-value",
"rpaas.extensions.tsuru.io/team-owner": "my-team",
"custom-annotation": "custom-value",
},
}

manager := &k8sRpaasManager{cli: fake.NewClientBuilder().WithScheme(scheme).WithRuntimeObjects(instance).Build()}
meta, err := manager.GetMetadata(context.Background(), "my-instance")
require.NoError(t, err)

assert.Equal(t, len(meta.Labels), 2)
assert.Contains(t, meta.Labels, clientTypes.MetadataItem{Name: "rpaas_instance", Value: "my-instance"})
assert.Contains(t, meta.Labels, clientTypes.MetadataItem{Name: "rpaas_service", Value: "my-service"})

assert.Equal(t, len(meta.Annotations), 1)
assert.Contains(t, meta.Annotations, clientTypes.MetadataItem{Name: "custom-annotation", Value: "custom-value"})
}
131 changes: 131 additions & 0 deletions internal/pkg/rpaas/metadata.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
// Copyright 2024 tsuru authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package rpaas

import (
"context"
"fmt"
"slices"
"strings"

clientTypes "github.com/tsuru/rpaas-operator/pkg/rpaas/client/types"
)

func filterMetadata(meta map[string]string) map[string]string {
filterAnnotations := make(map[string]string)
for key, val := range meta {
if !strings.HasPrefix(key, defaultKeyLabelPrefix) {
filterAnnotations[key] = val
}
}
return filterAnnotations
}

func flattenMetadata(meta map[string]string) []string {
var result []string
for k, v := range meta {
result = append(result, fmt.Sprintf("%s=%s", k, v))
}
slices.Sort(result)
return result
}

func (m *k8sRpaasManager) GetMetadata(ctx context.Context, instanceName string) (*clientTypes.Metadata, error) {
instance, err := m.GetInstance(ctx, instanceName)
if err != nil {
return nil, err
}

filteredLabels := filterMetadata(instance.Labels)
filteredAnnotations := filterMetadata(instance.Annotations)

metadata := &clientTypes.Metadata{}

for k, v := range filteredLabels {
item := clientTypes.MetadataItem{Name: k, Value: v}
metadata.Labels = append(metadata.Labels, item)
}

for k, v := range filteredAnnotations {
item := clientTypes.MetadataItem{Name: k, Value: v}
metadata.Annotations = append(metadata.Annotations, item)
}

return metadata, nil
}

func validateMetadata(items []clientTypes.MetadataItem) error {
for _, item := range items {
if strings.HasPrefix(item.Name, defaultKeyLabelPrefix) {
return &ValidationError{Msg: fmt.Sprintf("metadata key %q is reserved", item.Name)}
}
}
return nil
}

func (m *k8sRpaasManager) SetMetadata(ctx context.Context, instanceName string, metadata *clientTypes.Metadata) error {
instance, err := m.GetInstance(ctx, instanceName)
if err != nil {
return err
}

if err = validateMetadata(metadata.Labels); err != nil {
return err
}

if err = validateMetadata(metadata.Annotations); err != nil {
return err
}

originalInstance := instance.DeepCopy()

if metadata.Labels != nil {
if instance.Labels == nil {
instance.Labels = make(map[string]string)
}
for _, item := range metadata.Labels {
instance.Labels[item.Name] = item.Value
}
}

if metadata.Annotations != nil {
if instance.Annotations == nil {
instance.Annotations = make(map[string]string)
}
for _, item := range metadata.Annotations {
instance.Annotations[item.Name] = item.Value
}
}

return m.patchInstance(ctx, originalInstance, instance)
}

func (m *k8sRpaasManager) UnsetMetadata(ctx context.Context, instanceName string, metadata *clientTypes.Metadata) error {
instance, err := m.GetInstance(ctx, instanceName)
if err != nil {
return err
}
originalInstance := instance.DeepCopy()

if metadata.Labels != nil {
for _, item := range metadata.Labels {
if _, ok := instance.Labels[item.Name]; !ok {
return &NotFoundError{Msg: fmt.Sprintf("label %q not found in instance %q", item.Name, instanceName)}
}
delete(instance.Labels, item.Name)
}
}

if metadata.Annotations != nil {
for _, item := range metadata.Annotations {
if _, ok := instance.Annotations[item.Name]; !ok {
return &NotFoundError{Msg: fmt.Sprintf("annotation %q not found in instance %q", item.Name, instanceName)}
}
delete(instance.Annotations, item.Name)
}
}

return m.patchInstance(ctx, originalInstance, instance)
}
Loading

0 comments on commit d4adddc

Please sign in to comment.