Skip to content

Commit d9f6718

Browse files
committed
lib: add lib for applying objects
1 parent 415af2b commit d9f6718

File tree

9 files changed

+938
-0
lines changed

9 files changed

+938
-0
lines changed

lib/resourceapply/apiext.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package resourceapply
2+
3+
import (
4+
"github.com/openshift/cluster-version-operator/lib/resourcemerge"
5+
apiextv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
6+
apiextclientv1beta1 "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1beta1"
7+
apiextlistersv1beta1 "k8s.io/apiextensions-apiserver/pkg/client/listers/apiextensions/v1beta1"
8+
apierrors "k8s.io/apimachinery/pkg/api/errors"
9+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
10+
"k8s.io/utils/pointer"
11+
)
12+
13+
func ApplyCustomResourceDefinition(client apiextclientv1beta1.CustomResourceDefinitionsGetter, required *apiextv1beta1.CustomResourceDefinition) (*apiextv1beta1.CustomResourceDefinition, bool, error) {
14+
existing, err := client.CustomResourceDefinitions().Get(required.Name, metav1.GetOptions{})
15+
if apierrors.IsNotFound(err) {
16+
actual, err := client.CustomResourceDefinitions().Create(required)
17+
return actual, true, err
18+
}
19+
if err != nil {
20+
return nil, false, err
21+
}
22+
23+
modified := pointer.BoolPtr(false)
24+
resourcemerge.EnsureCustomResourceDefinition(modified, existing, *required)
25+
if !*modified {
26+
return existing, false, nil
27+
}
28+
29+
actual, err := client.CustomResourceDefinitions().Update(existing)
30+
return actual, true, err
31+
}
32+
33+
func ApplyCustomResourceDefinitionFromCache(lister apiextlistersv1beta1.CustomResourceDefinitionLister, client apiextclientv1beta1.CustomResourceDefinitionsGetter, required *apiextv1beta1.CustomResourceDefinition) (*apiextv1beta1.CustomResourceDefinition, bool, error) {
34+
existing, err := lister.Get(required.Name)
35+
if apierrors.IsNotFound(err) {
36+
actual, err := client.CustomResourceDefinitions().Create(required)
37+
return actual, true, err
38+
}
39+
if err != nil {
40+
return nil, false, err
41+
}
42+
43+
existing = existing.DeepCopy()
44+
modified := pointer.BoolPtr(false)
45+
resourcemerge.EnsureCustomResourceDefinition(modified, existing, *required)
46+
if !*modified {
47+
return existing, false, nil
48+
}
49+
50+
actual, err := client.CustomResourceDefinitions().Update(existing)
51+
return actual, true, err
52+
}

lib/resourceapply/apps.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package resourceapply
2+
3+
import (
4+
"github.com/openshift/cluster-version-operator/lib/resourcemerge"
5+
appsv1 "k8s.io/api/apps/v1"
6+
apierrors "k8s.io/apimachinery/pkg/api/errors"
7+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
8+
appsclientv1 "k8s.io/client-go/kubernetes/typed/apps/v1"
9+
appslisterv1 "k8s.io/client-go/listers/apps/v1"
10+
"k8s.io/utils/pointer"
11+
)
12+
13+
// ApplyDeployment applies the required deployment to the cluster.
14+
func ApplyDeployment(client appsclientv1.DeploymentsGetter, required *appsv1.Deployment) (*appsv1.Deployment, bool, error) {
15+
existing, err := client.Deployments(required.Namespace).Get(required.Name, metav1.GetOptions{})
16+
if apierrors.IsNotFound(err) {
17+
actual, err := client.Deployments(required.Namespace).Create(required)
18+
return actual, true, err
19+
}
20+
if err != nil {
21+
return nil, false, err
22+
}
23+
24+
modified := pointer.BoolPtr(false)
25+
resourcemerge.EnsureDeployment(modified, existing, *required)
26+
if !*modified {
27+
return existing, false, nil
28+
}
29+
30+
actual, err := client.Deployments(required.Namespace).Update(existing)
31+
return actual, true, err
32+
}
33+
34+
// ApplyDeploymentFromCache applies the required deployment to the cluster.
35+
func ApplyDeploymentFromCache(lister appslisterv1.DeploymentLister, client appsclientv1.DeploymentsGetter, required *appsv1.Deployment) (*appsv1.Deployment, bool, error) {
36+
existing, err := lister.Deployments(required.Namespace).Get(required.Name)
37+
if apierrors.IsNotFound(err) {
38+
actual, err := client.Deployments(required.Namespace).Create(required)
39+
return actual, true, err
40+
}
41+
if err != nil {
42+
return nil, false, err
43+
}
44+
45+
existing = existing.DeepCopy()
46+
modified := pointer.BoolPtr(false)
47+
resourcemerge.EnsureDeployment(modified, existing, *required)
48+
if !*modified {
49+
return existing, false, nil
50+
}
51+
52+
actual, err := client.Deployments(required.Namespace).Update(existing)
53+
return actual, true, err
54+
}

