Deploy operator-lifecycle-manager (OLM), node-maintenance-operator (NMO) and constellation-node-operator

Signed-off-by: Malte Poll <mp@edgeless.systems>
This commit is contained in:
Malte Poll 2022-08-04 16:15:52 +02:00 committed by Malte Poll
parent 18a89d2881
commit 2c7129987a
23 changed files with 8756 additions and 32 deletions

View file

@ -10,6 +10,8 @@ import (
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
const accessManagerNamespace = "kube-system"
// accessManagerDeployment holds the configuration for the SSH user creation pods. User/Key definitions are stored in the ConfigMap, and the manager is deployed on each node by the DaemonSet.
type accessManagerDeployment struct {
ConfigMap k8s.ConfigMap
@ -35,7 +37,7 @@ func NewAccessManagerDeployment(sshUsers map[string]string) *accessManagerDeploy
"app.kubernetes.io/managed-by": "Constellation",
},
Name: "constellation-access-manager",
Namespace: "kube-system",
Namespace: accessManagerNamespace,
},
AutomountServiceAccountToken: proto.Bool(true),
},
@ -46,7 +48,7 @@ func NewAccessManagerDeployment(sshUsers map[string]string) *accessManagerDeploy
},
ObjectMeta: v1.ObjectMeta{
Name: "ssh-users",
Namespace: "kube-system",
Namespace: accessManagerNamespace,
},
Data: sshUsers,
},
@ -57,7 +59,7 @@ func NewAccessManagerDeployment(sshUsers map[string]string) *accessManagerDeploy
},
ObjectMeta: v1.ObjectMeta{
Name: "constellation-access-manager",
Namespace: "kube-system",
Namespace: accessManagerNamespace,
Labels: map[string]string{
"app.kubernetes.io/instance": "constellation",
"app.kubernetes.io/name": "constellation-access-manager",
@ -148,7 +150,7 @@ func NewAccessManagerDeployment(sshUsers map[string]string) *accessManagerDeploy
"app.kubernetes.io/managed-by": "Constellation",
},
Name: "constellation-access-manager",
Namespace: "kube-system",
Namespace: accessManagerNamespace,
},
Rules: []rbac.PolicyRule{
{
@ -177,7 +179,7 @@ func NewAccessManagerDeployment(sshUsers map[string]string) *accessManagerDeploy
"app.kubernetes.io/managed-by": "Constellation",
},
Name: "constellation-access-manager",
Namespace: "kube-system",
Namespace: accessManagerNamespace,
},
RoleRef: rbac.RoleRef{
APIGroup: "rbac.authorization.k8s.io",
@ -188,11 +190,11 @@ func NewAccessManagerDeployment(sshUsers map[string]string) *accessManagerDeploy
{
Kind: "ServiceAccount",
Name: "constellation-access-manager",
Namespace: "kube-system",
Namespace: accessManagerNamespace,
},
},
},
ImagePullSecret: NewImagePullSecret(),
ImagePullSecret: NewImagePullSecret(accessManagerNamespace),
}
}

View file

