Skip to content

Commit

Permalink
Cherry-pick commit to make kube worker aware of Secret kube resource …
Browse files Browse the repository at this point in the history
…type

Signed-off-by: Max McAdam <max@fredcom.com>
  • Loading branch information
scwhaley authored and MaxMcAdam committed Jun 26, 2024
1 parent bfa3acb commit 1eebd85
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 7 deletions.
91 changes: 89 additions & 2 deletions kube_operator/api_objects.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import (
"context"
"encoding/base64"
"fmt"
"strings"
"time"

"github.com/golang/glog"
"github.com/open-horizon/anax/config"
"github.com/open-horizon/anax/cutil"
Expand All @@ -20,8 +23,6 @@ import (
"k8s.io/apimachinery/pkg/labels"
"k8s.io/apimachinery/pkg/runtime/schema"
dynamic "k8s.io/client-go/dynamic"
"strings"
"time"
)

type APIObjectInterface interface {
Expand Down Expand Up @@ -114,6 +115,25 @@ func sortAPIObjects(allObjects []APIObjects, customResources map[string][]*unstr
} else {
return objMap, namespace, fmt.Errorf(kwlog(fmt.Sprintf("Error: rolebinding object has unrecognized type %T: %v", obj.Object, obj.Object)))
}
case K8S_SECRET_TYPE:
if typedSecret, ok := obj.Object.(*corev1.Secret); ok {
if typedSecret.ObjectMeta.Namespace != "" {
if namespace == "" {
namespace = typedSecret.ObjectMeta.Namespace
} else if namespace != typedSecret.ObjectMeta.Namespace {
return objMap, namespace, fmt.Errorf(kwlog(fmt.Sprintf("Error: multiple namespaces specified in operator: %s and %s", namespace, typedSecret.ObjectMeta.Namespace)))
}
}
newSecret := SecretCoreV1{SecretObject: typedSecret}
if newSecret.Name() != "" {
glog.V(4).Infof(kwlog(fmt.Sprintf("Found kubernetes secret object %s.", newSecret.Name())))
objMap[K8S_SECRET_TYPE] = append(objMap[K8S_SECRET_TYPE], newSecret)
} else {
return objMap, namespace, fmt.Errorf(kwlog(fmt.Sprintf("Error: secret object must have a name in its metadata section.")))
}
} else {
return objMap, namespace, fmt.Errorf(kwlog(fmt.Sprintf("Error: secret object has unrecognized type %T: %v", obj.Object, obj.Object)))
}
case K8S_DEPLOYMENT_TYPE:
if typedDeployment, ok := obj.Object.(*appsv1.Deployment); ok {
if typedDeployment.ObjectMeta.Namespace != "" {
Expand Down Expand Up @@ -623,6 +643,73 @@ func (sa ServiceAccountCoreV1) Namespace() string {
return sa.ServiceAccountObject.ObjectMeta.Namespace
}

// ----------------Secret----------------
type SecretCoreV1 struct {
SecretObject *corev1.Secret
}

func (s SecretCoreV1) Install(c KubeClient, namespace string) error {
glog.V(3).Infof(kwlog(fmt.Sprintf("attempting to create secret %v", s.Name()))) // Don't display the whole object to avoid logging secret data
if namespace != s.Namespace() {
glog.Warningf(kwlog(fmt.Sprintf("Embedded namespace '%v' is ignored. Service will be deployed to '%v'.", s.Namespace(), namespace)))
s.SecretObject.ObjectMeta.Namespace = namespace
}

_, err := c.Client.CoreV1().Secrets(namespace).Create(context.Background(), s.SecretObject, metav1.CreateOptions{})
if err != nil && errors.IsAlreadyExists(err) {
glog.Warningf(kwlog(fmt.Sprintf("Secret %s already exists, deleting and re-creating", s.Name())))
s.Uninstall(c, s.Name())
_, err = c.Client.CoreV1().Secrets(namespace).Create(context.Background(), s.SecretObject, metav1.CreateOptions{})
}
if err != nil {
return fmt.Errorf(kwlog(fmt.Sprintf("Error creating the secret: %v", err)))
}
return nil
}

func (s SecretCoreV1) Uninstall(c KubeClient, secretName string) {
glog.V(3).Infof(kwlog(fmt.Sprintf("deleting secret %v", secretName)))
err := c.Client.CoreV1().Secrets(s.Namespace()).Delete(context.Background(), secretName, metav1.DeleteOptions{})
if err != nil {
glog.Errorf(kwlog(fmt.Sprintf("unable to delete secret %s. Error: %v", secretName, err)))
}
}

func (s SecretCoreV1) Status(c KubeClient, namespace string) (interface{}, error) {
secretFromKube, err := c.Client.CoreV1().Secrets(namespace).Get(context.Background(), s.Name(), metav1.GetOptions{})
if err != nil {
return nil, fmt.Errorf(kwlog(fmt.Sprintf("Error getting secret status: %v", err)))
}
return secretFromKube, nil
}

func (s SecretCoreV1) Update(c KubeClient, namespace string) error {
if secretFromKube, err := c.Client.CoreV1().Secrets(namespace).Get(context.Background(), s.SecretObject.Name, metav1.GetOptions{}); err != nil {
return fmt.Errorf(kwlog(fmt.Sprintf("Error getting secret from kube: %v", err)))
} else if secretFromKube == nil {
// invalid, return err
return fmt.Errorf(kwlog(fmt.Sprintf("Error updating secret %v in namespace %v: secret doesn't exist", s.SecretObject.Name, namespace)))
} else {
//Update the secret retrieved from kube with the new data
secretFromKube.Data = s.SecretObject.Data
updatedSecret, err := c.Client.CoreV1().Secrets(namespace).Update(context.Background(), secretFromKube, metav1.UpdateOptions{})
if err != nil {
return fmt.Errorf(kwlog(fmt.Sprintf("Error updating secret %v in namespace %v: %v", s.SecretObject.Name, namespace, err)))
}
glog.V(3).Infof(kwlog(fmt.Sprintf("Secret %v in namespace %v updated successfully", updatedSecret.Name, namespace)))
}

return nil
}

func (s SecretCoreV1) Name() string {
return s.SecretObject.ObjectMeta.Name
}

func (s SecretCoreV1) Namespace() string {
return s.SecretObject.ObjectMeta.Namespace
}

//----------------Deployment----------------
// The deployment object includes the environment variable config map and vault secret as k8s secret

Expand Down
15 changes: 10 additions & 5 deletions kube_operator/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@ import (
"context"
"encoding/base64"
"fmt"
"io"
"io/ioutil"
"reflect"
"strings"

"github.com/golang/glog"
"github.com/open-horizon/anax/config"
"github.com/open-horizon/anax/cutil"
Expand All @@ -15,8 +20,6 @@ import (
olmv1client "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1"
olmv1alpha1client "github.com/operator-framework/operator-lifecycle-manager/pkg/api/client/clientset/versioned/typed/operators/v1alpha1"
yaml "gopkg.in/yaml.v2"
"io"
"io/ioutil"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
rbacv1 "k8s.io/api/rbac/v1"
Expand All @@ -31,8 +34,6 @@ import (
dynamic "k8s.io/client-go/dynamic"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes/scheme"
"reflect"
"strings"
)

const (
Expand All @@ -54,12 +55,16 @@ const (
K8S_SERVICEACCOUNT_TYPE = "ServiceAccount"
K8S_CRD_TYPE = "CustomResourceDefinition"
K8S_NAMESPACE_TYPE = "Namespace"
K8S_SECRET_TYPE = "Secret"
K8S_UNSTRUCTURED_TYPE = "Unstructured"
K8S_OLM_OPERATOR_GROUP_TYPE = "OperatorGroup"
)

// Order is important here since it will be used to determine install order.
// For example, secrets should be before deployments,
// because it may be an image pull secret used by the deployment
func getBaseK8sKinds() []string {
return []string{K8S_NAMESPACE_TYPE, K8S_CLUSTER_ROLE_TYPE, K8S_CLUSTER_ROLEBINDING_TYPE, K8S_ROLE_TYPE, K8S_ROLEBINDING_TYPE, K8S_DEPLOYMENT_TYPE, K8S_SERVICEACCOUNT_TYPE, K8S_CRD_TYPE}
return []string{K8S_NAMESPACE_TYPE, K8S_CLUSTER_ROLE_TYPE, K8S_CLUSTER_ROLEBINDING_TYPE, K8S_ROLE_TYPE, K8S_ROLEBINDING_TYPE, K8S_SERVICEACCOUNT_TYPE, K8S_SECRET_TYPE, K8S_CRD_TYPE, K8S_DEPLOYMENT_TYPE}
}

func getDangerKinds() []string {
Expand Down

0 comments on commit 1eebd85

Please sign in to comment.