Skip to content
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

Create basic Reconcile methods for WatcherAPI #13

Conversation

cescgina
Copy link
Contributor

@cescgina cescgina commented Nov 26, 2024

This patch is basic recond methods to the watcherapi
controller, as well as some initial input validation.

The change adds the required CR spec and status, and creates the initial
structure for initialization and deletion. In addition it some some
input validation by accessing the osp secret and the database that
should be created by the watcher controller.

Finally, it is also adding some initial structure test for functional envtest
testing in WatcherAPI.

Related: OSPRH-11483

Copy link
Contributor

@amoralej amoralej left a comment

Choose a reason for hiding this comment

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

I think it would be good to add kuttl tests for basic WatcherAPI creation in a second commit in the same PR, even if it's just checking that the CR is properly created and conditions managed.

controllers/watcherapi_controller.go Outdated Show resolved Hide resolved
controllers/watcherapi_controller.go Outdated Show resolved Hide resolved
controllers/watcherapi_controller.go Outdated Show resolved Hide resolved
controllers/watcherapi_controller.go Show resolved Hide resolved
tests/functional/watcherapi_controller_test.go Outdated Show resolved Hide resolved
@cescgina cescgina force-pushed the watcherapi_controller branch from d886297 to a729c7f Compare November 26, 2024 15:07
@cescgina
Copy link
Contributor Author

thanks for the review @amoralej that was very helpful. I think I addressed all of your comments but the kuttl tests, I'll add those soon

@cescgina cescgina force-pushed the watcherapi_controller branch from a729c7f to d4a7511 Compare November 27, 2024 08:32
@cescgina cescgina force-pushed the watcherapi_controller branch 2 times, most recently from 0fe6435 to 7436585 Compare November 27, 2024 13:55
@cescgina cescgina force-pushed the watcherapi_controller branch 4 times, most recently from 4f85a57 to 634bfe8 Compare November 29, 2024 12:46
api/v1beta1/watcherapi_types.go Outdated Show resolved Hide resolved
tests/functional/sample_test.go Outdated Show resolved Hide resolved
@cescgina cescgina force-pushed the watcherapi_controller branch 2 times, most recently from e3e79da to 710986b Compare November 29, 2024 14:43
api/v1beta1/common_types.go Outdated Show resolved Hide resolved
@cescgina cescgina force-pushed the watcherapi_controller branch 3 times, most recently from 5e1c48c to 87371f7 Compare December 5, 2024 10:59
@SeanMooney SeanMooney self-requested a review December 6, 2024 14:19
@SeanMooney SeanMooney dismissed their stale review December 6, 2024 14:19

discussed this seperatly

Copy link

@marios marios left a comment

Choose a reason for hiding this comment

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

would be good to get some overview in the coming team calls to allow more folks to follow along beyond the core group creating the operators

@amoralej so initially I think mkopec was going to help but it seems it is now you and Joan. Is there scope for me to pickup something here or is everything already in progress

@raukadah
Copy link
Contributor

raukadah commented Dec 9, 2024

/lgtm

Thank you @cescgina for adding extensive test coverage, It looks good to go!.

@amoralej
Copy link
Contributor

@amoralej so initially I think mkopec was going to help but it seems it is now you and Joan. Is there scope for me to pickup something here or is everything already in progress

@raukadah is also working on operator. WRT scope, let's discuss in team calls, I'm sure there will be something.

@amoralej
Copy link
Contributor

lgtm too but I'm not sure if Sean wanted to review it after last changes before merge.

@cescgina cescgina force-pushed the watcherapi_controller branch from 87371f7 to d75f613 Compare December 10, 2024 17:19
@openshift-ci openshift-ci bot removed the lgtm label Dec 10, 2024
Copy link
Collaborator

@SeanMooney SeanMooney left a comment

Choose a reason for hiding this comment

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

i dont nessisarly see anythign preventing this form proceeding

