Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions lib/resourceapply/apiext.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,17 @@ package resourceapply
import (
"context"

"github.com/google/go-cmp/cmp"
"github.com/openshift/cluster-version-operator/lib/resourcemerge"
apiextv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
apiextclientv1 "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/diff"
"k8s.io/klog/v2"
"k8s.io/utils/pointer"
)

func ApplyCustomResourceDefinitionv1(ctx context.Context, client apiextclientv1.CustomResourceDefinitionsGetter, required *apiextv1.CustomResourceDefinition) (*apiextv1.CustomResourceDefinition, bool, error) {
func ApplyCustomResourceDefinitionv1(ctx context.Context, client apiextclientv1.CustomResourceDefinitionsGetter, required *apiextv1.CustomResourceDefinition, reconciling bool) (*apiextv1.CustomResourceDefinition, bool, error) {
Copy link
Member

@wking wking Jul 13, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we pass in the mode instead of passing in a reconciling bool? Like we do for ClusterOperators here. That way we don't have to bump cluster signatures if we need to make some other mode distinction later on.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I considered that and decided against it because it would leak abstractions. Mode is part of the resourcebuilder package, where as the resource creation/update logic is in the internal. If in the future the full mode is required more refactoring can be done where the mode is moved to a common package and then it can be passed to the apply function.

existing, err := client.CustomResourceDefinitions().Get(ctx, required.Name, metav1.GetOptions{})
if apierrors.IsNotFound(err) {
klog.V(2).Infof("CRD %s not found, creating", required.Name)
Expand All @@ -34,7 +34,9 @@ func ApplyCustomResourceDefinitionv1(ctx context.Context, client apiextclientv1.
return existing, false, nil
}

klog.V(2).Infof("Updating CRD %s due to diff: %v", required.Name, diff.ObjectDiff(existing, required))
if reconciling {
klog.V(4).Infof("Updating CRD %s due to diff: %v", required.Name, cmp.Diff(existing, required))
}

actual, err := client.CustomResourceDefinitions().Update(ctx, existing, metav1.UpdateOptions{})
return actual, true, err
Expand Down
68 changes: 7 additions & 61 deletions lib/resourceapply/apps.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,18 @@ package resourceapply
import (
"context"

"github.com/google/go-cmp/cmp"
"github.com/openshift/cluster-version-operator/lib/resourcemerge"
appsv1 "k8s.io/api/apps/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/diff"
appsclientv1 "k8s.io/client-go/kubernetes/typed/apps/v1"
appslisterv1 "k8s.io/client-go/listers/apps/v1"
"k8s.io/klog/v2"
"k8s.io/utils/pointer"
)

// ApplyDeploymentv1 applies the required deployment to the cluster.
func ApplyDeploymentv1(ctx context.Context, client appsclientv1.DeploymentsGetter, required *appsv1.Deployment) (*appsv1.Deployment, bool, error) {
func ApplyDeploymentv1(ctx context.Context, client appsclientv1.DeploymentsGetter, required *appsv1.Deployment, reconciling bool) (*appsv1.Deployment, bool, error) {
existing, err := client.Deployments(required.Namespace).Get(ctx, required.Name, metav1.GetOptions{})
if apierrors.IsNotFound(err) {
klog.V(2).Infof("Deployment %s/%s not found, creating", required.Namespace, required.Name)
Expand All @@ -35,42 +34,16 @@ func ApplyDeploymentv1(ctx context.Context, client appsclientv1.DeploymentsGette
if !*modified {
return existing, false, nil
}
klog.V(2).Infof("Updating Deployment %s/%s due to diff: %v", required.Namespace, required.Name, diff.ObjectDiff(existing, required))

actual, err := client.Deployments(required.Namespace).Update(ctx, existing, metav1.UpdateOptions{})
return actual, true, err
}

// ApplyDeploymentFromCache applies the required deployment to the cluster.
func ApplyDeploymentFromCache(ctx context.Context, lister appslisterv1.DeploymentLister, client appsclientv1.DeploymentsGetter, required *appsv1.Deployment) (*appsv1.Deployment, bool, error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note to self, this is catching up with 4b485ca (#10):

$ git show 4b485ca109cd271a10d32e47d3657331be8160fd | grep ApplyDeploymentFromCache
-       _, updated, err := resourceapply.ApplyDeploymentFromCache(optr.deployLister, optr.kubeClient.AppsV1(), cvo)

which removed the last consumer.

existing, err := lister.Deployments(required.Namespace).Get(required.Name)
if apierrors.IsNotFound(err) {
klog.V(2).Infof("Deployment %s/%s not found, creating", required.Namespace, required.Name)
actual, err := client.Deployments(required.Namespace).Create(ctx, required, metav1.CreateOptions{})
return actual, true, err
}
if err != nil {
return nil, false, err
}
// if we only create this resource, we have no need to continue further
if IsCreateOnly(required) {
return nil, false, nil
if reconciling {
klog.V(4).Infof("Updating Deployment %s/%s due to diff: %v", required.Namespace, required.Name, cmp.Diff(existing, required))
}

existing = existing.DeepCopy()
modified := pointer.BoolPtr(false)
resourcemerge.EnsureDeployment(modified, existing, *required)
if !*modified {
return existing, false, nil
}
klog.V(2).Infof("Updating Deployment %s/%s due to diff: %v", required.Namespace, required.Name, diff.ObjectDiff(existing, required))

actual, err := client.Deployments(required.Namespace).Update(ctx, existing, metav1.UpdateOptions{})
return actual, true, err
}

// ApplyDaemonSetv1 applies the required daemonset to the cluster.
func ApplyDaemonSetv1(ctx context.Context, client appsclientv1.DaemonSetsGetter, required *appsv1.DaemonSet) (*appsv1.DaemonSet, bool, error) {
func ApplyDaemonSetv1(ctx context.Context, client appsclientv1.DaemonSetsGetter, required *appsv1.DaemonSet, reconciling bool) (*appsv1.DaemonSet, bool, error) {
existing, err := client.DaemonSets(required.Namespace).Get(ctx, required.Name, metav1.GetOptions{})
if apierrors.IsNotFound(err) {
klog.V(2).Infof("DaemonSet %s/%s not found, creating", required.Namespace, required.Name)
Expand All @@ -91,36 +64,9 @@ func ApplyDaemonSetv1(ctx context.Context, client appsclientv1.DaemonSetsGetter,
return existing, false, nil
}

klog.V(2).Infof("Updating DaemonSet %s/%s due to diff: %v", required.Namespace, required.Name, diff.ObjectDiff(existing, required))

actual, err := client.DaemonSets(required.Namespace).Update(ctx, existing, metav1.UpdateOptions{})
return actual, true, err
}

// ApplyDaemonSetFromCache applies the required deployment to the cluster.
func ApplyDaemonSetFromCache(ctx context.Context, lister appslisterv1.DaemonSetLister, client appsclientv1.DaemonSetsGetter, required *appsv1.DaemonSet) (*appsv1.DaemonSet, bool, error) {
existing, err := lister.DaemonSets(required.Namespace).Get(required.Name)
if apierrors.IsNotFound(err) {
klog.V(2).Infof("DaemonSet %s/%s not found, creating", required.Namespace, required.Name)
actual, err := client.DaemonSets(required.Namespace).Create(ctx, required, metav1.CreateOptions{})
return actual, true, err
}
if err != nil {
return nil, false, err
if reconciling {
klog.V(4).Infof("Updating DaemonSet %s/%s due to diff: %v", required.Namespace, required.Name, cmp.Diff(existing, required))
}
// if we only create this resource, we have no need to continue further
if IsCreateOnly(required) {
return nil, false, nil
}

existing = existing.DeepCopy()
modified := pointer.BoolPtr(false)
resourcemerge.EnsureDaemonSet(modified, existing, *required)
if !*modified {
return existing, false, nil
}

klog.V(2).Infof("Updating DaemonSet %s/%s due to diff: %v", required.Namespace, required.Name, diff.ObjectDiff(existing, required))

actual, err := client.DaemonSets(required.Namespace).Update(ctx, existing, metav1.UpdateOptions{})
return actual, true, err
Expand Down
8 changes: 5 additions & 3 deletions lib/resourceapply/batch.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,18 @@ package resourceapply
import (
"context"

"github.com/google/go-cmp/cmp"
"github.com/openshift/cluster-version-operator/lib/resourcemerge"
batchv1 "k8s.io/api/batch/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/diff"
batchclientv1 "k8s.io/client-go/kubernetes/typed/batch/v1"
"k8s.io/klog/v2"
"k8s.io/utils/pointer"
)

// ApplyJobv1 applies the required Job to the cluster.
func ApplyJobv1(ctx context.Context, client batchclientv1.JobsGetter, required *batchv1.Job) (*batchv1.Job, bool, error) {
func ApplyJobv1(ctx context.Context, client batchclientv1.JobsGetter, required *batchv1.Job, reconciling bool) (*batchv1.Job, bool, error) {
existing, err := client.Jobs(required.Namespace).Get(ctx, required.Name, metav1.GetOptions{})
if apierrors.IsNotFound(err) {
klog.V(2).Infof("Job %s/%s not found, creating", required.Namespace, required.Name)
Expand All @@ -35,7 +35,9 @@ func ApplyJobv1(ctx context.Context, client batchclientv1.JobsGetter, required *
return existing, false, nil
}

klog.V(2).Infof("Updating Job %s/%s due to diff: %v", required.Namespace, required.Name, diff.ObjectDiff(existing, required))
if reconciling {
klog.V(4).Infof("Updating Job %s/%s due to diff: %v", required.Namespace, required.Name, cmp.Diff(existing, required))
}

actual, err := client.Jobs(required.Namespace).Update(ctx, existing, metav1.UpdateOptions{})
return actual, true, err
Expand Down
26 changes: 17 additions & 9 deletions lib/resourceapply/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,21 @@ package resourceapply
import (
"context"

"github.com/google/go-cmp/cmp"
"k8s.io/klog/v2"

corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/equality"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/diff"
coreclientv1 "k8s.io/client-go/kubernetes/typed/core/v1"
"k8s.io/utils/pointer"

"github.com/openshift/cluster-version-operator/lib/resourcemerge"
)

// ApplyNamespacev1 merges objectmeta, does not worry about anything else
func ApplyNamespacev1(ctx context.Context, client coreclientv1.NamespacesGetter, required *corev1.Namespace) (*corev1.Namespace, bool, error) {
func ApplyNamespacev1(ctx context.Context, client coreclientv1.NamespacesGetter, required *corev1.Namespace, reconciling bool) (*corev1.Namespace, bool, error) {
existing, err := client.Namespaces().Get(ctx, required.Name, metav1.GetOptions{})
if apierrors.IsNotFound(err) {
klog.V(2).Infof("Namespace %s not found, creating", required.Name)
Expand All @@ -37,7 +37,9 @@ func ApplyNamespacev1(ctx context.Context, client coreclientv1.NamespacesGetter,
if !*modified {
return existing, false, nil
}
klog.V(2).Infof("Updating Namespace %s due to diff: %v", required.Name, diff.ObjectDiff(existing, required))
if reconciling {
klog.V(4).Infof("Updating Namespace %s due to diff: %v", required.Name, cmp.Diff(existing, required))
}

actual, err := client.Namespaces().Update(ctx, existing, metav1.UpdateOptions{})
return actual, true, err
Expand All @@ -46,7 +48,7 @@ func ApplyNamespacev1(ctx context.Context, client coreclientv1.NamespacesGetter,
// ApplyServicev1 merges objectmeta and requires
// TODO, since this cannot determine whether changes are due to legitimate actors (api server) or illegitimate ones (users), we cannot update
// TODO I've special cased the selector for now
func ApplyServicev1(ctx context.Context, client coreclientv1.ServicesGetter, required *corev1.Service) (*corev1.Service, bool, error) {
func ApplyServicev1(ctx context.Context, client coreclientv1.ServicesGetter, required *corev1.Service, reconciling bool) (*corev1.Service, bool, error) {
existing, err := client.Services(required.Namespace).Get(ctx, required.Name, metav1.GetOptions{})
if apierrors.IsNotFound(err) {
klog.V(2).Infof("Service %s/%s not found, creating", required.Namespace, required.Name)
Expand All @@ -72,14 +74,16 @@ func ApplyServicev1(ctx context.Context, client coreclientv1.ServicesGetter, req
}
existing.Spec.Selector = required.Spec.Selector

klog.V(2).Infof("Updating Service %s/%s due to diff: %v", required.Namespace, required.Name, diff.ObjectDiff(existing, required))
if reconciling {
klog.V(4).Infof("Updating Service %s/%s due to diff: %v", required.Namespace, required.Name, cmp.Diff(existing, required))
}

actual, err := client.Services(required.Namespace).Update(ctx, existing, metav1.UpdateOptions{})
return actual, true, err
}

// ApplyServiceAccountv1 applies the required serviceaccount to the cluster.
func ApplyServiceAccountv1(ctx context.Context, client coreclientv1.ServiceAccountsGetter, required *corev1.ServiceAccount) (*corev1.ServiceAccount, bool, error) {
func ApplyServiceAccountv1(ctx context.Context, client coreclientv1.ServiceAccountsGetter, required *corev1.ServiceAccount, reconciling bool) (*corev1.ServiceAccount, bool, error) {
existing, err := client.ServiceAccounts(required.Namespace).Get(ctx, required.Name, metav1.GetOptions{})
if apierrors.IsNotFound(err) {
klog.V(2).Infof("ServiceAccount %s/%s not found, creating", required.Namespace, required.Name)
Expand All @@ -100,14 +104,16 @@ func ApplyServiceAccountv1(ctx context.Context, client coreclientv1.ServiceAccou
return existing, false, nil
}

klog.V(2).Infof("Updating ServiceAccount %s/%s due to diff: %v", required.Namespace, required.Name, diff.ObjectDiff(existing, required))
if reconciling {
klog.V(4).Infof("Updating ServiceAccount %s/%s due to diff: %v", required.Namespace, required.Name, cmp.Diff(existing, required))
}

actual, err := client.ServiceAccounts(required.Namespace).Update(ctx, existing, metav1.UpdateOptions{})
return actual, true, err
}

// ApplyConfigMapv1 applies the required serviceaccount to the cluster.
func ApplyConfigMapv1(ctx context.Context, client coreclientv1.ConfigMapsGetter, required *corev1.ConfigMap) (*corev1.ConfigMap, bool, error) {
func ApplyConfigMapv1(ctx context.Context, client coreclientv1.ConfigMapsGetter, required *corev1.ConfigMap, reconciling bool) (*corev1.ConfigMap, bool, error) {
existing, err := client.ConfigMaps(required.Namespace).Get(ctx, required.Name, metav1.GetOptions{})
if apierrors.IsNotFound(err) {
klog.V(2).Infof("ConfigMap %s/%s not found, creating", required.Namespace, required.Name)
Expand All @@ -128,7 +134,9 @@ func ApplyConfigMapv1(ctx context.Context, client coreclientv1.ConfigMapsGetter,
return existing, false, nil
}

klog.V(2).Infof("Updating ConfigMap %s/%s due to diff: %v", required.Namespace, required.Name, diff.ObjectDiff(existing, required))
if reconciling {
klog.V(4).Infof("Updating ConfigMap %s/%s due to diff: %v", required.Namespace, required.Name, cmp.Diff(existing, required))
}

actual, err := client.ConfigMaps(required.Namespace).Update(ctx, existing, metav1.UpdateOptions{})
return actual, true, err
Expand Down
30 changes: 2 additions & 28 deletions lib/resourceapply/cv.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,17 @@ package resourceapply
import (
"context"

"github.com/google/go-cmp/cmp"
configv1 "github.com/openshift/api/config/v1"
configclientv1 "github.com/openshift/client-go/config/clientset/versioned/typed/config/v1"
configlistersv1 "github.com/openshift/client-go/config/listers/config/v1"
"github.com/openshift/cluster-version-operator/lib/resourcemerge"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/diff"
"k8s.io/klog/v2"
"k8s.io/utils/pointer"
)

func ApplyClusterVersionv1(ctx context.Context, client configclientv1.ClusterVersionsGetter, required *configv1.ClusterVersion) (*configv1.ClusterVersion, bool, error) {
existing, err := client.ClusterVersions().Get(ctx, required.Name, metav1.GetOptions{})
if errors.IsNotFound(err) {
actual, err := client.ClusterVersions().Create(ctx, required, metav1.CreateOptions{})
return actual, true, err
}
if err != nil {
return nil, false, err
}
// if we only create this resource, we have no need to continue further
if IsCreateOnly(required) {
return nil, false, nil
}

modified := pointer.BoolPtr(false)
resourcemerge.EnsureClusterVersion(modified, existing, *required)
if !*modified {
return existing, false, nil
}

klog.V(2).Infof("Updating ClusterVersion %s due to diff: %v", required.Name, diff.ObjectDiff(existing, required))

actual, err := client.ClusterVersions().Update(ctx, existing, metav1.UpdateOptions{})
return actual, true, err
}

func ApplyClusterVersionFromCache(ctx context.Context, lister configlistersv1.ClusterVersionLister, client configclientv1.ClusterVersionsGetter, required *configv1.ClusterVersion) (*configv1.ClusterVersion, bool, error) {
obj, err := lister.Get(required.Name)
if errors.IsNotFound(err) {
Expand All @@ -62,7 +36,7 @@ func ApplyClusterVersionFromCache(ctx context.Context, lister configlistersv1.Cl
return existing, false, nil
}

klog.V(2).Infof("Updating ClusterVersion %s due to diff: %v", required.Name, diff.ObjectDiff(existing, required))
klog.V(4).Infof("Updating ClusterVersion %s due to diff: %v", required.Name, cmp.Diff(existing, required))

actual, err := client.ClusterVersions().Update(ctx, existing, metav1.UpdateOptions{})
return actual, true, err
Expand Down
7 changes: 6 additions & 1 deletion lib/resourceapply/imagestream.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,17 @@ package resourceapply
import (
"context"

"github.com/google/go-cmp/cmp"
imagev1 "github.com/openshift/api/image/v1"
imageclientv1 "github.com/openshift/client-go/image/clientset/versioned/typed/image/v1"
"github.com/openshift/cluster-version-operator/lib/resourcemerge"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/klog/v2"
"k8s.io/utils/pointer"
)

func ApplyImageStreamv1(ctx context.Context, client imageclientv1.ImageStreamsGetter, required *imagev1.ImageStream) (*imagev1.ImageStream, bool, error) {
func ApplyImageStreamv1(ctx context.Context, client imageclientv1.ImageStreamsGetter, required *imagev1.ImageStream, reconciling bool) (*imagev1.ImageStream, bool, error) {
existing, err := client.ImageStreams(required.Namespace).Get(ctx, required.Name, metav1.GetOptions{})
if errors.IsNotFound(err) {
actual, err := client.ImageStreams(required.Namespace).Create(ctx, required, metav1.CreateOptions{})
Expand All @@ -31,6 +33,9 @@ func ApplyImageStreamv1(ctx context.Context, client imageclientv1.ImageStreamsGe
return existing, false, nil
}

if reconciling {
klog.V(4).Infof("Updating Namespace %s due to diff: %v", required.Name, cmp.Diff(existing, required))
}
actual, err := client.ImageStreams(required.Namespace).Update(ctx, existing, metav1.UpdateOptions{})
return actual, true, err
}
Loading