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 new Subscription in pkg/apis/eventing as per the new spec. #421

Merged
merged 15 commits into from
Sep 14, 2018

Conversation

vaikas
Copy link
Contributor

@vaikas vaikas commented Sep 8, 2018

Fixes #

Proposed Changes

Add a new version of Subscription CRD as per the new Spec.

**** To reduce code churn, tests are incomplete Please only look at the subscription_types for now****

Release Note

@vaikas vaikas added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Sep 8, 2018
@knative-prow-robot knative-prow-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Sep 8, 2018
@knative-prow-robot knative-prow-robot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Sep 8, 2018
@scothis
Copy link
Contributor

scothis commented Sep 8, 2018

👍 on the general direction.

One idea worth considering. Instead of using strings for these properties we could use ObjectReferences. The corresponding resolved values for Processor and To can be added to SubscriptionStatus, so that dispatchers still don't need to resolve in the data plane. A centralized subscription controller can take responsibility for synchronizing the resolutions. Webhook validation can reject invalid configurations.

Advantages:

  • higher level resources, like Flow, are easier to implement because they don't need to preform the resolution themselves
  • resolutions are automatically resynchronized over time. More important for non-controlled subscriptions
  • any component that needs to resolve these targets will need rbac get access to the target component. Centralizing the resolution also enables centralizing the privilege. Adding a new CRD means adding a single new Role/RoleBinding.
  • easy to add support for common resources that are unlikely to implement our targetable interface (like k8s core Service)
  • future: a ClusterChannel CRD was discussed as a structured way to pass events between namespaces. An ObjectReference makes it easier to support other types in the future. This should be very rare though.
  • future: access controls could be applied to the subscription

Disadvantages:

  • ObjectReferences are more complex (forces all creators to know the resource kind)
  • Subscription creators would be unable to create custom resolution strategies, unless we introduce a manual mode
  • there is a delay between when a target resource changes its domainInternal status and when the subscription is re-synced. The current Flow resource also suffers this delay, however, provisioners with foreknowledge are less able to trigger an immediate update.

// Processor is the processor service DNS name. Events
// from the From channel will be delivered here and replies are sent
// to To channel.
Processor string `json:"processor,omitempty"`
Copy link
Contributor

Choose a reason for hiding this comment

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

How about Call?

Copy link
Contributor

Choose a reason for hiding this comment

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

since kubernetes resource yaml describes the desired declarative state to be reconciled by a controller, I personally prefer to avoid using verbs that suggest the yaml is defining the imperative logic

Copy link
Contributor

Choose a reason for hiding this comment

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

calls ?

Copy link
Member

Choose a reason for hiding this comment

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

From conversation in Slack, I'd like to see names which provide the following:

  1. Clearly unambiguous about the sequence (from, processor, to seems ambiguous whether to or processor is last).
  2. Work cleanly for all three cases (from, processor, to), (from, processor), (from, to).

Mostly, we seem to think from is clear. Here are some options for the other two:

  • processor: call, invoke, through, subscriber, apply
  • to: finally (collides with exception handling), then (may not be strong enough), result, out, continue (may collide with loops and not imply last item).

Copy link
Contributor

@markfisher markfisher Sep 11, 2018

Choose a reason for hiding this comment

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

Here's an option where there's always a to/from pair at top-level. If both processor and channel are included in the to, the processor will always be invoked prior to sending its result to the channel.

from: x
to:
  processor: foo
  channel: y
from: x
to:
  processor: foo
from: x
to:
  channel: y

The downside is that it adds a level of nesting in the config, but that might be worth the tradeoff since these resources would typically be generated from higher level resources and/or CLIs.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What's the upside of adding this extra level of nesting, since to: block will still have the same behaviour as if we kept it the top level?

// Target service DNS name for replies returned by the subscriber.
ReplyTo string `json:"replyTo,omitempty"`
// To is the name of the channel to send transformed events
To string `json:"to,omitempty"`
Copy link
Contributor

Choose a reason for hiding this comment

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

How about Continue ?

@vaikas
Copy link
Contributor Author

vaikas commented Sep 10, 2018

@scothis making them references is appealing for sure. I was left wondering how to actually then configure the underlying 'real channel' to wire things together. It's one thing to resolve the reference, but then once the wiring happens, how do you see that happening. Seems like once you resolve the referenced object, you'd need to modify that object to actually create the subscription. So, if a BetterChannel CRD was created and subscription resolved that it was the underlying channel, how would the SubscriptionController then know how to modify the BetterChannel resource?

@scothis
Copy link
Contributor

scothis commented Sep 10, 2018

@vaikas-google It may help to talk about the processor and to fields separately from the from field for this discussion. The processor and to fields are resolving from an ObjectRef to a domain name via the Targetable interface.

The from field is a bit more open ended since the Provisioner for the Channel is also the Provisioner for Subscription for that Channel. As an initial pass, I think we should force the ObjectRef Kind to channels.eventing.knativedev/v1alpha1 rejecting any other values. The Channel Provisioner is responsible for selecting which Subscriptions are for a Channel it provisioned and then provision the Subscription. For the stub bus this is by indexing the Subscription for the Channel in the dispatcher. For the Pub/Sub bus this is by creating a Subscription for the Topic in Cloud Pub/Sub and then receiving messages for that Subscription.

I don't think the SubscriptionController would ever modify the Channel resource, it would only be responsible for updating the SubcriptionStatus for the values it resolves. The Channel Provisioner is responsible for provisioning/reconciling the Subscription with the resolved properties.

@vaikas
Copy link
Contributor Author

vaikas commented Sep 10, 2018

But the SubscriptionController needs to somehow communicate to the resolved channel that there's a new subscription?
I think it's odd that the ChannelController would be looking at a spec for an object it does not control.
I'd expect something like this (only From considered here):

  1. Subscription is created: From is resolved to FromChannel
  2. SubscriptionController modifies FromChannel.Spec to add this new subscription
  3. ChannelController sees the FromChannel.Spec and does the thing it needs to do

Ideally (I think) Channel would have a subresource that the SubscriptionController would twiddle, but in lieue of that, we could make it so that the "contract" (given that we do refs, and we need to have some commonality there in the future) would be that a target of a ChannelRef resolve to an object that in it's spec has a Subscriptions List (or something like that), and the SubscriptionController then can just Read Modify Write the list by adding (or removing on deletion) the new (or deleted) subscriber.

And yes, rejecting anything other than channels.eventing.knative.dev/v1alpha1 for now is fine, just thinking how this could look like for superduperchannel that comes next and what that contract may look like.

Lastly, as per the document discussed, this will move to:
eventing.knative.dev/v1alpha1
I just made this WIP here to show only the minimal set of changes, once we agree on things, I'll move this to pkg/apis/eventing/v1alpha1/subscription_types

@scothis
Copy link
Contributor

scothis commented Sep 10, 2018

@vaikas-google Ah, I understand your proposal for Subscriptions now. The doc so far has been quiet about how Channel Provisioners discover Subscriptions.

Setting the resolved Subscriptions on the Channel resource should work so long as the subscriptions are fairly stable. It will create more work for the channel provisioner to tease apart which subscription was mutated/added/removed when the channel resource is updated. With the benefit of watching a single resource instead of two. I'll need to think about this a bit more.

Lastly, as per the document discussed, this will move to:
eventing.knative.dev/v1alpha1

Yes, I was merging the kind and apiVersion in my head. channels.eventing.knative.dev (future) vs channels.channels.knative.dev (today)

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.

This only renames the fields, and does not update our samples or existing code.

My understanding is that this will be moved to the eventing.knative.dev package before submit, so as not to break current users.

name: "missing to",
c: &SubscriptionSpec{
From: "fromChannel",
To: "toChannel",
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 "processor", or should "to" be left off? (This matches the next test case right now.)

// Processor is the processor service DNS name. Events
// from the From channel will be delivered here and replies are sent
// to To channel.
Processor string `json:"processor,omitempty"`
Copy link
Member

Choose a reason for hiding this comment

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

From conversation in Slack, I'd like to see names which provide the following:

  1. Clearly unambiguous about the sequence (from, processor, to seems ambiguous whether to or processor is last).
  2. Work cleanly for all three cases (from, processor, to), (from, processor), (from, to).

Mostly, we seem to think from is clear. Here are some options for the other two:

  • processor: call, invoke, through, subscriber, apply
  • to: finally (collides with exception handling), then (may not be strong enough), result, out, continue (may collide with loops and not imply last item).

@vaikas
Copy link
Contributor Author

vaikas commented Sep 10, 2018

to->follower?

Copy link
Contributor

@scothis scothis left a comment

Choose a reason for hiding this comment

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

The validation logic from the previous commit will need to be updated now that these are ObjectRefs instead of Strings

// to these events for further processing.
//
// For example, this could be a reference to a Route resource
// or a Configuration resource.
Copy link
Contributor

Choose a reason for hiding this comment

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

s/Configuration/Service/

Configuration is not targetable.

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

// - Kind
// - APIVersion
// - Name
From *corev1.ObjectReference `json:"from,omitempty"`

// Processor is the processor service DNS name. Events
Copy link
Contributor

Choose a reason for hiding this comment

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

no longer a DNS 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.

done

@vaikas
Copy link
Contributor Author

vaikas commented Sep 11, 2018

@scothis yes, validation needs to change and things need to move to right location. Just trying to minimize churn and only focus on the API definition and semantics for now. Once we agree on that, I'll move this to eventing/pkg/apis/eventing/v1alpha1/ and do all the remaining work there.

return fe
}

if equality.Semantic.DeepEqual(ss.Processor, &corev1.ObjectReference{}) && equality.Semantic.DeepEqual(ss.To, &corev1.ObjectReference{}) {
Copy link
Contributor

Choose a reason for hiding this comment

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

could also cause issues if one is nil and the other is empty

@@ -49,7 +57,7 @@ func (current *Subscription) CheckImmutableFields(og apis.Immutable) *apis.Field
return nil
}

ignoreArguments := cmpopts.IgnoreFields(SubscriptionSpec{}, "Subscriber", "Arguments")
ignoreArguments := cmpopts.IgnoreFields(SubscriptionSpec{}, "Processor", "Arguments")
Copy link
Contributor

Choose a reason for hiding this comment

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

To should also allow mutation, only From should be immutable. It was an oversight that ReplyTo is immutable right now.

ProcessorName = "processor"
)

func getValidFromRef() *corev1.ObjectReference {
Copy link
Contributor

Choose a reason for hiding this comment

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

should also test invalid From and To ObjectReferences:

  • non channel Kind and APIVersion
  • fields other than Kind, APIVersion and 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.

Working on it... Just want to resolve the names...

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.

(I'm not commenting on the naming beyond the 🚲 🏠 I did previously, but I'm not a big fan of the current from/processor/to names.)

// You can specify only the following fields of the ObjectReference:
// - Kind
// - APIVersion
// - Name
Copy link
Member

Choose a reason for hiding this comment

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

What about UID?

I'm assuming that Namespace is specifically excluded?

Copy link
Contributor

Choose a reason for hiding this comment

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

What about UID?

Is there a good way to lookup a resource by UID?

I'm assuming that Namespace is specifically excluded?

Keeping subscriptions within a single namespace is a good idea until we understand fully understand the tenancy consequences of allowing them to cross namespaces.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Let's start with names (no UIDs), and a single namespace until we have more understanding on what cases this does not handel?

fe.Details = "the Subscription must reference a Channel"
if ss.From == nil || equality.Semantic.DeepEqual(ss.From, &corev1.ObjectReference{}) {
fe := apis.ErrMissingField("from")
fe.Details = "the Subscription must reference a from channel"
Copy link
Member

Choose a reason for hiding this comment

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

This should probably also ensure that the ss.From.Name and ss.From.Kind (at least) are non-empty.

(In general, it feels like there should be a function to validate an ObjectReference in the context of Subscription.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

le sigh :) Yes, there's bunch of more work to be done here :) Thanks for the comments, I just don't want to keep churning these things until we settle on the shape and the names. I'm going to add validation for now that it can only be a Channel for now as discussed in Slack yesterday, and later on we can relax.

// - APIVersion
// - Name
// +optional
Processor *corev1.ObjectReference `json:"processor,omitempty"`
Copy link
Member

Choose a reason for hiding this comment

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

Is the idea that you would need to create a k8s Service to be able to call something which is not on the k8s cluster (e.g. a VM)? Previously we had the idea that a targetable was either a DNS name or an ObjectReference.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, so, this is a bit interesting in a sense, that I'd expect that if you're hitting something that's outside the cluster, just a DNS entry is probably not going to cut it. I'd expect things like credentials to be involved on that, so as not to just be wide open to everything. I could hoist this into a higher level object to give us some future proofing for now.

Copy link
Contributor

Choose a reason for hiding this comment

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

Another option is to allow the reference for a targetable to also include a k8s Service. It doesn't implement the targetable interface, but we know how to shoehorn it into what we need.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@scothis when we talked about this wrt Targetable, thinking was that a service was not enough, that it would actually have to be a URI. So, I'm hoisting that up.

// - APIVersion
// - Name
// +optional
To *corev1.ObjectReference `json:"to,omitempty"`
Copy link
Member

Choose a reason for hiding this comment

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

I can't comment on other parts of this CRD, so leaving the comment here:

  1. Can we remove Arguments until we need them, and prefer to have Subscription-specific arguments rather than Channel-specific Arguments? (See also s/[]Arguments/runtime.RawExtension/.)
  2. What conditions do we need? I think we probably want at least 2 Types: Ready and ReferencesResolved, where Ready is the canonical "happy state" type.
    • Do we need LastUpdateTime and LastTransitionTime? I'd be inclined to leave off that bookkeeping until we have evidence we need it.

Copy link
Contributor

Choose a reason for hiding this comment

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

Can we remove Arguments until we need them

Yes, we haven't come across a use case for argument/params with the current buses.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

removed.

@scothis
Copy link
Contributor

scothis commented Sep 12, 2018

A subscription triggers sending events from a channel to a subscriber; the subscriber's replies (if any) are forwarded to a channel for subsequent processing.

spec:
  channel: <channel-ref>
  subscriber: <targetable-ref>
  replyStrategy:
    channel: <channel-ref>

The key elements of the SubscriptionSpec are the channel being subscribed to and the subscriber being targeted. Handling replies from the subscriber are managed by a strategy for which we have an two implementations:

  • forwarding to a hardwired channel
  • "/dev/null" where the reply is logged and tossed

As discussed in Slack we want the ability to define other strategies for mapping or dynamic resolution.

@vaikas
Copy link
Contributor Author

vaikas commented Sep 12, 2018

@scothis this was the idea that you'd have Subscription coordinate with the Function what the return headers are and then dispatchers will dynamically route to different channels based on that?

@markfisher
Copy link
Contributor

markfisher commented Sep 13, 2018

I'd like to make one last push for preferring nouns since the resource is describing desired state in a declarative way, not imperative logic. I had proposed "channel"->"subscriber" as the essence of what a Subscription describes, and the "replyStrategy" would describe how to handle a reply from the subscriber.

That said, if we are going to stick with "call" then I would prefer consistency for what is currently "result" (i.e. if one is a verb, they both should be). The latter could be "forward" or "reply" (I would probably choose "reply" since that is commonly used for describing this role in messaging systems - e.g. via "replyTo" headers - even if it's not immediately replying back to an original caller but instead continuing to flow through a sequence of subsequent channels/subscribers).

Also, if we are going to use a preposition, then "from" is actually not very clear, given that one subscribes to a channel (this was even more confusing when we also had "to" for the other direction).

@scothis
Copy link
Contributor

scothis commented Sep 13, 2018

This gives us an out for Channel-like things to be switched in-place of channels.

I want to be clear that I do not think we should support "channel-like things". The thinking was that we may have other kinds of channels in the future. The only concrete thought I have in this direction is a ClusterChannel to enable eventing between namespaces in a clearly defined way. Same behavior, but a separate CRD because that's how k8s works.

@grantr
Copy link
Contributor

grantr commented Sep 13, 2018

The only concrete thought I have in this direction is a ClusterChannel to enable eventing between namespaces in a clearly defined way. Same behavior, but a separate CRD because that's how k8s works.

I don't think @n3wscott is proposing that "channel-like things" don't implement the Channel contract; rather ClusterChannel is a perfect example of a "channel-like thing". I think we are in agreement. :)

"github.com/knative/pkg/webhook"
"k8s.io/api/core/v1"
corev1 "k8s.io/api/core/v1"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Copy link
Contributor

Choose a reason for hiding this comment

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

Non-blocking nit: can this be renamed to metav1 for consistency?

@knative-prow-robot knative-prow-robot removed the lgtm Indicates that a PR is ready to be merged. label Sep 13, 2018
@vaikas vaikas removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Sep 13, 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 Sep 13, 2018
@vaikas
Copy link
Contributor Author

vaikas commented Sep 13, 2018

Ok, I think this is ready for a review. My most sincere apologies if I missed some comments in the flurry of discussions, here, doc and slack.

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.

/approve

The naming seems good enough to me, just some minor nits. Glad to see that the only file with any real logic has 100% test coverage. Thank you!

}

func (ss *SubscriptionSpec) SetDefaults() {
// TODO anything?
Copy link
Member

Choose a reason for hiding this comment

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

Do we need this file if we don't default anything?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For consistency with other files, I'm leaving this in for now. If you feel strongly, I can remove.

}

// Callable specifies the reference to an object that's expected to
// provide the resolved target of the action. Currently we inspect
Copy link
Member

Choose a reason for hiding this comment

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

Paragraph before "Currently"

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

// This ensures that we can support external targets and for ease of use
// we also allow for an URI to be specified.
// There of course is also a requirement for the resolved Callable to
// behave properly at the data plane level.
Copy link
Member

Choose a reason for hiding this comment

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

Do we want to document what this means?

I think we mean "Receive an event payload, and respond with one of: success and an optional response event, or failure. Delivery failures may be retries by the from Channel."

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. I felt like we should have a pointer to a spec and have a link to it here. We don't, so added what you proposed.

// we can utilize a dynamic client instead of having to understand all
// kinds of different types of objects. As long as they adhere to this
// particular contract, they can be used as a Target.
// This ensures that we can support external targets and for ease of use
Copy link
Member

Choose a reason for hiding this comment

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

Paragraph (blank line) here?

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

type SubscriptionConditionType string

const (
// SubscriptionReady is when the From,Channel and Result have been reconciled successfully.
Copy link
Member

Choose a reason for hiding this comment

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

"From,Channel and Result"?

"From, Call, and Result"?

Call seems to have both noun and verb definitions in computing (per Google), so I'm okay with these as declarative.

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.

Copy link
Contributor

@markfisher markfisher Sep 14, 2018

Choose a reason for hiding this comment

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

@evankanderson sure "call" can be used as a noun, but IMO "call" is going to be interpreted as a verb by anyone who uses this, especially when combined with "from", which is a preposition and the logical starting point among the components involved thereby setting an imperative context (also as I mentioned earlier, when creating a subscription you are actually subscribing TO a channel, not from).

I think all 3 should be nouns, and not ambiguous ones. I'm personally not even convinced the current "channel" and "subscriber" should change, since those are the most straightforwardly descriptive names for the 2 primary roles. Everything related to the handling of a subscriber's response is a side-effect, except in the (rare) "bridge" case, and for that I think it's best to view as a no-op subscriber since a channel should not be interpreted as the direct subscriber of another channel (even if the "bridge" is logical with no physical resource, it's enforcing the tinker-toy conceptual model, a.k.a. pipes-and-filters). I do see how "replyChannel" or something similar would be a better alternative to "replyTo" since the latter presents the same problem of an imperative context, and if we are going to support dynamic channel resolution in addition to hardwired literal values, then "replyStrategy" could be the top-level as @scothis proposed earlier (with the "mapping" example).

Sorry if this seems like bike-shedding. I do not view it that way, since these are not names used in an internal implementation. When defining the resources that users interact with, the names of those resources and their properties are among the most important things to get right.

}

// We require always From
// Also at least one of 'call' and 'result' must be defined (non-nill and non-empty)
Copy link
Member

Choose a reason for hiding this comment

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

(You mention "result", but we have no JSON element with that name.)

}

func isValidCallable(c Callable) *apis.FieldError {
if c.TargetURI != nil && c.Target != nil && !equality.Semantic.DeepEqual(c.Target, &corev1.ObjectReference{}) {
Copy link
Member

Choose a reason for hiding this comment

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

Do you want to check for TargetURI != "" as well?

Copy link
Member

Choose a reason for hiding this comment

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

Do you need to check both c.Target != nil and !equality.Semantic.DeepEqual(c.Target, &corev1.ObjectReference{})? I'd expect that nil would not be equal to the other object reference.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Something in my readings led me to believe you needed to do this. I could totally be wrong about this however.

@knative-prow-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: evankanderson, vaikas-google

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:
  • OWNERS [evankanderson,vaikas-google]

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

@knative-metrics-robot
Copy link

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

File Old Coverage New Coverage Delta
pkg/apis/eventing/v1alpha1/register.go Do not exist 0.0%
pkg/apis/eventing/v1alpha1/subscription_defaults.go Do not exist 0.0%
pkg/apis/eventing/v1alpha1/subscription_types.go Do not exist 0.0%
pkg/apis/eventing/v1alpha1/subscription_validation.go Do not exist 100.0%

@vaikas
Copy link
Contributor Author

vaikas commented Sep 14, 2018 via email

@vaikas vaikas removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Sep 14, 2018
@vaikas vaikas changed the title [WIP] Rename Subscription fields to: from,to,processor Create new Subscription in pkg/apis/eventing as per the new spec. Sep 14, 2018
@markfisher
Copy link
Contributor

@vaikas-google that is fine with me. In fact I think having a dedicated discussion about the names in a WG meeting with some proposals being presented with their rationale followed by discussion would be better than having that discussion intermingled with other comments in a PR. I'll make sure we don't forget to follow-up ;-)

@markfisher
Copy link
Contributor

/lgtm

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. 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.

8 participants