lib/resourceapply/cv.go

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
package resourceapply
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/openshift/cluster-version-operator/lib/resourcemerge"
7+
"github.com/openshift/cluster-version-operator/pkg/apis/clusterversion.openshift.io/v1"
8+
clientv1 "github.com/openshift/cluster-version-operator/pkg/generated/clientset/versioned/typed/clusterversion.openshift.io/v1"
9+
listersv1 "github.com/openshift/cluster-version-operator/pkg/generated/listers/clusterversion.openshift.io/v1"
10+
"k8s.io/apimachinery/pkg/api/errors"
11+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
12+
"k8s.io/utils/pointer"
13+
)
14+
15+
func ApplyOperatorStatus(client clientv1.OperatorStatusesGetter, required *v1.OperatorStatus) (*v1.OperatorStatus, bool, error) {
16+
if required.Extension.Raw != nil && required.Extension.Object != nil {
17+
return nil, false, fmt.Errorf("both extension.Raw and extension.Object should not be set")
18+
}
19+
existing, err := client.OperatorStatuses(required.Namespace).Get(required.Name, metav1.GetOptions{})
20+
if errors.IsNotFound(err) {
21+
actual, err := client.OperatorStatuses(required.Namespace).Create(required)
22+
return actual, true, err
23+
}
24+
if err != nil {
25+
return nil, false, err
26+
}
27+
28+
modified := pointer.BoolPtr(false)
29+
resourcemerge.EnsureOperatorStatus(modified, existing, *required)
30+
if !*modified {
31+
return existing, false, nil
32+
}
33+
34+
actual, err := client.OperatorStatuses(required.Namespace).Update(existing)
35+
return actual, true, err
36+
}
37+
38+
func ApplyOperatorStatusFromCache(lister listersv1.OperatorStatusLister, client clientv1.OperatorStatusesGetter, required *v1.OperatorStatus) (*v1.OperatorStatus, bool, error) {
39+
if required.Extension.Raw != nil && required.Extension.Object != nil {
40+
return nil, false, fmt.Errorf("both extension.Raw and extension.Object should not be set")
41+
}
42+
existing, err := lister.OperatorStatuses(required.Namespace).Get(required.Name)
43+
if errors.IsNotFound(err) {
44+
actual, err := client.OperatorStatuses(required.Namespace).Create(required)
45+
return actual, true, err
46+
}
47+
if err != nil {
48+
return nil, false, err
49+
}
50+
51+
// Don't want to mutate cache.
52+
existing = existing.DeepCopy()
53+
modified := pointer.BoolPtr(false)
54+
resourcemerge.EnsureOperatorStatus(modified, existing, *required)
55+
if !*modified {
56+
return existing, false, nil
57+
}
58+
59+
actual, err := client.OperatorStatuses(required.Namespace).Update(existing)
60+
return actual, true, err
61+
}
62+
63+
func ApplyCVOConfig(client clientv1.CVOConfigsGetter, required *v1.CVOConfig) (*v1.CVOConfig, bool, error) {
64+
existing, err := client.CVOConfigs(required.Namespace).Get(required.Name, metav1.GetOptions{})
65+
if errors.IsNotFound(err) {
66+
actual, err := client.CVOConfigs(required.Namespace).Create(required)
67+
return actual, true, err
68+
}
69+
if err != nil {
70+
return nil, false, err
71+
}
72+
73+
modified := pointer.BoolPtr(false)
74+
resourcemerge.EnsureCVOConfig(modified, existing, *required)
75+
if !*modified {
76+
return existing, false, nil
77+
}
78+
79+
actual, err := client.CVOConfigs(required.Namespace).Update(existing)
80+
return actual, true, err
81+
}
82+
83+
func ApplyCVOConfigFromCache(lister listersv1.CVOConfigLister, client clientv1.CVOConfigsGetter, required *v1.CVOConfig) (*v1.CVOConfig, bool, error) {
84+
obj, err := lister.CVOConfigs(required.Namespace).Get(required.Name)
85+
if errors.IsNotFound(err) {
86+
actual, err := client.CVOConfigs(required.Namespace).Create(required)
87+
return actual, true, err
88+
}
89+
if err != nil {
90+
return nil, false, err
91+
}
92+
93+
// Don't want to mutate cache.
94+
existing := new(v1.CVOConfig)
95+
obj.DeepCopyInto(existing)
96+
modified := pointer.BoolPtr(false)
97+
resourcemerge.EnsureCVOConfig(modified, existing, *required)
98+
if !*modified {
99+
return existing, false, nil
100+
}
101+
102+
actual, err := client.CVOConfigs(required.Namespace).Update(existing)
103+
return actual, true, err
104+
}

