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

Adds Kafka Channel Provisioner Controllers #468

Merged
merged 32 commits into from
Nov 9, 2018

Conversation

neosab
Copy link
Contributor

@neosab neosab commented Sep 27, 2018

Related to #442

PR adds basic code for Kafka Channel Provisioner.

Note: This is based on my interpretation of the spec. Please correct me if I am wrong.

Proposed Changes

  • Controller for reconciling ClusterProvisioner
  • Controller for reconciling Channel
  • Provision/Deprovision topic for Channel

Limitations

  • Only reconciles and updates status for a single configured ClusterProvisioner
    • I am not sure how to deal with multiple ClusterProvisioner that target different kafka clusters. For now the controller updates status for a configured ClusterProvisioner that targets a single kafka cluster. I am open to suggestions.
  • Mostly assumes ClusterProvisioner but can be improved to be generic and handle Provisioner in the future.

Release Note

@knative-prow-robot knative-prow-robot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Sep 27, 2018
@knative-prow-robot knative-prow-robot added the size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files. label Sep 27, 2018
Copy link
Contributor

@grantr grantr 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 this is the first PR for a Channel implementation in the new model! Thanks @neosab, awesome work.

I haven't reviewed the whole thing because it's WIP, but I have a few comments that might be interesting to you. Feel free to ignore.

pkg/provisioners/kafka/main.go Outdated Show resolved Hide resolved
pkg/provisioners/kafka/controller/reconcile.go Outdated Show resolved Hide resolved
}

// Skip channel provisioners that we don't manage
if provisioner.Name != config.Name || provisioner.Namespace != config.Namespace {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this filtering should be done in the Watch call in the provider. That way the informer cache doesn't even store the other provisioners locally.

Unfortunately this feature doesn't exist in controller-runtime, though it doesn't seem too hard to add. We need a variant of source.Kind that allows filtering by field values. In the meantime we can prototype using source.Informer given a filtered informer.

This will be a common pattern in these controllers so IMO it makes sense to invest in making this easy.

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 for the pointer. I took a quick glance, I do see the generated NewFilteredClusterProvisionerInformer, I will give this a try soon.

@neosab
Copy link
Contributor Author

neosab commented Sep 28, 2018

@grantr @adamharwayne Thanks for your quick reviews! 👍 Sorry about the late response though.

@neosab
Copy link
Contributor Author

neosab commented Oct 8, 2018

Sorry about the delay with this PR. I was on vacation 🛫 last week and just getting back to this!

@neosab
Copy link
Contributor Author

neosab commented Oct 8, 2018

I removed the logic to fetch the provisioner configmap in the controller and instead read it from a mounted volume. This way the controller does not need the cluster-wide privilege to read all config maps.

@neosab neosab changed the title WIP: Adds Kafka Channel Provisioner Controllers Adds Kafka Channel Provisioner Controllers Oct 8, 2018
@knative-prow-robot knative-prow-robot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Oct 8, 2018
@neosab
Copy link
Contributor Author

neosab commented Oct 9, 2018

/assign grantr

Copy link
Contributor

@n3wscott n3wscott left a comment

Choose a reason for hiding this comment

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

Nice start. I would still call it WIP because you don't do any work on the channels yet.

@grantr and I have been talking about the ups and downs of using controller runtime vs meta controller and this PR is exactly what I was talking about with the boilerplate required to get controller runtime up and running. It is not super fun as the dev to implement all this and we think we have an idea to refactor some of this closer inline with how meta-controller does things while still using controller-runtime. You can see, #513, I did a lot of the same stuff (but I did not add tests yet :D)

config/provisioners/kafka/clusterprovisioner.yaml Outdated Show resolved Hide resolved
config/provisioners/kafka/clusterrole.yaml Outdated Show resolved Hide resolved
config/provisioners/kafka/controller.yaml Outdated Show resolved Hide resolved
config/provisioners/kafka/clusterrole.yaml Outdated Show resolved Hide resolved
config/provisioners/kafka/kafka-provisioner-config.yaml Outdated Show resolved Hide resolved
pkg/provisioners/kafka/controller/channel/reconcile.go Outdated Show resolved Hide resolved
pkg/provisioners/kafka/controller/channel/reconcile.go Outdated Show resolved Hide resolved

// Skip channel not managed by this provisioner
provisionerRef := channel.Spec.Provisioner.Ref
clusterProvisioner, err := r.getClusterProvisioner()
Copy link
Contributor

Choose a reason for hiding this comment

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

this is a cool idea! I wonder if the flexibility of setting the name of the provisioner should be a argument though, what does it mean for the controller to change which provisioner it is servicing while it is running?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The idea was to support multiple provisioners not just the one in the kafka.yaml. The configmap can be updated when new provisioners are added. You are right, it is not that useful with just one provisioner. I can remove this and make the name a const if there is a strong opinion.

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 removed the flexibility of the setting the provisioner name with the latest commit. I don't find a use case as of now. And this will be in line with the in-memory channel provisioner.

}

// Skip channel not managed by this provisioner
provisionerRef := channel.Spec.Provisioner.Ref
Copy link
Contributor

