github.com/oam-dev/kubevela@v1.9.11/pkg/addon/registry.go (about)

     1  /*
     2  Copyright 2021 The KubeVela Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package addon
    18  
    19  import (
    20  	"context"
    21  	"encoding/json"
    22  	"fmt"
    23  
    24  	v1 "k8s.io/api/core/v1"
    25  	apierrors "k8s.io/apimachinery/pkg/api/errors"
    26  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    27  	"k8s.io/apimachinery/pkg/types"
    28  	"sigs.k8s.io/controller-runtime/pkg/client"
    29  
    30  	velatypes "github.com/oam-dev/kubevela/apis/types"
    31  )
    32  
    33  const registryConfigMapName = "vela-addon-registry"
    34  const registriesKey = "registries"
    35  
    36  // Registry represent a addon registry model
    37  type Registry struct {
    38  	Name string `json:"name"`
    39  
    40  	Helm   *HelmSource        `json:"helm,omitempty"`
    41  	Git    *GitAddonSource    `json:"git,omitempty"`
    42  	OSS    *OSSAddonSource    `json:"oss,omitempty"`
    43  	Gitee  *GiteeAddonSource  `json:"gitee,omitempty"`
    44  	Gitlab *GitlabAddonSource `json:"gitlab,omitempty"`
    45  }
    46  
    47  // RegistryDataStore CRUD addon registry data in configmap
    48  type RegistryDataStore interface {
    49  	ListRegistries(context.Context) ([]Registry, error)
    50  	AddRegistry(context.Context, Registry) error
    51  	DeleteRegistry(context.Context, string) error
    52  	UpdateRegistry(context.Context, Registry) error
    53  	GetRegistry(context.Context, string) (Registry, error)
    54  }
    55  
    56  // NewRegistryDataStore get RegistryDataStore operation interface
    57  func NewRegistryDataStore(cli client.Client) RegistryDataStore {
    58  	return registryImpl{cli}
    59  }
    60  
    61  type registryImpl struct {
    62  	client client.Client
    63  }
    64  
    65  func (r registryImpl) ListRegistries(ctx context.Context) ([]Registry, error) {
    66  	cm := &v1.ConfigMap{}
    67  	if err := r.client.Get(ctx, types.NamespacedName{Namespace: velatypes.DefaultKubeVelaNS, Name: registryConfigMapName}, cm); err != nil {
    68  		return nil, err
    69  	}
    70  	if _, ok := cm.Data[registriesKey]; !ok {
    71  		return nil, NewAddonError("Error addon registry configmap registry-key not exist")
    72  	}
    73  	registries := map[string]Registry{}
    74  	if err := json.Unmarshal([]byte(cm.Data[registriesKey]), &registries); err != nil {
    75  		return nil, err
    76  	}
    77  	var res []Registry
    78  	for _, registry := range registries {
    79  		res = append(res, registry)
    80  	}
    81  	return res, nil
    82  }
    83  
    84  func (r registryImpl) AddRegistry(ctx context.Context, registry Registry) error {
    85  	cm := &v1.ConfigMap{}
    86  	if err := r.client.Get(ctx, types.NamespacedName{Namespace: velatypes.DefaultKubeVelaNS, Name: registryConfigMapName}, cm); err != nil {
    87  		if apierrors.IsNotFound(err) {
    88  			b, err := json.Marshal(map[string]Registry{
    89  				registry.Name: registry,
    90  			})
    91  			if err != nil {
    92  				return err
    93  			}
    94  			cm = &v1.ConfigMap{
    95  				ObjectMeta: metav1.ObjectMeta{
    96  					Name:      registryConfigMapName,
    97  					Namespace: velatypes.DefaultKubeVelaNS,
    98  				},
    99  				Data: map[string]string{
   100  					registriesKey: string(b),
   101  				},
   102  			}
   103  			if err := r.client.Create(ctx, cm); err != nil {
   104  				return err
   105  			}
   106  			return nil
   107  		}
   108  		return err
   109  	}
   110  	registries := map[string]Registry{}
   111  	if err := json.Unmarshal([]byte(cm.Data[registriesKey]), &registries); err != nil {
   112  		return err
   113  	}
   114  	registries[registry.Name] = registry
   115  	b, err := json.Marshal(registries)
   116  	if err != nil {
   117  		return err
   118  	}
   119  	cm.Data = map[string]string{
   120  		registriesKey: string(b),
   121  	}
   122  	if err := r.client.Update(ctx, cm); err != nil {
   123  		return err
   124  	}
   125  	return nil
   126  }
   127  
   128  func (r registryImpl) DeleteRegistry(ctx context.Context, name string) error {
   129  	cm := &v1.ConfigMap{}
   130  	if err := r.client.Get(ctx, types.NamespacedName{Namespace: velatypes.DefaultKubeVelaNS, Name: registryConfigMapName}, cm); err != nil {
   131  		return err
   132  	}
   133  	registries := map[string]Registry{}
   134  	if err := json.Unmarshal([]byte(cm.Data[registriesKey]), &registries); err != nil {
   135  		return err
   136  	}
   137  	delete(registries, name)
   138  	b, err := json.Marshal(registries)
   139  	if err != nil {
   140  		return err
   141  	}
   142  	cm.Data = map[string]string{
   143  		registriesKey: string(b),
   144  	}
   145  	if err := r.client.Update(ctx, cm); err != nil {
   146  		return err
   147  	}
   148  	return nil
   149  }
   150  
   151  func (r registryImpl) UpdateRegistry(ctx context.Context, registry Registry) error {
   152  	cm := &v1.ConfigMap{}
   153  	if err := r.client.Get(ctx, types.NamespacedName{Namespace: velatypes.DefaultKubeVelaNS, Name: registryConfigMapName}, cm); err != nil {
   154  		return err
   155  	}
   156  	registries := map[string]Registry{}
   157  	if err := json.Unmarshal([]byte(cm.Data[registriesKey]), &registries); err != nil {
   158  		return err
   159  	}
   160  	if _, ok := registries[registry.Name]; !ok {
   161  		return fmt.Errorf("addon registry %s not exist", registry.Name)
   162  	}
   163  	registries[registry.Name] = registry
   164  	b, err := json.Marshal(registries)
   165  	if err != nil {
   166  		return err
   167  	}
   168  	cm.Data = map[string]string{
   169  		registriesKey: string(b),
   170  	}
   171  	if err := r.client.Update(ctx, cm); err != nil {
   172  		return err
   173  	}
   174  	return nil
   175  }
   176  
   177  func (r registryImpl) GetRegistry(ctx context.Context, name string) (Registry, error) {
   178  	var res Registry
   179  	cm := &v1.ConfigMap{}
   180  	if err := r.client.Get(ctx, types.NamespacedName{Namespace: velatypes.DefaultKubeVelaNS, Name: registryConfigMapName}, cm); err != nil {
   181  		return res, err
   182  	}
   183  	registries := map[string]Registry{}
   184  	if err := json.Unmarshal([]byte(cm.Data[registriesKey]), &registries); err != nil {
   185  		return res, err
   186  	}
   187  	var notExist bool
   188  	if res, notExist = registries[name]; !notExist {
   189  		return res, fmt.Errorf("registry name %s not found", name)
   190  	}
   191  	return res, nil
   192  }