but i do have some comment inline regarding possible tech debth

}, timeout, interval).Should(ContainElement("openstack.org/watcherapi"))
})
})
When("the secret is created with all the expected fields", func() {
Copy link
Collaborator

Choose a reason for hiding this comment

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

if we are adding the input ready condition we should also be testing the negitve case.

currently you are only testing the positive case.

we should be testing creating a cr where the secret does not exist and assert that we get the approate input-ready false condition with a suitable error

that will pass the defaulting and validation web hook and need to be checked in the reconcile loop.

the same is true for the database instance or any other CR that is passed by name.

// WatcherAPISpec defines the desired state of WatcherAPI
type WatcherAPISpec struct {
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
// Important: Run "make" to regenerate code after modifying this file

// Foo is an example field of WatcherAPI. Edit watcherapi_types.go to remove/update
Foo string `json:"foo,omitempty"`
WatcherCommon `json:",inline"`
Copy link
Collaborator

Choose a reason for hiding this comment

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

so the openstack version is now used to set the conteinr to use.
since we do not have integration with that until we integrate in the
meta operator we need to have the contianr URL here with 3 levels of precedence

the lowest level is a default in code to the quay.io container
the next level of precedence will be an environment variable set in the bundle and the final level of percendce is the container URL.

when we integrate with the OpenStack version CRD the contienr URL in the CRD will be removed and we will use the OpenStack version as the highest level of precedence.

I'm not sure is we want to defer adding that to when we actually start creating the containers.

we probably can do that.
the other option is to just not add the URL at the CRD level and instead just have the first 2 levels of precedence

the bundle level ENV var and the hard coded quay.io default.

i think I'm leaning in that direction to avoid the CRD churn
what do others think?

Copy link

Choose a reason for hiding this comment

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

so, first of all, I believe you are commenting on the lack of

ContainerImage string `json:"containerImage"` 

in this proposal right? i.e. the fact that we don't carry it here (because this is now) set by OpenStackVersion)
I think your proposal about avoiding CRD churn is reasonable, but not sure if it would be 'unexpected' for anyone that would go looking for the containerImage on the crd (though as you said, eventually we'd want to remove that one too?)

Copy link
Contributor

Choose a reason for hiding this comment

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

I'd vote for having the three proposed levels, including the URL in the CRD. I may be missing something but IIUC, in a particular version of operator we may want to deploy different container URLs (for CI testing, or even out of it and having the URL in the watcher CRDs is the easiest way. Also, I think that's what others operators do?

In any case, I'd defer setting the container image parameter until we actually use it. We can discuss it there.

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 purposely left this parameter option out until it could be used (when we implement the deployment) in hopes of having PRs as small as possible. @amoralej has a good point about CI, we might want to use a different container image than the one in the bundle

Copy link
Collaborator

Choose a reason for hiding this comment

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

so some context

all the lower level crd used to have a required

ContainerImage string json:"containerImage"

filed that was set via the upper layers

but when we created the OpenStack version CRD we moved the URL form the individual CRDs to that common one.

since we don't have that integration for watcher we have 2 choices.

either we only implement the other two levels of precedence

hardcoded fallback to quey.io:latest when an environment variable is not set (vai the bundle)

or we can temporary add ContainerImage string json:"containerImage"

I'm leang toward defering this until we add support for the container (stateful set) creation

we can choose if we want to only support the first 2 levels fo precendce and defer the configibale URL until we have integration with the OpenStack Version CRD
or we can add ContainerImage string json:"containerImage" as an interim solution.

// Important: Run "make" to regenerate code after modifying this file

// WatcherCommon defines a spec based reusable for all the CRDs
type WatcherCommon struct {
// +kubebuilder:validation:Optional
// +kubebuilder:default=osp-secret
Copy link
Collaborator

Choose a reason for hiding this comment

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

so we do have an issue here.

the secreate field can have a default at the top level

however at the watcherApi level it should be a required filed without a default.

the watcher controller should be creating new secrets for the watcherAPI controller to consume. initially it can just pass the fully secret but we cant share the same definition of the secret field between the top level CRD and the rest.

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 think we should leave this to fix in a follow-up. I was looking at barbican-operator and they seem to use the same approach taken here, the BarbicanAPISpec https://github.com/openstack-k8s-operators/barbican-operator/blob/eaecb1b3e25ad17676b1b10f9c4a3d853effb21a/api/v1beta1/barbicanapi_types.go#L62 contains a BarbicanTemplate which defines the secret shared by all components. What is the problem with this approach?

Copy link
Contributor

Choose a reason for hiding this comment

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

good point.

Copy link
Collaborator

Choose a reason for hiding this comment

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

its basicaly insecure, the watcher operator shoudl not have access to the barbican secrets :)

openstack-k8s-operators/nova-operator#419
which as part fo https://issues.redhat.com/browse/OSPRH-98 and https://issues.redhat.com/browse/OSPRH-200

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok, that makes a lot of sense, thanks!

// If we're not deleting this and the service object doesn't have our finalizer, add it.
if instance.DeletionTimestamp.IsZero() && controllerutil.AddFinalizer(instance, helper.GetFinalizer()) || isNewInstance {
return ctrl.Result{}, nil
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

i was going to say this feels like a bug but now
its correct, there is a very explicit reason we have a finaliser on our selves

https://github.com/openstack-k8s-operators/nova-operator/blob/main/controllers/novaapi_controller.go#L160-L163

when the watcherAPI controller reconsoles a CR and create other CRs like stateful sets and configmaps for that API instance we add a finalser to those.

resource or to the keystone resouses as is the case in the nova example.

we place a finalise on the CR were are reconciling to have an opportunity to clean up any resources during delete without the CR deletion completing until we are done.

Copy link

Choose a reason for hiding this comment

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

thanks, your comment prompted me to go read about these https://kubernetes.io/docs/concepts/overview/working-with-objects/finalizers/

Copy link
Collaborator

Choose a reason for hiding this comment

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

so the assert for step one assert that a watcher kind is created

as well ad the db and osp secret.

https://github.com/openstack-k8s-operators/watcher-operator/blob/main/tests/kuttl/test-suites/default/test/01-assert.yaml

the default watcher kind should deploy a default watcher-api cr too.

although i assume that is not implemented yet which is why you are not asserting that?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

exactly, I'm testing now the current behaviour (need to deploy WatcherAPI explicitely) and will change the tests once the Watcher controller creates the WatcherAPI

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes. So far, we are testing independently. Once we integrate WatcherApi (and the rest) into Watcher, we will also integrate the asserts for 2nd level CRDs into Watcher creation

Copy link
Collaborator

Choose a reason for hiding this comment

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

once we can create the watcherAPI via the watcher cer we should refactor this to do that.

for now this is fine.

databaseInstance: openstack
passwordSelectors:
service: WatcherPassword
secret: osp-secret
Copy link
Collaborator

Choose a reason for hiding this comment

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

this is testing the defaulting behavior.
+1

metadata:
finalizers:
- openstack.org/watcherapi
name: watcherapi-kuttl
Copy link
Collaborator

Choose a reason for hiding this comment

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

this is testign the self finaliser behvior.

if we replace this with creating the watcher API by using the top-level watcher cr we will also need to add the watcher controller finaliser here in the future.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

thanks, fixed

Copy link
Contributor

Choose a reason for hiding this comment

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

That was my fault in a previous PS. Although, we may fix it in a specific commit in this PR to have proper CI coverage on it.

@cescgina cescgina force-pushed the watcherapi_controller branch from d75f613 to ead5fae Compare December 11, 2024 09:31
@cescgina
Copy link
Contributor Author

@SeanMooney I made a couple of small changes here (fix the kuttl file and getting the db before marking input ready), but will be addressing the rest in a follow-up PR

@cescgina cescgina force-pushed the watcherapi_controller branch 2 times, most recently from 016f04c to 94feadf Compare December 11, 2024 10:32
This patch is basic recond methods to the watcherapi
controller, as well as some initial input validation.

The change adds the required CR spec and status, and creates the initial
structure for initialization and deletion. In addition it some some
input validation by accessing the osp secret and the database that
should be created by the watcher controller.

Finally, it is also adding some initial structure test for functional envtest
testing in WatcherAPI.

Related: OSPRH-11483
@cescgina cescgina force-pushed the watcherapi_controller branch from 94feadf to 0ae9838 Compare December 11, 2024 11:51
db, err := mariadbv1.GetDatabaseByNameAndAccount(ctx, helper, watcher.DatabaseCRName, instance.Spec.DatabaseAccount, instance.Namespace)
if err != nil {
instance.Status.Conditions.Set(condition.FalseCondition(
condition.ServiceConfigReadyCondition,
Copy link
Collaborator

Choose a reason for hiding this comment

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

nit: this shoudl really be InputReadyCondition not ServiceConfigReadyCondition

Copy link
Contributor Author

Choose a reason for hiding this comment

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

indeed, I forgot to update this when I moved the code, I'll correct it on my follow-up PR, thanks!

Copy link
Collaborator

@SeanMooney SeanMooney left a comment

Choose a reason for hiding this comment

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

im ok with moving forward with this as is

@openshift-ci openshift-ci bot added the lgtm label Dec 11, 2024
@amoralej
Copy link
Contributor

/approve

Copy link

openshift-ci bot commented Dec 11, 2024

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: amoralej

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-merge-bot openshift-merge-bot bot merged commit ae12ade into openstack-k8s-operators:main Dec 11, 2024
6 checks passed
@cescgina cescgina deleted the watcherapi_controller branch December 11, 2024 13:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants