From 2fab5b74a2f91f2c49446918b62658de3e5e2bab Mon Sep 17 00:00:00 2001 From: Andrew Merenbach Date: Mon, 19 Mar 2018 09:44:36 -0700 Subject: [PATCH 01/38] Clone repositor to new config service --- server/configmap/configmap.go | 170 +++++++++++++++++++++++++++++++ server/configmap/configmap.proto | 62 +++++++++++ 2 files changed, 232 insertions(+) create mode 100644 server/configmap/configmap.go create mode 100644 server/configmap/configmap.proto diff --git a/server/configmap/configmap.go b/server/configmap/configmap.go new file mode 100644 index 0000000000000..4f946243a6b9a --- /dev/null +++ b/server/configmap/configmap.go @@ -0,0 +1,170 @@ +package configmap + +import ( + "fmt" + "hash/fnv" + "strings" + + "github.com/argoproj/argo-cd/common" + appsv1 "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1" + appclientset "github.com/argoproj/argo-cd/pkg/client/clientset/versioned" + "github.com/argoproj/argo-cd/util/git" + "golang.org/x/net/context" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + apiv1 "k8s.io/api/core/v1" + apierr "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/selection" + "k8s.io/client-go/kubernetes" +) + +// Server provides a Repository service +type Server struct { + ns string + kubeclientset kubernetes.Interface + appclientset appclientset.Interface +} + +// NewServer returns a new instance of the Repository service +func NewServer(namespace string, kubeclientset kubernetes.Interface, appclientset appclientset.Interface) *Server { + return &Server{ + ns: namespace, + appclientset: appclientset, + kubeclientset: kubeclientset, + } +} + +// List returns list of repositories +func (s *Server) List(ctx context.Context, q *ConfigMapQuery) (*appsv1.ConfigMapList, error) { + listOpts := metav1.ListOptions{} + labelSelector := labels.NewSelector() + req, err := labels.NewRequirement(common.LabelKeySecretType, selection.Equals, []string{common.SecretTypeRepository}) + if err != nil { + return nil, err + } + labelSelector = labelSelector.Add(*req) + listOpts.LabelSelector = labelSelector.String() + repoSecrets, err := s.kubeclientset.CoreV1().Secrets(s.ns).List(listOpts) + if err != nil { + return nil, err + } + repoList := appsv1.RepositoryList{ + Items: make([]appsv1.Repository, len(repoSecrets.Items)), + } + for i, repoSec := range repoSecrets.Items { + repoList.Items[i] = *secretToRepo(&repoSec) + } + return &repoList, nil +} + +// Create creates a repository +func (s *Server) Create(ctx context.Context, r *appsv1.Repository) (*appsv1.Repository, error) { + shallowCopy := *r + r = &shallowCopy + r.Repo = git.NormalizeGitURL(r.Repo) + err := git.TestRepo(r.Repo, r.Username, r.Password, r.SSHPrivateKey) + if err != nil { + return nil, err + } + secName := repoURLToSecretName(r.Repo) + repoSecret := &apiv1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: secName, + Labels: map[string]string{ + common.LabelKeySecretType: common.SecretTypeRepository, + }, + }, + } + repoSecret.StringData = repoToStringData(r) + repoSecret, err = s.kubeclientset.CoreV1().Secrets(s.ns).Create(repoSecret) + if err != nil { + if apierr.IsAlreadyExists(err) { + return nil, grpc.Errorf(codes.AlreadyExists, "repository '%s' already exists", r.Repo) + } + return nil, err + } + return secretToRepo(repoSecret), nil +} + +func (s *Server) getRepoSecret(repo string) (*apiv1.Secret, error) { + secName := repoURLToSecretName(repo) + repoSecret, err := s.kubeclientset.CoreV1().Secrets(s.ns).Get(secName, metav1.GetOptions{}) + if err != nil { + if apierr.IsNotFound(err) { + return nil, grpc.Errorf(codes.NotFound, "repo '%s' not found", repo) + } + return nil, err + } + return repoSecret, nil +} + +// Get returns a repository by URL +func (s *Server) Get(ctx context.Context, q *RepoQuery) (*appsv1.Repository, error) { + repoSecret, err := s.getRepoSecret(q.Repo) + if err != nil { + return nil, err + } + return secretToRepo(repoSecret), nil +} + +// Update updates a repository +func (s *Server) Update(ctx context.Context, r *appsv1.Repository) (*appsv1.Repository, error) { + err := git.TestRepo(r.Repo, r.Username, r.Password, r.SSHPrivateKey) + if err != nil { + return nil, err + } + repoSecret, err := s.getRepoSecret(r.Repo) + if err != nil { + return nil, err + } + repoSecret.StringData = repoToStringData(r) + repoSecret, err = s.kubeclientset.CoreV1().Secrets(s.ns).Update(repoSecret) + if err != nil { + return nil, err + } + return secretToRepo(repoSecret), nil +} + +// UpdateREST updates a repository (from a REST request) +func (s *Server) UpdateREST(ctx context.Context, r *RepoUpdateRequest) (*appsv1.Repository, error) { + return s.Update(ctx, r.Repo) +} + +// Delete updates a repository +func (s *Server) Delete(ctx context.Context, q *RepoQuery) (*RepoResponse, error) { + secName := repoURLToSecretName(q.Repo) + err := s.kubeclientset.CoreV1().Secrets(s.ns).Delete(secName, &metav1.DeleteOptions{}) + return &RepoResponse{}, err +} + +// repoURLToSecretName hashes repo URL to the secret name using a formula. +// Part of the original repo name is incorporated for debugging purposes +func repoURLToSecretName(repo string) string { + repo = git.NormalizeGitURL(repo) + h := fnv.New32a() + _, _ = h.Write([]byte(repo)) + parts := strings.Split(strings.TrimSuffix(repo, ".git"), "/") + return fmt.Sprintf("repo-%s-%v", parts[len(parts)-1], h.Sum32()) +} + +// repoToStringData converts a repository object to string data for serialization to a secret +func repoToStringData(r *appsv1.Repository) map[string]string { + return map[string]string{ + "repository": r.Repo, + "username": r.Username, + "password": r.Password, + "sshPrivateKey": r.SSHPrivateKey, + } +} + +// secretToRepo converts a secret into a repository object +func secretToRepo(s *apiv1.Secret) *appsv1.Repository { + return &appsv1.Repository{ + Repo: string(s.Data["repository"]), + Username: string(s.Data["username"]), + Password: string(s.Data["password"]), + SSHPrivateKey: string(s.Data["sshPrivateKey"]), + } +} diff --git a/server/configmap/configmap.proto b/server/configmap/configmap.proto new file mode 100644 index 0000000000000..1548c50c72e21 --- /dev/null +++ b/server/configmap/configmap.proto @@ -0,0 +1,62 @@ +syntax = "proto3"; +option go_package = "github.com/argoproj/argo-cd/server/repository"; + +// Repository Service +// +// Repository Service API performs CRUD actions against repository resources +package configmap; + +import "gogoproto/gogo.proto"; +import "google/api/annotations.proto"; +import "k8s.io/api/core/v1/generated.proto"; +import "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1/generated.proto"; + + +// ConfigMapQuery is a query for ConfigMap resources +message ConfigMapQuery { + string name = 1; +} + +message ConfigMapResponse {} + +message DeleteConfigMapRequest { + string name = 1; + string namespace = 2; + string server = 3; +} + +// ConfigMapService +service ConfigMapService { + + // List returns list of ConfigMap + rpc List(ConfigMapQuery) returns (github.com.argoproj.argo_cd.pkg.apis.application.v1alpha1.ConfigMapList) { + option (google.api.http).get = "/api/v1/configmaps"; + } + + // Create creates a ConfigMap + rpc Create(github.com.argoproj.argo_cd.pkg.apis.application.v1alpha1.ConfigMap) returns (github.com.argoproj.argo_cd.pkg.apis.application.v1alpha1.Repository) { + option (google.api.http) = { + post: "/api/v1/configmaps" + body: "*" + }; + } + + // Get returns a ConfigMap by name + rpc Get(ConfigMapQuery) returns (github.com.argoproj.argo_cd.pkg.apis.application.v1alpha1.ConfigMap) { + option (google.api.http).get = "/api/v1/configmaps/{name}"; + } + + // Update updates a ConfigMap + rpc Update(github.com.argoproj.argo_cd.pkg.apis.application.v1alpha1.ConfigMap) returns (github.com.argoproj.argo_cd.pkg.apis.application.v1alpha1.ConfigMap) { + option (google.api.http) = { + put: "/api/v1/configmaps/{metadata.name}" + body: "*" + }; + } + + // Delete updates a ConfigMap + rpc Delete(DeleteConfigMapRequest) returns (ConfigMapResponse) { + option (google.api.http).delete = "/api/v1/configmaps/{name}"; + } + +} From de6acdbb26d25d07e11661256ff03c359e179f05 Mon Sep 17 00:00:00 2001 From: Andrew Merenbach Date: Mon, 19 Mar 2018 14:16:06 -0700 Subject: [PATCH 02/38] Update configmap files --- server/configmap/configmap.pb.go | 355 +++++++++++++++++++++++++++ server/configmap/configmap.pb.gw.go | 363 ++++++++++++++++++++++++++++ server/configmap/configmap.proto | 8 +- 3 files changed, 722 insertions(+), 4 deletions(-) create mode 100644 server/configmap/configmap.pb.go create mode 100644 server/configmap/configmap.pb.gw.go diff --git a/server/configmap/configmap.pb.go b/server/configmap/configmap.pb.go new file mode 100644 index 0000000000000..9bf596a20c27e --- /dev/null +++ b/server/configmap/configmap.pb.go @@ -0,0 +1,355 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// source: server/configmap/configmap.proto + +/* +Package configmap is a generated protocol buffer package. + +ConfigMap Service + +ConfigMap Service API performs CRUD actions against ConfigMap resources + +It is generated from these files: + server/configmap/configmap.proto + +It has these top-level messages: + ConfigMapQuery + ConfigMapResponse + DeleteConfigMapRequest +*/ +package configmap + +import proto "github.com/golang/protobuf/proto" +import fmt "fmt" +import math "math" +import _ "github.com/gogo/protobuf/gogoproto" +import _ "google.golang.org/genproto/googleapis/api/annotations" +import _ "k8s.io/api/core/v1" +import github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1 "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1" + +import ( + context "golang.org/x/net/context" + grpc "google.golang.org/grpc" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package + +// ConfigMapQuery is a query for ConfigMap resources +type ConfigMapQuery struct { + Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` +} + +func (m *ConfigMapQuery) Reset() { *m = ConfigMapQuery{} } +func (m *ConfigMapQuery) String() string { return proto.CompactTextString(m) } +func (*ConfigMapQuery) ProtoMessage() {} +func (*ConfigMapQuery) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } + +func (m *ConfigMapQuery) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +type ConfigMapResponse struct { +} + +func (m *ConfigMapResponse) Reset() { *m = ConfigMapResponse{} } +func (m *ConfigMapResponse) String() string { return proto.CompactTextString(m) } +func (*ConfigMapResponse) ProtoMessage() {} +func (*ConfigMapResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } + +type DeleteConfigMapRequest struct { + Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` + Namespace string `protobuf:"bytes,2,opt,name=namespace" json:"namespace,omitempty"` + Server string `protobuf:"bytes,3,opt,name=server" json:"server,omitempty"` +} + +func (m *DeleteConfigMapRequest) Reset() { *m = DeleteConfigMapRequest{} } +func (m *DeleteConfigMapRequest) String() string { return proto.CompactTextString(m) } +func (*DeleteConfigMapRequest) ProtoMessage() {} +func (*DeleteConfigMapRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } + +func (m *DeleteConfigMapRequest) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *DeleteConfigMapRequest) GetNamespace() string { + if m != nil { + return m.Namespace + } + return "" +} + +func (m *DeleteConfigMapRequest) GetServer() string { + if m != nil { + return m.Server + } + return "" +} + +func init() { + proto.RegisterType((*ConfigMapQuery)(nil), "configmap.ConfigMapQuery") + proto.RegisterType((*ConfigMapResponse)(nil), "configmap.ConfigMapResponse") + proto.RegisterType((*DeleteConfigMapRequest)(nil), "configmap.DeleteConfigMapRequest") +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// Client API for ConfigMapService service + +type ConfigMapServiceClient interface { + // List returns list of ConfigMap + List(ctx context.Context, in *ConfigMapQuery, opts ...grpc.CallOption) (*github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMapList, error) + // Create creates a ConfigMap + Create(ctx context.Context, in *github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap, opts ...grpc.CallOption) (*github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap, error) + // Get returns a ConfigMap by name + Get(ctx context.Context, in *ConfigMapQuery, opts ...grpc.CallOption) (*github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap, error) + // Update updates a ConfigMap + Update(ctx context.Context, in *github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap, opts ...grpc.CallOption) (*github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap, error) + // Delete updates a ConfigMap + Delete(ctx context.Context, in *DeleteConfigMapRequest, opts ...grpc.CallOption) (*ConfigMapResponse, error) +} + +type configMapServiceClient struct { + cc *grpc.ClientConn +} + +func NewConfigMapServiceClient(cc *grpc.ClientConn) ConfigMapServiceClient { + return &configMapServiceClient{cc} +} + +func (c *configMapServiceClient) List(ctx context.Context, in *ConfigMapQuery, opts ...grpc.CallOption) (*github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMapList, error) { + out := new(github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMapList) + err := grpc.Invoke(ctx, "/configmap.ConfigMapService/List", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *configMapServiceClient) Create(ctx context.Context, in *github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap, opts ...grpc.CallOption) (*github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap, error) { + out := new(github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap) + err := grpc.Invoke(ctx, "/configmap.ConfigMapService/Create", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *configMapServiceClient) Get(ctx context.Context, in *ConfigMapQuery, opts ...grpc.CallOption) (*github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap, error) { + out := new(github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap) + err := grpc.Invoke(ctx, "/configmap.ConfigMapService/Get", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *configMapServiceClient) Update(ctx context.Context, in *github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap, opts ...grpc.CallOption) (*github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap, error) { + out := new(github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap) + err := grpc.Invoke(ctx, "/configmap.ConfigMapService/Update", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *configMapServiceClient) Delete(ctx context.Context, in *DeleteConfigMapRequest, opts ...grpc.CallOption) (*ConfigMapResponse, error) { + out := new(ConfigMapResponse) + err := grpc.Invoke(ctx, "/configmap.ConfigMapService/Delete", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// Server API for ConfigMapService service + +type ConfigMapServiceServer interface { + // List returns list of ConfigMap + List(context.Context, *ConfigMapQuery) (*github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMapList, error) + // Create creates a ConfigMap + Create(context.Context, *github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap) (*github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap, error) + // Get returns a ConfigMap by name + Get(context.Context, *ConfigMapQuery) (*github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap, error) + // Update updates a ConfigMap + Update(context.Context, *github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap) (*github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap, error) + // Delete updates a ConfigMap + Delete(context.Context, *DeleteConfigMapRequest) (*ConfigMapResponse, error) +} + +func RegisterConfigMapServiceServer(s *grpc.Server, srv ConfigMapServiceServer) { + s.RegisterService(&_ConfigMapService_serviceDesc, srv) +} + +func _ConfigMapService_List_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ConfigMapQuery) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ConfigMapServiceServer).List(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/configmap.ConfigMapService/List", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ConfigMapServiceServer).List(ctx, req.(*ConfigMapQuery)) + } + return interceptor(ctx, in, info, handler) +} + +func _ConfigMapService_Create_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ConfigMapServiceServer).Create(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/configmap.ConfigMapService/Create", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ConfigMapServiceServer).Create(ctx, req.(*github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap)) + } + return interceptor(ctx, in, info, handler) +} + +func _ConfigMapService_Get_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ConfigMapQuery) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ConfigMapServiceServer).Get(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/configmap.ConfigMapService/Get", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ConfigMapServiceServer).Get(ctx, req.(*ConfigMapQuery)) + } + return interceptor(ctx, in, info, handler) +} + +func _ConfigMapService_Update_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ConfigMapServiceServer).Update(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/configmap.ConfigMapService/Update", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ConfigMapServiceServer).Update(ctx, req.(*github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap)) + } + return interceptor(ctx, in, info, handler) +} + +func _ConfigMapService_Delete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteConfigMapRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ConfigMapServiceServer).Delete(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/configmap.ConfigMapService/Delete", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ConfigMapServiceServer).Delete(ctx, req.(*DeleteConfigMapRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _ConfigMapService_serviceDesc = grpc.ServiceDesc{ + ServiceName: "configmap.ConfigMapService", + HandlerType: (*ConfigMapServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "List", + Handler: _ConfigMapService_List_Handler, + }, + { + MethodName: "Create", + Handler: _ConfigMapService_Create_Handler, + }, + { + MethodName: "Get", + Handler: _ConfigMapService_Get_Handler, + }, + { + MethodName: "Update", + Handler: _ConfigMapService_Update_Handler, + }, + { + MethodName: "Delete", + Handler: _ConfigMapService_Delete_Handler, + }, + }, + Streams: []grpc.StreamDesc{}, + Metadata: "server/configmap/configmap.proto", +} + +func init() { proto.RegisterFile("server/configmap/configmap.proto", fileDescriptor0) } + +var fileDescriptor0 = []byte{ + // 456 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x94, 0xc1, 0x6e, 0x13, 0x31, + 0x10, 0x86, 0xb5, 0x6d, 0xb5, 0x52, 0x7c, 0x40, 0x60, 0xaa, 0x92, 0x2e, 0x41, 0x6a, 0x57, 0x48, + 0xa0, 0x8a, 0xda, 0x0a, 0x5c, 0x10, 0x47, 0x5a, 0x09, 0x90, 0xe0, 0x40, 0x11, 0x17, 0x2e, 0x68, + 0xe2, 0x1d, 0x5c, 0x93, 0xcd, 0xda, 0xd8, 0xce, 0x4a, 0x08, 0x71, 0xe1, 0x82, 0xb8, 0xc2, 0xa3, + 0xf0, 0x08, 0x3c, 0x02, 0xaf, 0xc0, 0x83, 0xa0, 0x9d, 0xa4, 0xbb, 0x81, 0x2e, 0x3d, 0xe5, 0xc0, + 0x29, 0x13, 0xcf, 0xec, 0x3f, 0xbf, 0xbf, 0xd1, 0x98, 0xed, 0x05, 0xf4, 0x35, 0x7a, 0xa9, 0x6c, + 0xf5, 0xc6, 0xe8, 0x19, 0xb8, 0x2e, 0x12, 0xce, 0xdb, 0x68, 0xf9, 0xa0, 0x3d, 0xc8, 0xb6, 0xb5, + 0xd5, 0x96, 0x4e, 0x65, 0x13, 0x2d, 0x0a, 0xb2, 0x91, 0xb6, 0x56, 0x97, 0x28, 0xc1, 0x19, 0x09, + 0x55, 0x65, 0x23, 0x44, 0x63, 0xab, 0xb0, 0xcc, 0xe6, 0xd3, 0xfb, 0x41, 0x18, 0x4b, 0x59, 0x65, + 0x3d, 0xca, 0x7a, 0x2c, 0x35, 0x56, 0xe8, 0x21, 0x62, 0xb1, 0xac, 0x79, 0xa2, 0x4d, 0x3c, 0x9d, + 0x4f, 0x84, 0xb2, 0x33, 0x09, 0x9e, 0x5a, 0xbc, 0xa5, 0xe0, 0x50, 0x15, 0xd2, 0x4d, 0x75, 0xf3, + 0x71, 0x90, 0xe0, 0x5c, 0x69, 0x14, 0x89, 0xcb, 0x7a, 0x0c, 0xa5, 0x3b, 0x85, 0x73, 0x52, 0xf9, + 0x4d, 0x76, 0xe9, 0x88, 0xfc, 0x3e, 0x03, 0xf7, 0x7c, 0x8e, 0xfe, 0x3d, 0xe7, 0x6c, 0xab, 0x82, + 0x19, 0x0e, 0x93, 0xbd, 0xe4, 0xf6, 0xe0, 0x84, 0xe2, 0xfc, 0x2a, 0xbb, 0xd2, 0x56, 0x9d, 0x60, + 0x70, 0xb6, 0x0a, 0x98, 0x4f, 0xd8, 0xce, 0x31, 0x96, 0x18, 0x71, 0x25, 0xf5, 0x6e, 0x8e, 0x21, + 0xf6, 0x49, 0xf0, 0x11, 0x1b, 0x34, 0xbf, 0xc1, 0x81, 0xc2, 0xe1, 0x06, 0x25, 0xba, 0x03, 0xbe, + 0xc3, 0xd2, 0x05, 0xd8, 0xe1, 0x26, 0xa5, 0x96, 0xff, 0xee, 0x7e, 0x4d, 0xd9, 0xe5, 0x56, 0xfe, + 0x05, 0xfa, 0xda, 0x28, 0xe4, 0x9f, 0x13, 0xb6, 0xf5, 0xd4, 0x84, 0xc8, 0x77, 0x45, 0x07, 0xff, + 0xcf, 0x5b, 0x64, 0x8f, 0x45, 0xc7, 0x48, 0x9c, 0x31, 0xa2, 0xe0, 0xb5, 0x2a, 0x84, 0x9b, 0x6a, + 0xd1, 0x30, 0x12, 0x2b, 0x8c, 0xc4, 0x19, 0xa3, 0x4e, 0xaa, 0x69, 0x92, 0x67, 0x9f, 0x7e, 0xfe, + 0xfa, 0xb6, 0xb1, 0xcd, 0x39, 0x8d, 0xa4, 0x1e, 0x77, 0x03, 0x0f, 0xfc, 0x7b, 0xc2, 0xd2, 0x23, + 0x8f, 0x10, 0x91, 0x1f, 0xaf, 0xa3, 0x61, 0xb6, 0x16, 0x95, 0xfc, 0x06, 0x59, 0xbe, 0x96, 0xf7, + 0x58, 0x7e, 0x90, 0x1c, 0xf0, 0x2f, 0x09, 0xdb, 0x7c, 0x84, 0x17, 0xe2, 0x5b, 0x8f, 0x8f, 0x7d, + 0xf2, 0x71, 0x9d, 0xef, 0x9e, 0xf7, 0x21, 0x3f, 0x34, 0xc3, 0xff, 0xc8, 0x7f, 0x24, 0x2c, 0x7d, + 0xe9, 0x8a, 0xff, 0x8d, 0xe0, 0x21, 0x39, 0xbf, 0x95, 0xe5, 0x7d, 0xce, 0x67, 0x18, 0xa1, 0x80, + 0x08, 0x82, 0xae, 0xd0, 0x10, 0x2d, 0x59, 0xba, 0x58, 0x05, 0xbe, 0xbf, 0xc2, 0xb4, 0x7f, 0x3b, + 0xb2, 0x51, 0x1f, 0xf6, 0x76, 0xab, 0x96, 0xcc, 0x0e, 0xfe, 0xcd, 0xec, 0xa1, 0x78, 0x75, 0xe7, + 0xa2, 0x07, 0xe0, 0xef, 0x17, 0x6a, 0x92, 0xd2, 0xaa, 0xdf, 0xfb, 0x1d, 0x00, 0x00, 0xff, 0xff, + 0x26, 0x60, 0x63, 0x0d, 0xbc, 0x04, 0x00, 0x00, +} diff --git a/server/configmap/configmap.pb.gw.go b/server/configmap/configmap.pb.gw.go new file mode 100644 index 0000000000000..1518bcfdfde57 --- /dev/null +++ b/server/configmap/configmap.pb.gw.go @@ -0,0 +1,363 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: server/configmap/configmap.proto + +/* +Package configmap is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package configmap + +import ( + "io" + "net/http" + + "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1" + "github.com/golang/protobuf/proto" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/grpc-ecosystem/grpc-gateway/utilities" + "golang.org/x/net/context" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/status" +) + +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray + +var ( + filter_ConfigMapService_List_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} +) + +func request_ConfigMapService_List_0(ctx context.Context, marshaler runtime.Marshaler, client ConfigMapServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ConfigMapQuery + var metadata runtime.ServerMetadata + + if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_ConfigMapService_List_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.List(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func request_ConfigMapService_Create_0(ctx context.Context, marshaler runtime.Marshaler, client ConfigMapServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq v1alpha1.ConfigMap + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.Create(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func request_ConfigMapService_Get_0(ctx context.Context, marshaler runtime.Marshaler, client ConfigMapServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ConfigMapQuery + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") + } + + protoReq.Name, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) + } + + msg, err := client.Get(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func request_ConfigMapService_Update_0(ctx context.Context, marshaler runtime.Marshaler, client ConfigMapServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq v1alpha1.ConfigMap + var metadata runtime.ServerMetadata + + if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["metadata.name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "metadata.name") + } + + protoReq.GetMetadata().Name, err = runtime.StringP(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "metadata.name", err) + } + + msg, err := client.Update(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +var ( + filter_ConfigMapService_Delete_0 = &utilities.DoubleArray{Encoding: map[string]int{"name": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} +) + +func request_ConfigMapService_Delete_0(ctx context.Context, marshaler runtime.Marshaler, client ConfigMapServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq DeleteConfigMapRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["name"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") + } + + protoReq.Name, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) + } + + if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_ConfigMapService_Delete_0); err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.Delete(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +// RegisterConfigMapServiceHandlerFromEndpoint is same as RegisterConfigMapServiceHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterConfigMapServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterConfigMapServiceHandler(ctx, mux, conn) +} + +// RegisterConfigMapServiceHandler registers the http handlers for service ConfigMapService to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterConfigMapServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterConfigMapServiceHandlerClient(ctx, mux, NewConfigMapServiceClient(conn)) +} + +// RegisterConfigMapServiceHandler registers the http handlers for service ConfigMapService to "mux". +// The handlers forward requests to the grpc endpoint over the given implementation of "ConfigMapServiceClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "ConfigMapServiceClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "ConfigMapServiceClient" to call the correct interceptors. +func RegisterConfigMapServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client ConfigMapServiceClient) error { + + mux.Handle("GET", pattern_ConfigMapService_List_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + if cn, ok := w.(http.CloseNotifier); ok { + go func(done <-chan struct{}, closed <-chan bool) { + select { + case <-done: + case <-closed: + cancel() + } + }(ctx.Done(), cn.CloseNotify()) + } + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_ConfigMapService_List_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_ConfigMapService_List_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_ConfigMapService_Create_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + if cn, ok := w.(http.CloseNotifier); ok { + go func(done <-chan struct{}, closed <-chan bool) { + select { + case <-done: + case <-closed: + cancel() + } + }(ctx.Done(), cn.CloseNotify()) + } + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_ConfigMapService_Create_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_ConfigMapService_Create_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("GET", pattern_ConfigMapService_Get_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + if cn, ok := w.(http.CloseNotifier); ok { + go func(done <-chan struct{}, closed <-chan bool) { + select { + case <-done: + case <-closed: + cancel() + } + }(ctx.Done(), cn.CloseNotify()) + } + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_ConfigMapService_Get_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_ConfigMapService_Get_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("PUT", pattern_ConfigMapService_Update_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + if cn, ok := w.(http.CloseNotifier); ok { + go func(done <-chan struct{}, closed <-chan bool) { + select { + case <-done: + case <-closed: + cancel() + } + }(ctx.Done(), cn.CloseNotify()) + } + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_ConfigMapService_Update_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_ConfigMapService_Update_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("DELETE", pattern_ConfigMapService_Delete_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + if cn, ok := w.(http.CloseNotifier); ok { + go func(done <-chan struct{}, closed <-chan bool) { + select { + case <-done: + case <-closed: + cancel() + } + }(ctx.Done(), cn.CloseNotify()) + } + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_ConfigMapService_Delete_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_ConfigMapService_Delete_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_ConfigMapService_List_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "configmaps"}, "")) + + pattern_ConfigMapService_Create_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "configmaps"}, "")) + + pattern_ConfigMapService_Get_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v1", "configmaps", "name"}, "")) + + pattern_ConfigMapService_Update_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v1", "configmaps", "metadata.name"}, "")) + + pattern_ConfigMapService_Delete_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v1", "configmaps", "name"}, "")) +) + +var ( + forward_ConfigMapService_List_0 = runtime.ForwardResponseMessage + + forward_ConfigMapService_Create_0 = runtime.ForwardResponseMessage + + forward_ConfigMapService_Get_0 = runtime.ForwardResponseMessage + + forward_ConfigMapService_Update_0 = runtime.ForwardResponseMessage + + forward_ConfigMapService_Delete_0 = runtime.ForwardResponseMessage +) diff --git a/server/configmap/configmap.proto b/server/configmap/configmap.proto index 1548c50c72e21..61d9a71f13427 100644 --- a/server/configmap/configmap.proto +++ b/server/configmap/configmap.proto @@ -1,9 +1,9 @@ syntax = "proto3"; -option go_package = "github.com/argoproj/argo-cd/server/repository"; +option go_package = "github.com/argoproj/argo-cd/server/configmap"; -// Repository Service +// ConfigMap Service // -// Repository Service API performs CRUD actions against repository resources +// ConfigMap Service API performs CRUD actions against ConfigMap resources package configmap; import "gogoproto/gogo.proto"; @@ -34,7 +34,7 @@ service ConfigMapService { } // Create creates a ConfigMap - rpc Create(github.com.argoproj.argo_cd.pkg.apis.application.v1alpha1.ConfigMap) returns (github.com.argoproj.argo_cd.pkg.apis.application.v1alpha1.Repository) { + rpc Create(github.com.argoproj.argo_cd.pkg.apis.application.v1alpha1.ConfigMap) returns (github.com.argoproj.argo_cd.pkg.apis.application.v1alpha1.ConfigMap) { option (google.api.http) = { post: "/api/v1/configmaps" body: "*" From ee751c263f32b6ec8176420ef6b5571ce698bc92 Mon Sep 17 00:00:00 2001 From: Andrew Merenbach Date: Mon, 19 Mar 2018 15:02:00 -0700 Subject: [PATCH 03/38] Update configmap --- server/configmap/configmap.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/server/configmap/configmap.go b/server/configmap/configmap.go index 4f946243a6b9a..dc95a5c831059 100644 --- a/server/configmap/configmap.go +++ b/server/configmap/configmap.go @@ -50,8 +50,8 @@ func (s *Server) List(ctx context.Context, q *ConfigMapQuery) (*appsv1.ConfigMap if err != nil { return nil, err } - repoList := appsv1.RepositoryList{ - Items: make([]appsv1.Repository, len(repoSecrets.Items)), + repoList := appsv1.ConfigMapList{ + Items: make([]appsv1.ConfigMap, len(repoSecrets.Items)), } for i, repoSec := range repoSecrets.Items { repoList.Items[i] = *secretToRepo(&repoSec) @@ -101,7 +101,7 @@ func (s *Server) getRepoSecret(repo string) (*apiv1.Secret, error) { } // Get returns a repository by URL -func (s *Server) Get(ctx context.Context, q *RepoQuery) (*appsv1.Repository, error) { +func (s *Server) Get(ctx context.Context, q *ConfigMapQuery) (*appsv1.Repository, error) { repoSecret, err := s.getRepoSecret(q.Repo) if err != nil { return nil, err @@ -133,10 +133,10 @@ func (s *Server) UpdateREST(ctx context.Context, r *RepoUpdateRequest) (*appsv1. } // Delete updates a repository -func (s *Server) Delete(ctx context.Context, q *RepoQuery) (*RepoResponse, error) { +func (s *Server) Delete(ctx context.Context, q *ConfigMapQuery) (*ConfigMapResponse, error) { secName := repoURLToSecretName(q.Repo) err := s.kubeclientset.CoreV1().Secrets(s.ns).Delete(secName, &metav1.DeleteOptions{}) - return &RepoResponse{}, err + return &ConfigMapResponse{}, err } // repoURLToSecretName hashes repo URL to the secret name using a formula. From f7066f67fc478c5d0092c1915e39b8d0192e5212 Mon Sep 17 00:00:00 2001 From: Andrew Merenbach Date: Mon, 19 Mar 2018 15:02:09 -0700 Subject: [PATCH 04/38] Don't make a service for this --- server/configmap/configmap.go | 170 ------------- server/configmap/configmap.pb.go | 355 --------------------------- server/configmap/configmap.pb.gw.go | 363 ---------------------------- server/configmap/configmap.proto | 62 ----- 4 files changed, 950 deletions(-) delete mode 100644 server/configmap/configmap.go delete mode 100644 server/configmap/configmap.pb.go delete mode 100644 server/configmap/configmap.pb.gw.go delete mode 100644 server/configmap/configmap.proto diff --git a/server/configmap/configmap.go b/server/configmap/configmap.go deleted file mode 100644 index dc95a5c831059..0000000000000 --- a/server/configmap/configmap.go +++ /dev/null @@ -1,170 +0,0 @@ -package configmap - -import ( - "fmt" - "hash/fnv" - "strings" - - "github.com/argoproj/argo-cd/common" - appsv1 "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1" - appclientset "github.com/argoproj/argo-cd/pkg/client/clientset/versioned" - "github.com/argoproj/argo-cd/util/git" - "golang.org/x/net/context" - "google.golang.org/grpc" - "google.golang.org/grpc/codes" - apiv1 "k8s.io/api/core/v1" - apierr "k8s.io/apimachinery/pkg/api/errors" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/selection" - "k8s.io/client-go/kubernetes" -) - -// Server provides a Repository service -type Server struct { - ns string - kubeclientset kubernetes.Interface - appclientset appclientset.Interface -} - -// NewServer returns a new instance of the Repository service -func NewServer(namespace string, kubeclientset kubernetes.Interface, appclientset appclientset.Interface) *Server { - return &Server{ - ns: namespace, - appclientset: appclientset, - kubeclientset: kubeclientset, - } -} - -// List returns list of repositories -func (s *Server) List(ctx context.Context, q *ConfigMapQuery) (*appsv1.ConfigMapList, error) { - listOpts := metav1.ListOptions{} - labelSelector := labels.NewSelector() - req, err := labels.NewRequirement(common.LabelKeySecretType, selection.Equals, []string{common.SecretTypeRepository}) - if err != nil { - return nil, err - } - labelSelector = labelSelector.Add(*req) - listOpts.LabelSelector = labelSelector.String() - repoSecrets, err := s.kubeclientset.CoreV1().Secrets(s.ns).List(listOpts) - if err != nil { - return nil, err - } - repoList := appsv1.ConfigMapList{ - Items: make([]appsv1.ConfigMap, len(repoSecrets.Items)), - } - for i, repoSec := range repoSecrets.Items { - repoList.Items[i] = *secretToRepo(&repoSec) - } - return &repoList, nil -} - -// Create creates a repository -func (s *Server) Create(ctx context.Context, r *appsv1.Repository) (*appsv1.Repository, error) { - shallowCopy := *r - r = &shallowCopy - r.Repo = git.NormalizeGitURL(r.Repo) - err := git.TestRepo(r.Repo, r.Username, r.Password, r.SSHPrivateKey) - if err != nil { - return nil, err - } - secName := repoURLToSecretName(r.Repo) - repoSecret := &apiv1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: secName, - Labels: map[string]string{ - common.LabelKeySecretType: common.SecretTypeRepository, - }, - }, - } - repoSecret.StringData = repoToStringData(r) - repoSecret, err = s.kubeclientset.CoreV1().Secrets(s.ns).Create(repoSecret) - if err != nil { - if apierr.IsAlreadyExists(err) { - return nil, grpc.Errorf(codes.AlreadyExists, "repository '%s' already exists", r.Repo) - } - return nil, err - } - return secretToRepo(repoSecret), nil -} - -func (s *Server) getRepoSecret(repo string) (*apiv1.Secret, error) { - secName := repoURLToSecretName(repo) - repoSecret, err := s.kubeclientset.CoreV1().Secrets(s.ns).Get(secName, metav1.GetOptions{}) - if err != nil { - if apierr.IsNotFound(err) { - return nil, grpc.Errorf(codes.NotFound, "repo '%s' not found", repo) - } - return nil, err - } - return repoSecret, nil -} - -// Get returns a repository by URL -func (s *Server) Get(ctx context.Context, q *ConfigMapQuery) (*appsv1.Repository, error) { - repoSecret, err := s.getRepoSecret(q.Repo) - if err != nil { - return nil, err - } - return secretToRepo(repoSecret), nil -} - -// Update updates a repository -func (s *Server) Update(ctx context.Context, r *appsv1.Repository) (*appsv1.Repository, error) { - err := git.TestRepo(r.Repo, r.Username, r.Password, r.SSHPrivateKey) - if err != nil { - return nil, err - } - repoSecret, err := s.getRepoSecret(r.Repo) - if err != nil { - return nil, err - } - repoSecret.StringData = repoToStringData(r) - repoSecret, err = s.kubeclientset.CoreV1().Secrets(s.ns).Update(repoSecret) - if err != nil { - return nil, err - } - return secretToRepo(repoSecret), nil -} - -// UpdateREST updates a repository (from a REST request) -func (s *Server) UpdateREST(ctx context.Context, r *RepoUpdateRequest) (*appsv1.Repository, error) { - return s.Update(ctx, r.Repo) -} - -// Delete updates a repository -func (s *Server) Delete(ctx context.Context, q *ConfigMapQuery) (*ConfigMapResponse, error) { - secName := repoURLToSecretName(q.Repo) - err := s.kubeclientset.CoreV1().Secrets(s.ns).Delete(secName, &metav1.DeleteOptions{}) - return &ConfigMapResponse{}, err -} - -// repoURLToSecretName hashes repo URL to the secret name using a formula. -// Part of the original repo name is incorporated for debugging purposes -func repoURLToSecretName(repo string) string { - repo = git.NormalizeGitURL(repo) - h := fnv.New32a() - _, _ = h.Write([]byte(repo)) - parts := strings.Split(strings.TrimSuffix(repo, ".git"), "/") - return fmt.Sprintf("repo-%s-%v", parts[len(parts)-1], h.Sum32()) -} - -// repoToStringData converts a repository object to string data for serialization to a secret -func repoToStringData(r *appsv1.Repository) map[string]string { - return map[string]string{ - "repository": r.Repo, - "username": r.Username, - "password": r.Password, - "sshPrivateKey": r.SSHPrivateKey, - } -} - -// secretToRepo converts a secret into a repository object -func secretToRepo(s *apiv1.Secret) *appsv1.Repository { - return &appsv1.Repository{ - Repo: string(s.Data["repository"]), - Username: string(s.Data["username"]), - Password: string(s.Data["password"]), - SSHPrivateKey: string(s.Data["sshPrivateKey"]), - } -} diff --git a/server/configmap/configmap.pb.go b/server/configmap/configmap.pb.go deleted file mode 100644 index 9bf596a20c27e..0000000000000 --- a/server/configmap/configmap.pb.go +++ /dev/null @@ -1,355 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: server/configmap/configmap.proto - -/* -Package configmap is a generated protocol buffer package. - -ConfigMap Service - -ConfigMap Service API performs CRUD actions against ConfigMap resources - -It is generated from these files: - server/configmap/configmap.proto - -It has these top-level messages: - ConfigMapQuery - ConfigMapResponse - DeleteConfigMapRequest -*/ -package configmap - -import proto "github.com/golang/protobuf/proto" -import fmt "fmt" -import math "math" -import _ "github.com/gogo/protobuf/gogoproto" -import _ "google.golang.org/genproto/googleapis/api/annotations" -import _ "k8s.io/api/core/v1" -import github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1 "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1" - -import ( - context "golang.org/x/net/context" - grpc "google.golang.org/grpc" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package - -// ConfigMapQuery is a query for ConfigMap resources -type ConfigMapQuery struct { - Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` -} - -func (m *ConfigMapQuery) Reset() { *m = ConfigMapQuery{} } -func (m *ConfigMapQuery) String() string { return proto.CompactTextString(m) } -func (*ConfigMapQuery) ProtoMessage() {} -func (*ConfigMapQuery) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} } - -func (m *ConfigMapQuery) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -type ConfigMapResponse struct { -} - -func (m *ConfigMapResponse) Reset() { *m = ConfigMapResponse{} } -func (m *ConfigMapResponse) String() string { return proto.CompactTextString(m) } -func (*ConfigMapResponse) ProtoMessage() {} -func (*ConfigMapResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} } - -type DeleteConfigMapRequest struct { - Name string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"` - Namespace string `protobuf:"bytes,2,opt,name=namespace" json:"namespace,omitempty"` - Server string `protobuf:"bytes,3,opt,name=server" json:"server,omitempty"` -} - -func (m *DeleteConfigMapRequest) Reset() { *m = DeleteConfigMapRequest{} } -func (m *DeleteConfigMapRequest) String() string { return proto.CompactTextString(m) } -func (*DeleteConfigMapRequest) ProtoMessage() {} -func (*DeleteConfigMapRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} } - -func (m *DeleteConfigMapRequest) GetName() string { - if m != nil { - return m.Name - } - return "" -} - -func (m *DeleteConfigMapRequest) GetNamespace() string { - if m != nil { - return m.Namespace - } - return "" -} - -func (m *DeleteConfigMapRequest) GetServer() string { - if m != nil { - return m.Server - } - return "" -} - -func init() { - proto.RegisterType((*ConfigMapQuery)(nil), "configmap.ConfigMapQuery") - proto.RegisterType((*ConfigMapResponse)(nil), "configmap.ConfigMapResponse") - proto.RegisterType((*DeleteConfigMapRequest)(nil), "configmap.DeleteConfigMapRequest") -} - -// Reference imports to suppress errors if they are not otherwise used. -var _ context.Context -var _ grpc.ClientConn - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the grpc package it is being compiled against. -const _ = grpc.SupportPackageIsVersion4 - -// Client API for ConfigMapService service - -type ConfigMapServiceClient interface { - // List returns list of ConfigMap - List(ctx context.Context, in *ConfigMapQuery, opts ...grpc.CallOption) (*github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMapList, error) - // Create creates a ConfigMap - Create(ctx context.Context, in *github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap, opts ...grpc.CallOption) (*github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap, error) - // Get returns a ConfigMap by name - Get(ctx context.Context, in *ConfigMapQuery, opts ...grpc.CallOption) (*github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap, error) - // Update updates a ConfigMap - Update(ctx context.Context, in *github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap, opts ...grpc.CallOption) (*github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap, error) - // Delete updates a ConfigMap - Delete(ctx context.Context, in *DeleteConfigMapRequest, opts ...grpc.CallOption) (*ConfigMapResponse, error) -} - -type configMapServiceClient struct { - cc *grpc.ClientConn -} - -func NewConfigMapServiceClient(cc *grpc.ClientConn) ConfigMapServiceClient { - return &configMapServiceClient{cc} -} - -func (c *configMapServiceClient) List(ctx context.Context, in *ConfigMapQuery, opts ...grpc.CallOption) (*github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMapList, error) { - out := new(github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMapList) - err := grpc.Invoke(ctx, "/configmap.ConfigMapService/List", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *configMapServiceClient) Create(ctx context.Context, in *github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap, opts ...grpc.CallOption) (*github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap, error) { - out := new(github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap) - err := grpc.Invoke(ctx, "/configmap.ConfigMapService/Create", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *configMapServiceClient) Get(ctx context.Context, in *ConfigMapQuery, opts ...grpc.CallOption) (*github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap, error) { - out := new(github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap) - err := grpc.Invoke(ctx, "/configmap.ConfigMapService/Get", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *configMapServiceClient) Update(ctx context.Context, in *github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap, opts ...grpc.CallOption) (*github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap, error) { - out := new(github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap) - err := grpc.Invoke(ctx, "/configmap.ConfigMapService/Update", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -func (c *configMapServiceClient) Delete(ctx context.Context, in *DeleteConfigMapRequest, opts ...grpc.CallOption) (*ConfigMapResponse, error) { - out := new(ConfigMapResponse) - err := grpc.Invoke(ctx, "/configmap.ConfigMapService/Delete", in, out, c.cc, opts...) - if err != nil { - return nil, err - } - return out, nil -} - -// Server API for ConfigMapService service - -type ConfigMapServiceServer interface { - // List returns list of ConfigMap - List(context.Context, *ConfigMapQuery) (*github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMapList, error) - // Create creates a ConfigMap - Create(context.Context, *github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap) (*github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap, error) - // Get returns a ConfigMap by name - Get(context.Context, *ConfigMapQuery) (*github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap, error) - // Update updates a ConfigMap - Update(context.Context, *github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap) (*github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap, error) - // Delete updates a ConfigMap - Delete(context.Context, *DeleteConfigMapRequest) (*ConfigMapResponse, error) -} - -func RegisterConfigMapServiceServer(s *grpc.Server, srv ConfigMapServiceServer) { - s.RegisterService(&_ConfigMapService_serviceDesc, srv) -} - -func _ConfigMapService_List_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ConfigMapQuery) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ConfigMapServiceServer).List(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/configmap.ConfigMapService/List", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ConfigMapServiceServer).List(ctx, req.(*ConfigMapQuery)) - } - return interceptor(ctx, in, info, handler) -} - -func _ConfigMapService_Create_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ConfigMapServiceServer).Create(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/configmap.ConfigMapService/Create", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ConfigMapServiceServer).Create(ctx, req.(*github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap)) - } - return interceptor(ctx, in, info, handler) -} - -func _ConfigMapService_Get_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(ConfigMapQuery) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ConfigMapServiceServer).Get(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/configmap.ConfigMapService/Get", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ConfigMapServiceServer).Get(ctx, req.(*ConfigMapQuery)) - } - return interceptor(ctx, in, info, handler) -} - -func _ConfigMapService_Update_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ConfigMapServiceServer).Update(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/configmap.ConfigMapService/Update", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ConfigMapServiceServer).Update(ctx, req.(*github_com_argoproj_argo_cd_pkg_apis_application_v1alpha1.ConfigMap)) - } - return interceptor(ctx, in, info, handler) -} - -func _ConfigMapService_Delete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { - in := new(DeleteConfigMapRequest) - if err := dec(in); err != nil { - return nil, err - } - if interceptor == nil { - return srv.(ConfigMapServiceServer).Delete(ctx, in) - } - info := &grpc.UnaryServerInfo{ - Server: srv, - FullMethod: "/configmap.ConfigMapService/Delete", - } - handler := func(ctx context.Context, req interface{}) (interface{}, error) { - return srv.(ConfigMapServiceServer).Delete(ctx, req.(*DeleteConfigMapRequest)) - } - return interceptor(ctx, in, info, handler) -} - -var _ConfigMapService_serviceDesc = grpc.ServiceDesc{ - ServiceName: "configmap.ConfigMapService", - HandlerType: (*ConfigMapServiceServer)(nil), - Methods: []grpc.MethodDesc{ - { - MethodName: "List", - Handler: _ConfigMapService_List_Handler, - }, - { - MethodName: "Create", - Handler: _ConfigMapService_Create_Handler, - }, - { - MethodName: "Get", - Handler: _ConfigMapService_Get_Handler, - }, - { - MethodName: "Update", - Handler: _ConfigMapService_Update_Handler, - }, - { - MethodName: "Delete", - Handler: _ConfigMapService_Delete_Handler, - }, - }, - Streams: []grpc.StreamDesc{}, - Metadata: "server/configmap/configmap.proto", -} - -func init() { proto.RegisterFile("server/configmap/configmap.proto", fileDescriptor0) } - -var fileDescriptor0 = []byte{ - // 456 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x94, 0xc1, 0x6e, 0x13, 0x31, - 0x10, 0x86, 0xb5, 0x6d, 0xb5, 0x52, 0x7c, 0x40, 0x60, 0xaa, 0x92, 0x2e, 0x41, 0x6a, 0x57, 0x48, - 0xa0, 0x8a, 0xda, 0x0a, 0x5c, 0x10, 0x47, 0x5a, 0x09, 0x90, 0xe0, 0x40, 0x11, 0x17, 0x2e, 0x68, - 0xe2, 0x1d, 0x5c, 0x93, 0xcd, 0xda, 0xd8, 0xce, 0x4a, 0x08, 0x71, 0xe1, 0x82, 0xb8, 0xc2, 0xa3, - 0xf0, 0x08, 0x3c, 0x02, 0xaf, 0xc0, 0x83, 0xa0, 0x9d, 0xa4, 0xbb, 0x81, 0x2e, 0x3d, 0xe5, 0xc0, - 0x29, 0x13, 0xcf, 0xec, 0x3f, 0xbf, 0xbf, 0xd1, 0x98, 0xed, 0x05, 0xf4, 0x35, 0x7a, 0xa9, 0x6c, - 0xf5, 0xc6, 0xe8, 0x19, 0xb8, 0x2e, 0x12, 0xce, 0xdb, 0x68, 0xf9, 0xa0, 0x3d, 0xc8, 0xb6, 0xb5, - 0xd5, 0x96, 0x4e, 0x65, 0x13, 0x2d, 0x0a, 0xb2, 0x91, 0xb6, 0x56, 0x97, 0x28, 0xc1, 0x19, 0x09, - 0x55, 0x65, 0x23, 0x44, 0x63, 0xab, 0xb0, 0xcc, 0xe6, 0xd3, 0xfb, 0x41, 0x18, 0x4b, 0x59, 0x65, - 0x3d, 0xca, 0x7a, 0x2c, 0x35, 0x56, 0xe8, 0x21, 0x62, 0xb1, 0xac, 0x79, 0xa2, 0x4d, 0x3c, 0x9d, - 0x4f, 0x84, 0xb2, 0x33, 0x09, 0x9e, 0x5a, 0xbc, 0xa5, 0xe0, 0x50, 0x15, 0xd2, 0x4d, 0x75, 0xf3, - 0x71, 0x90, 0xe0, 0x5c, 0x69, 0x14, 0x89, 0xcb, 0x7a, 0x0c, 0xa5, 0x3b, 0x85, 0x73, 0x52, 0xf9, - 0x4d, 0x76, 0xe9, 0x88, 0xfc, 0x3e, 0x03, 0xf7, 0x7c, 0x8e, 0xfe, 0x3d, 0xe7, 0x6c, 0xab, 0x82, - 0x19, 0x0e, 0x93, 0xbd, 0xe4, 0xf6, 0xe0, 0x84, 0xe2, 0xfc, 0x2a, 0xbb, 0xd2, 0x56, 0x9d, 0x60, - 0x70, 0xb6, 0x0a, 0x98, 0x4f, 0xd8, 0xce, 0x31, 0x96, 0x18, 0x71, 0x25, 0xf5, 0x6e, 0x8e, 0x21, - 0xf6, 0x49, 0xf0, 0x11, 0x1b, 0x34, 0xbf, 0xc1, 0x81, 0xc2, 0xe1, 0x06, 0x25, 0xba, 0x03, 0xbe, - 0xc3, 0xd2, 0x05, 0xd8, 0xe1, 0x26, 0xa5, 0x96, 0xff, 0xee, 0x7e, 0x4d, 0xd9, 0xe5, 0x56, 0xfe, - 0x05, 0xfa, 0xda, 0x28, 0xe4, 0x9f, 0x13, 0xb6, 0xf5, 0xd4, 0x84, 0xc8, 0x77, 0x45, 0x07, 0xff, - 0xcf, 0x5b, 0x64, 0x8f, 0x45, 0xc7, 0x48, 0x9c, 0x31, 0xa2, 0xe0, 0xb5, 0x2a, 0x84, 0x9b, 0x6a, - 0xd1, 0x30, 0x12, 0x2b, 0x8c, 0xc4, 0x19, 0xa3, 0x4e, 0xaa, 0x69, 0x92, 0x67, 0x9f, 0x7e, 0xfe, - 0xfa, 0xb6, 0xb1, 0xcd, 0x39, 0x8d, 0xa4, 0x1e, 0x77, 0x03, 0x0f, 0xfc, 0x7b, 0xc2, 0xd2, 0x23, - 0x8f, 0x10, 0x91, 0x1f, 0xaf, 0xa3, 0x61, 0xb6, 0x16, 0x95, 0xfc, 0x06, 0x59, 0xbe, 0x96, 0xf7, - 0x58, 0x7e, 0x90, 0x1c, 0xf0, 0x2f, 0x09, 0xdb, 0x7c, 0x84, 0x17, 0xe2, 0x5b, 0x8f, 0x8f, 0x7d, - 0xf2, 0x71, 0x9d, 0xef, 0x9e, 0xf7, 0x21, 0x3f, 0x34, 0xc3, 0xff, 0xc8, 0x7f, 0x24, 0x2c, 0x7d, - 0xe9, 0x8a, 0xff, 0x8d, 0xe0, 0x21, 0x39, 0xbf, 0x95, 0xe5, 0x7d, 0xce, 0x67, 0x18, 0xa1, 0x80, - 0x08, 0x82, 0xae, 0xd0, 0x10, 0x2d, 0x59, 0xba, 0x58, 0x05, 0xbe, 0xbf, 0xc2, 0xb4, 0x7f, 0x3b, - 0xb2, 0x51, 0x1f, 0xf6, 0x76, 0xab, 0x96, 0xcc, 0x0e, 0xfe, 0xcd, 0xec, 0xa1, 0x78, 0x75, 0xe7, - 0xa2, 0x07, 0xe0, 0xef, 0x17, 0x6a, 0x92, 0xd2, 0xaa, 0xdf, 0xfb, 0x1d, 0x00, 0x00, 0xff, 0xff, - 0x26, 0x60, 0x63, 0x0d, 0xbc, 0x04, 0x00, 0x00, -} diff --git a/server/configmap/configmap.pb.gw.go b/server/configmap/configmap.pb.gw.go deleted file mode 100644 index 1518bcfdfde57..0000000000000 --- a/server/configmap/configmap.pb.gw.go +++ /dev/null @@ -1,363 +0,0 @@ -// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. -// source: server/configmap/configmap.proto - -/* -Package configmap is a reverse proxy. - -It translates gRPC into RESTful JSON APIs. -*/ -package configmap - -import ( - "io" - "net/http" - - "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1" - "github.com/golang/protobuf/proto" - "github.com/grpc-ecosystem/grpc-gateway/runtime" - "github.com/grpc-ecosystem/grpc-gateway/utilities" - "golang.org/x/net/context" - "google.golang.org/grpc" - "google.golang.org/grpc/codes" - "google.golang.org/grpc/grpclog" - "google.golang.org/grpc/status" -) - -var _ codes.Code -var _ io.Reader -var _ status.Status -var _ = runtime.String -var _ = utilities.NewDoubleArray - -var ( - filter_ConfigMapService_List_0 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)} -) - -func request_ConfigMapService_List_0(ctx context.Context, marshaler runtime.Marshaler, client ConfigMapServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq ConfigMapQuery - var metadata runtime.ServerMetadata - - if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_ConfigMapService_List_0); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - - msg, err := client.List(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -func request_ConfigMapService_Create_0(ctx context.Context, marshaler runtime.Marshaler, client ConfigMapServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq v1alpha1.ConfigMap - var metadata runtime.ServerMetadata - - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - - msg, err := client.Create(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -func request_ConfigMapService_Get_0(ctx context.Context, marshaler runtime.Marshaler, client ConfigMapServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq ConfigMapQuery - var metadata runtime.ServerMetadata - - var ( - val string - ok bool - err error - _ = err - ) - - val, ok = pathParams["name"] - if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") - } - - protoReq.Name, err = runtime.String(val) - - if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) - } - - msg, err := client.Get(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -func request_ConfigMapService_Update_0(ctx context.Context, marshaler runtime.Marshaler, client ConfigMapServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq v1alpha1.ConfigMap - var metadata runtime.ServerMetadata - - if err := marshaler.NewDecoder(req.Body).Decode(&protoReq); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - - var ( - val string - ok bool - err error - _ = err - ) - - val, ok = pathParams["metadata.name"] - if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "metadata.name") - } - - protoReq.GetMetadata().Name, err = runtime.StringP(val) - - if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "metadata.name", err) - } - - msg, err := client.Update(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -var ( - filter_ConfigMapService_Delete_0 = &utilities.DoubleArray{Encoding: map[string]int{"name": 0}, Base: []int{1, 1, 0}, Check: []int{0, 1, 2}} -) - -func request_ConfigMapService_Delete_0(ctx context.Context, marshaler runtime.Marshaler, client ConfigMapServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { - var protoReq DeleteConfigMapRequest - var metadata runtime.ServerMetadata - - var ( - val string - ok bool - err error - _ = err - ) - - val, ok = pathParams["name"] - if !ok { - return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name") - } - - protoReq.Name, err = runtime.String(val) - - if err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err) - } - - if err := runtime.PopulateQueryParameters(&protoReq, req.URL.Query(), filter_ConfigMapService_Delete_0); err != nil { - return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) - } - - msg, err := client.Delete(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) - return msg, metadata, err - -} - -// RegisterConfigMapServiceHandlerFromEndpoint is same as RegisterConfigMapServiceHandler but -// automatically dials to "endpoint" and closes the connection when "ctx" gets done. -func RegisterConfigMapServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { - conn, err := grpc.Dial(endpoint, opts...) - if err != nil { - return err - } - defer func() { - if err != nil { - if cerr := conn.Close(); cerr != nil { - grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr) - } - return - } - go func() { - <-ctx.Done() - if cerr := conn.Close(); cerr != nil { - grpclog.Printf("Failed to close conn to %s: %v", endpoint, cerr) - } - }() - }() - - return RegisterConfigMapServiceHandler(ctx, mux, conn) -} - -// RegisterConfigMapServiceHandler registers the http handlers for service ConfigMapService to "mux". -// The handlers forward requests to the grpc endpoint over "conn". -func RegisterConfigMapServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { - return RegisterConfigMapServiceHandlerClient(ctx, mux, NewConfigMapServiceClient(conn)) -} - -// RegisterConfigMapServiceHandler registers the http handlers for service ConfigMapService to "mux". -// The handlers forward requests to the grpc endpoint over the given implementation of "ConfigMapServiceClient". -// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "ConfigMapServiceClient" -// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in -// "ConfigMapServiceClient" to call the correct interceptors. -func RegisterConfigMapServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client ConfigMapServiceClient) error { - - mux.Handle("GET", pattern_ConfigMapService_List_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - if cn, ok := w.(http.CloseNotifier); ok { - go func(done <-chan struct{}, closed <-chan bool) { - select { - case <-done: - case <-closed: - cancel() - } - }(ctx.Done(), cn.CloseNotify()) - } - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_ConfigMapService_List_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_ConfigMapService_List_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - mux.Handle("POST", pattern_ConfigMapService_Create_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - if cn, ok := w.(http.CloseNotifier); ok { - go func(done <-chan struct{}, closed <-chan bool) { - select { - case <-done: - case <-closed: - cancel() - } - }(ctx.Done(), cn.CloseNotify()) - } - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_ConfigMapService_Create_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_ConfigMapService_Create_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - mux.Handle("GET", pattern_ConfigMapService_Get_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - if cn, ok := w.(http.CloseNotifier); ok { - go func(done <-chan struct{}, closed <-chan bool) { - select { - case <-done: - case <-closed: - cancel() - } - }(ctx.Done(), cn.CloseNotify()) - } - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_ConfigMapService_Get_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_ConfigMapService_Get_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - mux.Handle("PUT", pattern_ConfigMapService_Update_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - if cn, ok := w.(http.CloseNotifier); ok { - go func(done <-chan struct{}, closed <-chan bool) { - select { - case <-done: - case <-closed: - cancel() - } - }(ctx.Done(), cn.CloseNotify()) - } - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_ConfigMapService_Update_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_ConfigMapService_Update_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - mux.Handle("DELETE", pattern_ConfigMapService_Delete_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { - ctx, cancel := context.WithCancel(req.Context()) - defer cancel() - if cn, ok := w.(http.CloseNotifier); ok { - go func(done <-chan struct{}, closed <-chan bool) { - select { - case <-done: - case <-closed: - cancel() - } - }(ctx.Done(), cn.CloseNotify()) - } - inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) - rctx, err := runtime.AnnotateContext(ctx, mux, req) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - resp, md, err := request_ConfigMapService_Delete_0(rctx, inboundMarshaler, client, req, pathParams) - ctx = runtime.NewServerMetadataContext(ctx, md) - if err != nil { - runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) - return - } - - forward_ConfigMapService_Delete_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) - - }) - - return nil -} - -var ( - pattern_ConfigMapService_List_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "configmaps"}, "")) - - pattern_ConfigMapService_Create_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"api", "v1", "configmaps"}, "")) - - pattern_ConfigMapService_Get_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v1", "configmaps", "name"}, "")) - - pattern_ConfigMapService_Update_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v1", "configmaps", "metadata.name"}, "")) - - pattern_ConfigMapService_Delete_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"api", "v1", "configmaps", "name"}, "")) -) - -var ( - forward_ConfigMapService_List_0 = runtime.ForwardResponseMessage - - forward_ConfigMapService_Create_0 = runtime.ForwardResponseMessage - - forward_ConfigMapService_Get_0 = runtime.ForwardResponseMessage - - forward_ConfigMapService_Update_0 = runtime.ForwardResponseMessage - - forward_ConfigMapService_Delete_0 = runtime.ForwardResponseMessage -) diff --git a/server/configmap/configmap.proto b/server/configmap/configmap.proto deleted file mode 100644 index 61d9a71f13427..0000000000000 --- a/server/configmap/configmap.proto +++ /dev/null @@ -1,62 +0,0 @@ -syntax = "proto3"; -option go_package = "github.com/argoproj/argo-cd/server/configmap"; - -// ConfigMap Service -// -// ConfigMap Service API performs CRUD actions against ConfigMap resources -package configmap; - -import "gogoproto/gogo.proto"; -import "google/api/annotations.proto"; -import "k8s.io/api/core/v1/generated.proto"; -import "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1/generated.proto"; - - -// ConfigMapQuery is a query for ConfigMap resources -message ConfigMapQuery { - string name = 1; -} - -message ConfigMapResponse {} - -message DeleteConfigMapRequest { - string name = 1; - string namespace = 2; - string server = 3; -} - -// ConfigMapService -service ConfigMapService { - - // List returns list of ConfigMap - rpc List(ConfigMapQuery) returns (github.com.argoproj.argo_cd.pkg.apis.application.v1alpha1.ConfigMapList) { - option (google.api.http).get = "/api/v1/configmaps"; - } - - // Create creates a ConfigMap - rpc Create(github.com.argoproj.argo_cd.pkg.apis.application.v1alpha1.ConfigMap) returns (github.com.argoproj.argo_cd.pkg.apis.application.v1alpha1.ConfigMap) { - option (google.api.http) = { - post: "/api/v1/configmaps" - body: "*" - }; - } - - // Get returns a ConfigMap by name - rpc Get(ConfigMapQuery) returns (github.com.argoproj.argo_cd.pkg.apis.application.v1alpha1.ConfigMap) { - option (google.api.http).get = "/api/v1/configmaps/{name}"; - } - - // Update updates a ConfigMap - rpc Update(github.com.argoproj.argo_cd.pkg.apis.application.v1alpha1.ConfigMap) returns (github.com.argoproj.argo_cd.pkg.apis.application.v1alpha1.ConfigMap) { - option (google.api.http) = { - put: "/api/v1/configmaps/{metadata.name}" - body: "*" - }; - } - - // Delete updates a ConfigMap - rpc Delete(DeleteConfigMapRequest) returns (ConfigMapResponse) { - option (google.api.http).delete = "/api/v1/configmaps/{name}"; - } - -} From 3a25184261bf7832362affe085030b64f96479bd Mon Sep 17 00:00:00 2001 From: Andrew Merenbach Date: Mon, 19 Mar 2018 15:10:31 -0700 Subject: [PATCH 05/38] Add config map command-line flag --- cmd/argocd/commands/install.go | 1 + 1 file changed, 1 insertion(+) diff --git a/cmd/argocd/commands/install.go b/cmd/argocd/commands/install.go index 61421a0d0e8e9..bdccd81db97db 100644 --- a/cmd/argocd/commands/install.go +++ b/cmd/argocd/commands/install.go @@ -28,6 +28,7 @@ func NewInstallCommand() *cobra.Command { } command.Flags().BoolVar(&installOpts.Upgrade, "upgrade", false, "upgrade controller/ui deployments and configmap if already installed") command.Flags().BoolVar(&installOpts.DryRun, "dry-run", false, "print the kubernetes manifests to stdout instead of installing") + command.Flags().StringVar(&installOpts.configMap, "config-map", "", "apply settings from a Kubernetes config map") command.Flags().StringVar(&installOpts.Namespace, "install-namespace", install.DefaultInstallNamespace, "install into a specific namespace") command.Flags().StringVar(&installOpts.ControllerImage, "controller-image", install.DefaultControllerImage, "use a specified controller image") command.Flags().StringVar(&installOpts.ServerImage, "server-image", install.DefaultServerImage, "use a specified api server image") From 467205a01b26102824ba1f26877efa3138e213f1 Mon Sep 17 00:00:00 2001 From: Andrew Merenbach Date: Mon, 19 Mar 2018 16:17:29 -0700 Subject: [PATCH 06/38] Add config map install step --- install/install.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/install/install.go b/install/install.go index 8ea1eb1c909fb..07d1997a32f36 100644 --- a/install/install.go +++ b/install/install.go @@ -37,9 +37,11 @@ var ( DefaultRepoServerImage = imageNamespace + "/argocd-repo-server:" + imageTag ) +// InstallOptions stores a collection of installation settings. type InstallOptions struct { DryRun bool Upgrade bool + ConfigMap string Namespace string ControllerImage string UIImage string @@ -74,6 +76,7 @@ func NewInstaller(config *rest.Config, opts InstallOptions) (*Installer, error) func (i *Installer) Install() { i.InstallNamespace() + i.InstallConfigMap() i.InstallApplicationCRD() i.InstallApplicationController() i.InstallArgoCDServer() @@ -168,6 +171,10 @@ func (i *Installer) InstallArgoCDRepoServer() { i.MustInstallResource(kube.MustToUnstructured(&argoCDRepoServerService)) } +func (i *Installer) InstallConfigMap() { + // install configuration here +} + func (i *Installer) unmarshalManifest(fileName string, obj interface{}) { yamlBytes, err := i.box.MustBytes(fileName) errors.CheckError(err) From 63076f25a8b0fd384436753ecde0cacb19613180 Mon Sep 17 00:00:00 2001 From: Andrew Merenbach Date: Mon, 19 Mar 2018 16:44:04 -0700 Subject: [PATCH 07/38] Add new secrets file --- common/common.go | 3 +++ util/secrets.go | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 util/secrets.go diff --git a/common/common.go b/common/common.go index cdebf67f30551..22175f50d4d63 100644 --- a/common/common.go +++ b/common/common.go @@ -14,6 +14,9 @@ const ( // SecretTypeCluster indicates a secret type of cluster SecretTypeCluster = "cluster" + + // SecretTypePassword indicates a password + SecretTypePassword = "password" ) var ( diff --git a/util/secrets.go b/util/secrets.go new file mode 100644 index 0000000000000..9ddb7a5a4f753 --- /dev/null +++ b/util/secrets.go @@ -0,0 +1,46 @@ + +import "github.com/argoproj/argo-cd/common" + +// CreateSecret stores a new secret in Kubernetes. +func (s *Server) CreateSecret(name, value, secretType string) (secret *apiv1.Secret, err error) { + newSecret := &apiv1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: secName, + Labels: map[string]string{ + common.LabelKeySecretType: secretType, + }, + }, + StringData: value, + } + secret, err = s.kubeclientset.CoreV1().Secrets(s.ns).Create(newSecret) + if err != nil { + secret = nil + } + return +} + +// ReadSecret retrieves a secret from Kubernetes. +func (s *Server) ReadSecret(name string) (secret *apiv1.Secret, err error) { + secret, err = s.kubeclientset.CoreV1().Secrets(s.ns).Get(name, metav1.GetOptions{}) + if err != nil { + secret = nil + } + return +} + +// UpdateSecret updates an existing secret in Kubernetes. +func (s *Server) UpdateSecret(name, value string) (secret *apiv1.Secret, err error) { + existingSecret = s.ReadSecret(name) + existingSecret.StringData = value + secret, err = s.kubeclientset.CoreV1().Secrets(s.ns).Update(existingSecret) + if err != nil { + secret = nil + } + return +} + +// DeleteSecret removes a secret from Kubernetes. +func (s *Server) DeleteSecret(name string) (err error) { + err = s.kubeclientset.CoreV1().Secrets(s.ns).Delete(name, &metav1.DeleteOptions{}) + return +} From adb8a2d2a09b004712880203f2fc0fd12b0ba0f8 Mon Sep 17 00:00:00 2001 From: Andrew Merenbach Date: Mon, 19 Mar 2018 17:01:11 -0700 Subject: [PATCH 08/38] Update secret retrieval --- util/secrets.go | 52 +++++++++++++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 19 deletions(-) diff --git a/util/secrets.go b/util/secrets.go index 9ddb7a5a4f753..4c2b94b3e116a 100644 --- a/util/secrets.go +++ b/util/secrets.go @@ -1,46 +1,60 @@ +package util -import "github.com/argoproj/argo-cd/common" +import ( + "fmt" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + "github.com/argoproj/argo-cd/common" + apiv1 "k8s.io/api/core/v1" + "k8s.io/client-go/kubernetes" +) + +func makeKubeclientset() (kubeclientset *kubernetes.Clientset) { + kubeclientset, err := kubernetes.NewForConfig(config) + if err != nil { + return fmt.Errorf("REST config invalid: %s", err) + } + _, err = kubeclientset.ServerVersion() + if err != nil { + return fmt.Errorf("REST config invalid: %s", err) + } + return nil +} // CreateSecret stores a new secret in Kubernetes. -func (s *Server) CreateSecret(name, value, secretType string) (secret *apiv1.Secret, err error) { +func CreateSecret(namespace, name string, value map[string]string, secretType string) (secret *apiv1.Secret, err error) { newSecret := &apiv1.Secret{ ObjectMeta: metav1.ObjectMeta{ - Name: secName, + Name: name, Labels: map[string]string{ common.LabelKeySecretType: secretType, }, }, StringData: value, } - secret, err = s.kubeclientset.CoreV1().Secrets(s.ns).Create(newSecret) - if err != nil { - secret = nil - } + secret, err = makeKubeclientset().CoreV1().Secrets(namespace).Create(newSecret) return } // ReadSecret retrieves a secret from Kubernetes. -func (s *Server) ReadSecret(name string) (secret *apiv1.Secret, err error) { - secret, err = s.kubeclientset.CoreV1().Secrets(s.ns).Get(name, metav1.GetOptions{}) - if err != nil { - secret = nil - } +func ReadSecret(namespace, name string) (secret *apiv1.Secret, err error) { + secret, err = makeKubeclientset().CoreV1().Secrets(namespace).Get(name, metav1.GetOptions{}) return } // UpdateSecret updates an existing secret in Kubernetes. -func (s *Server) UpdateSecret(name, value string) (secret *apiv1.Secret, err error) { - existingSecret = s.ReadSecret(name) - existingSecret.StringData = value - secret, err = s.kubeclientset.CoreV1().Secrets(s.ns).Update(existingSecret) +func UpdateSecret(namespace, name string, value map[string]string) (secret *apiv1.Secret, err error) { + existingSecret, err := ReadSecret(namespace, name) if err != nil { - secret = nil + existingSecret.StringData = value + secret, err = makeKubeclientset().CoreV1().Secrets(namespace).Update(existingSecret) } return } // DeleteSecret removes a secret from Kubernetes. -func (s *Server) DeleteSecret(name string) (err error) { - err = s.kubeclientset.CoreV1().Secrets(s.ns).Delete(name, &metav1.DeleteOptions{}) +func DeleteSecret(namespace, name string) (err error) { + err = makeKubeclientset().CoreV1().Secrets(namespace).Delete(name, &metav1.DeleteOptions{}) return } From c278f49ceef667f208bed2cfad1f21e387731765 Mon Sep 17 00:00:00 2001 From: Andrew Merenbach Date: Mon, 19 Mar 2018 17:36:27 -0700 Subject: [PATCH 09/38] Flesh out secret retrieval API --- cmd/argocd/commands/install.go | 2 +- install/install.go | 6 +++++- util/secrets.go | 39 ++++++++++++++++++---------------- 3 files changed, 27 insertions(+), 20 deletions(-) diff --git a/cmd/argocd/commands/install.go b/cmd/argocd/commands/install.go index bdccd81db97db..3c0a55cfe2a37 100644 --- a/cmd/argocd/commands/install.go +++ b/cmd/argocd/commands/install.go @@ -28,7 +28,7 @@ func NewInstallCommand() *cobra.Command { } command.Flags().BoolVar(&installOpts.Upgrade, "upgrade", false, "upgrade controller/ui deployments and configmap if already installed") command.Flags().BoolVar(&installOpts.DryRun, "dry-run", false, "print the kubernetes manifests to stdout instead of installing") - command.Flags().StringVar(&installOpts.configMap, "config-map", "", "apply settings from a Kubernetes config map") + command.Flags().StringVar(&installOpts.ConfigMap, "config-map", "", "apply settings from a Kubernetes config map") command.Flags().StringVar(&installOpts.Namespace, "install-namespace", install.DefaultInstallNamespace, "install into a specific namespace") command.Flags().StringVar(&installOpts.ControllerImage, "controller-image", install.DefaultControllerImage, "use a specified controller image") command.Flags().StringVar(&installOpts.ServerImage, "server-image", install.DefaultServerImage, "use a specified api server image") diff --git a/install/install.go b/install/install.go index 07d1997a32f36..c1b5c7a4648c0 100644 --- a/install/install.go +++ b/install/install.go @@ -6,6 +6,7 @@ import ( "strings" "github.com/argoproj/argo-cd/errors" + "github.com/argoproj/argo-cd/util" "github.com/argoproj/argo-cd/util/diff" "github.com/argoproj/argo-cd/util/kube" "github.com/ghodss/yaml" @@ -171,8 +172,11 @@ func (i *Installer) InstallArgoCDRepoServer() { i.MustInstallResource(kube.MustToUnstructured(&argoCDRepoServerService)) } -func (i *Installer) InstallConfigMap() { +func (i *Installer) InstallConfigMap() (err error) { // install configuration here + config := i.config + server, err := util.NewSecretServer("namespace", config) + fmt.Println("HELLO, WORLD!") } func (i *Installer) unmarshalManifest(fileName string, obj interface{}) { diff --git a/util/secrets.go b/util/secrets.go index 4c2b94b3e116a..06b6cfb2b601e 100644 --- a/util/secrets.go +++ b/util/secrets.go @@ -1,29 +1,32 @@ package util import ( - "fmt" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "github.com/argoproj/argo-cd/common" apiv1 "k8s.io/api/core/v1" "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" ) -func makeKubeclientset() (kubeclientset *kubernetes.Clientset) { +// SecretServer holds config info for a new server with which to access secrets +type SecretServer struct { + namespace string + kubeclientset kubernetes.Interface +} + +// NewSecretServer generates a new SecretServer pointer and returns it +func NewSecretServer(namespace string, config *rest.Config) (server *SecretServer, err error) { kubeclientset, err := kubernetes.NewForConfig(config) if err != nil { - return fmt.Errorf("REST config invalid: %s", err) + return } - _, err = kubeclientset.ServerVersion() - if err != nil { - return fmt.Errorf("REST config invalid: %s", err) - } - return nil + server = &SecretServer{namespace, kubeclientset} + return } // CreateSecret stores a new secret in Kubernetes. -func CreateSecret(namespace, name string, value map[string]string, secretType string) (secret *apiv1.Secret, err error) { +func (server *SecretServer) CreateSecret(name string, value map[string]string, secretType string) (secret *apiv1.Secret, err error) { newSecret := &apiv1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: name, @@ -33,28 +36,28 @@ func CreateSecret(namespace, name string, value map[string]string, secretType st }, StringData: value, } - secret, err = makeKubeclientset().CoreV1().Secrets(namespace).Create(newSecret) + secret, err = server.kubeclientset.CoreV1().Secrets(server.namespace).Create(newSecret) return } // ReadSecret retrieves a secret from Kubernetes. -func ReadSecret(namespace, name string) (secret *apiv1.Secret, err error) { - secret, err = makeKubeclientset().CoreV1().Secrets(namespace).Get(name, metav1.GetOptions{}) +func (server *SecretServer) ReadSecret(name string) (secret *apiv1.Secret, err error) { + secret, err = server.kubeclientset.CoreV1().Secrets(server.namespace).Get(name, metav1.GetOptions{}) return } // UpdateSecret updates an existing secret in Kubernetes. -func UpdateSecret(namespace, name string, value map[string]string) (secret *apiv1.Secret, err error) { - existingSecret, err := ReadSecret(namespace, name) +func (server *SecretServer) UpdateSecret(name string, value map[string]string) (secret *apiv1.Secret, err error) { + existingSecret, err := server.ReadSecret(name) if err != nil { existingSecret.StringData = value - secret, err = makeKubeclientset().CoreV1().Secrets(namespace).Update(existingSecret) + secret, err = server.kubeclientset.CoreV1().Secrets(server.namespace).Update(existingSecret) } return } // DeleteSecret removes a secret from Kubernetes. -func DeleteSecret(namespace, name string) (err error) { - err = makeKubeclientset().CoreV1().Secrets(namespace).Delete(name, &metav1.DeleteOptions{}) +func (server *SecretServer) DeleteSecret(name string) (err error) { + err = server.kubeclientset.CoreV1().Secrets(server.namespace).Delete(name, &metav1.DeleteOptions{}) return } From 0e975ca68fb647189d4c6d80261279bd53825f57 Mon Sep 17 00:00:00 2001 From: Andrew Merenbach Date: Tue, 20 Mar 2018 08:52:19 -0700 Subject: [PATCH 10/38] Update secret.go --- util/{secrets.go => secret.go} | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) rename util/{secrets.go => secret.go} (53%) diff --git a/util/secrets.go b/util/secret.go similarity index 53% rename from util/secrets.go rename to util/secret.go index 06b6cfb2b601e..e3c173a712cab 100644 --- a/util/secrets.go +++ b/util/secret.go @@ -9,30 +9,32 @@ import ( "k8s.io/client-go/rest" ) -// SecretServer holds config info for a new server with which to access secrets -type SecretServer struct { +// secretManager holds config info for a new server with which to access secrets +type secretManager struct { namespace string kubeclientset kubernetes.Interface } -// NewSecretServer generates a new SecretServer pointer and returns it -func NewSecretServer(namespace string, config *rest.Config) (server *SecretServer, err error) { +// NewSecretManager generates a new secretManager pointer and returns it +func NewSecretManager(namespace string, config *rest.Config) (server *secretManager, err error) { kubeclientset, err := kubernetes.NewForConfig(config) if err != nil { return } - server = &SecretServer{namespace, kubeclientset} + server = &secretManager{namespace, kubeclientset} return } -// CreateSecret stores a new secret in Kubernetes. -func (server *SecretServer) CreateSecret(name string, value map[string]string, secretType string) (secret *apiv1.Secret, err error) { +// CreateSecret stores a new secret in Kubernetes. Set secretType to "" for no label. +func (server *secretManager) CreateSecret(name string, value map[string]string, secretType string) (secret *apiv1.Secret, err error) { + labels := make(map[string]string) + if secretType != "" { + labels[common.LabelKeySecretType] = secretType + } newSecret := &apiv1.Secret{ ObjectMeta: metav1.ObjectMeta{ - Name: name, - Labels: map[string]string{ - common.LabelKeySecretType: secretType, - }, + Name: name, + Labels: labels, }, StringData: value, } @@ -41,15 +43,15 @@ func (server *SecretServer) CreateSecret(name string, value map[string]string, s } // ReadSecret retrieves a secret from Kubernetes. -func (server *SecretServer) ReadSecret(name string) (secret *apiv1.Secret, err error) { +func (server *secretManager) ReadSecret(name string) (secret *apiv1.Secret, err error) { secret, err = server.kubeclientset.CoreV1().Secrets(server.namespace).Get(name, metav1.GetOptions{}) return } // UpdateSecret updates an existing secret in Kubernetes. -func (server *SecretServer) UpdateSecret(name string, value map[string]string) (secret *apiv1.Secret, err error) { +func (server *secretManager) UpdateSecret(name string, value map[string]string) (secret *apiv1.Secret, err error) { existingSecret, err := server.ReadSecret(name) - if err != nil { + if err == nil { existingSecret.StringData = value secret, err = server.kubeclientset.CoreV1().Secrets(server.namespace).Update(existingSecret) } @@ -57,7 +59,7 @@ func (server *SecretServer) UpdateSecret(name string, value map[string]string) ( } // DeleteSecret removes a secret from Kubernetes. -func (server *SecretServer) DeleteSecret(name string) (err error) { +func (server *secretManager) DeleteSecret(name string) (err error) { err = server.kubeclientset.CoreV1().Secrets(server.namespace).Delete(name, &metav1.DeleteOptions{}) return } From d76096d127e66b73279fec3810e189c8480dab30 Mon Sep 17 00:00:00 2001 From: Andrew Merenbach Date: Tue, 20 Mar 2018 09:15:50 -0700 Subject: [PATCH 11/38] Create configmap/secret manipulation tools --- util/configmap.go | 59 +++++++++++++++++++++++++++++++++++++++++++++++ util/secret.go | 18 +++++++-------- 2 files changed, 68 insertions(+), 9 deletions(-) create mode 100644 util/configmap.go diff --git a/util/configmap.go b/util/configmap.go new file mode 100644 index 0000000000000..18318b6f3dd76 --- /dev/null +++ b/util/configmap.go @@ -0,0 +1,59 @@ +package util + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + apiv1 "k8s.io/api/core/v1" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" +) + +// ConfigMapManager holds config info for a new server with which to access Kubernetes ConfigMaps. +type ConfigMapManager struct { + namespace string + kubeclientset kubernetes.Interface +} + +// NewConfigMapManager generates a new ConfigMapManager pointer and returns it +func NewConfigMapManager(namespace string, config *rest.Config) (server *ConfigMapManager, err error) { + kubeclientset, err := kubernetes.NewForConfig(config) + if err != nil { + return + } + server = &ConfigMapManager{namespace, kubeclientset} + return +} + +// CreateConfigMap stores a new config map in Kubernetes. +func (server *ConfigMapManager) CreateConfigMap(name string, value map[string]string) (configMap *apiv1.ConfigMap, err error) { + newConfigMap := &apiv1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + Data: value, + } + configMap, err = server.kubeclientset.CoreV1().ConfigMaps(server.namespace).Create(newConfigMap) + return +} + +// ReadConfigMap retrieves a config map from Kubernetes. +func (server *ConfigMapManager) ReadConfigMap(name string) (configMap *apiv1.ConfigMap, err error) { + configMap, err = server.kubeclientset.CoreV1().ConfigMaps(server.namespace).Get(name, metav1.GetOptions{}) + return +} + +// UpdateConfigMap updates an existing config map in Kubernetes. +func (server *ConfigMapManager) UpdateConfigMap(name string, value map[string]string) (configMap *apiv1.ConfigMap, err error) { + existingConfigMap, err := server.ReadConfigMap(name) + if err == nil { + existingConfigMap.Data = value + configMap, err = server.kubeclientset.CoreV1().ConfigMaps(server.namespace).Update(existingConfigMap) + } + return +} + +// DeleteConfigMap removes a config map from Kubernetes. +func (server *ConfigMapManager) DeleteConfigMap(name string) (err error) { + err = server.kubeclientset.CoreV1().ConfigMaps(server.namespace).Delete(name, &metav1.DeleteOptions{}) + return +} diff --git a/util/secret.go b/util/secret.go index e3c173a712cab..b26604eebd66b 100644 --- a/util/secret.go +++ b/util/secret.go @@ -9,24 +9,24 @@ import ( "k8s.io/client-go/rest" ) -// secretManager holds config info for a new server with which to access secrets -type secretManager struct { +// SecretManager holds config info for a new server with which to access Kubernetes Secrets. +type SecretManager struct { namespace string kubeclientset kubernetes.Interface } -// NewSecretManager generates a new secretManager pointer and returns it -func NewSecretManager(namespace string, config *rest.Config) (server *secretManager, err error) { +// NewSecretManager generates a new SecretManager pointer and returns it +func NewSecretManager(namespace string, config *rest.Config) (server *SecretManager, err error) { kubeclientset, err := kubernetes.NewForConfig(config) if err != nil { return } - server = &secretManager{namespace, kubeclientset} + server = &SecretManager{namespace, kubeclientset} return } // CreateSecret stores a new secret in Kubernetes. Set secretType to "" for no label. -func (server *secretManager) CreateSecret(name string, value map[string]string, secretType string) (secret *apiv1.Secret, err error) { +func (server *SecretManager) CreateSecret(name string, value map[string]string, secretType string) (secret *apiv1.Secret, err error) { labels := make(map[string]string) if secretType != "" { labels[common.LabelKeySecretType] = secretType @@ -43,13 +43,13 @@ func (server *secretManager) CreateSecret(name string, value map[string]string, } // ReadSecret retrieves a secret from Kubernetes. -func (server *secretManager) ReadSecret(name string) (secret *apiv1.Secret, err error) { +func (server *SecretManager) ReadSecret(name string) (secret *apiv1.Secret, err error) { secret, err = server.kubeclientset.CoreV1().Secrets(server.namespace).Get(name, metav1.GetOptions{}) return } // UpdateSecret updates an existing secret in Kubernetes. -func (server *secretManager) UpdateSecret(name string, value map[string]string) (secret *apiv1.Secret, err error) { +func (server *SecretManager) UpdateSecret(name string, value map[string]string) (secret *apiv1.Secret, err error) { existingSecret, err := server.ReadSecret(name) if err == nil { existingSecret.StringData = value @@ -59,7 +59,7 @@ func (server *secretManager) UpdateSecret(name string, value map[string]string) } // DeleteSecret removes a secret from Kubernetes. -func (server *secretManager) DeleteSecret(name string) (err error) { +func (server *SecretManager) DeleteSecret(name string) (err error) { err = server.kubeclientset.CoreV1().Secrets(server.namespace).Delete(name, &metav1.DeleteOptions{}) return } From 2a8ead9170aa1bbc9dfd14f9ac7e387e65243262 Mon Sep 17 00:00:00 2001 From: Andrew Merenbach Date: Tue, 20 Mar 2018 09:21:27 -0700 Subject: [PATCH 12/38] Slight tweaks to logic in util functions --- util/configmap.go | 5 ++--- util/secret.go | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/util/configmap.go b/util/configmap.go index 18318b6f3dd76..155d16dac7300 100644 --- a/util/configmap.go +++ b/util/configmap.go @@ -17,10 +17,9 @@ type ConfigMapManager struct { // NewConfigMapManager generates a new ConfigMapManager pointer and returns it func NewConfigMapManager(namespace string, config *rest.Config) (server *ConfigMapManager, err error) { kubeclientset, err := kubernetes.NewForConfig(config) - if err != nil { - return + if err == nil { + server = &ConfigMapManager{namespace, kubeclientset} } - server = &ConfigMapManager{namespace, kubeclientset} return } diff --git a/util/secret.go b/util/secret.go index b26604eebd66b..827025f39eb22 100644 --- a/util/secret.go +++ b/util/secret.go @@ -18,10 +18,9 @@ type SecretManager struct { // NewSecretManager generates a new SecretManager pointer and returns it func NewSecretManager(namespace string, config *rest.Config) (server *SecretManager, err error) { kubeclientset, err := kubernetes.NewForConfig(config) - if err != nil { - return + if err == nil { + server = &SecretManager{namespace, kubeclientset} } - server = &SecretManager{namespace, kubeclientset} return } From 95055b8ef53aa78c62b9c345e24d7cee4cafa381 Mon Sep 17 00:00:00 2001 From: Andrew Merenbach Date: Tue, 20 Mar 2018 11:41:27 -0700 Subject: [PATCH 13/38] Add test for configmap code --- util/configmap_test.go | 70 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) create mode 100644 util/configmap_test.go diff --git a/util/configmap_test.go b/util/configmap_test.go new file mode 100644 index 0000000000000..2ce4ce5ec0f78 --- /dev/null +++ b/util/configmap_test.go @@ -0,0 +1,70 @@ +package util + +import ( + "reflect" + "testing" + + "github.com/pborman/uuid" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" +) + +const testConfigMapNamespace = "default" + +// makeTestConfigMapClientConfig creates an empty client config to use for K8s API calls +// TODO (@merenbach): make this more general for use in other tests +func makeTestConfigMapClientConfig() (config *rest.Config, err error) { + loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() + loadingRules.DefaultClientConfig = &clientcmd.DefaultClientConfig + overrides := clientcmd.ConfigOverrides{} + configRaw := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, &overrides) + config, err = configRaw.ClientConfig() + return +} + +func TestConfigMapManager(t *testing.T) { + configMapName := uuid.New() + configMapData1 := map[string]string{ + "some": "data", + "hello": "world", + } + configMapData2 := map[string]string{ + "other": "data", + "some": "thing else", + "world": "hello", + } + + config, err := makeTestConfigMapClientConfig() + if err != nil { + t.Errorf("Could not create test client config: %v", err) + } + mgr, err := NewConfigMapManager(testConfigMapNamespace, config) + if err != nil { + t.Errorf("Could not create config map manager: %v", err) + } + configmap, err := mgr.CreateConfigMap(configMapName, configMapData1) + if err != nil || !reflect.DeepEqual(configmap.Data, configMapData1) { + t.Errorf("Err = %v; Created data did not match: had %v, wanted %v", err, configmap, configMapData1) + } + + configmap, err = mgr.ReadConfigMap(configMapName) + if err != nil || !reflect.DeepEqual(configmap.Data, configMapData1) { + t.Errorf("Err = %v; Read data did not match: had %v, wanted %v", err, configmap, configMapData1) + } + + configmap, err = mgr.UpdateConfigMap(configMapName, configMapData2) + if err != nil || !reflect.DeepEqual(configmap.Data, configMapData2) { + t.Errorf("Err = %v; Read data did not match: had %v, wanted %v", err, configmap, configMapData1) + } + + err = mgr.DeleteConfigMap(configMapName) + if err != nil { + t.Errorf("Err = %v", err) + } + + configmap, err = mgr.ReadConfigMap(configMapName) + if err == nil { + t.Errorf("Err = %v; Read data did not match: had %v, wanted nil; trying again, but it may need to be deleted manually", err, configmap) + _ = mgr.DeleteConfigMap(configMapName) + } +} From c0bd7b93567160df85fdae34f279f4a661a3223b Mon Sep 17 00:00:00 2001 From: Andrew Merenbach Date: Tue, 20 Mar 2018 13:36:18 -0700 Subject: [PATCH 14/38] Update configmap/secret tests and code --- util/configmap.go | 2 +- util/configmap_test.go | 22 ++++----- util/secret.go | 4 +- util/secret_test.go | 101 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 115 insertions(+), 14 deletions(-) create mode 100644 util/secret_test.go diff --git a/util/configmap.go b/util/configmap.go index 155d16dac7300..4148e7db0ce4b 100644 --- a/util/configmap.go +++ b/util/configmap.go @@ -41,7 +41,7 @@ func (server *ConfigMapManager) ReadConfigMap(name string) (configMap *apiv1.Con return } -// UpdateConfigMap updates an existing config map in Kubernetes. +// UpdateConfigMap overwrite-updates an existing config map in Kubernetes. This overwrite is in contrast to the merge-update done for secrets. func (server *ConfigMapManager) UpdateConfigMap(name string, value map[string]string) (configMap *apiv1.ConfigMap, err error) { existingConfigMap, err := server.ReadConfigMap(name) if err == nil { diff --git a/util/configmap_test.go b/util/configmap_test.go index 2ce4ce5ec0f78..881f2cfb50de6 100644 --- a/util/configmap_test.go +++ b/util/configmap_test.go @@ -42,19 +42,19 @@ func TestConfigMapManager(t *testing.T) { if err != nil { t.Errorf("Could not create config map manager: %v", err) } - configmap, err := mgr.CreateConfigMap(configMapName, configMapData1) - if err != nil || !reflect.DeepEqual(configmap.Data, configMapData1) { - t.Errorf("Err = %v; Created data did not match: had %v, wanted %v", err, configmap, configMapData1) + configMap, err := mgr.CreateConfigMap(configMapName, configMapData1) + if err != nil || !reflect.DeepEqual(configMap.Data, configMapData1) { + t.Errorf("Err = %v; Created data did not match: had %v, wanted %v", err, configMap.Data, configMapData1) } - configmap, err = mgr.ReadConfigMap(configMapName) - if err != nil || !reflect.DeepEqual(configmap.Data, configMapData1) { - t.Errorf("Err = %v; Read data did not match: had %v, wanted %v", err, configmap, configMapData1) + configMap, err = mgr.ReadConfigMap(configMapName) + if err != nil || !reflect.DeepEqual(configMap.Data, configMapData1) { + t.Errorf("Err = %v; Read data did not match: had %v, wanted %v", err, configMap.Data, configMapData1) } - configmap, err = mgr.UpdateConfigMap(configMapName, configMapData2) - if err != nil || !reflect.DeepEqual(configmap.Data, configMapData2) { - t.Errorf("Err = %v; Read data did not match: had %v, wanted %v", err, configmap, configMapData1) + configMap, err = mgr.UpdateConfigMap(configMapName, configMapData2) + if err != nil || !reflect.DeepEqual(configMap.Data, configMapData2) { + t.Errorf("Err = %v; Updated data did not match: had %v, wanted %v", err, configMap.Data, configMapData1) } err = mgr.DeleteConfigMap(configMapName) @@ -62,9 +62,9 @@ func TestConfigMapManager(t *testing.T) { t.Errorf("Err = %v", err) } - configmap, err = mgr.ReadConfigMap(configMapName) + configMap, err = mgr.ReadConfigMap(configMapName) if err == nil { - t.Errorf("Err = %v; Read data did not match: had %v, wanted nil; trying again, but it may need to be deleted manually", err, configmap) + t.Errorf("Err = %v; Read data did not match: had %v, wanted nil; trying again, but it may need to be deleted manually", err, configMap.Data) _ = mgr.DeleteConfigMap(configMapName) } } diff --git a/util/secret.go b/util/secret.go index 827025f39eb22..6d6f0ef4d4f82 100644 --- a/util/secret.go +++ b/util/secret.go @@ -35,8 +35,8 @@ func (server *SecretManager) CreateSecret(name string, value map[string]string, Name: name, Labels: labels, }, - StringData: value, } + newSecret.StringData = value secret, err = server.kubeclientset.CoreV1().Secrets(server.namespace).Create(newSecret) return } @@ -47,7 +47,7 @@ func (server *SecretManager) ReadSecret(name string) (secret *apiv1.Secret, err return } -// UpdateSecret updates an existing secret in Kubernetes. +// UpdateSecret merge-updates an existing secret in Kubernetes. This merge-update is in contrast to the overwrite-update done for config maps. func (server *SecretManager) UpdateSecret(name string, value map[string]string) (secret *apiv1.Secret, err error) { existingSecret, err := server.ReadSecret(name) if err == nil { diff --git a/util/secret_test.go b/util/secret_test.go new file mode 100644 index 0000000000000..7a78efbea0507 --- /dev/null +++ b/util/secret_test.go @@ -0,0 +1,101 @@ +package util + +import ( + "reflect" + "testing" + + "github.com/pborman/uuid" + apiv1 "k8s.io/api/core/v1" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" +) + +const testSecretNamespace = "default" + +// makeTestSecretClientConfig creates an empty client config to use for K8s API calls +// TODO (@merenbach): make this more general for use in other tests +func makeTestSecretClientConfig() (config *rest.Config, err error) { + loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() + loadingRules.DefaultClientConfig = &clientcmd.DefaultClientConfig + overrides := clientcmd.ConfigOverrides{} + configRaw := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, &overrides) + config, err = configRaw.ClientConfig() + return +} + +// testConvertSecretStringData returns a mapping of a secret data as a map[string]string instead of map[string][]byte. +func testConvertSecretStringData(secret *apiv1.Secret) map[string]string { + out := make(map[string]string) + for k, v := range secret.Data { + out[k] = string(v) + } + return out +} + +func TestSecretManager(t *testing.T) { + var ( + secret *apiv1.Secret + err error + ) + + secretName := uuid.New() + label := "test" + secretData1 := map[string]string{ + "some": "data", + "hello": "world", + } + secretData2 := map[string]string{ + "other": "data", + "some": "thing else", + "world": "hello", + } + secretDataAfterUpdate := map[string]string{ + "other": "data", + "some": "thing else", + "world": "hello", + "hello": "world", + } + + config, err := makeTestSecretClientConfig() + if err != nil { + t.Errorf("Could not create test client config: %v", err) + } + mgr, err := NewSecretManager(testSecretNamespace, config) + if err != nil { + t.Errorf("Could not create secret manager: %v", err) + } + + secret, err = mgr.CreateSecret(secretName, secretData1, label) + if secretDataRetrieved := testConvertSecretStringData(secret); !reflect.DeepEqual(secretDataRetrieved, secretData1) { + t.Errorf("Err = %v; Created data did not match: had %v, wanted %v", err, secretDataRetrieved, secretData1) + } + + secret, err = mgr.ReadSecret(secretName) + if err != nil { + t.Errorf("Could not read secret: %v", err) + } + + if secretDataRetrieved := testConvertSecretStringData(secret); !reflect.DeepEqual(secretDataRetrieved, secretData1) { + t.Errorf("Read data did not match: had %v, wanted %v", secretDataRetrieved, secretData1) + } + + secret, err = mgr.UpdateSecret(secretName, secretData2) + if err != nil { + t.Errorf("Could not update secret: %v", err) + } + if secretDataRetrieved := testConvertSecretStringData(secret); !reflect.DeepEqual(secretDataRetrieved, secretDataAfterUpdate) { + t.Errorf("Updated data did not match: had %v, wanted %v", secretDataRetrieved, secretData1) + } + + err = mgr.DeleteSecret(secretName) + if err != nil { + t.Errorf("Could not delete secret: %v", err) + } + + secret, err = mgr.ReadSecret(secretName) + if err == nil { + secretDataRetrieved := testConvertSecretStringData(secret) + t.Errorf("Read data did not match: had %v, wanted nil; trying again, but it may need to be deleted manually", secretDataRetrieved) + _ = mgr.DeleteSecret(secretName) + } +} From b9f54da150dbe64e759104c57bd994d0ca0c2670 Mon Sep 17 00:00:00 2001 From: Andrew Merenbach Date: Tue, 20 Mar 2018 13:46:51 -0700 Subject: [PATCH 15/38] Update installation settings --- install/install.go | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/install/install.go b/install/install.go index c1b5c7a4648c0..4dd4922346120 100644 --- a/install/install.go +++ b/install/install.go @@ -6,7 +6,6 @@ import ( "strings" "github.com/argoproj/argo-cd/errors" - "github.com/argoproj/argo-cd/util" "github.com/argoproj/argo-cd/util/diff" "github.com/argoproj/argo-cd/util/kube" "github.com/ghodss/yaml" @@ -77,7 +76,6 @@ func NewInstaller(config *rest.Config, opts InstallOptions) (*Installer, error) func (i *Installer) Install() { i.InstallNamespace() - i.InstallConfigMap() i.InstallApplicationCRD() i.InstallApplicationController() i.InstallArgoCDServer() @@ -149,6 +147,9 @@ func (i *Installer) InstallArgoCDServer() { i.unmarshalManifest("03b_argocd-server-role.yaml", &argoCDServerControllerRole) i.unmarshalManifest("03c_argocd-server-rolebinding.yaml", &argoCDServerControllerRoleBinding) i.unmarshalManifest("03d_argocd-server-deployment.yaml", &argoCDServerControllerDeployment) + // Use a Kubernetes ConfigMap, if provided. + argoCDServerControllerDeployment.ConfigMap = i.InstallOptions.ConfigMap + i.unmarshalManifest("03e_argocd-server-service.yaml", &argoCDServerService) argoCDServerControllerDeployment.Spec.Template.Spec.InitContainers[0].Image = i.UIImage argoCDServerControllerDeployment.Spec.Template.Spec.InitContainers[0].ImagePullPolicy = apiv1.PullPolicy(i.ImagePullPolicy) @@ -172,13 +173,6 @@ func (i *Installer) InstallArgoCDRepoServer() { i.MustInstallResource(kube.MustToUnstructured(&argoCDRepoServerService)) } -func (i *Installer) InstallConfigMap() (err error) { - // install configuration here - config := i.config - server, err := util.NewSecretServer("namespace", config) - fmt.Println("HELLO, WORLD!") -} - func (i *Installer) unmarshalManifest(fileName string, obj interface{}) { yamlBytes, err := i.box.MustBytes(fileName) errors.CheckError(err) From b208bbf2cc09c72558a533a39a740c1ad6dc0b4e Mon Sep 17 00:00:00 2001 From: Andrew Merenbach Date: Tue, 20 Mar 2018 13:47:15 -0700 Subject: [PATCH 16/38] Revert secret type field --- common/common.go | 3 --- 1 file changed, 3 deletions(-) diff --git a/common/common.go b/common/common.go index 22175f50d4d63..cdebf67f30551 100644 --- a/common/common.go +++ b/common/common.go @@ -14,9 +14,6 @@ const ( // SecretTypeCluster indicates a secret type of cluster SecretTypeCluster = "cluster" - - // SecretTypePassword indicates a password - SecretTypePassword = "password" ) var ( From a54a8ab5d7f17a7b018ee5ff9f105e69254ff426 Mon Sep 17 00:00:00 2001 From: Andrew Merenbach Date: Tue, 20 Mar 2018 14:29:23 -0700 Subject: [PATCH 17/38] Fix subfield access --- install/install.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/install.go b/install/install.go index 4dd4922346120..4031210d85f9c 100644 --- a/install/install.go +++ b/install/install.go @@ -148,7 +148,7 @@ func (i *Installer) InstallArgoCDServer() { i.unmarshalManifest("03c_argocd-server-rolebinding.yaml", &argoCDServerControllerRoleBinding) i.unmarshalManifest("03d_argocd-server-deployment.yaml", &argoCDServerControllerDeployment) // Use a Kubernetes ConfigMap, if provided. - argoCDServerControllerDeployment.ConfigMap = i.InstallOptions.ConfigMap + argoCDServerControllerDeployment.Spec.ConfigMap = i.InstallOptions.ConfigMap i.unmarshalManifest("03e_argocd-server-service.yaml", &argoCDServerService) argoCDServerControllerDeployment.Spec.Template.Spec.InitContainers[0].Image = i.UIImage From 449ab9e3f60b09e42c14f7b380c6501067a93221 Mon Sep 17 00:00:00 2001 From: Andrew Merenbach Date: Tue, 20 Mar 2018 15:08:53 -0700 Subject: [PATCH 18/38] Update container command --- install/install.go | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/install/install.go b/install/install.go index 4031210d85f9c..1a876166ea535 100644 --- a/install/install.go +++ b/install/install.go @@ -147,14 +147,18 @@ func (i *Installer) InstallArgoCDServer() { i.unmarshalManifest("03b_argocd-server-role.yaml", &argoCDServerControllerRole) i.unmarshalManifest("03c_argocd-server-rolebinding.yaml", &argoCDServerControllerRoleBinding) i.unmarshalManifest("03d_argocd-server-deployment.yaml", &argoCDServerControllerDeployment) - // Use a Kubernetes ConfigMap, if provided. - argoCDServerControllerDeployment.Spec.ConfigMap = i.InstallOptions.ConfigMap i.unmarshalManifest("03e_argocd-server-service.yaml", &argoCDServerService) argoCDServerControllerDeployment.Spec.Template.Spec.InitContainers[0].Image = i.UIImage argoCDServerControllerDeployment.Spec.Template.Spec.InitContainers[0].ImagePullPolicy = apiv1.PullPolicy(i.ImagePullPolicy) argoCDServerControllerDeployment.Spec.Template.Spec.Containers[0].Image = i.ServerImage argoCDServerControllerDeployment.Spec.Template.Spec.Containers[0].ImagePullPolicy = apiv1.PullPolicy(i.ImagePullPolicy) + // Use a Kubernetes ConfigMap, if provided. + if i.InstallOptions.ConfigMap != "" { + container := &argoCDServerControllerDeployment.Spec.Template.Spec.InitContainers[0] + + container.Command = append(container.Command, "--config-map", i.InstallOptions.ConfigMap) + } i.MustInstallResource(kube.MustToUnstructured(&argoCDServerServiceAccount)) i.MustInstallResource(kube.MustToUnstructured(&argoCDServerControllerRole)) i.MustInstallResource(kube.MustToUnstructured(&argoCDServerControllerRoleBinding)) From ac0266d36edc95aad117109f95745b6287239371 Mon Sep 17 00:00:00 2001 From: Andrew Merenbach Date: Tue, 20 Mar 2018 15:09:26 -0700 Subject: [PATCH 19/38] Rm unnecessary newline --- install/install.go | 1 - 1 file changed, 1 deletion(-) diff --git a/install/install.go b/install/install.go index 1a876166ea535..51297216962ea 100644 --- a/install/install.go +++ b/install/install.go @@ -156,7 +156,6 @@ func (i *Installer) InstallArgoCDServer() { // Use a Kubernetes ConfigMap, if provided. if i.InstallOptions.ConfigMap != "" { container := &argoCDServerControllerDeployment.Spec.Template.Spec.InitContainers[0] - container.Command = append(container.Command, "--config-map", i.InstallOptions.ConfigMap) } i.MustInstallResource(kube.MustToUnstructured(&argoCDServerServiceAccount)) From f3069588709530a795a0945115b772fae4e8b565 Mon Sep 17 00:00:00 2001 From: Andrew Merenbach Date: Tue, 20 Mar 2018 15:13:07 -0700 Subject: [PATCH 20/38] Quote configmap parameter --- install/install.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/install/install.go b/install/install.go index 51297216962ea..bf87fae5077f3 100644 --- a/install/install.go +++ b/install/install.go @@ -3,6 +3,7 @@ package install import ( "fmt" "log" + "strconv" "strings" "github.com/argoproj/argo-cd/errors" @@ -155,8 +156,9 @@ func (i *Installer) InstallArgoCDServer() { argoCDServerControllerDeployment.Spec.Template.Spec.Containers[0].ImagePullPolicy = apiv1.PullPolicy(i.ImagePullPolicy) // Use a Kubernetes ConfigMap, if provided. if i.InstallOptions.ConfigMap != "" { + configMap := strconv.Quote(i.InstallOptions.ConfigMap) container := &argoCDServerControllerDeployment.Spec.Template.Spec.InitContainers[0] - container.Command = append(container.Command, "--config-map", i.InstallOptions.ConfigMap) + container.Command = append(container.Command, "--config-map", configMap) } i.MustInstallResource(kube.MustToUnstructured(&argoCDServerServiceAccount)) i.MustInstallResource(kube.MustToUnstructured(&argoCDServerControllerRole)) From 0a8b1176853ccbbdd07f7e01908df17423bb9127 Mon Sep 17 00:00:00 2001 From: Andrew Merenbach Date: Tue, 20 Mar 2018 15:19:15 -0700 Subject: [PATCH 21/38] Update printouts from tests --- util/configmap_test.go | 2 +- util/secret_test.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/util/configmap_test.go b/util/configmap_test.go index 881f2cfb50de6..367ab21aafe35 100644 --- a/util/configmap_test.go +++ b/util/configmap_test.go @@ -64,7 +64,7 @@ func TestConfigMapManager(t *testing.T) { configMap, err = mgr.ReadConfigMap(configMapName) if err == nil { - t.Errorf("Err = %v; Read data did not match: had %v, wanted nil; trying again, but it may need to be deleted manually", err, configMap.Data) + t.Errorf("Read data did not match: had %v, wanted nil for name %s; trying again, but it may need to be deleted manually", configMap.Data, configMapName) _ = mgr.DeleteConfigMap(configMapName) } } diff --git a/util/secret_test.go b/util/secret_test.go index 7a78efbea0507..993118181db02 100644 --- a/util/secret_test.go +++ b/util/secret_test.go @@ -95,7 +95,7 @@ func TestSecretManager(t *testing.T) { secret, err = mgr.ReadSecret(secretName) if err == nil { secretDataRetrieved := testConvertSecretStringData(secret) - t.Errorf("Read data did not match: had %v, wanted nil; trying again, but it may need to be deleted manually", secretDataRetrieved) + t.Errorf("Read data did not match: had %v, wanted nil for name %s and label %s; trying again, but it may need to be deleted manually", secretDataRetrieved, secretName, label) _ = mgr.DeleteSecret(secretName) } } From 5fa2f23992dc3012b3af9d7b3eb24653dba01757 Mon Sep 17 00:00:00 2001 From: Andrew Merenbach Date: Tue, 20 Mar 2018 15:28:52 -0700 Subject: [PATCH 22/38] Rm unnecessary suffixes from util functions --- util/configmap.go | 22 +++++++++++----------- util/configmap_test.go | 12 ++++++------ util/secret.go | 22 +++++++++++----------- util/secret_test.go | 12 ++++++------ 4 files changed, 34 insertions(+), 34 deletions(-) diff --git a/util/configmap.go b/util/configmap.go index 4148e7db0ce4b..800a238024111 100644 --- a/util/configmap.go +++ b/util/configmap.go @@ -10,8 +10,8 @@ import ( // ConfigMapManager holds config info for a new server with which to access Kubernetes ConfigMaps. type ConfigMapManager struct { - namespace string - kubeclientset kubernetes.Interface + Namespace string + Clientset kubernetes.Interface } // NewConfigMapManager generates a new ConfigMapManager pointer and returns it @@ -24,35 +24,35 @@ func NewConfigMapManager(namespace string, config *rest.Config) (server *ConfigM } // CreateConfigMap stores a new config map in Kubernetes. -func (server *ConfigMapManager) CreateConfigMap(name string, value map[string]string) (configMap *apiv1.ConfigMap, err error) { +func (server *ConfigMapManager) Create(name string, value map[string]string) (configMap *apiv1.ConfigMap, err error) { newConfigMap := &apiv1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: name, }, Data: value, } - configMap, err = server.kubeclientset.CoreV1().ConfigMaps(server.namespace).Create(newConfigMap) + configMap, err = server.Clientset.CoreV1().ConfigMaps(server.Namespace).Create(newConfigMap) return } // ReadConfigMap retrieves a config map from Kubernetes. -func (server *ConfigMapManager) ReadConfigMap(name string) (configMap *apiv1.ConfigMap, err error) { - configMap, err = server.kubeclientset.CoreV1().ConfigMaps(server.namespace).Get(name, metav1.GetOptions{}) +func (server *ConfigMapManager) Read(name string) (configMap *apiv1.ConfigMap, err error) { + configMap, err = server.Clientset.CoreV1().ConfigMaps(server.Namespace).Get(name, metav1.GetOptions{}) return } // UpdateConfigMap overwrite-updates an existing config map in Kubernetes. This overwrite is in contrast to the merge-update done for secrets. -func (server *ConfigMapManager) UpdateConfigMap(name string, value map[string]string) (configMap *apiv1.ConfigMap, err error) { - existingConfigMap, err := server.ReadConfigMap(name) +func (server *ConfigMapManager) Update(name string, value map[string]string) (configMap *apiv1.ConfigMap, err error) { + existingConfigMap, err := server.Read(name) if err == nil { existingConfigMap.Data = value - configMap, err = server.kubeclientset.CoreV1().ConfigMaps(server.namespace).Update(existingConfigMap) + configMap, err = server.Clientset.CoreV1().ConfigMaps(server.Namespace).Update(existingConfigMap) } return } // DeleteConfigMap removes a config map from Kubernetes. -func (server *ConfigMapManager) DeleteConfigMap(name string) (err error) { - err = server.kubeclientset.CoreV1().ConfigMaps(server.namespace).Delete(name, &metav1.DeleteOptions{}) +func (server *ConfigMapManager) Delete(name string) (err error) { + err = server.Clientset.CoreV1().ConfigMaps(server.Namespace).Delete(name, &metav1.DeleteOptions{}) return } diff --git a/util/configmap_test.go b/util/configmap_test.go index 367ab21aafe35..6ca2881b4022c 100644 --- a/util/configmap_test.go +++ b/util/configmap_test.go @@ -42,29 +42,29 @@ func TestConfigMapManager(t *testing.T) { if err != nil { t.Errorf("Could not create config map manager: %v", err) } - configMap, err := mgr.CreateConfigMap(configMapName, configMapData1) + configMap, err := mgr.Create(configMapName, configMapData1) if err != nil || !reflect.DeepEqual(configMap.Data, configMapData1) { t.Errorf("Err = %v; Created data did not match: had %v, wanted %v", err, configMap.Data, configMapData1) } - configMap, err = mgr.ReadConfigMap(configMapName) + configMap, err = mgr.Read(configMapName) if err != nil || !reflect.DeepEqual(configMap.Data, configMapData1) { t.Errorf("Err = %v; Read data did not match: had %v, wanted %v", err, configMap.Data, configMapData1) } - configMap, err = mgr.UpdateConfigMap(configMapName, configMapData2) + configMap, err = mgr.Update(configMapName, configMapData2) if err != nil || !reflect.DeepEqual(configMap.Data, configMapData2) { t.Errorf("Err = %v; Updated data did not match: had %v, wanted %v", err, configMap.Data, configMapData1) } - err = mgr.DeleteConfigMap(configMapName) + err = mgr.Delete(configMapName) if err != nil { t.Errorf("Err = %v", err) } - configMap, err = mgr.ReadConfigMap(configMapName) + configMap, err = mgr.Read(configMapName) if err == nil { t.Errorf("Read data did not match: had %v, wanted nil for name %s; trying again, but it may need to be deleted manually", configMap.Data, configMapName) - _ = mgr.DeleteConfigMap(configMapName) + _ = mgr.Delete(configMapName) } } diff --git a/util/secret.go b/util/secret.go index 6d6f0ef4d4f82..d4dea3209db61 100644 --- a/util/secret.go +++ b/util/secret.go @@ -11,8 +11,8 @@ import ( // SecretManager holds config info for a new server with which to access Kubernetes Secrets. type SecretManager struct { - namespace string - kubeclientset kubernetes.Interface + Namespace string + Clientset kubernetes.Interface } // NewSecretManager generates a new SecretManager pointer and returns it @@ -25,7 +25,7 @@ func NewSecretManager(namespace string, config *rest.Config) (server *SecretMana } // CreateSecret stores a new secret in Kubernetes. Set secretType to "" for no label. -func (server *SecretManager) CreateSecret(name string, value map[string]string, secretType string) (secret *apiv1.Secret, err error) { +func (server *SecretManager) Create(name string, value map[string]string, secretType string) (secret *apiv1.Secret, err error) { labels := make(map[string]string) if secretType != "" { labels[common.LabelKeySecretType] = secretType @@ -37,28 +37,28 @@ func (server *SecretManager) CreateSecret(name string, value map[string]string, }, } newSecret.StringData = value - secret, err = server.kubeclientset.CoreV1().Secrets(server.namespace).Create(newSecret) + secret, err = server.Clientset.CoreV1().Secrets(server.Namespace).Create(newSecret) return } // ReadSecret retrieves a secret from Kubernetes. -func (server *SecretManager) ReadSecret(name string) (secret *apiv1.Secret, err error) { - secret, err = server.kubeclientset.CoreV1().Secrets(server.namespace).Get(name, metav1.GetOptions{}) +func (server *SecretManager) Read(name string) (secret *apiv1.Secret, err error) { + secret, err = server.Clientset.CoreV1().Secrets(server.Namespace).Get(name, metav1.GetOptions{}) return } // UpdateSecret merge-updates an existing secret in Kubernetes. This merge-update is in contrast to the overwrite-update done for config maps. -func (server *SecretManager) UpdateSecret(name string, value map[string]string) (secret *apiv1.Secret, err error) { - existingSecret, err := server.ReadSecret(name) +func (server *SecretManager) Update(name string, value map[string]string) (secret *apiv1.Secret, err error) { + existingSecret, err := server.Read(name) if err == nil { existingSecret.StringData = value - secret, err = server.kubeclientset.CoreV1().Secrets(server.namespace).Update(existingSecret) + secret, err = server.Clientset.CoreV1().Secrets(server.Namespace).Update(existingSecret) } return } // DeleteSecret removes a secret from Kubernetes. -func (server *SecretManager) DeleteSecret(name string) (err error) { - err = server.kubeclientset.CoreV1().Secrets(server.namespace).Delete(name, &metav1.DeleteOptions{}) +func (server *SecretManager) Delete(name string) (err error) { + err = server.Clientset.CoreV1().Secrets(server.Namespace).Delete(name, &metav1.DeleteOptions{}) return } diff --git a/util/secret_test.go b/util/secret_test.go index 993118181db02..8ddd444e337f3 100644 --- a/util/secret_test.go +++ b/util/secret_test.go @@ -65,12 +65,12 @@ func TestSecretManager(t *testing.T) { t.Errorf("Could not create secret manager: %v", err) } - secret, err = mgr.CreateSecret(secretName, secretData1, label) + secret, err = mgr.Create(secretName, secretData1, label) if secretDataRetrieved := testConvertSecretStringData(secret); !reflect.DeepEqual(secretDataRetrieved, secretData1) { t.Errorf("Err = %v; Created data did not match: had %v, wanted %v", err, secretDataRetrieved, secretData1) } - secret, err = mgr.ReadSecret(secretName) + secret, err = mgr.Read(secretName) if err != nil { t.Errorf("Could not read secret: %v", err) } @@ -79,7 +79,7 @@ func TestSecretManager(t *testing.T) { t.Errorf("Read data did not match: had %v, wanted %v", secretDataRetrieved, secretData1) } - secret, err = mgr.UpdateSecret(secretName, secretData2) + secret, err = mgr.Update(secretName, secretData2) if err != nil { t.Errorf("Could not update secret: %v", err) } @@ -87,15 +87,15 @@ func TestSecretManager(t *testing.T) { t.Errorf("Updated data did not match: had %v, wanted %v", secretDataRetrieved, secretData1) } - err = mgr.DeleteSecret(secretName) + err = mgr.Delete(secretName) if err != nil { t.Errorf("Could not delete secret: %v", err) } - secret, err = mgr.ReadSecret(secretName) + secret, err = mgr.Read(secretName) if err == nil { secretDataRetrieved := testConvertSecretStringData(secret) t.Errorf("Read data did not match: had %v, wanted nil for name %s and label %s; trying again, but it may need to be deleted manually", secretDataRetrieved, secretName, label) - _ = mgr.DeleteSecret(secretName) + _ = mgr.Delete(secretName) } } From bc535f45ba111fda15bdfaa57ab9068b8faf3ba5 Mon Sep 17 00:00:00 2001 From: Andrew Merenbach Date: Tue, 20 Mar 2018 15:43:16 -0700 Subject: [PATCH 23/38] Update comments to match method names --- util/configmap.go | 8 ++++---- util/secret.go | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/util/configmap.go b/util/configmap.go index 800a238024111..f3349872c11e1 100644 --- a/util/configmap.go +++ b/util/configmap.go @@ -23,7 +23,7 @@ func NewConfigMapManager(namespace string, config *rest.Config) (server *ConfigM return } -// CreateConfigMap stores a new config map in Kubernetes. +// Create stores a new config map in Kubernetes. func (server *ConfigMapManager) Create(name string, value map[string]string) (configMap *apiv1.ConfigMap, err error) { newConfigMap := &apiv1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ @@ -35,13 +35,13 @@ func (server *ConfigMapManager) Create(name string, value map[string]string) (co return } -// ReadConfigMap retrieves a config map from Kubernetes. +// Read retrieves a config map from Kubernetes. func (server *ConfigMapManager) Read(name string) (configMap *apiv1.ConfigMap, err error) { configMap, err = server.Clientset.CoreV1().ConfigMaps(server.Namespace).Get(name, metav1.GetOptions{}) return } -// UpdateConfigMap overwrite-updates an existing config map in Kubernetes. This overwrite is in contrast to the merge-update done for secrets. +// Update overwrite-updates an existing config map in Kubernetes. This overwrite is in contrast to the merge-update done for secrets. func (server *ConfigMapManager) Update(name string, value map[string]string) (configMap *apiv1.ConfigMap, err error) { existingConfigMap, err := server.Read(name) if err == nil { @@ -51,7 +51,7 @@ func (server *ConfigMapManager) Update(name string, value map[string]string) (co return } -// DeleteConfigMap removes a config map from Kubernetes. +// Delete removes a config map from Kubernetes. func (server *ConfigMapManager) Delete(name string) (err error) { err = server.Clientset.CoreV1().ConfigMaps(server.Namespace).Delete(name, &metav1.DeleteOptions{}) return diff --git a/util/secret.go b/util/secret.go index d4dea3209db61..4c15617ea237c 100644 --- a/util/secret.go +++ b/util/secret.go @@ -24,7 +24,7 @@ func NewSecretManager(namespace string, config *rest.Config) (server *SecretMana return } -// CreateSecret stores a new secret in Kubernetes. Set secretType to "" for no label. +// Create stores a new secret in Kubernetes. Set secretType to "" for no label. func (server *SecretManager) Create(name string, value map[string]string, secretType string) (secret *apiv1.Secret, err error) { labels := make(map[string]string) if secretType != "" { @@ -41,13 +41,13 @@ func (server *SecretManager) Create(name string, value map[string]string, secret return } -// ReadSecret retrieves a secret from Kubernetes. +// Read retrieves a secret from Kubernetes. func (server *SecretManager) Read(name string) (secret *apiv1.Secret, err error) { secret, err = server.Clientset.CoreV1().Secrets(server.Namespace).Get(name, metav1.GetOptions{}) return } -// UpdateSecret merge-updates an existing secret in Kubernetes. This merge-update is in contrast to the overwrite-update done for config maps. +// Update merge-updates an existing secret in Kubernetes. This merge-update is in contrast to the overwrite-update done for config maps. func (server *SecretManager) Update(name string, value map[string]string) (secret *apiv1.Secret, err error) { existingSecret, err := server.Read(name) if err == nil { @@ -57,7 +57,7 @@ func (server *SecretManager) Update(name string, value map[string]string) (secre return } -// DeleteSecret removes a secret from Kubernetes. +// Delete removes a secret from Kubernetes. func (server *SecretManager) Delete(name string) (err error) { err = server.Clientset.CoreV1().Secrets(server.Namespace).Delete(name, &metav1.DeleteOptions{}) return From 50a4bd123c1943a50c5b21b44efbb5d2e7b63283 Mon Sep 17 00:00:00 2001 From: Andrew Merenbach Date: Tue, 20 Mar 2018 17:33:13 -0700 Subject: [PATCH 24/38] Rm secret/configmap code for now --- util/configmap.go | 58 ----------------------- util/configmap_test.go | 70 ---------------------------- util/secret.go | 64 -------------------------- util/secret_test.go | 101 ----------------------------------------- 4 files changed, 293 deletions(-) delete mode 100644 util/configmap.go delete mode 100644 util/configmap_test.go delete mode 100644 util/secret.go delete mode 100644 util/secret_test.go diff --git a/util/configmap.go b/util/configmap.go deleted file mode 100644 index f3349872c11e1..0000000000000 --- a/util/configmap.go +++ /dev/null @@ -1,58 +0,0 @@ -package util - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - apiv1 "k8s.io/api/core/v1" - "k8s.io/client-go/kubernetes" - "k8s.io/client-go/rest" -) - -// ConfigMapManager holds config info for a new server with which to access Kubernetes ConfigMaps. -type ConfigMapManager struct { - Namespace string - Clientset kubernetes.Interface -} - -// NewConfigMapManager generates a new ConfigMapManager pointer and returns it -func NewConfigMapManager(namespace string, config *rest.Config) (server *ConfigMapManager, err error) { - kubeclientset, err := kubernetes.NewForConfig(config) - if err == nil { - server = &ConfigMapManager{namespace, kubeclientset} - } - return -} - -// Create stores a new config map in Kubernetes. -func (server *ConfigMapManager) Create(name string, value map[string]string) (configMap *apiv1.ConfigMap, err error) { - newConfigMap := &apiv1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - }, - Data: value, - } - configMap, err = server.Clientset.CoreV1().ConfigMaps(server.Namespace).Create(newConfigMap) - return -} - -// Read retrieves a config map from Kubernetes. -func (server *ConfigMapManager) Read(name string) (configMap *apiv1.ConfigMap, err error) { - configMap, err = server.Clientset.CoreV1().ConfigMaps(server.Namespace).Get(name, metav1.GetOptions{}) - return -} - -// Update overwrite-updates an existing config map in Kubernetes. This overwrite is in contrast to the merge-update done for secrets. -func (server *ConfigMapManager) Update(name string, value map[string]string) (configMap *apiv1.ConfigMap, err error) { - existingConfigMap, err := server.Read(name) - if err == nil { - existingConfigMap.Data = value - configMap, err = server.Clientset.CoreV1().ConfigMaps(server.Namespace).Update(existingConfigMap) - } - return -} - -// Delete removes a config map from Kubernetes. -func (server *ConfigMapManager) Delete(name string) (err error) { - err = server.Clientset.CoreV1().ConfigMaps(server.Namespace).Delete(name, &metav1.DeleteOptions{}) - return -} diff --git a/util/configmap_test.go b/util/configmap_test.go deleted file mode 100644 index 6ca2881b4022c..0000000000000 --- a/util/configmap_test.go +++ /dev/null @@ -1,70 +0,0 @@ -package util - -import ( - "reflect" - "testing" - - "github.com/pborman/uuid" - "k8s.io/client-go/rest" - "k8s.io/client-go/tools/clientcmd" -) - -const testConfigMapNamespace = "default" - -// makeTestConfigMapClientConfig creates an empty client config to use for K8s API calls -// TODO (@merenbach): make this more general for use in other tests -func makeTestConfigMapClientConfig() (config *rest.Config, err error) { - loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() - loadingRules.DefaultClientConfig = &clientcmd.DefaultClientConfig - overrides := clientcmd.ConfigOverrides{} - configRaw := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, &overrides) - config, err = configRaw.ClientConfig() - return -} - -func TestConfigMapManager(t *testing.T) { - configMapName := uuid.New() - configMapData1 := map[string]string{ - "some": "data", - "hello": "world", - } - configMapData2 := map[string]string{ - "other": "data", - "some": "thing else", - "world": "hello", - } - - config, err := makeTestConfigMapClientConfig() - if err != nil { - t.Errorf("Could not create test client config: %v", err) - } - mgr, err := NewConfigMapManager(testConfigMapNamespace, config) - if err != nil { - t.Errorf("Could not create config map manager: %v", err) - } - configMap, err := mgr.Create(configMapName, configMapData1) - if err != nil || !reflect.DeepEqual(configMap.Data, configMapData1) { - t.Errorf("Err = %v; Created data did not match: had %v, wanted %v", err, configMap.Data, configMapData1) - } - - configMap, err = mgr.Read(configMapName) - if err != nil || !reflect.DeepEqual(configMap.Data, configMapData1) { - t.Errorf("Err = %v; Read data did not match: had %v, wanted %v", err, configMap.Data, configMapData1) - } - - configMap, err = mgr.Update(configMapName, configMapData2) - if err != nil || !reflect.DeepEqual(configMap.Data, configMapData2) { - t.Errorf("Err = %v; Updated data did not match: had %v, wanted %v", err, configMap.Data, configMapData1) - } - - err = mgr.Delete(configMapName) - if err != nil { - t.Errorf("Err = %v", err) - } - - configMap, err = mgr.Read(configMapName) - if err == nil { - t.Errorf("Read data did not match: had %v, wanted nil for name %s; trying again, but it may need to be deleted manually", configMap.Data, configMapName) - _ = mgr.Delete(configMapName) - } -} diff --git a/util/secret.go b/util/secret.go deleted file mode 100644 index 4c15617ea237c..0000000000000 --- a/util/secret.go +++ /dev/null @@ -1,64 +0,0 @@ -package util - -import ( - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - "github.com/argoproj/argo-cd/common" - apiv1 "k8s.io/api/core/v1" - "k8s.io/client-go/kubernetes" - "k8s.io/client-go/rest" -) - -// SecretManager holds config info for a new server with which to access Kubernetes Secrets. -type SecretManager struct { - Namespace string - Clientset kubernetes.Interface -} - -// NewSecretManager generates a new SecretManager pointer and returns it -func NewSecretManager(namespace string, config *rest.Config) (server *SecretManager, err error) { - kubeclientset, err := kubernetes.NewForConfig(config) - if err == nil { - server = &SecretManager{namespace, kubeclientset} - } - return -} - -// Create stores a new secret in Kubernetes. Set secretType to "" for no label. -func (server *SecretManager) Create(name string, value map[string]string, secretType string) (secret *apiv1.Secret, err error) { - labels := make(map[string]string) - if secretType != "" { - labels[common.LabelKeySecretType] = secretType - } - newSecret := &apiv1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Labels: labels, - }, - } - newSecret.StringData = value - secret, err = server.Clientset.CoreV1().Secrets(server.Namespace).Create(newSecret) - return -} - -// Read retrieves a secret from Kubernetes. -func (server *SecretManager) Read(name string) (secret *apiv1.Secret, err error) { - secret, err = server.Clientset.CoreV1().Secrets(server.Namespace).Get(name, metav1.GetOptions{}) - return -} - -// Update merge-updates an existing secret in Kubernetes. This merge-update is in contrast to the overwrite-update done for config maps. -func (server *SecretManager) Update(name string, value map[string]string) (secret *apiv1.Secret, err error) { - existingSecret, err := server.Read(name) - if err == nil { - existingSecret.StringData = value - secret, err = server.Clientset.CoreV1().Secrets(server.Namespace).Update(existingSecret) - } - return -} - -// Delete removes a secret from Kubernetes. -func (server *SecretManager) Delete(name string) (err error) { - err = server.Clientset.CoreV1().Secrets(server.Namespace).Delete(name, &metav1.DeleteOptions{}) - return -} diff --git a/util/secret_test.go b/util/secret_test.go deleted file mode 100644 index 8ddd444e337f3..0000000000000 --- a/util/secret_test.go +++ /dev/null @@ -1,101 +0,0 @@ -package util - -import ( - "reflect" - "testing" - - "github.com/pborman/uuid" - apiv1 "k8s.io/api/core/v1" - "k8s.io/client-go/rest" - "k8s.io/client-go/tools/clientcmd" -) - -const testSecretNamespace = "default" - -// makeTestSecretClientConfig creates an empty client config to use for K8s API calls -// TODO (@merenbach): make this more general for use in other tests -func makeTestSecretClientConfig() (config *rest.Config, err error) { - loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() - loadingRules.DefaultClientConfig = &clientcmd.DefaultClientConfig - overrides := clientcmd.ConfigOverrides{} - configRaw := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, &overrides) - config, err = configRaw.ClientConfig() - return -} - -// testConvertSecretStringData returns a mapping of a secret data as a map[string]string instead of map[string][]byte. -func testConvertSecretStringData(secret *apiv1.Secret) map[string]string { - out := make(map[string]string) - for k, v := range secret.Data { - out[k] = string(v) - } - return out -} - -func TestSecretManager(t *testing.T) { - var ( - secret *apiv1.Secret - err error - ) - - secretName := uuid.New() - label := "test" - secretData1 := map[string]string{ - "some": "data", - "hello": "world", - } - secretData2 := map[string]string{ - "other": "data", - "some": "thing else", - "world": "hello", - } - secretDataAfterUpdate := map[string]string{ - "other": "data", - "some": "thing else", - "world": "hello", - "hello": "world", - } - - config, err := makeTestSecretClientConfig() - if err != nil { - t.Errorf("Could not create test client config: %v", err) - } - mgr, err := NewSecretManager(testSecretNamespace, config) - if err != nil { - t.Errorf("Could not create secret manager: %v", err) - } - - secret, err = mgr.Create(secretName, secretData1, label) - if secretDataRetrieved := testConvertSecretStringData(secret); !reflect.DeepEqual(secretDataRetrieved, secretData1) { - t.Errorf("Err = %v; Created data did not match: had %v, wanted %v", err, secretDataRetrieved, secretData1) - } - - secret, err = mgr.Read(secretName) - if err != nil { - t.Errorf("Could not read secret: %v", err) - } - - if secretDataRetrieved := testConvertSecretStringData(secret); !reflect.DeepEqual(secretDataRetrieved, secretData1) { - t.Errorf("Read data did not match: had %v, wanted %v", secretDataRetrieved, secretData1) - } - - secret, err = mgr.Update(secretName, secretData2) - if err != nil { - t.Errorf("Could not update secret: %v", err) - } - if secretDataRetrieved := testConvertSecretStringData(secret); !reflect.DeepEqual(secretDataRetrieved, secretDataAfterUpdate) { - t.Errorf("Updated data did not match: had %v, wanted %v", secretDataRetrieved, secretData1) - } - - err = mgr.Delete(secretName) - if err != nil { - t.Errorf("Could not delete secret: %v", err) - } - - secret, err = mgr.Read(secretName) - if err == nil { - secretDataRetrieved := testConvertSecretStringData(secret) - t.Errorf("Read data did not match: had %v, wanted nil for name %s and label %s; trying again, but it may need to be deleted manually", secretDataRetrieved, secretName, label) - _ = mgr.Delete(secretName) - } -} From b2ad562ddec4629f1a847ce3718eeaa30849f6db Mon Sep 17 00:00:00 2001 From: Andrew Merenbach Date: Tue, 20 Mar 2018 17:36:39 -0700 Subject: [PATCH 25/38] Rm spurious newline --- install/install.go | 1 - 1 file changed, 1 deletion(-) diff --git a/install/install.go b/install/install.go index bf87fae5077f3..d60cff281056e 100644 --- a/install/install.go +++ b/install/install.go @@ -148,7 +148,6 @@ func (i *Installer) InstallArgoCDServer() { i.unmarshalManifest("03b_argocd-server-role.yaml", &argoCDServerControllerRole) i.unmarshalManifest("03c_argocd-server-rolebinding.yaml", &argoCDServerControllerRoleBinding) i.unmarshalManifest("03d_argocd-server-deployment.yaml", &argoCDServerControllerDeployment) - i.unmarshalManifest("03e_argocd-server-service.yaml", &argoCDServerService) argoCDServerControllerDeployment.Spec.Template.Spec.InitContainers[0].Image = i.UIImage argoCDServerControllerDeployment.Spec.Template.Spec.InitContainers[0].ImagePullPolicy = apiv1.PullPolicy(i.ImagePullPolicy) From d6112b0922c978a4e60413c8ff0632df3335fd63 Mon Sep 17 00:00:00 2001 From: Andrew Merenbach Date: Tue, 20 Mar 2018 17:45:07 -0700 Subject: [PATCH 26/38] Add config-map argument to argocd-server --- cmd/argocd-server/commands/root.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/cmd/argocd-server/commands/root.go b/cmd/argocd-server/commands/root.go index f181ec764a4b5..2f1151aac5c18 100644 --- a/cmd/argocd-server/commands/root.go +++ b/cmd/argocd-server/commands/root.go @@ -19,6 +19,7 @@ func NewCommand() *cobra.Command { clientConfig clientcmd.ClientConfig staticAssetsDir string repoServerAddress string + configMapName string ) var command = &cobra.Command{ Use: cliName, @@ -48,6 +49,7 @@ func NewCommand() *cobra.Command { command.Flags().StringVar(&staticAssetsDir, "staticassets", "", "Static assets directory path") command.Flags().StringVar(&logLevel, "loglevel", "info", "Set the logging level. One of: debug|info|warn|error") command.Flags().StringVar(&repoServerAddress, "repo-server", "localhost:8081", "Repo server address.") + command.Flags().StringVar(&configMapName, "config-map", "", "Name of a Kubernetes config map to use.") command.AddCommand(cli.NewVersionCmd(cliName)) return command } From 037af32a98e8fbc3d95aefd9ec7d2a31d3ea1c64 Mon Sep 17 00:00:00 2001 From: Andrew Merenbach Date: Wed, 21 Mar 2018 09:49:34 -0700 Subject: [PATCH 27/38] Use Containers, not InitContainers, thanks @alexmt --- install/install.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install/install.go b/install/install.go index d60cff281056e..fd7527cf34f54 100644 --- a/install/install.go +++ b/install/install.go @@ -156,7 +156,7 @@ func (i *Installer) InstallArgoCDServer() { // Use a Kubernetes ConfigMap, if provided. if i.InstallOptions.ConfigMap != "" { configMap := strconv.Quote(i.InstallOptions.ConfigMap) - container := &argoCDServerControllerDeployment.Spec.Template.Spec.InitContainers[0] + container := &argoCDServerControllerDeployment.Spec.Template.Spec.Containers[0] container.Command = append(container.Command, "--config-map", configMap) } i.MustInstallResource(kube.MustToUnstructured(&argoCDServerServiceAccount)) From 26de1e74dec13cbbbead3535b52706bcd9a170d8 Mon Sep 17 00:00:00 2001 From: Andrew Merenbach Date: Wed, 21 Mar 2018 10:35:17 -0700 Subject: [PATCH 28/38] Reintroduce config map reading --- cmd/argocd-server/commands/root.go | 2 +- server/server.go | 10 ++++- util/configmap.go | 57 ++++++++++++++++++++++++ util/configmap_test.go | 69 ++++++++++++++++++++++++++++++ 4 files changed, 136 insertions(+), 2 deletions(-) create mode 100644 util/configmap.go create mode 100644 util/configmap_test.go diff --git a/cmd/argocd-server/commands/root.go b/cmd/argocd-server/commands/root.go index 2f1151aac5c18..c1978c2c850bc 100644 --- a/cmd/argocd-server/commands/root.go +++ b/cmd/argocd-server/commands/root.go @@ -40,7 +40,7 @@ func NewCommand() *cobra.Command { appclientset := appclientset.NewForConfigOrDie(config) repoclientset := reposerver.NewRepositoryServerClientset(repoServerAddress) - argocd := server.NewServer(kubeclientset, appclientset, repoclientset, namespace, staticAssetsDir) + argocd := server.NewServer(kubeclientset, appclientset, repoclientset, namespace, staticAssetsDir, configMapName) argocd.Run() }, } diff --git a/server/server.go b/server/server.go index 0049b5e51e881..6fc4989b7d4e1 100644 --- a/server/server.go +++ b/server/server.go @@ -15,6 +15,7 @@ import ( "github.com/argoproj/argo-cd/server/cluster" "github.com/argoproj/argo-cd/server/repository" "github.com/argoproj/argo-cd/server/version" + "github.com/argoproj/argo-cd/util" grpc_util "github.com/argoproj/argo-cd/util/grpc" jsonutil "github.com/argoproj/argo-cd/util/json" grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" @@ -23,6 +24,7 @@ import ( log "github.com/sirupsen/logrus" "github.com/soheilhy/cmux" "google.golang.org/grpc" + apiv1 "k8s.io/api/core/v1" "k8s.io/client-go/kubernetes" ) @@ -41,12 +43,17 @@ type ArgoCDServer struct { kubeclientset kubernetes.Interface appclientset appclientset.Interface repoclientset reposerver.Clientset + configMap apiv1.ConfigMap log *log.Entry } // NewServer returns a new instance of the ArgoCD API server func NewServer( - kubeclientset kubernetes.Interface, appclientset appclientset.Interface, repoclientset reposerver.Clientset, namespace string, staticAssetsDir string) *ArgoCDServer { + kubeclientset kubernetes.Interface, appclientset appclientset.Interface, repoclientset reposerver.Clientset, namespace, staticAssetsDir, configMapName string) *ArgoCDServer { + var configMap apiv1.ConfigMap + if configMapName != "" { + configMap := (&util.ConfigMapClientsetWrapper{kubeclientset}).Get(namespace, configMapName) + } return &ArgoCDServer{ ns: namespace, kubeclientset: kubeclientset, @@ -54,6 +61,7 @@ func NewServer( repoclientset: repoclientset, log: log.NewEntry(log.New()), staticAssetsDir: staticAssetsDir, + configMap: configMap, } } diff --git a/util/configmap.go b/util/configmap.go new file mode 100644 index 0000000000000..49e8d8d9b3d4e --- /dev/null +++ b/util/configmap.go @@ -0,0 +1,57 @@ +package util + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + apiv1 "k8s.io/api/core/v1" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" +) + +// ConfigMapClientsetWrapper holds config info for a new manager with which to access Kubernetes ConfigMaps. +type ConfigMapClientsetWrapper struct { + Clientset kubernetes.Interface +} + +// NewConfigMapClientsetWrapper generates a new ConfigMapClientsetWrapper pointer and returns it +func NewConfigMapClientsetWrapper(config *rest.Config) (manager *ConfigMapClientsetWrapper, err error) { + kubeclientset, err := kubernetes.NewForConfig(config) + if err == nil { + manager = &ConfigMapClientsetWrapper{kubeclientset} + } + return +} + +// Create stores a new config map in Kubernetes. +func (manager *ConfigMapClientsetWrapper) Create(namespace, name string, value map[string]string) (configMap *apiv1.ConfigMap, err error) { + newConfigMap := &apiv1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + Data: value, + } + configMap, err = manager.Clientset.CoreV1().ConfigMaps(namespace).Create(newConfigMap) + return +} + +// Read retrieves a config map from Kubernetes. +func (manager *ConfigMapClientsetWrapper) Read(namespace, name string) (configMap *apiv1.ConfigMap, err error) { + configMap, err = manager.Clientset.CoreV1().ConfigMaps(namespace).Get(name, metav1.GetOptions{}) + return +} + +// Update overwrite-updates an existing config map in Kubernetes. This overwrite is in contrast to the merge-update done for secrets. +func (manager *ConfigMapClientsetWrapper) Update(namespace, name string, value map[string]string) (configMap *apiv1.ConfigMap, err error) { + existingConfigMap, err := manager.Read(namespace, name) + if err == nil { + existingConfigMap.Data = value + configMap, err = manager.Clientset.CoreV1().ConfigMaps(namespace).Update(existingConfigMap) + } + return +} + +// Delete removes a config map from Kubernetes. +func (manager *ConfigMapClientsetWrapper) Delete(namespace, name string) (err error) { + err = manager.Clientset.CoreV1().ConfigMaps(namespace).Delete(name, &metav1.DeleteOptions{}) + return +} diff --git a/util/configmap_test.go b/util/configmap_test.go new file mode 100644 index 0000000000000..e9a458378ab43 --- /dev/null +++ b/util/configmap_test.go @@ -0,0 +1,69 @@ +package util + +import ( + "reflect" + "testing" + + "github.com/pborman/uuid" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" +) + +// makeTestConfigMapClientConfig creates an empty client config to use for K8s API calls +// TODO (@merenbach): make this more general for use in other tests +func makeTestConfigMapClientConfig() (config *rest.Config, err error) { + loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() + loadingRules.DefaultClientConfig = &clientcmd.DefaultClientConfig + overrides := clientcmd.ConfigOverrides{} + configRaw := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, &overrides) + config, err = configRaw.ClientConfig() + return +} + +func TestConfigMapClientsetWrapper(t *testing.T) { + const namespace = "default" + configMapName := uuid.New() + configMapData1 := map[string]string{ + "some": "data", + "hello": "world", + } + configMapData2 := map[string]string{ + "other": "data", + "some": "thing else", + "world": "hello", + } + + config, err := makeTestConfigMapClientConfig() + if err != nil { + t.Errorf("Could not create test client config: %v", err) + } + mgr, err := NewConfigMapClientsetWrapper(config) + if err != nil { + t.Errorf("Could not create config map manager: %v", err) + } + configMap, err := mgr.Create(namespace, configMapName, configMapData1) + if err != nil || !reflect.DeepEqual(configMap.Data, configMapData1) { + t.Errorf("Err = %v; Created data did not match: had %v, wanted %v", err, configMap.Data, configMapData1) + } + + configMap, err = mgr.Read(namespace, configMapName) + if err != nil || !reflect.DeepEqual(configMap.Data, configMapData1) { + t.Errorf("Err = %v; Read data did not match: had %v, wanted %v", err, configMap.Data, configMapData1) + } + + configMap, err = mgr.Update(namespace, configMapName, configMapData2) + if err != nil || !reflect.DeepEqual(configMap.Data, configMapData2) { + t.Errorf("Err = %v; Updated data did not match: had %v, wanted %v", err, configMap.Data, configMapData1) + } + + err = mgr.Delete(namespace, configMapName) + if err != nil { + t.Errorf("Err = %v", err) + } + + configMap, err = mgr.Read(namespace, configMapName) + if err == nil { + t.Errorf("Read data did not match: had %v, wanted nil for name %s; trying again, but it may need to be deleted manually", configMap.Data, configMapName) + _ = mgr.Delete(namespace, configMapName) + } +} From 8e8ce2e397840ff9e473b527774a9bfa8623c6db Mon Sep 17 00:00:00 2001 From: Andrew Merenbach Date: Wed, 21 Mar 2018 12:50:26 -0700 Subject: [PATCH 29/38] Rename wrapper into ConfigManager --- util/configmap.go | 36 ++++++++++++++++++------------------ util/configmap_test.go | 16 ++++++++-------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/util/configmap.go b/util/configmap.go index 49e8d8d9b3d4e..68b8500d85508 100644 --- a/util/configmap.go +++ b/util/configmap.go @@ -8,50 +8,50 @@ import ( "k8s.io/client-go/rest" ) -// ConfigMapClientsetWrapper holds config info for a new manager with which to access Kubernetes ConfigMaps. -type ConfigMapClientsetWrapper struct { +// ConfigManager holds config info for a new manager with which to access Kubernetes ConfigMaps. +type ConfigManager struct { Clientset kubernetes.Interface } -// NewConfigMapClientsetWrapper generates a new ConfigMapClientsetWrapper pointer and returns it -func NewConfigMapClientsetWrapper(config *rest.Config) (manager *ConfigMapClientsetWrapper, err error) { +// NewConfigManager generates a new ConfigManager pointer and returns it +func NewConfigManager(config *rest.Config) (mgr *ConfigManager, err error) { kubeclientset, err := kubernetes.NewForConfig(config) if err == nil { - manager = &ConfigMapClientsetWrapper{kubeclientset} + mgr = &ConfigManager{kubeclientset} } return } -// Create stores a new config map in Kubernetes. -func (manager *ConfigMapClientsetWrapper) Create(namespace, name string, value map[string]string) (configMap *apiv1.ConfigMap, err error) { +// CreateConfigMap stores a new config map in Kubernetes. +func (mgr *ConfigManager) CreateConfigMap(namespace, name string, value map[string]string) (configMap *apiv1.ConfigMap, err error) { newConfigMap := &apiv1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: name, }, Data: value, } - configMap, err = manager.Clientset.CoreV1().ConfigMaps(namespace).Create(newConfigMap) + configMap, err = mgr.Clientset.CoreV1().ConfigMaps(namespace).Create(newConfigMap) return } -// Read retrieves a config map from Kubernetes. -func (manager *ConfigMapClientsetWrapper) Read(namespace, name string) (configMap *apiv1.ConfigMap, err error) { - configMap, err = manager.Clientset.CoreV1().ConfigMaps(namespace).Get(name, metav1.GetOptions{}) +// ReadConfigMap retrieves a config map from Kubernetes. +func (mgr *ConfigManager) ReadConfigMap(namespace, name string) (configMap *apiv1.ConfigMap, err error) { + configMap, err = mgr.Clientset.CoreV1().ConfigMaps(namespace).Get(name, metav1.GetOptions{}) return } -// Update overwrite-updates an existing config map in Kubernetes. This overwrite is in contrast to the merge-update done for secrets. -func (manager *ConfigMapClientsetWrapper) Update(namespace, name string, value map[string]string) (configMap *apiv1.ConfigMap, err error) { - existingConfigMap, err := manager.Read(namespace, name) +// UpdateConfigMap overwrite-updates an existing config map in Kubernetes. This overwrite is in contrast to the merge-update done for secrets. +func (mgr *ConfigManager) UpdateConfigMap(namespace, name string, value map[string]string) (configMap *apiv1.ConfigMap, err error) { + existingConfigMap, err := mgr.ReadConfigMap(namespace, name) if err == nil { existingConfigMap.Data = value - configMap, err = manager.Clientset.CoreV1().ConfigMaps(namespace).Update(existingConfigMap) + configMap, err = mgr.Clientset.CoreV1().ConfigMaps(namespace).Update(existingConfigMap) } return } -// Delete removes a config map from Kubernetes. -func (manager *ConfigMapClientsetWrapper) Delete(namespace, name string) (err error) { - err = manager.Clientset.CoreV1().ConfigMaps(namespace).Delete(name, &metav1.DeleteOptions{}) +// DeleteConfigMap removes a config map from Kubernetes. +func (mgr *ConfigManager) DeleteConfigMap(namespace, name string) (err error) { + err = mgr.Clientset.CoreV1().ConfigMaps(namespace).Delete(name, &metav1.DeleteOptions{}) return } diff --git a/util/configmap_test.go b/util/configmap_test.go index e9a458378ab43..ced076a05d64d 100644 --- a/util/configmap_test.go +++ b/util/configmap_test.go @@ -20,7 +20,7 @@ func makeTestConfigMapClientConfig() (config *rest.Config, err error) { return } -func TestConfigMapClientsetWrapper(t *testing.T) { +func TestConfigManager(t *testing.T) { const namespace = "default" configMapName := uuid.New() configMapData1 := map[string]string{ @@ -37,33 +37,33 @@ func TestConfigMapClientsetWrapper(t *testing.T) { if err != nil { t.Errorf("Could not create test client config: %v", err) } - mgr, err := NewConfigMapClientsetWrapper(config) + mgr, err := NewConfigManager(config) if err != nil { t.Errorf("Could not create config map manager: %v", err) } - configMap, err := mgr.Create(namespace, configMapName, configMapData1) + configMap, err := mgr.CreateConfigMap(namespace, configMapName, configMapData1) if err != nil || !reflect.DeepEqual(configMap.Data, configMapData1) { t.Errorf("Err = %v; Created data did not match: had %v, wanted %v", err, configMap.Data, configMapData1) } - configMap, err = mgr.Read(namespace, configMapName) + configMap, err = mgr.ReadConfigMap(namespace, configMapName) if err != nil || !reflect.DeepEqual(configMap.Data, configMapData1) { t.Errorf("Err = %v; Read data did not match: had %v, wanted %v", err, configMap.Data, configMapData1) } - configMap, err = mgr.Update(namespace, configMapName, configMapData2) + configMap, err = mgr.UpdateConfigMap(namespace, configMapName, configMapData2) if err != nil || !reflect.DeepEqual(configMap.Data, configMapData2) { t.Errorf("Err = %v; Updated data did not match: had %v, wanted %v", err, configMap.Data, configMapData1) } - err = mgr.Delete(namespace, configMapName) + err = mgr.DeleteConfigMap(namespace, configMapName) if err != nil { t.Errorf("Err = %v", err) } - configMap, err = mgr.Read(namespace, configMapName) + configMap, err = mgr.ReadConfigMap(namespace, configMapName) if err == nil { t.Errorf("Read data did not match: had %v, wanted nil for name %s; trying again, but it may need to be deleted manually", configMap.Data, configMapName) - _ = mgr.Delete(namespace, configMapName) + _ = mgr.DeleteConfigMap(namespace, configMapName) } } From 83e499242ae709097120af5efd63db8f910b8d28 Mon Sep 17 00:00:00 2001 From: Andrew Merenbach Date: Wed, 21 Mar 2018 12:51:07 -0700 Subject: [PATCH 30/38] Rename configmap => configmanager --- util/{configmap.go => configmanager.go} | 0 util/{configmap_test.go => configmanager_test.go} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename util/{configmap.go => configmanager.go} (100%) rename util/{configmap_test.go => configmanager_test.go} (100%) diff --git a/util/configmap.go b/util/configmanager.go similarity index 100% rename from util/configmap.go rename to util/configmanager.go diff --git a/util/configmap_test.go b/util/configmanager_test.go similarity index 100% rename from util/configmap_test.go rename to util/configmanager_test.go From c4c1c14261f4c4e0e598a7a7bacd0bc7c42e8162 Mon Sep 17 00:00:00 2001 From: Andrew Merenbach Date: Wed, 21 Mar 2018 12:54:03 -0700 Subject: [PATCH 31/38] Break ConfigManager invocation into two lines --- server/server.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/server/server.go b/server/server.go index 6fc4989b7d4e1..c70e07c07e25c 100644 --- a/server/server.go +++ b/server/server.go @@ -52,7 +52,8 @@ func NewServer( kubeclientset kubernetes.Interface, appclientset appclientset.Interface, repoclientset reposerver.Clientset, namespace, staticAssetsDir, configMapName string) *ArgoCDServer { var configMap apiv1.ConfigMap if configMapName != "" { - configMap := (&util.ConfigMapClientsetWrapper{kubeclientset}).Get(namespace, configMapName) + configManager := util.ConfigManager{kubeclientset} + configMap := configManager.Get(namespace, configMapName) } return &ArgoCDServer{ ns: namespace, From 922cd10d5c66512217763e4067f715377ff17688 Mon Sep 17 00:00:00 2001 From: Andrew Merenbach Date: Wed, 21 Mar 2018 12:55:00 -0700 Subject: [PATCH 32/38] Privatize Clientset field --- util/configmanager.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/util/configmanager.go b/util/configmanager.go index 68b8500d85508..088fa0acd7a43 100644 --- a/util/configmanager.go +++ b/util/configmanager.go @@ -10,7 +10,7 @@ import ( // ConfigManager holds config info for a new manager with which to access Kubernetes ConfigMaps. type ConfigManager struct { - Clientset kubernetes.Interface + clientset kubernetes.Interface } // NewConfigManager generates a new ConfigManager pointer and returns it @@ -30,13 +30,13 @@ func (mgr *ConfigManager) CreateConfigMap(namespace, name string, value map[stri }, Data: value, } - configMap, err = mgr.Clientset.CoreV1().ConfigMaps(namespace).Create(newConfigMap) + configMap, err = mgr.clientset.CoreV1().ConfigMaps(namespace).Create(newConfigMap) return } // ReadConfigMap retrieves a config map from Kubernetes. func (mgr *ConfigManager) ReadConfigMap(namespace, name string) (configMap *apiv1.ConfigMap, err error) { - configMap, err = mgr.Clientset.CoreV1().ConfigMaps(namespace).Get(name, metav1.GetOptions{}) + configMap, err = mgr.clientset.CoreV1().ConfigMaps(namespace).Get(name, metav1.GetOptions{}) return } @@ -45,13 +45,13 @@ func (mgr *ConfigManager) UpdateConfigMap(namespace, name string, value map[stri existingConfigMap, err := mgr.ReadConfigMap(namespace, name) if err == nil { existingConfigMap.Data = value - configMap, err = mgr.Clientset.CoreV1().ConfigMaps(namespace).Update(existingConfigMap) + configMap, err = mgr.clientset.CoreV1().ConfigMaps(namespace).Update(existingConfigMap) } return } // DeleteConfigMap removes a config map from Kubernetes. func (mgr *ConfigManager) DeleteConfigMap(namespace, name string) (err error) { - err = mgr.Clientset.CoreV1().ConfigMaps(namespace).Delete(name, &metav1.DeleteOptions{}) + err = mgr.clientset.CoreV1().ConfigMaps(namespace).Delete(name, &metav1.DeleteOptions{}) return } From 417fbc3d74ab8b3b96dc6585461e086e39498a4d Mon Sep 17 00:00:00 2001 From: Andrew Merenbach Date: Wed, 21 Mar 2018 13:26:13 -0700 Subject: [PATCH 33/38] Support Listing config maps --- util/configmanager.go | 6 ++++++ util/configmanager_test.go | 14 +++++++++++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/util/configmanager.go b/util/configmanager.go index 088fa0acd7a43..86015489cd712 100644 --- a/util/configmanager.go +++ b/util/configmanager.go @@ -22,6 +22,12 @@ func NewConfigManager(config *rest.Config) (mgr *ConfigManager, err error) { return } +// ListConfigMaps returns a list of existing config maps. +func (mgr *ConfigManager) ListConfigMaps(namespace string) (configMaps *apiv1.ConfigMapList, err error) { + configMaps, err = mgr.clientset.CoreV1().ConfigMaps(namespace).List(metav1.ListOptions{}) + return +} + // CreateConfigMap stores a new config map in Kubernetes. func (mgr *ConfigManager) CreateConfigMap(namespace, name string, value map[string]string) (configMap *apiv1.ConfigMap, err error) { newConfigMap := &apiv1.ConfigMap{ diff --git a/util/configmanager_test.go b/util/configmanager_test.go index ced076a05d64d..89f95e258c5ab 100644 --- a/util/configmanager_test.go +++ b/util/configmanager_test.go @@ -4,6 +4,8 @@ import ( "reflect" "testing" + apiv1 "k8s.io/api/core/v1" + "github.com/pborman/uuid" "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" @@ -33,6 +35,11 @@ func TestConfigManager(t *testing.T) { "world": "hello", } + var ( + configMap *apiv1.ConfigMap + configMaps *apiv1.ConfigMapList + ) + config, err := makeTestConfigMapClientConfig() if err != nil { t.Errorf("Could not create test client config: %v", err) @@ -41,7 +48,7 @@ func TestConfigManager(t *testing.T) { if err != nil { t.Errorf("Could not create config map manager: %v", err) } - configMap, err := mgr.CreateConfigMap(namespace, configMapName, configMapData1) + configMap, err = mgr.CreateConfigMap(namespace, configMapName, configMapData1) if err != nil || !reflect.DeepEqual(configMap.Data, configMapData1) { t.Errorf("Err = %v; Created data did not match: had %v, wanted %v", err, configMap.Data, configMapData1) } @@ -56,6 +63,11 @@ func TestConfigManager(t *testing.T) { t.Errorf("Err = %v; Updated data did not match: had %v, wanted %v", err, configMap.Data, configMapData1) } + configMaps, err = mgr.ListConfigMaps(namespace) + if err != nil || !reflect.DeepEqual(configMaps.Items[0], *configMap) { + t.Errorf("Err = %v; Updated data in List did not match: had %v, wanted %v", err, configMaps.Items[0], configMap) + } + err = mgr.DeleteConfigMap(namespace, configMapName) if err != nil { t.Errorf("Err = %v", err) From fcae9e6c470659673cd5bb838cafe9f98c323cb5 Mon Sep 17 00:00:00 2001 From: Andrew Merenbach Date: Wed, 21 Mar 2018 13:51:47 -0700 Subject: [PATCH 34/38] Simplify client manager instantiation --- server/server.go | 9 +++++++-- util/configmanager.go | 8 ++------ util/configmanager_test.go | 16 ++++++++-------- 3 files changed, 17 insertions(+), 16 deletions(-) diff --git a/server/server.go b/server/server.go index c70e07c07e25c..0359164ff02e0 100644 --- a/server/server.go +++ b/server/server.go @@ -36,6 +36,11 @@ var ( endpoint = fmt.Sprintf("localhost:%d", port) ) +// ArgoCDServerConfig holds in-memory runtime configuration options. +type ArgoCDServerConfig struct { + AdminPasswordSecretName string +} + // ArgoCDServer is the API server for ArgoCD type ArgoCDServer struct { ns string @@ -43,7 +48,7 @@ type ArgoCDServer struct { kubeclientset kubernetes.Interface appclientset appclientset.Interface repoclientset reposerver.Clientset - configMap apiv1.ConfigMap + configuration ArgoCDServerConfig log *log.Entry } @@ -52,7 +57,7 @@ func NewServer( kubeclientset kubernetes.Interface, appclientset appclientset.Interface, repoclientset reposerver.Clientset, namespace, staticAssetsDir, configMapName string) *ArgoCDServer { var configMap apiv1.ConfigMap if configMapName != "" { - configManager := util.ConfigManager{kubeclientset} + configManager := util.NewConfigManager(kubeclientset) configMap := configManager.Get(namespace, configMapName) } return &ArgoCDServer{ diff --git a/util/configmanager.go b/util/configmanager.go index 86015489cd712..c0c47ddb8f0ef 100644 --- a/util/configmanager.go +++ b/util/configmanager.go @@ -5,7 +5,6 @@ import ( apiv1 "k8s.io/api/core/v1" "k8s.io/client-go/kubernetes" - "k8s.io/client-go/rest" ) // ConfigManager holds config info for a new manager with which to access Kubernetes ConfigMaps. @@ -14,11 +13,8 @@ type ConfigManager struct { } // NewConfigManager generates a new ConfigManager pointer and returns it -func NewConfigManager(config *rest.Config) (mgr *ConfigManager, err error) { - kubeclientset, err := kubernetes.NewForConfig(config) - if err == nil { - mgr = &ConfigManager{kubeclientset} - } +func NewConfigManager(clientset kubernetes.Interface) (mgr *ConfigManager) { + mgr = &ConfigManager{clientset} return } diff --git a/util/configmanager_test.go b/util/configmanager_test.go index 89f95e258c5ab..96ee827afcd5d 100644 --- a/util/configmanager_test.go +++ b/util/configmanager_test.go @@ -7,18 +7,21 @@ import ( apiv1 "k8s.io/api/core/v1" "github.com/pborman/uuid" - "k8s.io/client-go/rest" + "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" ) // makeTestConfigMapClientConfig creates an empty client config to use for K8s API calls // TODO (@merenbach): make this more general for use in other tests -func makeTestConfigMapClientConfig() (config *rest.Config, err error) { +func makeTestConfigManagerClientset() (clientset kubernetes.Interface, err error) { loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() loadingRules.DefaultClientConfig = &clientcmd.DefaultClientConfig overrides := clientcmd.ConfigOverrides{} configRaw := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, &overrides) - config, err = configRaw.ClientConfig() + config, err := configRaw.ClientConfig() + if err == nil { + clientset, err = kubernetes.NewForConfig(config) + } return } @@ -40,14 +43,11 @@ func TestConfigManager(t *testing.T) { configMaps *apiv1.ConfigMapList ) - config, err := makeTestConfigMapClientConfig() + clientset, err := makeTestConfigManagerClientset() if err != nil { t.Errorf("Could not create test client config: %v", err) } - mgr, err := NewConfigManager(config) - if err != nil { - t.Errorf("Could not create config map manager: %v", err) - } + mgr := NewConfigManager(clientset) configMap, err = mgr.CreateConfigMap(namespace, configMapName, configMapData1) if err != nil || !reflect.DeepEqual(configMap.Data, configMapData1) { t.Errorf("Err = %v; Created data did not match: had %v, wanted %v", err, configMap.Data, configMapData1) From 409e6cef93dc7786e8288c4e5bc430f541f70a70 Mon Sep 17 00:00:00 2001 From: Andrew Merenbach Date: Wed, 21 Mar 2018 15:00:05 -0700 Subject: [PATCH 35/38] Update settings config --- server/server.go | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/server/server.go b/server/server.go index 0359164ff02e0..1c9a65388055a 100644 --- a/server/server.go +++ b/server/server.go @@ -37,10 +37,20 @@ var ( ) // ArgoCDServerConfig holds in-memory runtime configuration options. -type ArgoCDServerConfig struct { +type ArgoCDServerSettings struct { AdminPasswordSecretName string } +func makeSettingsFromConfigMap(configMap *apiv1.ConfigMap) (settings ArgoCDServerSettings) { + if configMap != nil { + adminPasswordSecretName, ok := configMap.Data["adminPasswordSecretName"] + if ok { + settings.AdminPasswordSecretName = adminPasswordSecretName + } + } + return +} + // ArgoCDServer is the API server for ArgoCD type ArgoCDServer struct { ns string @@ -48,17 +58,20 @@ type ArgoCDServer struct { kubeclientset kubernetes.Interface appclientset appclientset.Interface repoclientset reposerver.Clientset - configuration ArgoCDServerConfig + settings ArgoCDServerSettings log *log.Entry } // NewServer returns a new instance of the ArgoCD API server func NewServer( kubeclientset kubernetes.Interface, appclientset appclientset.Interface, repoclientset reposerver.Clientset, namespace, staticAssetsDir, configMapName string) *ArgoCDServer { - var configMap apiv1.ConfigMap + var configMap *apiv1.ConfigMap if configMapName != "" { configManager := util.NewConfigManager(kubeclientset) - configMap := configManager.Get(namespace, configMapName) + configMap, err := configManager.ReadConfigMap(namespace, configMapName) + if err != nil { + log.Warnf("Could not read config map with name \"%s\"; proceeding with default settings. Error: %v", configMap, err) + } } return &ArgoCDServer{ ns: namespace, @@ -67,7 +80,7 @@ func NewServer( repoclientset: repoclientset, log: log.NewEntry(log.New()), staticAssetsDir: staticAssetsDir, - configMap: configMap, + settings: makeSettingsFromConfigMap(configMap), } } From f4e2fa8be08ea1583b850c11869883f390eb933d Mon Sep 17 00:00:00 2001 From: Andrew Merenbach Date: Wed, 21 Mar 2018 15:43:36 -0700 Subject: [PATCH 36/38] Add Secret management to ConfigManager --- util/configmanager.go | 46 +++++++++++++++++++++ util/configmanager_test.go | 82 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 128 insertions(+) diff --git a/util/configmanager.go b/util/configmanager.go index c0c47ddb8f0ef..3074ade1094c0 100644 --- a/util/configmanager.go +++ b/util/configmanager.go @@ -1,6 +1,7 @@ package util import ( + "github.com/argoproj/argo-cd/common" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" apiv1 "k8s.io/api/core/v1" @@ -57,3 +58,48 @@ func (mgr *ConfigManager) DeleteConfigMap(namespace, name string) (err error) { err = mgr.clientset.CoreV1().ConfigMaps(namespace).Delete(name, &metav1.DeleteOptions{}) return } + +// ListSecrets returns a list of existing config maps. +func (mgr *ConfigManager) ListSecrets(namespace string) (secrets *apiv1.SecretList, err error) { + secrets, err = mgr.clientset.CoreV1().Secrets(namespace).List(metav1.ListOptions{}) + return +} + +// CreateSecret stores a new secret in Kubernetes. Set secretType to "" for no label. +func (mgr *ConfigManager) CreateSecret(namespace, name string, value map[string]string, secretType string) (secret *apiv1.Secret, err error) { + labels := make(map[string]string) + if secretType != "" { + labels[common.LabelKeySecretType] = secretType + } + newSecret := &apiv1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + Labels: labels, + }, + } + newSecret.StringData = value + secret, err = mgr.clientset.CoreV1().Secrets(namespace).Create(newSecret) + return +} + +// Read retrieves a secret from Kubernetes. +func (mgr *ConfigManager) ReadSecret(namespace, name string) (secret *apiv1.Secret, err error) { + secret, err = mgr.clientset.CoreV1().Secrets(namespace).Get(name, metav1.GetOptions{}) + return +} + +// UpdateSecret merge-updates an existing secret in Kubernetes. This merge-update is in contrast to the overwrite-update done for config maps. +func (mgr *ConfigManager) UpdateSecret(namespace, name string, value map[string]string) (secret *apiv1.Secret, err error) { + existingSecret, err := mgr.ReadSecret(namespace, name) + if err == nil { + existingSecret.StringData = value + secret, err = mgr.clientset.CoreV1().Secrets(namespace).Update(existingSecret) + } + return +} + +// DeleteSecret removes a secret from Kubernetes. +func (mgr *ConfigManager) DeleteSecret(namespace, name string) (err error) { + err = mgr.clientset.CoreV1().Secrets(namespace).Delete(name, &metav1.DeleteOptions{}) + return +} diff --git a/util/configmanager_test.go b/util/configmanager_test.go index 96ee827afcd5d..2d9de55731cb5 100644 --- a/util/configmanager_test.go +++ b/util/configmanager_test.go @@ -48,6 +48,7 @@ func TestConfigManager(t *testing.T) { t.Errorf("Could not create test client config: %v", err) } mgr := NewConfigManager(clientset) + configMap, err = mgr.CreateConfigMap(namespace, configMapName, configMapData1) if err != nil || !reflect.DeepEqual(configMap.Data, configMapData1) { t.Errorf("Err = %v; Created data did not match: had %v, wanted %v", err, configMap.Data, configMapData1) @@ -79,3 +80,84 @@ func TestConfigManager(t *testing.T) { _ = mgr.DeleteConfigMap(namespace, configMapName) } } + +// testConvertSecretStringData returns a mapping of a secret data as a map[string]string instead of map[string][]byte. +func testConvertSecretStringData(secret *apiv1.Secret) map[string]string { + out := make(map[string]string) + for k, v := range secret.Data { + out[k] = string(v) + } + return out +} + +func TestSecretManager(t *testing.T) { + const namespace = "default" + var ( + secret *apiv1.Secret + secrets *apiv1.SecretList + err error + ) + + secretName := uuid.New() + label := "test" + secretData1 := map[string]string{ + "some": "data", + "hello": "world", + } + secretData2 := map[string]string{ + "other": "data", + "some": "thing else", + "world": "hello", + } + secretDataAfterUpdate := map[string]string{ + "other": "data", + "some": "thing else", + "world": "hello", + "hello": "world", + } + + clientset, err := makeTestConfigManagerClientset() + if err != nil { + t.Errorf("Could not create test client config: %v", err) + } + mgr := NewConfigManager(clientset) + + secret, err = mgr.CreateSecret(namespace, secretName, secretData1, label) + if secretDataRetrieved := testConvertSecretStringData(secret); !reflect.DeepEqual(secretDataRetrieved, secretData1) { + t.Errorf("Err = %v; Created data did not match: had %v, wanted %v", err, secretDataRetrieved, secretData1) + } + + secret, err = mgr.ReadSecret(namespace, secretName) + if err != nil { + t.Errorf("Could not read secret: %v", err) + } + + if secretDataRetrieved := testConvertSecretStringData(secret); !reflect.DeepEqual(secretDataRetrieved, secretData1) { + t.Errorf("Read data did not match: had %v, wanted %v", secretDataRetrieved, secretData1) + } + + secret, err = mgr.UpdateSecret(namespace, secretName, secretData2) + if err != nil { + t.Errorf("Could not update secret: %v", err) + } + if secretDataRetrieved := testConvertSecretStringData(secret); !reflect.DeepEqual(secretDataRetrieved, secretDataAfterUpdate) { + t.Errorf("Updated data did not match: had %v, wanted %v", secretDataRetrieved, secretData1) + } + + secrets, err = mgr.ListSecrets(namespace) + if err != nil || !reflect.DeepEqual(secrets.Items[0], *secret) { + t.Errorf("Err = %v; Updated data in List did not match: had %v, wanted %v", err, secrets.Items[0], secret) + } + + err = mgr.DeleteSecret(namespace, secretName) + if err != nil { + t.Errorf("Could not delete secret: %v", err) + } + + secret, err = mgr.ReadSecret(namespace, secretName) + if err == nil { + secretDataRetrieved := testConvertSecretStringData(secret) + t.Errorf("Read data did not match: had %v, wanted nil for name %s and label %s; trying again, but it may need to be deleted manually", secretDataRetrieved, secretName, label) + _ = mgr.DeleteSecret(namespace, secretName) + } +} From eb46fab18fb1bd20cbfa943cd48b6825cfa9596c Mon Sep 17 00:00:00 2001 From: Andrew Merenbach Date: Wed, 21 Mar 2018 17:25:21 -0700 Subject: [PATCH 37/38] Address scoping concerns --- server/server.go | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/server/server.go b/server/server.go index 1c9a65388055a..7ef1eb1ddb499 100644 --- a/server/server.go +++ b/server/server.go @@ -36,17 +36,16 @@ var ( endpoint = fmt.Sprintf("localhost:%d", port) ) -// ArgoCDServerConfig holds in-memory runtime configuration options. +// ArgoCDServerSettings holds in-memory runtime configuration options. type ArgoCDServerSettings struct { AdminPasswordSecretName string } func makeSettingsFromConfigMap(configMap *apiv1.ConfigMap) (settings ArgoCDServerSettings) { - if configMap != nil { - adminPasswordSecretName, ok := configMap.Data["adminPasswordSecretName"] - if ok { - settings.AdminPasswordSecretName = adminPasswordSecretName - } + const adminPasswordKeyName = "adminPasswordSecretName" + adminPasswordSecretName, ok := configMap.Data[adminPasswordKeyName] + if ok { + settings.AdminPasswordSecretName = adminPasswordSecretName } return } @@ -65,12 +64,14 @@ type ArgoCDServer struct { // NewServer returns a new instance of the ArgoCD API server func NewServer( kubeclientset kubernetes.Interface, appclientset appclientset.Interface, repoclientset reposerver.Clientset, namespace, staticAssetsDir, configMapName string) *ArgoCDServer { - var configMap *apiv1.ConfigMap + var settings ArgoCDServerSettings if configMapName != "" { configManager := util.NewConfigManager(kubeclientset) - configMap, err := configManager.ReadConfigMap(namespace, configMapName) + configMap, err := configManager.ReadConfigMap("default", configMapName) if err != nil { - log.Warnf("Could not read config map with name \"%s\"; proceeding with default settings. Error: %v", configMap, err) + log.Warnf("Could not read config map with name \"%s\"; proceeding with default settings. Error: %v", configMapName, err) + } else { + settings = makeSettingsFromConfigMap(configMap) } } return &ArgoCDServer{ @@ -80,7 +81,7 @@ func NewServer( repoclientset: repoclientset, log: log.NewEntry(log.New()), staticAssetsDir: staticAssetsDir, - settings: makeSettingsFromConfigMap(configMap), + settings: settings, } } From c739946ff78d6a79fe93723f41c220e5390ea529 Mon Sep 17 00:00:00 2001 From: Andrew Merenbach Date: Thu, 22 Mar 2018 14:22:55 -0700 Subject: [PATCH 38/38] Refactor config manager, thanks @alexmt --- server/server.go | 30 +------ util/configmanager.go | 116 ++++++++------------------ util/configmanager_test.go | 163 ------------------------------------- 3 files changed, 39 insertions(+), 270 deletions(-) delete mode 100644 util/configmanager_test.go diff --git a/server/server.go b/server/server.go index 7ef1eb1ddb499..d698621e907f5 100644 --- a/server/server.go +++ b/server/server.go @@ -24,7 +24,6 @@ import ( log "github.com/sirupsen/logrus" "github.com/soheilhy/cmux" "google.golang.org/grpc" - apiv1 "k8s.io/api/core/v1" "k8s.io/client-go/kubernetes" ) @@ -36,20 +35,6 @@ var ( endpoint = fmt.Sprintf("localhost:%d", port) ) -// ArgoCDServerSettings holds in-memory runtime configuration options. -type ArgoCDServerSettings struct { - AdminPasswordSecretName string -} - -func makeSettingsFromConfigMap(configMap *apiv1.ConfigMap) (settings ArgoCDServerSettings) { - const adminPasswordKeyName = "adminPasswordSecretName" - adminPasswordSecretName, ok := configMap.Data[adminPasswordKeyName] - if ok { - settings.AdminPasswordSecretName = adminPasswordSecretName - } - return -} - // ArgoCDServer is the API server for ArgoCD type ArgoCDServer struct { ns string @@ -57,23 +42,14 @@ type ArgoCDServer struct { kubeclientset kubernetes.Interface appclientset appclientset.Interface repoclientset reposerver.Clientset - settings ArgoCDServerSettings + settings util.ArgoCDSettings log *log.Entry } // NewServer returns a new instance of the ArgoCD API server func NewServer( kubeclientset kubernetes.Interface, appclientset appclientset.Interface, repoclientset reposerver.Clientset, namespace, staticAssetsDir, configMapName string) *ArgoCDServer { - var settings ArgoCDServerSettings - if configMapName != "" { - configManager := util.NewConfigManager(kubeclientset) - configMap, err := configManager.ReadConfigMap("default", configMapName) - if err != nil { - log.Warnf("Could not read config map with name \"%s\"; proceeding with default settings. Error: %v", configMapName, err) - } else { - settings = makeSettingsFromConfigMap(configMap) - } - } + configManager := util.NewConfigManager(kubeclientset, namespace, configMapName) return &ArgoCDServer{ ns: namespace, kubeclientset: kubeclientset, @@ -81,7 +57,7 @@ func NewServer( repoclientset: repoclientset, log: log.NewEntry(log.New()), staticAssetsDir: staticAssetsDir, - settings: settings, + settings: configManager.GetSettings(), } } diff --git a/util/configmanager.go b/util/configmanager.go index 3074ade1094c0..c8a7ecea601c2 100644 --- a/util/configmanager.go +++ b/util/configmanager.go @@ -1,105 +1,61 @@ package util import ( - "github.com/argoproj/argo-cd/common" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" apiv1 "k8s.io/api/core/v1" "k8s.io/client-go/kubernetes" ) -// ConfigManager holds config info for a new manager with which to access Kubernetes ConfigMaps. -type ConfigManager struct { - clientset kubernetes.Interface -} - -// NewConfigManager generates a new ConfigManager pointer and returns it -func NewConfigManager(clientset kubernetes.Interface) (mgr *ConfigManager) { - mgr = &ConfigManager{clientset} - return -} - -// ListConfigMaps returns a list of existing config maps. -func (mgr *ConfigManager) ListConfigMaps(namespace string) (configMaps *apiv1.ConfigMapList, err error) { - configMaps, err = mgr.clientset.CoreV1().ConfigMaps(namespace).List(metav1.ListOptions{}) - return -} - -// CreateConfigMap stores a new config map in Kubernetes. -func (mgr *ConfigManager) CreateConfigMap(namespace, name string, value map[string]string) (configMap *apiv1.ConfigMap, err error) { - newConfigMap := &apiv1.ConfigMap{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - }, - Data: value, - } - configMap, err = mgr.clientset.CoreV1().ConfigMaps(namespace).Create(newConfigMap) - return -} - -// ReadConfigMap retrieves a config map from Kubernetes. -func (mgr *ConfigManager) ReadConfigMap(namespace, name string) (configMap *apiv1.ConfigMap, err error) { - configMap, err = mgr.clientset.CoreV1().ConfigMaps(namespace).Get(name, metav1.GetOptions{}) - return +// ArgoCDSettings holds in-memory runtime configuration options. +type ArgoCDSettings struct { + AdminPassword string } -// UpdateConfigMap overwrite-updates an existing config map in Kubernetes. This overwrite is in contrast to the merge-update done for secrets. -func (mgr *ConfigManager) UpdateConfigMap(namespace, name string, value map[string]string) (configMap *apiv1.ConfigMap, err error) { - existingConfigMap, err := mgr.ReadConfigMap(namespace, name) +// ConfigManager holds config info for a new manager with which to access Kubernetes ConfigMaps. +type ConfigManager struct { + clientset kubernetes.Interface + namespace string + configMapName string +} + +// GetSettings retrieves settings from the ConfigManager. +func (mgr *ConfigManager) GetSettings() (settings ArgoCDSettings) { + const ( + adminPasswordKeyName = "adminPasswordSecretName" + adminPasswordValueName = "admin.password" + ) + configMap, err := mgr.readConfigMap(mgr.configMapName) if err == nil { - existingConfigMap.Data = value - configMap, err = mgr.clientset.CoreV1().ConfigMaps(namespace).Update(existingConfigMap) + adminPasswordSecretName, ok := configMap.Data[adminPasswordKeyName] + if ok { + adminPassword, err := mgr.readSecret(adminPasswordSecretName) + if err == nil { + settings.AdminPassword = string(adminPassword.Data[adminPasswordValueName]) + } + } } return } -// DeleteConfigMap removes a config map from Kubernetes. -func (mgr *ConfigManager) DeleteConfigMap(namespace, name string) (err error) { - err = mgr.clientset.CoreV1().ConfigMaps(namespace).Delete(name, &metav1.DeleteOptions{}) - return -} - -// ListSecrets returns a list of existing config maps. -func (mgr *ConfigManager) ListSecrets(namespace string) (secrets *apiv1.SecretList, err error) { - secrets, err = mgr.clientset.CoreV1().Secrets(namespace).List(metav1.ListOptions{}) - return -} - -// CreateSecret stores a new secret in Kubernetes. Set secretType to "" for no label. -func (mgr *ConfigManager) CreateSecret(namespace, name string, value map[string]string, secretType string) (secret *apiv1.Secret, err error) { - labels := make(map[string]string) - if secretType != "" { - labels[common.LabelKeySecretType] = secretType - } - newSecret := &apiv1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: name, - Labels: labels, - }, +// NewConfigManager generates a new ConfigManager pointer and returns it +func NewConfigManager(clientset kubernetes.Interface, namespace, configMapName string) (mgr *ConfigManager) { + mgr = &ConfigManager{ + clientset: clientset, + namespace: namespace, + configMapName: configMapName, } - newSecret.StringData = value - secret, err = mgr.clientset.CoreV1().Secrets(namespace).Create(newSecret) - return -} - -// Read retrieves a secret from Kubernetes. -func (mgr *ConfigManager) ReadSecret(namespace, name string) (secret *apiv1.Secret, err error) { - secret, err = mgr.clientset.CoreV1().Secrets(namespace).Get(name, metav1.GetOptions{}) return } -// UpdateSecret merge-updates an existing secret in Kubernetes. This merge-update is in contrast to the overwrite-update done for config maps. -func (mgr *ConfigManager) UpdateSecret(namespace, name string, value map[string]string) (secret *apiv1.Secret, err error) { - existingSecret, err := mgr.ReadSecret(namespace, name) - if err == nil { - existingSecret.StringData = value - secret, err = mgr.clientset.CoreV1().Secrets(namespace).Update(existingSecret) - } +// ReadConfigMap retrieves a config map from Kubernetes. +func (mgr *ConfigManager) readConfigMap(name string) (configMap *apiv1.ConfigMap, err error) { + configMap, err = mgr.clientset.CoreV1().ConfigMaps(mgr.namespace).Get(name, metav1.GetOptions{}) return } -// DeleteSecret removes a secret from Kubernetes. -func (mgr *ConfigManager) DeleteSecret(namespace, name string) (err error) { - err = mgr.clientset.CoreV1().Secrets(namespace).Delete(name, &metav1.DeleteOptions{}) +// ReadSecret retrieves a secret from Kubernetes. +func (mgr *ConfigManager) readSecret(name string) (secret *apiv1.Secret, err error) { + secret, err = mgr.clientset.CoreV1().Secrets(mgr.namespace).Get(name, metav1.GetOptions{}) return } diff --git a/util/configmanager_test.go b/util/configmanager_test.go deleted file mode 100644 index 2d9de55731cb5..0000000000000 --- a/util/configmanager_test.go +++ /dev/null @@ -1,163 +0,0 @@ -package util - -import ( - "reflect" - "testing" - - apiv1 "k8s.io/api/core/v1" - - "github.com/pborman/uuid" - "k8s.io/client-go/kubernetes" - "k8s.io/client-go/tools/clientcmd" -) - -// makeTestConfigMapClientConfig creates an empty client config to use for K8s API calls -// TODO (@merenbach): make this more general for use in other tests -func makeTestConfigManagerClientset() (clientset kubernetes.Interface, err error) { - loadingRules := clientcmd.NewDefaultClientConfigLoadingRules() - loadingRules.DefaultClientConfig = &clientcmd.DefaultClientConfig - overrides := clientcmd.ConfigOverrides{} - configRaw := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, &overrides) - config, err := configRaw.ClientConfig() - if err == nil { - clientset, err = kubernetes.NewForConfig(config) - } - return -} - -func TestConfigManager(t *testing.T) { - const namespace = "default" - configMapName := uuid.New() - configMapData1 := map[string]string{ - "some": "data", - "hello": "world", - } - configMapData2 := map[string]string{ - "other": "data", - "some": "thing else", - "world": "hello", - } - - var ( - configMap *apiv1.ConfigMap - configMaps *apiv1.ConfigMapList - ) - - clientset, err := makeTestConfigManagerClientset() - if err != nil { - t.Errorf("Could not create test client config: %v", err) - } - mgr := NewConfigManager(clientset) - - configMap, err = mgr.CreateConfigMap(namespace, configMapName, configMapData1) - if err != nil || !reflect.DeepEqual(configMap.Data, configMapData1) { - t.Errorf("Err = %v; Created data did not match: had %v, wanted %v", err, configMap.Data, configMapData1) - } - - configMap, err = mgr.ReadConfigMap(namespace, configMapName) - if err != nil || !reflect.DeepEqual(configMap.Data, configMapData1) { - t.Errorf("Err = %v; Read data did not match: had %v, wanted %v", err, configMap.Data, configMapData1) - } - - configMap, err = mgr.UpdateConfigMap(namespace, configMapName, configMapData2) - if err != nil || !reflect.DeepEqual(configMap.Data, configMapData2) { - t.Errorf("Err = %v; Updated data did not match: had %v, wanted %v", err, configMap.Data, configMapData1) - } - - configMaps, err = mgr.ListConfigMaps(namespace) - if err != nil || !reflect.DeepEqual(configMaps.Items[0], *configMap) { - t.Errorf("Err = %v; Updated data in List did not match: had %v, wanted %v", err, configMaps.Items[0], configMap) - } - - err = mgr.DeleteConfigMap(namespace, configMapName) - if err != nil { - t.Errorf("Err = %v", err) - } - - configMap, err = mgr.ReadConfigMap(namespace, configMapName) - if err == nil { - t.Errorf("Read data did not match: had %v, wanted nil for name %s; trying again, but it may need to be deleted manually", configMap.Data, configMapName) - _ = mgr.DeleteConfigMap(namespace, configMapName) - } -} - -// testConvertSecretStringData returns a mapping of a secret data as a map[string]string instead of map[string][]byte. -func testConvertSecretStringData(secret *apiv1.Secret) map[string]string { - out := make(map[string]string) - for k, v := range secret.Data { - out[k] = string(v) - } - return out -} - -func TestSecretManager(t *testing.T) { - const namespace = "default" - var ( - secret *apiv1.Secret - secrets *apiv1.SecretList - err error - ) - - secretName := uuid.New() - label := "test" - secretData1 := map[string]string{ - "some": "data", - "hello": "world", - } - secretData2 := map[string]string{ - "other": "data", - "some": "thing else", - "world": "hello", - } - secretDataAfterUpdate := map[string]string{ - "other": "data", - "some": "thing else", - "world": "hello", - "hello": "world", - } - - clientset, err := makeTestConfigManagerClientset() - if err != nil { - t.Errorf("Could not create test client config: %v", err) - } - mgr := NewConfigManager(clientset) - - secret, err = mgr.CreateSecret(namespace, secretName, secretData1, label) - if secretDataRetrieved := testConvertSecretStringData(secret); !reflect.DeepEqual(secretDataRetrieved, secretData1) { - t.Errorf("Err = %v; Created data did not match: had %v, wanted %v", err, secretDataRetrieved, secretData1) - } - - secret, err = mgr.ReadSecret(namespace, secretName) - if err != nil { - t.Errorf("Could not read secret: %v", err) - } - - if secretDataRetrieved := testConvertSecretStringData(secret); !reflect.DeepEqual(secretDataRetrieved, secretData1) { - t.Errorf("Read data did not match: had %v, wanted %v", secretDataRetrieved, secretData1) - } - - secret, err = mgr.UpdateSecret(namespace, secretName, secretData2) - if err != nil { - t.Errorf("Could not update secret: %v", err) - } - if secretDataRetrieved := testConvertSecretStringData(secret); !reflect.DeepEqual(secretDataRetrieved, secretDataAfterUpdate) { - t.Errorf("Updated data did not match: had %v, wanted %v", secretDataRetrieved, secretData1) - } - - secrets, err = mgr.ListSecrets(namespace) - if err != nil || !reflect.DeepEqual(secrets.Items[0], *secret) { - t.Errorf("Err = %v; Updated data in List did not match: had %v, wanted %v", err, secrets.Items[0], secret) - } - - err = mgr.DeleteSecret(namespace, secretName) - if err != nil { - t.Errorf("Could not delete secret: %v", err) - } - - secret, err = mgr.ReadSecret(namespace, secretName) - if err == nil { - secretDataRetrieved := testConvertSecretStringData(secret) - t.Errorf("Read data did not match: had %v, wanted nil for name %s and label %s; trying again, but it may need to be deleted manually", secretDataRetrieved, secretName, label) - _ = mgr.DeleteSecret(namespace, secretName) - } -}