-
Notifications
You must be signed in to change notification settings - Fork 231
fix feature gate #293
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix feature gate #293
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| apiVersion: apiextensions.k8s.io/v1beta1 | ||
| kind: CustomResourceDefinition | ||
| metadata: | ||
| name: featuregates.config.openshift.io | ||
| spec: | ||
| group: config.openshift.io | ||
| version: v1 | ||
| scope: Cluster | ||
| names: | ||
| kind: FeatureGate | ||
| singular: featuregate | ||
| plural: featuregates | ||
| listKind: FeatureGateList | ||
| versions: | ||
| - name: v1 | ||
| served: true | ||
| storage: true | ||
| validation: | ||
| openAPIV3Schema: | ||
| properties: | ||
| apiVersion: | ||
| description: 'APIVersion defines the versioned schema of this representation | ||
| of an object. Servers should convert recognized schemas to the latest | ||
| internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' | ||
| type: string | ||
| kind: | ||
| description: 'Kind is a string value representing the REST resource this | ||
| object represents. Servers may infer this from the endpoint the client | ||
| submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' | ||
| type: string | ||
| metadata: | ||
| description: Standard object's metadata. | ||
| type: object | ||
| spec: | ||
| description: spec holds user settable values for configuration | ||
| properties: | ||
| featureSet: | ||
| description: featureSet changes the list of features in the cluster. The | ||
| default is empty. Be very careful adjusting this setting. Turning | ||
| on or off features may cause irreversible changes in your cluster | ||
| which cannot be undone. | ||
| type: string | ||
| type: object | ||
| status: | ||
| description: status holds observed values from the cluster. They may not | ||
| be overridden. | ||
| type: object | ||
| required: | ||
| - spec | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -50,6 +50,16 @@ rules: | |
| verbs: | ||
| - get | ||
|
|
||
| - apiGroups: | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Addressed in #295 |
||
| - config.openshift.io | ||
| resources: | ||
| - featuregates | ||
| - featuregates/status | ||
| verbs: | ||
| - get | ||
| - list | ||
| - watch | ||
|
|
||
| - apiGroups: | ||
| - metalkube.org | ||
| resources: | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -181,21 +181,34 @@ func deploymentHasContainer(d *appsv1.Deployment, containerName string) bool { | |
| return false | ||
| } | ||
|
|
||
| func TestOperatorSyncClusterAPIControllerHealthCheckControllerNotDeployed(t *testing.T) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I put the tests under two separete functions so it's obvious which case is tested. Though, if you feel it's better this way, I am fine with that.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. table driven tests is the recommended approach i guess, https://github.com/golang/go/wiki/TableDrivenTests
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I find that it depends. Quite often table driven tests end up adding complexity and sometimes I find it easier to do: func TestFooDoesX
func TestFooErrorsWithBar
func TestFooSucceedsWithKnownInputs |
||
| fg := &v1.FeatureGate{ | ||
| ObjectMeta: metav1.ObjectMeta{ | ||
| Name: MachineAPIFeatureGateName, | ||
| func TestOperatorSyncClusterAPIControllerHealthCheckController(t *testing.T) { | ||
| tests := []struct { | ||
| featureGate *v1.FeatureGate | ||
| expectedMachineHealthCheckController bool | ||
| }{{ | ||
| featureGate: &v1.FeatureGate{ | ||
| ObjectMeta: metav1.ObjectMeta{ | ||
| Name: MachineAPIFeatureGateName, | ||
| }, | ||
| Spec: v1.FeatureGateSpec{ | ||
| FeatureSet: configv1.Default, | ||
| }, | ||
| }, | ||
| Spec: v1.FeatureGateSpec{ | ||
| FeatureSet: configv1.Default, | ||
| expectedMachineHealthCheckController: false, | ||
| }, { | ||
| featureGate: &v1.FeatureGate{}, | ||
| expectedMachineHealthCheckController: false, | ||
| }, { | ||
| featureGate: &v1.FeatureGate{ | ||
| ObjectMeta: metav1.ObjectMeta{ | ||
| Name: MachineAPIFeatureGateName, | ||
| }, | ||
| Spec: v1.FeatureGateSpec{ | ||
| FeatureSet: configv1.TechPreviewNoUpgrade, | ||
| }, | ||
| }, | ||
| } | ||
|
|
||
| kubeclientSet := fakekube.NewSimpleClientset() | ||
| op, err := initOperator(fg, kubeclientSet) | ||
| if err != nil { | ||
| t.Errorf("Unable to init operator: %v", err) | ||
| } | ||
| expectedMachineHealthCheckController: true, | ||
| }} | ||
|
|
||
| oc := OperatorConfig{ | ||
| TargetNamespace: targetNamespace, | ||
|
|
@@ -206,59 +219,24 @@ func TestOperatorSyncClusterAPIControllerHealthCheckControllerNotDeployed(t *tes | |
| }, | ||
| } | ||
|
|
||
| if err := op.syncClusterAPIController(oc); err != nil { | ||
| t.Errorf("Failed to sync machine API controller: %v", err) | ||
| } | ||
|
|
||
| d, err := kubeclientSet.AppsV1().Deployments(targetNamespace).Get(deploymentName, metav1.GetOptions{}) | ||
| if err != nil { | ||
| t.Errorf("Failed to get %q deployment: %v", deploymentName, err) | ||
| } | ||
|
|
||
| if deploymentHasContainer(d, hcControllerName) { | ||
| t.Errorf("Did not expect to find %q container", hcControllerName) | ||
| } else { | ||
| t.Logf("%q container not found as expected", hcControllerName) | ||
| } | ||
| } | ||
|
|
||
| func TestOperatorSyncClusterAPIControllerHealthCheckControllerDeployed(t *testing.T) { | ||
| fg := &v1.FeatureGate{ | ||
| ObjectMeta: metav1.ObjectMeta{ | ||
| Name: MachineAPIFeatureGateName, | ||
| }, | ||
| Spec: v1.FeatureGateSpec{ | ||
| FeatureSet: configv1.TechPreviewNoUpgrade, | ||
| }, | ||
| } | ||
|
|
||
| kubeclientSet := fakekube.NewSimpleClientset() | ||
| op, err := initOperator(fg, kubeclientSet) | ||
| if err != nil { | ||
| t.Errorf("Unable to init operator: %v", err) | ||
| } | ||
|
|
||
| oc := OperatorConfig{ | ||
| TargetNamespace: targetNamespace, | ||
| Controllers: Controllers{ | ||
| Provider: "controllers-provider", | ||
| NodeLink: "controllers-nodelink", | ||
| MachineHealthCheck: "controllers-machinehealthcheck", | ||
| }, | ||
| } | ||
| for _, tc := range tests { | ||
| kubeclientSet := fakekube.NewSimpleClientset() | ||
| op, err := initOperator(tc.featureGate, kubeclientSet) | ||
| if err != nil { | ||
| t.Fatalf("Unable to init operator: %v", err) | ||
| } | ||
|
|
||
| if err := op.syncClusterAPIController(oc); err != nil { | ||
| t.Errorf("Failed to sync machine API controller: %v", err) | ||
| } | ||
| if err := op.syncClusterAPIController(oc); err != nil { | ||
| t.Errorf("Failed to sync machine API controller: %v", err) | ||
| } | ||
|
|
||
| d, err := op.deployLister.Deployments(targetNamespace).Get(deploymentName) | ||
| if err != nil { | ||
| t.Errorf("Failed to get %q deployment: %v", deploymentName, err) | ||
| } | ||
| d, err := op.deployLister.Deployments(targetNamespace).Get(deploymentName) | ||
| if err != nil { | ||
| t.Errorf("Failed to get %q deployment: %v", deploymentName, err) | ||
| } | ||
|
|
||
| if deploymentHasContainer(d, hcControllerName) { | ||
| t.Logf("%q container found as expected", hcControllerName) | ||
| } else { | ||
| t.Errorf("Failed to find find %q container", hcControllerName) | ||
| if deploymentHasContainer(d, hcControllerName) != tc.expectedMachineHealthCheckController { | ||
| t.Errorf("Expected deploymentHasContainer for %q container to be %t", hcControllerName, tc.expectedMachineHealthCheckController) | ||
| } | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/value, and/value and
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I copy-pasted the CRD, cant' fix that.