@ -10,7 +10,7 @@ import (
)
// NewImagePullSecret creates a new k8s.Secret from the config for authenticating when pulling images.
func NewImagePullSecret() k8s.Secret {
func NewImagePullSecret(namespace string) k8s.Secret {
base64EncodedSecret := base64.StdEncoding.EncodeToString(
[]byte(fmt.Sprintf("%s:%s", secrets.PullSecretUser, secrets.PullSecretToken)),
)
@ -24,7 +24,7 @@ func NewImagePullSecret() k8s.Secret {
},
ObjectMeta: meta.ObjectMeta{
Name: secrets.PullSecretName,
Namespace: "kube-system",
Namespace: namespace,
},
StringData: map[string]string{".dockerconfigjson": pullSecretDockerCfgJSON},
Type: "kubernetes.io/dockerconfigjson",

View file

@ -7,7 +7,8 @@ import (
)
func TestImagePullSecret(t *testing.T) {
imgPullSec := NewImagePullSecret()
imgPullSec := NewImagePullSecret("namespace")
_, err := imgPullSec.Marshal()
assert.NoError(t, err)
assert.Equal(t, "namespace", imgPullSec.Namespace)
}

View file

@ -13,6 +13,8 @@ import (
"k8s.io/apimachinery/pkg/util/intstr"
)
const kmsNamespace = "kube-system"
type kmsDeployment struct {
ServiceAccount k8s.ServiceAccount
Service k8s.Service
@ -43,7 +45,7 @@ func NewKMSDeployment(csp string, config KMSConfig) *kmsDeployment {
},
ObjectMeta: meta.ObjectMeta{
Name: "kms",
Namespace: "kube-system",
Namespace: kmsNamespace,
},
},
Service: k8s.Service{
@ -53,7 +55,7 @@ func NewKMSDeployment(csp string, config KMSConfig) *kmsDeployment {
},
ObjectMeta: meta.ObjectMeta{
Name: "kms",
Namespace: "kube-system",
Namespace: kmsNamespace,
},
Spec: k8s.ServiceSpec{
Type: k8s.ServiceTypeClusterIP,
@ -106,7 +108,7 @@ func NewKMSDeployment(csp string, config KMSConfig) *kmsDeployment {
{
Kind: "ServiceAccount",
Name: "kms",
Namespace: "kube-system",
Namespace: kmsNamespace,
},
},
},
@ -120,7 +122,7 @@ func NewKMSDeployment(csp string, config KMSConfig) *kmsDeployment {
"k8s-app": "kms",
},
Name: "kms",
Namespace: "kube-system",
Namespace: kmsNamespace,
},
Spec: apps.DeploymentSpec{
Selector: &meta.LabelSelector{
@ -239,7 +241,7 @@ func NewKMSDeployment(csp string, config KMSConfig) *kmsDeployment {
},
ObjectMeta: meta.ObjectMeta{
Name: constants.ConstellationMasterSecretStoreName,
Namespace: "kube-system",
Namespace: kmsNamespace,
},
Data: map[string][]byte{
constants.ConstellationMasterSecretKey: config.MasterSecret,
@ -247,7 +249,7 @@ func NewKMSDeployment(csp string, config KMSConfig) *kmsDeployment {
},
Type: "Opaque",
},
ImagePullSecret: NewImagePullSecret(),
ImagePullSecret: NewImagePullSecret(kmsNamespace),
}
}

View file

@ -0,0 +1,78 @@
package resources
import (
"time"
"github.com/edgelesssys/constellation/internal/versions"
operatorsv1 "github.com/operator-framework/api/pkg/operators/v1"
operatorsv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
const (
nodeMaintenanceOperatorNamespace = "kube-system"
nodeMaintenanceOperatorCatalogNamespace = "olm"
)
type nodeMaintenanceOperatorDeployment struct {
CatalogSource operatorsv1alpha1.CatalogSource
OperatorGroup operatorsv1.OperatorGroup
Subscription operatorsv1alpha1.Subscription
}
// NewNodeMaintenanceOperatorDeployment creates a new node maintenance operator (NMO) deployment.
// See https://github.com/medik8s/node-maintenance-operator for more information.
func NewNodeMaintenanceOperatorDeployment() *nodeMaintenanceOperatorDeployment {
return &nodeMaintenanceOperatorDeployment{
CatalogSource: operatorsv1alpha1.CatalogSource{
TypeMeta: metav1.TypeMeta{APIVersion: "operators.coreos.com/v1alpha1", Kind: "CatalogSource"},
ObjectMeta: metav1.ObjectMeta{
Name: "node-maintenance-operator-catalog",
Namespace: nodeMaintenanceOperatorCatalogNamespace,
},
Spec: operatorsv1alpha1.CatalogSourceSpec{
SourceType: "grpc",
Image: versions.NodeMaintenanceOperatorCatalogImage + ":" + versions.NodeMaintenanceOperatorVersion,
DisplayName: "Node Maintenance Operator",
Publisher: "Medik8s Team",
UpdateStrategy: &operatorsv1alpha1.UpdateStrategy{
RegistryPoll: &operatorsv1alpha1.RegistryPoll{
RawInterval: "1m0s",
Interval: &metav1.Duration{
Duration: time.Minute,
},
},
},
},
},
OperatorGroup: operatorsv1.OperatorGroup{
TypeMeta: metav1.TypeMeta{APIVersion: "operators.coreos.com/v1", Kind: "OperatorGroup"},
ObjectMeta: metav1.ObjectMeta{
Name: "constellation-og",
Namespace: nodeMaintenanceOperatorNamespace,
},
Spec: operatorsv1.OperatorGroupSpec{
UpgradeStrategy: operatorsv1.UpgradeStrategyDefault,
},
},
Subscription: operatorsv1alpha1.Subscription{
TypeMeta: metav1.TypeMeta{APIVersion: "operators.coreos.com/v1alpha1", Kind: "Subscription"},
ObjectMeta: metav1.ObjectMeta{
Name: "node-maintenance-operator-sub",
Namespace: nodeMaintenanceOperatorNamespace,
},
Spec: &operatorsv1alpha1.SubscriptionSpec{
Channel: "stable",
Package: "node-maintenance-operator",
CatalogSource: "node-maintenance-operator-catalog",
CatalogSourceNamespace: "olm",
InstallPlanApproval: operatorsv1alpha1.ApprovalAutomatic,
StartingCSV: "node-maintenance-operator." + versions.NodeMaintenanceOperatorVersion,
},
},
}
}
func (c *nodeMaintenanceOperatorDeployment) Marshal() ([]byte, error) {
return MarshalK8SResources(c)
}

View file

@ -0,0 +1,21 @@
package resources
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestNodeMaintenanceOperatorMarshalUnmarshal(t *testing.T) {
require := require.New(t)
assert := assert.New(t)
nmoDepl := NewNodeMaintenanceOperatorDeployment()
data, err := nmoDepl.Marshal()
require.NoError(err)
var recreated nodeMaintenanceOperatorDeployment
require.NoError(UnmarshalK8SResources(data, &recreated))
assert.Equal(nmoDepl, &recreated)
}

View file

@ -0,0 +1,98 @@
package resources
import (
_ "embed"
"time"
"github.com/edgelesssys/constellation/internal/secrets"
"github.com/edgelesssys/constellation/internal/versions"
operatorsv1 "github.com/operator-framework/api/pkg/operators/v1"
operatorsv1alpha1 "github.com/operator-framework/api/pkg/operators/v1alpha1"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
const (
nodeOperatorNamespace = "kube-system"
nodeOperatorCatalogNamespace = "olm"
)
// NodeOperatorCRDNames are the names of the custom resource definitions that are used by the node operator.
var NodeOperatorCRDNames = []string{
"autoscalingstrategies.update.edgeless.systems",
"nodeimages.update.edgeless.systems",
"pendingnodes.update.edgeless.systems",
"scalinggroups.update.edgeless.systems",
}
type nodeOperatorDeployment struct {
CatalogSource operatorsv1alpha1.CatalogSource
OperatorGroup operatorsv1.OperatorGroup
Subscription operatorsv1alpha1.Subscription
CatalogPullSecret corev1.Secret
ImagePullSecret corev1.Secret
}
// NewNodeOperatorDeployment creates a new constellation node operator deployment.
// See /operators/constellation-node-operator for more information.
func NewNodeOperatorDeployment(cloudProvider string, uid string) *nodeOperatorDeployment {
return &nodeOperatorDeployment{
CatalogSource: operatorsv1alpha1.CatalogSource{
TypeMeta: metav1.TypeMeta{APIVersion: "operators.coreos.com/v1alpha1", Kind: "CatalogSource"},
ObjectMeta: metav1.ObjectMeta{
Name: "constellation-node-operator-catalog",
Namespace: nodeOperatorCatalogNamespace,
},
Spec: operatorsv1alpha1.CatalogSourceSpec{
SourceType: "grpc",
Secrets: []string{secrets.PullSecretName},
Image: versions.NodeOperatorCatalogImage + ":" + versions.NodeOperatorVersion,
DisplayName: "Constellation Node Operator",
Publisher: "Edgeless Systems",
UpdateStrategy: &operatorsv1alpha1.UpdateStrategy{
RegistryPoll: &operatorsv1alpha1.RegistryPoll{
RawInterval: "1m0s",
Interval: &metav1.Duration{Duration: 1 * time.Minute},
},
},
},
},
OperatorGroup: operatorsv1.OperatorGroup{
TypeMeta: metav1.TypeMeta{APIVersion: "operators.coreos.com/v1", Kind: "OperatorGroup"},
ObjectMeta: metav1.ObjectMeta{
Name: "constellation-og",
Namespace: nodeOperatorNamespace,
},
Spec: operatorsv1.OperatorGroupSpec{
UpgradeStrategy: operatorsv1.UpgradeStrategyDefault,
},
},
Subscription: operatorsv1alpha1.Subscription{
TypeMeta: metav1.TypeMeta{APIVersion: "operators.coreos.com/v1alpha1", Kind: "Subscription"},
ObjectMeta: metav1.ObjectMeta{
Name: "constellation-node-operator-sub",
Namespace: nodeOperatorNamespace,
},
Spec: &operatorsv1alpha1.SubscriptionSpec{
Channel: "alpha",
Package: "node-operator",
CatalogSource: "constellation-node-operator-catalog",
CatalogSourceNamespace: "olm",
InstallPlanApproval: operatorsv1alpha1.ApprovalAutomatic,
StartingCSV: "node-operator." + versions.NodeOperatorVersion,
Config: &operatorsv1alpha1.SubscriptionConfig{
Env: []corev1.EnvVar{
{Name: "CONSTEL_CSP", Value: cloudProvider},
{Name: "constellation-uid", Value: uid},
},
},
},
},
CatalogPullSecret: NewImagePullSecret(nodeOperatorCatalogNamespace),
ImagePullSecret: NewImagePullSecret(nodeOperatorNamespace),
}
}
func (c *nodeOperatorDeployment) Marshal() ([]byte, error) {
return MarshalK8SResources(c)
}

View file

@ -0,0 +1,21 @@
package resources
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestNodeOperatorMarshalUnmarshal(t *testing.T) {
require := require.New(t)
assert := assert.New(t)
nmoDepl := NewNodeOperatorDeployment("csp", "uid")
data, err := nmoDepl.Marshal()
require.NoError(err)
var recreated nodeOperatorDeployment
require.NoError(UnmarshalK8SResources(data, &recreated))
assert.Equal(nmoDepl, &recreated)
}

View file

@ -0,0 +1,31 @@
package resources
import "github.com/edgelesssys/constellation/internal/crds"
// OLMCRDNames are the names of the custom resource definitions that are used by the olm operator.
var OLMCRDNames = []string{
"catalogsources.operators.coreos.com",
"clusterserviceversions.operators.coreos.com",
"installplans.operators.coreos.com",
"olmconfigs.operators.coreos.com",
"operatorconditions.operators.coreos.com",
"operatorgroups.operators.coreos.com",
"operators.operators.coreos.com",
"subscriptions.operators.coreos.com",
}
// OperatorLifecycleManagerCRDs contains custom resource definitions used by the olm operator.
type OperatorLifecycleManagerCRDs struct{}
// Marshal returns the already marshalled CRDs.
func (m *OperatorLifecycleManagerCRDs) Marshal() ([]byte, error) {
return crds.OLMCRDs, nil
}
// OperatorLifecycleManager is the deployment of the olm operator.
type OperatorLifecycleManager struct{}
// Marshal returns the already marshalled deployment yaml.
func (m *OperatorLifecycleManager) Marshal() ([]byte, error) {
return crds.OLM, nil
}