lib/resourcemerge/apiext.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package resourcemerge
2+
3+
import (
4+
apiextv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
5+
"k8s.io/apimachinery/pkg/api/equality"
6+
)
7+
8+
// EnsureCustomResourceDefinition ensures that the existing matches the required.
9+
// modified is set to true when existing had to be updated with required.
10+
func EnsureCustomResourceDefinition(modified *bool, existing *apiextv1beta1.CustomResourceDefinition, required apiextv1beta1.CustomResourceDefinition) {
11+
EnsureObjectMeta(modified, &existing.ObjectMeta, required.ObjectMeta)
12+
13+
// we stomp everything
14+
if !equality.Semantic.DeepEqual(existing.Spec, required.Spec) {
15+
*modified = true
16+
existing.Spec = required.Spec
17+
}
18+
}

lib/resourcemerge/apps.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package resourcemerge
2+
3+
import (
4+
appsv1 "k8s.io/api/apps/v1"
5+
"k8s.io/apimachinery/pkg/api/equality"
6+
)
7+
8+
// EnsureDeployment ensures that the existing matches the required.
9+
// modified is set to true when existing had to be updated with required.
10+
func EnsureDeployment(modified *bool, existing *appsv1.Deployment, required appsv1.Deployment) {
11+
EnsureObjectMeta(modified, &existing.ObjectMeta, required.ObjectMeta)
12+
13+
if existing.Spec.Selector == nil {
14+
*modified = true
15+
existing.Spec.Selector = required.Spec.Selector
16+
}
17+
if !equality.Semantic.DeepEqual(existing.Spec.Selector, required.Spec.Selector) {
18+
*modified = true
19+
existing.Spec.Selector = required.Spec.Selector
20+
}
21+
22+
ensurePodTemplateSpec(modified, &existing.Spec.Template, required.Spec.Template)
23+
}

0 commit comments

Comments
 (0)