Choose a reason for hiding this comment

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

perhaps all of this validating the provisioner logic can be moved to a helper function called before the deepcopy has to happen.

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 see that #484 also has similar logic (so would most channel provisioners) and would like to move into a common util method once we have both PR's in.

pkg/provisioners/kafka/controller/channel/reconcile.go Outdated Show resolved Hide resolved
@neosab
Copy link
Contributor Author

neosab commented Oct 11, 2018

Nice start. I would still call it WIP because you don't do any work on the channels yet.

When I posted this couple of weeks back there was no reference implementation for cluster provisioners so I just wanted to test the waters by addressing the Task 1 in #442. If you wish I can implement kafka channel provisioning in this PR itself.

@grantr and I have been talking about the ups and downs of using controller runtime vs meta controller and this PR is exactly what I was talking about with the boilerplate required to get controller runtime up and running. It is not super fun as the dev to implement all this and we think we have an idea to refactor some of this closer inline with how meta-controller does things while still using controller-runtime. You can see, #513, I did a lot of the same stuff (but I did not add tests yet :D)

I agree it's a lot of boilerplate code (w/ tests) when implementing provisioners. Not too familiar with meta-controller impl, let me take a look at it to see what you intend to do.


type reconciler struct {
client client.Client
restConfig *rest.Config
Copy link
Contributor

Choose a reason for hiding this comment

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

This looks unused.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done

return nil
}

// Skip Channel as it is not targeting any provisioner
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the decision of whether or not to reconcile should happen earlier. For example, when delete does something, we might not remember that it is not checking whether this controller should be controlling this channel.

My preference is to check before calling reconcile(). At least checking everything but the status of the ClusterProvisioner itself.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Makes sense, I refactored this.

@neosab neosab changed the title Adds Kafka Channel Provisioner Controllers WIP: Adds Kafka Channel Provisioner Controllers Oct 15, 2018
@knative-prow-robot knative-prow-robot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Oct 15, 2018
@neosab neosab mentioned this pull request Nov 7, 2018
Copy link
Member

@evankanderson evankanderson left a comment

Choose a reason for hiding this comment

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

A few comments, but this looks like it's close to ready.

config/provisioners/kafka/README.md Show resolved Hide resolved
```
ko apply -f config/provisioners/kafka/kafka-provisioner.yaml
```
> Note: If you are using Strimzi, you need to update the `KAFKA_BOOTSTRAP_SERVERS` value in the `kafka-channel-controller-config` ConfigMap to `my-cluster-kafka-bootstrap.kafka.9092`.
Copy link
Member

Choose a reason for hiding this comment

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

Can this be done after the ko apply using kubectl edit?

Copy link
Member

Choose a reason for hiding this comment

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

correct - will update

