Skip to content

Commit

Permalink
ProjectClaim controller creates ProjectReference (#15)
Browse files Browse the repository at this point in the history
Create ProjectReference from ProjectClaim

When a ProjectClaim resource is created, a ProjectReference resource is automatically created in the operator namespace gcp-project-operator
* ProjectClaimCRLink links to the corresponding ProjectClaim
* ProjectReferenceCRLink links to the corresponding ProjectReference
* LegalEntity content copied from ProjectClaim
* When the ProjectClaim gets removed, the ProjectReference resource is removed automatically as well
  • Loading branch information
NautiluX committed Feb 26, 2020
1 parent 0849dc4 commit 56e509f
Show file tree
Hide file tree
Showing 121 changed files with 9,342 additions and 1,471 deletions.
9 changes: 1 addition & 8 deletions cmd/manager/main.go
Expand Up @@ -15,7 +15,6 @@ import (
"github.com/openshift/gcp-project-operator/pkg/apis"
"github.com/openshift/gcp-project-operator/pkg/controller"

"github.com/operator-framework/operator-sdk/pkg/k8sutil"
"github.com/operator-framework/operator-sdk/pkg/leader"
"github.com/operator-framework/operator-sdk/pkg/log/zap"
"github.com/operator-framework/operator-sdk/pkg/metrics"
Expand Down Expand Up @@ -72,12 +71,6 @@ func run() error {

printVersion()

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

// Get a config to talk to the apiserver
cfg, err := config.GetConfig()
if err != nil {
Expand All @@ -96,7 +89,7 @@ func run() error {

// Create a new Cmd to provide shared dependencies and start components
mgr, err := manager.New(cfg, manager.Options{
Namespace: namespace,
Namespace: "", //watch all namespaces
MapperProvider: restmapper.NewDynamicRESTMapper,
MetricsBindAddress: fmt.Sprintf("%s:%d", metricsHost, metricsPort),
})
Expand Down
17 changes: 9 additions & 8 deletions go.mod
Expand Up @@ -7,9 +7,9 @@ require (
github.com/appscode/jsonpatch v0.0.0-20190108182946-7c0e3b262f30 // indirect
github.com/coreos/prometheus-operator v0.26.0 // indirect
github.com/dgrijalva/jwt-go v3.2.0+incompatible // indirect
github.com/emicklei/go-restful v2.8.1+incompatible // indirect
github.com/go-logr/logr v0.1.0
github.com/go-logr/zapr v0.1.0 // indirect
github.com/go-openapi/spec v0.18.0
github.com/go-openapi/spec v0.19.2
github.com/golang/groupcache v0.0.0-20191002201903-404acd9df4cc // indirect
github.com/golang/mock v1.4.0
github.com/google/go-cmp v0.4.0
Expand All @@ -19,14 +19,13 @@ require (
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7 // indirect
github.com/grpc-ecosystem/grpc-gateway v1.8.5 // indirect
github.com/hashicorp/golang-lru v0.5.3 // indirect
github.com/imdario/mergo v0.3.6 // indirect
github.com/onsi/ginkgo v1.12.0
github.com/onsi/gomega v1.9.0
github.com/openshift/api v0.0.0-20200217161739-c99157bc6492 // indirect
github.com/openshift/api v3.9.1-0.20190927182313-d4a64ec2cbd8+incompatible // indirect
github.com/openshift/cluster-api v0.0.0-20191129101638-b09907ac6668
github.com/openshift/cluster-network-operator v0.0.0-20190207145423-c226dcab667e // indirect
github.com/openshift/hive v0.0.0-20191114203647-105cae8c337d
github.com/operator-framework/operator-sdk v0.8.3-0.20190722210327-daf62d44e47e
github.com/pborman/uuid v0.0.0-20180906182336-adf5a7427709 // indirect
github.com/peterbourgon/diskv v2.0.1+incompatible // indirect
github.com/prometheus/client_golang v1.4.0 // indirect
github.com/rogpeppe/go-internal v1.5.0 // indirect
Expand All @@ -36,6 +35,7 @@ require (
go.uber.org/atomic v1.3.2 // indirect
go.uber.org/multierr v1.1.0 // indirect
go.uber.org/zap v1.9.1 // indirect
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 // indirect
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
golang.org/x/time v0.0.0-20191023065245-6d3f0bb11be5 // indirect
golang.org/x/tools v0.0.0-20200131161117-97da75b46c2a // indirect
Expand All @@ -47,9 +47,10 @@ require (
k8s.io/client-go v2.0.0-alpha.0.0.20181126152608-d082d5923d3c+incompatible
k8s.io/code-generator v0.17.1
k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6
k8s.io/kube-openapi v0.0.0-20180711000925-0cf8f7e6ed1d
sigs.k8s.io/controller-runtime v0.1.10
sigs.k8s.io/controller-tools v0.1.10
k8s.io/klog v1.0.0 // indirect
k8s.io/kube-openapi v0.0.0-20190816220812-743ec37842bf
sigs.k8s.io/controller-runtime v0.2.0-beta.2
sigs.k8s.io/controller-tools v0.2.2-0.20190919191502-76a25b63325a
sigs.k8s.io/testing_frameworks v0.1.0 // indirect
)

Expand Down
95 changes: 73 additions & 22 deletions go.sum

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions pkg/apis/gcp/v1alpha1/projectreference_types.go
Expand Up @@ -46,6 +46,11 @@ type ProjectReferenceConditionType string
// ProjectReferenceState is a valid value from ProjectReference.Status
type ProjectReferenceState string

// ProjectReferenceNamespace namespace, where ProjectReference CRs will be created
const (
ProjectReferenceNamespace string = "gcp-project-operator"
)

const (
// ProjectReferenceStatusCreating creating status for a ProjectReference CR
ProjectReferenceStatusCreating ProjectReferenceState = "Creating"
Expand Down
10 changes: 10 additions & 0 deletions pkg/controller/add_projectclaim.go
@@ -0,0 +1,10 @@
package controller

import (
"github.com/openshift/gcp-project-operator/pkg/controller/projectclaim"
)

func init() {
// AddToManagerFuncs is a list of functions to create controllers and add them to a manager.
AddToManagerFuncs = append(AddToManagerFuncs, projectclaim.Add)
}
131 changes: 131 additions & 0 deletions pkg/controller/projectclaim/customresourceadapter.go
@@ -0,0 +1,131 @@
package projectclaim

import (
"context"

"github.com/go-logr/logr"
"github.com/openshift/cluster-api/pkg/util"
gcpv1alpha1 "github.com/openshift/gcp-project-operator/pkg/apis/gcp/v1alpha1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
)

type CustomResourceAdapter struct {
projectClaim *gcpv1alpha1.ProjectClaim
logger logr.Logger
client client.Client
projectReference *gcpv1alpha1.ProjectReference
}

type ObjectState bool

const (
ObjectModified ObjectState = true
ObjectUnchanged ObjectState = false
)

const ProjectClaimFinalizer string = "finalizer.gcp.managed.openshift.io"

func NewCustomResourceAdapter(projectClaim *gcpv1alpha1.ProjectClaim, logger logr.Logger, client client.Client) *CustomResourceAdapter {
projectReference := newMatchingProjectReference(projectClaim)
return &CustomResourceAdapter{projectClaim, logger, client, projectReference}
}

func newMatchingProjectReference(projectClaim *gcpv1alpha1.ProjectClaim) *gcpv1alpha1.ProjectReference {

return &gcpv1alpha1.ProjectReference{
ObjectMeta: metav1.ObjectMeta{
Name: projectClaim.GetNamespace() + "-" + projectClaim.GetName(),
Namespace: gcpv1alpha1.ProjectReferenceNamespace,
},
Spec: gcpv1alpha1.ProjectReferenceSpec{
GCPProjectID: "",
ProjectClaimCRLink: gcpv1alpha1.NamespacedName{
Name: projectClaim.GetName(),
Namespace: projectClaim.GetNamespace(),
},
LegalEntity: *projectClaim.Spec.LegalEntity.DeepCopy(),
},
}
}

func (c *CustomResourceAdapter) ProjectReferenceExists() (bool, error) {
found := &gcpv1alpha1.ProjectReference{}
err := c.client.Get(context.TODO(), types.NamespacedName{Name: c.projectReference.Name, Namespace: c.projectReference.Namespace}, found)
if err != nil {
if errors.IsNotFound(err) {
return false, nil
}
return false, err
}
return true, nil
}

func (c *CustomResourceAdapter) IsProjectClaimDeletion() bool {
return c.projectClaim.DeletionTimestamp != nil
}

func (c *CustomResourceAdapter) FinalizeProjectClaim() error {
projectReferenceExists, err := c.ProjectReferenceExists()
if err != nil {
return err
}

if projectReferenceExists {
err := c.client.Delete(context.TODO(), c.projectReference)
if err != nil {
return err
}
}
finalizers := c.projectClaim.GetFinalizers()
if util.Contains(finalizers, ProjectClaimFinalizer) {
c.projectClaim.SetFinalizers(util.Filter(finalizers, ProjectClaimFinalizer))
return c.client.Update(context.TODO(), c.projectClaim)
}
return nil
}

func (c *CustomResourceAdapter) EnsureProjectReferenceLink() (ObjectState, error) {
expectedLink := gcpv1alpha1.NamespacedName{
Name: c.projectReference.GetName(),
Namespace: c.projectReference.GetNamespace(),
}
if c.projectClaim.Spec.ProjectReferenceCRLink == expectedLink {
return ObjectUnchanged, nil
}
c.projectClaim.Spec.ProjectReferenceCRLink = expectedLink
err := c.client.Update(context.TODO(), c.projectClaim)
if err != nil {
return ObjectUnchanged, err
}
return ObjectModified, nil
}

func (c *CustomResourceAdapter) EnsureFinalizer() (ObjectState, error) {
if !util.Contains(c.projectClaim.GetFinalizers(), ProjectClaimFinalizer) {
c.logger.Info("Adding Finalizer to the ProjectClaim")
c.projectClaim.SetFinalizers(append(c.projectClaim.GetFinalizers(), ProjectClaimFinalizer))

err := c.client.Update(context.TODO(), c.projectClaim)
if err != nil {
c.logger.Error(err, "Failed to update ProjectClaim with finalizer")
return ObjectUnchanged, err
}
return ObjectModified, nil
}
return ObjectUnchanged, nil
}

func (c *CustomResourceAdapter) EnsureProjectReferenceExists() error {
projectReferenceExists, err := c.ProjectReferenceExists()
if err != nil {
return err
}

if !projectReferenceExists {
return c.client.Create(context.TODO(), c.projectReference)
}
return nil
}

0 comments on commit 56e509f

Please sign in to comment.