Skip to content

Commit

Permalink
feature: make hco crd a singleton (#484)
Browse files Browse the repository at this point in the history
Update the HCO CustomResourceDefinition to accept only resources of a
particular name|namespace.

Signed-off-by: David Zager <dzager@redhat.com>
  • Loading branch information
kubevirt-bot authored Mar 4, 2020
1 parent 638dace commit 4b201fa
Show file tree
Hide file tree
Showing 12 changed files with 107 additions and 39 deletions.
28 changes: 23 additions & 5 deletions cmd/hyperconverged-cluster-operator/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (

sspopv1 "github.com/MarSik/kubevirt-ssp-operator/pkg/apis"
networkaddons "github.com/kubevirt/cluster-network-addons-operator/pkg/apis"
hcoutil "github.com/kubevirt/hyperconverged-cluster-operator/pkg/util"
kubemetrics "github.com/operator-framework/operator-sdk/pkg/kube-metrics"
sdkVersion "github.com/operator-framework/operator-sdk/version"
corev1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -70,16 +71,33 @@ func main() {

printVersion()

namespace, err := k8sutil.GetWatchNamespace()
watchNamespace, err := k8sutil.GetWatchNamespace()
if err != nil {
log.Error(err, "Failed to get watch namespace")
os.Exit(1)
}

// Get the namespace the operator is currently deployed in.
operatorNs, err := k8sutil.GetOperatorNamespace()
depOperatorNs, err := k8sutil.GetOperatorNamespace()
if err != nil {
log.Error(err, "")
log.Error(err, "Failed to get operator namespace")
os.Exit(1)
}

// Get the namespace the operator should be deployed in.
operatorNsEnv, err := hcoutil.GetOperatorNamespaceFromEnv()
if err != nil {
log.Error(err, "Failed to get operator namespace from the environment")
os.Exit(1)
}

if depOperatorNs != operatorNsEnv {
log.Error(
fmt.Errorf("Operator running in different namespace than expected"),
fmt.Sprintf("Please re-deploy this operator into %v namespace", operatorNsEnv),
"Expected.Namespace", operatorNsEnv,
"Deployed.Namespace", depOperatorNs,
)
os.Exit(1)
}

Expand Down Expand Up @@ -110,7 +128,7 @@ func main() {

// Create a new Cmd to provide shared dependencies and start components
mgr, err := manager.New(cfg, manager.Options{
Namespace: namespace,
Namespace: watchNamespace,
MapperProvider: restmapper.NewDynamicRESTMapper,
MetricsBindAddress: fmt.Sprintf("%s:%d", metricsHost, metricsPort),
})
Expand Down Expand Up @@ -158,7 +176,7 @@ func main() {
// CreateServiceMonitors will automatically create the prometheus-operator ServiceMonitor resources
// necessary to configure Prometheus to scrape metrics from this operator.
services := []*corev1.Service{service}
_, err = metrics.CreateServiceMonitors(cfg, operatorNs, services)
_, err = metrics.CreateServiceMonitors(cfg, depOperatorNs, services)
if err != nil {
log.Info("Could not create ServiceMonitor object", "error", err.Error())
// If this operator is deployed to a cluster without the prometheus-operator running, it will return
Expand Down
11 changes: 11 additions & 0 deletions deploy/crds/hco00.crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,17 @@ spec:
scope: Namespaced
subresources:
status: {}
validation:
openAPIV3Schema:
properties:
metadata:
properties:
name:
pattern: kubevirt-hyperconverged
type: string
namespace:
pattern: kubevirt-hyperconverged
type: string
version: v1alpha1
versions:
- name: v1alpha1
Expand Down
11 changes: 11 additions & 0 deletions deploy/olm-catalog/kubevirt-hyperconverged/1.0.0/hco00.crd.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,17 @@ spec:
scope: Namespaced
subresources:
status: {}
validation:
openAPIV3Schema:
properties:
metadata:
properties:
name:
pattern: kubevirt-hyperconverged
type: string
namespace:
pattern: kubevirt-hyperconverged
type: string
version: v1alpha1
versions:
- name: v1alpha1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ metadata:
categories: OpenShift Optional
certified: "false"
containerImage: quay.io/kubevirt/hyperconverged-cluster-operator:latest
createdAt: "2020-03-03 10:02:37"
createdAt: "2020-03-04 08:25:27"
description: |-
**HyperConverged Cluster Operator** is an Operator pattern for managing multi-operator products.
Specifcally, the HyperConverged Cluster Operator manages the deployment of KubeVirt,
Expand Down Expand Up @@ -1279,9 +1279,7 @@ spec:
- name: OPERATOR_NAME
value: hyperconverged-cluster-operator
- name: OPERATOR_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
value: kubevirt-hyperconverged
- name: POD_NAME
valueFrom:
fieldRef:
Expand Down
4 changes: 1 addition & 3 deletions deploy/operator.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,7 @@ spec:
- name: OPERATOR_NAME
value: hyperconverged-cluster-operator
- name: OPERATOR_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
value: kubevirt-hyperconverged
- name: POD_NAME
valueFrom:
fieldRef:
Expand Down
2 changes: 0 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -573,8 +573,6 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/krolaw/dhcp4 v0.0.0-20180925202202-7cead472c414/go.mod h1:0AqAH3ZogsCrvrtUpvc6EtVKbc3w6xwZhkvGLuqyi3o=
github.com/kshvakov/clickhouse v1.3.5/go.mod h1:DMzX7FxRymoNkVgizH0DWAL8Cur7wHLgx3MUnGwJqpE=
github.com/kubernetes-csi/external-snapshotter v0.0.0-20190509204040-e49856eb417c/go.mod h1:oYfxnsuh48V1UDYORl77YQxQbbdokNy7D73phuFpksY=
github.com/kubevirt/cluster-network-addons-operator v0.3.1-0.20200218183849-6edefcb6812d h1:3DubZhlj8KBknyPFelutJdmDpUIuOULsfO2gpENCzEY=
github.com/kubevirt/cluster-network-addons-operator v0.3.1-0.20200218183849-6edefcb6812d/go.mod h1:+FR0H6lVSDWOQL7ILd0/+HzeFrjh8Ce2v5HEjFO9wEY=
github.com/kubevirt/cluster-network-addons-operator v0.3.1-0.20200226122004-919521cbbe11 h1:0Z4nj5cwmpLz1Lld39V+EPXIJ6u7jmgYGN9v08zyMhU=
github.com/kubevirt/cluster-network-addons-operator v0.3.1-0.20200226122004-919521cbbe11/go.mod h1:+FR0H6lVSDWOQL7ILd0/+HzeFrjh8Ce2v5HEjFO9wEY=
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
Expand Down
3 changes: 3 additions & 0 deletions pkg/apis/hco/v1alpha1/hyperconverged_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ import (
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
// Important: Run "operator-sdk generate k8s" to regenerate code after modifying this file

// HyperConvergedName is the name of the HyperConverged resource that will be reconciled
const HyperConvergedName = "kubevirt-hyperconverged"

// HyperConvergedSpec defines the desired state of HyperConverged
// +k8s:openapi-gen=true
type HyperConvergedSpec struct {
Expand Down
45 changes: 30 additions & 15 deletions pkg/components/components.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ type StrategyDetailsDeployment struct {

const hcoName = "hyperconverged-cluster-operator"

func GetDeployment(image, imagePullPolicy, conversionContainer, vmwareContainerString string) appsv1.Deployment {
func GetDeployment(namespace, image, imagePullPolicy, conversionContainer, vmwareContainerString string) appsv1.Deployment {
return appsv1.Deployment{
TypeMeta: metav1.TypeMeta{
APIVersion: "apps/v1",
Expand All @@ -53,11 +53,11 @@ func GetDeployment(image, imagePullPolicy, conversionContainer, vmwareContainerS
"name": hcoName,
},
},
Spec: GetDeploymentSpec(image, imagePullPolicy, conversionContainer, vmwareContainerString),
Spec: GetDeploymentSpec(namespace, image, imagePullPolicy, conversionContainer, vmwareContainerString),
}
}

func GetDeploymentSpec(image, imagePullPolicy, conversionContainer, vmwareContainer string) appsv1.DeploymentSpec {
func GetDeploymentSpec(namespace, image, imagePullPolicy, conversionContainer, vmwareContainer string) appsv1.DeploymentSpec {
return appsv1.DeploymentSpec{
Replicas: int32Ptr(1),
Selector: &metav1.LabelSelector{
Expand Down Expand Up @@ -107,12 +107,8 @@ func GetDeploymentSpec(image, imagePullPolicy, conversionContainer, vmwareContai
Value: hcoName,
},
{
Name: "OPERATOR_NAMESPACE",
ValueFrom: &corev1.EnvVarSource{
FieldRef: &corev1.ObjectFieldSelector{
FieldPath: "metadata.namespace",
},
},
Name: "OPERATOR_NAMESPACE",
Value: namespace,
},
{
Name: "POD_NAME",
Expand Down Expand Up @@ -402,7 +398,7 @@ func GetClusterRoleBinding(namespace string) rbacv1.ClusterRoleBinding {
}
}

func GetOperatorCRD() *extv1beta1.CustomResourceDefinition {
func GetOperatorCRD(namespace string) *extv1beta1.CustomResourceDefinition {
return &extv1beta1.CustomResourceDefinition{
TypeMeta: metav1.TypeMeta{
APIVersion: "apiextensions.k8s.io/v1beta1",
Expand Down Expand Up @@ -437,6 +433,25 @@ func GetOperatorCRD() *extv1beta1.CustomResourceDefinition {
Subresources: &extv1beta1.CustomResourceSubresources{
Status: &extv1beta1.CustomResourceSubresourceStatus{},
},

Validation: &extv1beta1.CustomResourceValidation{
OpenAPIV3Schema: &extv1beta1.JSONSchemaProps{
Properties: map[string]extv1beta1.JSONSchemaProps{
"metadata": {
Properties: map[string]extv1beta1.JSONSchemaProps{
"name": extv1beta1.JSONSchemaProps{
Type: "string",
Pattern: hcov1alpha1.HyperConvergedName,
},
"namespace": extv1beta1.JSONSchemaProps{
Type: "string",
Pattern: namespace,
},
},
},
},
},
},
},
}
}
Expand Down Expand Up @@ -488,12 +503,12 @@ func GetOperatorCR() *hcov1alpha1.HyperConverged {
}

// GetInstallStrategyBase returns the basics of an HCO InstallStrategy
func GetInstallStrategyBase(image, imagePullPolicy, conversionContainer, vmwareContainer string) *StrategyDetailsDeployment {
func GetInstallStrategyBase(namespace, image, imagePullPolicy, conversionContainer, vmwareContainer string) *StrategyDetailsDeployment {
return &StrategyDetailsDeployment{
DeploymentSpecs: []StrategyDeploymentSpec{
StrategyDeploymentSpec{
Name: "hco-operator",
Spec: GetDeploymentSpec(image, imagePullPolicy, conversionContainer, vmwareContainer),
Spec: GetDeploymentSpec(namespace, image, imagePullPolicy, conversionContainer, vmwareContainer),
},
},
Permissions: []StrategyDeploymentPermissions{},
Expand All @@ -507,14 +522,14 @@ func GetInstallStrategyBase(image, imagePullPolicy, conversionContainer, vmwareC
}

// GetCSVBase returns a base HCO CSV without an InstallStrategy
func GetCSVBase(name, hcCRNamespace, displayName, description, image, replaces string, version semver.Version, crdDisplay string) *csvv1alpha1.ClusterServiceVersion {
func GetCSVBase(name, namespace, displayName, description, image, replaces string, version semver.Version, crdDisplay string) *csvv1alpha1.ClusterServiceVersion {
almExamples, _ := json.Marshal([]interface{}{
map[string]interface{}{
"apiVersion": "hco.kubevirt.io/v1alpha1",
"kind": "HyperConverged",
"metadata": map[string]string{
"name": "kubevirt-hyperconverged",
"namespace": hcCRNamespace,
"namespace": namespace,
},
"spec": map[string]interface{}{
"BareMetalPlatform": false,
Expand All @@ -540,7 +555,7 @@ func GetCSVBase(name, hcCRNamespace, displayName, description, image, replaces s
"description": description,
"repository": "https://github.com/kubevirt/hyperconverged-cluster-operator",
"support": "false",
"operatorframework.io/suggested-namespace": hcCRNamespace,
"operatorframework.io/suggested-namespace": namespace,
},
},
Spec: csvv1alpha1.ClusterServiceVersionSpec{
Expand Down
14 changes: 6 additions & 8 deletions pkg/controller/hyperconverged/hyperconverged_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import (
networkaddonsv1alpha1 "github.com/kubevirt/cluster-network-addons-operator/pkg/apis/networkaddonsoperator/v1alpha1"
networkaddonsnames "github.com/kubevirt/cluster-network-addons-operator/pkg/names"
hcov1alpha1 "github.com/kubevirt/hyperconverged-cluster-operator/pkg/apis/hco/v1alpha1"
hcoutil "github.com/kubevirt/hyperconverged-cluster-operator/pkg/util"
conditionsv1 "github.com/openshift/custom-resource-status/conditions/v1"
objectreferencesv1 "github.com/openshift/custom-resource-status/objectreferences/v1"

Expand All @@ -46,9 +47,6 @@ const (
// use finalizers to manage the cleanup.
FinalizerName = "hyperconvergeds.hco.kubevirt.io"

HyperConvergedName = "kubevirt-hyperconverged"
OperatorNamespaceEnv = "OPERATOR_NAMESPACE"

// UndefinedNamespace is for cluster scoped resources
UndefinedNamespace string = ""

Expand Down Expand Up @@ -1206,14 +1204,14 @@ func isKVMAvailable() bool {
// getHyperconverged returns the name/namespace of the HyperConverged resource
func getHyperconverged() (types.NamespacedName, error) {
hco := types.NamespacedName{
Name: HyperConvergedName,
Name: hcov1alpha1.HyperConvergedName,
}

if namespace, ok := os.LookupEnv(OperatorNamespaceEnv); ok {
hco.Namespace = namespace
} else {
return hco, fmt.Errorf("%s unset or empty in environment", OperatorNamespaceEnv)
namespace, err := hcoutil.GetOperatorNamespaceFromEnv()
if err != nil {
return hco, err
}
hco.Namespace = namespace

return hco, nil
}
Expand Down
16 changes: 16 additions & 0 deletions pkg/util/util.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package util

import (
"fmt"
"os"
)

const OperatorNamespaceEnv = "OPERATOR_NAMESPACE"

func GetOperatorNamespaceFromEnv() (string, error) {
if namespace, ok := os.LookupEnv(OperatorNamespaceEnv); ok {
return namespace, nil
}

return "", fmt.Errorf("%s unset or empty in environment", OperatorNamespaceEnv)
}
3 changes: 2 additions & 1 deletion tools/csv-merger/csv-merger.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ var (

func gen_hco_crds() {
// Write out CRDs and CR
util.MarshallObject(components.GetOperatorCRD(), os.Stdout)
util.MarshallObject(components.GetOperatorCRD(*namespace), os.Stdout)
util.MarshallObject(components.GetV2VCRD(), os.Stdout)
}

Expand Down Expand Up @@ -138,6 +138,7 @@ func main() {

// This is the base deployment + rbac for the HCO CSV
installStrategyBase := components.GetInstallStrategyBase(
*namespace,
*operatorImage,
"IfNotPresent",
*imsConversionImage,
Expand Down
3 changes: 2 additions & 1 deletion tools/manifest-templator/manifest-templator.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,7 @@ func main() {
// same service account multiple times.
deployments := []appsv1.Deployment{
components.GetDeployment(
*operatorNamespace,
*operatorImage,
"IfNotPresent",
*imsConversionImage,
Expand Down Expand Up @@ -276,7 +277,7 @@ func main() {

// Write out CRDs and CR
util.MarshallObject(components.GetOperatorCR(), operatorCr)
util.MarshallObject(components.GetOperatorCRD(), operatorCrd)
util.MarshallObject(components.GetOperatorCRD(*operatorNamespace), operatorCrd)
util.MarshallObject(components.GetV2VCRD(), v2vCrd)

// Write out deployments
Expand Down

0 comments on commit 4b201fa

Please sign in to comment.