kind: ClusterChannelProvisioner
name: kafka-channel
```
1. (Optional) Install [Kail](https://github.com/boz/kail) - Kubernetes tail
Copy link
Member

Choose a reason for hiding this comment

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

@Harwayne is working on allowing a default provisioner if not specified. It might be worth a commented item here to suggest being able to set this as default.

```
ko apply -f config/provisioners/kafka/kafka-provisioner.yaml
```
> Note: If you are using Strimzi, you need to update the `KAFKA_BOOTSTRAP_SERVERS` value in the `kafka-channel-controller-config` ConfigMap to `my-cluster-kafka-bootstrap.kafka.9092`.
Copy link
Member

Choose a reason for hiding this comment

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

For non-Strimzi Kafka, are there other parameters (servers and/or credentials) that need to be configured?

Copy link
Member

Choose a reason for hiding this comment

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

just the bootstrap server - in both cases: Strimzi and no strimzi

* ClusterChannelProvisioner Controller
* Channel Controller Config Map

The ClusterChannelProvisioner Controller and the Channel Controller are colocated in one Pod.
Copy link
Member

Choose a reason for hiding this comment

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

+1, I think this is a good colocation.

}

err := kafkaClusterAdmin.CreateTopic(topicName, &sarama.TopicDetail{
ReplicationFactor: 1,
Copy link
Member

Choose a reason for hiding this comment

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

Should this be another argument?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It could be but it wasn't in the previous ClusterBus implementation hence I didn't make it an argument. Maybe something that can be done later?

// If we didn't change anything then don't call updateStatus.
// This is important because the copy we loaded from the informer's
// cache may be stale and we don't want to overwrite a prior update
// to status with this stale state.
Copy link
Member

Choose a reason for hiding this comment

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

It looks like the when-to-update logic here is different than for Channel. Am I mis-reading?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

You are right. Actually, I added a util method to update provisioner status in #560. I missed to use it here. I fixed it.

Copy link
Contributor Author

@neosab neosab Nov 8, 2018

Choose a reason for hiding this comment

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

Actually, my bad, I do use the util method but in #573. But I also went ahead and changed it here.

pkg/provisioners/kafka/main.go Show resolved Hide resolved
@googlebot
Copy link

So there's good news and bad news.

👍 The good news is that everyone that needs to sign a CLA (the pull request submitter and all commit authors) have done so. Everything is all good there.

😕 The bad news is that it appears that one or more commits were authored or co-authored by someone other than the pull request submitter. We need to confirm that all authors are ok with their commits being contributed to this project. Please have them confirm that here in the pull request.

Note to project maintainer: This is a terminal state, meaning the cla/google commit status will not change from this state. It's up to you to confirm consent of all the commit author(s), set the cla label to yes (if enabled on your project), and then merge this pull request when appropriate.

@googlebot googlebot added cla: no Indicates the PR's author has not signed the CLA. and removed cla: yes Indicates the PR's author has signed the CLA. labels Nov 8, 2018
@knative-metrics-robot
Copy link

The following is the coverage report on pkg/.
Say /test pull-knative-eventing-go-coverage to re-run this coverage report

File Old Coverage New Coverage Delta
pkg/provisioners/kafka/controller/channel/provider.go Do not exist 0.0%
pkg/provisioners/kafka/controller/channel/reconcile.go Do not exist 84.2%
pkg/provisioners/kafka/controller/provider.go Do not exist 0.0%
pkg/provisioners/kafka/controller/reconcile.go Do not exist 86.7%
pkg/provisioners/kafka/main.go Do not exist 0.0%
pkg/provisioners/logging.go Do not exist 0.0%

@knative-metrics-robot
Copy link

The following is the coverage report on pkg/.
Say /test pull-knative-eventing-go-coverage to re-run this coverage report

File Old Coverage New Coverage Delta
pkg/provisioners/kafka/controller/channel/provider.go Do not exist 0.0%
pkg/provisioners/kafka/controller/channel/reconcile.go Do not exist 84.2%
pkg/provisioners/kafka/controller/provider.go Do not exist 0.0%
pkg/provisioners/kafka/controller/reconcile.go Do not exist 86.7%
pkg/provisioners/kafka/main.go Do not exist 0.0%
pkg/provisioners/logging.go Do not exist 0.0%

@matzew
Copy link
Member

matzew commented Nov 8, 2018

@evankanderson the CLA bot needs, again, some help.
not sure why he does not like two folks on one PR :-(

@vaikas
Copy link
Contributor

vaikas commented Nov 8, 2018

/lgtm

@knative-prow-robot knative-prow-robot added the lgtm Indicates that a PR is ready to be merged. label Nov 8, 2018
@vaikas
Copy link
Contributor

vaikas commented Nov 8, 2018

Please jump through the hoops and both add a comment stating that you are ok with these changes to appease the CLA manual approval process.

@matzew
Copy link
Member

matzew commented Nov 8, 2018

I am 💯 OK w/ the changes!

/lgtm

@neosab
Copy link
Contributor Author

neosab commented Nov 8, 2018

I am ok with the change too

@vaikas vaikas added cla: yes Indicates the PR's author has signed the CLA. and removed cla: no Indicates the PR's author has not signed the CLA. labels Nov 8, 2018
@googlebot
Copy link

A Googler has manually verified that the CLAs look good.

(Googler, please make sure the reason for overriding the CLA status is clearly documented in these comments.)

@vaikas
Copy link
Contributor

vaikas commented Nov 8, 2018

ok, I'm leaving for Evan to approve, flipped the CLA bit.

@matzew
Copy link
Member

matzew commented Nov 8, 2018

we have two PRs, depending on this. so we can - and will - address issues one way or the other 😹

Copy link
Member

@evankanderson evankanderson left a comment

Choose a reason for hiding this comment

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

/lgtm
/approve

)

type channelArgs struct {
NumPartitions int32 `json:"NumPartitions,omitempty"`
Copy link
Member

Choose a reason for hiding this comment

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

(FYI) You don't need to supply a name parameter here the name is the same as the public field name.

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 it in #573


if errors.IsNotFound(err) {
r.logger.Info("could not find channel", zap.Any("request", request))
return reconcile.Result{}, nil
Copy link
Member

Choose a reason for hiding this comment

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

I'm not sure why the dependent resources (e.g. topic in Kafka) would have been deleted when the apiserver resource was deleted. Wouldn't that be the job of this controller? (In particular, the code on line 122.)

(You can fix this in #573 if it is a bug)

err = r.reconcile(newChannel)
} else {
newChannel.Status.MarkNotProvisioned("NotProvisioned", "ClusterChannelProvisioner %s is not ready", clusterChannelProvisioner.Name)
err = fmt.Errorf("ClusterChannelProvisioner %s is not ready", clusterChannelProvisioner.Name)
Copy link
Member

Choose a reason for hiding this comment

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

Ah, I'd missed that err below was scoped to the if block. Thanks for changing the name.

@knative-prow-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: evankanderson, neosab

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

@knative-prow-robot knative-prow-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Nov 8, 2018
@knative-prow-robot knative-prow-robot merged commit 160c27c into knative:master Nov 9, 2018
@nak3 nak3 mentioned this pull request Mar 8, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. cla: yes Indicates the PR's author has signed the CLA. lgtm Indicates that a PR is ready to be merged. size/XXL Denotes a PR that changes 1000+ lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants