Repository: knative/serving
Pull request #9925 (2020-10-23 11:13:42)

[Automated] Update net-certmanager nightly
Produced via:
```shell
for x in net-certmanager.yaml; do
  curl https://storage.googleapis.com/knative-nightly/net-certmanager/latest/$x > ${GITHUB_WORKSPACE}/./third_party/cert-manager-latest/$x
done
```
/assign @knative/networking-wg-leads
/cc @knative/networking-wg-leads

knative-prow-robot: Hi @knative-automation. Thanks for your PR.

I'm waiting for a [knative](https://github.com/orgs/knative/people) member to verify that this patch is reasonable to test. If it is, they should reply with `/ok-to-test` on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should [join the org](https://github.com/orgs/knative/people) to skip this step.

Once the patch is verified, the new status will be reflected by the `ok-to-test` label.

I understand the commands that are listed [here](https://go.k8s.io/bot-commands?repo=knative%2Fserving).

<details>

Instructions for interacting with me using PR comments are available [here](https://git.k8s.io/community/contributors/guide/pull-requests.md).  If you have questions or suggestions related to my behavior, please file an issue against the [kubernetes/test-infra](https://github.com/kubernetes/test-infra/issues/new?title=Prow%20issue:) repository.
</details>

knative-prow-robot: [APPROVALNOTIFIER] This PR is **NOT APPROVED**

This pull-request has been approved by: *<a href="https://github.com/knative/serving/pull/9925#" title="Author self-approved">knative-automation</a>*
To complete the [pull request process](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process), please assign **jrbancel** after the PR has been reviewed.
You can assign the PR to them by writing `/assign @jrbancel` in a comment when ready.

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=knative%2Fserving).

<details open>
Needs approval from an approver in each of these files:

- **[third_party/OWNERS](https://github.com/knative/serving/blob/master/third_party/OWNERS)**

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":["jrbancel"]} -->
codecov[bot]: # [Codecov](https://codecov.io/gh/knative/serving/pull/9925?src=pr&el=h1) Report
> Merging [#9925](https://codecov.io/gh/knative/serving/pull/9925?src=pr&el=desc) into [master](https://codecov.io/gh/knative/serving/commit/78b41623d1565abdb9cfc92bface512e9f0664a5?el=desc) will **increase** coverage by `0.01%`.
> The diff coverage is `n/a`.

[![Impacted file tree graph](https://codecov.io/gh/knative/serving/pull/9925/graphs/tree.svg?width=650&height=150&src=pr&token=MPpDfAj4Ui)](https://codecov.io/gh/knative/serving/pull/9925?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master    #9925      +/-   ##
==========================================
+ Coverage   87.83%   87.84%   +0.01%     
==========================================
  Files         183      183              
  Lines        8631     8631              
==========================================
+ Hits         7581     7582       +1     
  Misses        800      800              
+ Partials      250      249       -1     
```


| [Impacted Files](https://codecov.io/gh/knative/serving/pull/9925?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pkg/autoscaler/statforwarder/forwarder.go](https://codecov.io/gh/knative/serving/pull/9925/diff?src=pr&el=tree#diff-cGtnL2F1dG9zY2FsZXIvc3RhdGZvcndhcmRlci9mb3J3YXJkZXIuZ28=) | `81.18% <0.00%> (-1.08%)` | :arrow_down: |
| [pkg/reconciler/configuration/configuration.go](https://codecov.io/gh/knative/serving/pull/9925/diff?src=pr&el=tree#diff-cGtnL3JlY29uY2lsZXIvY29uZmlndXJhdGlvbi9jb25maWd1cmF0aW9uLmdv) | `88.28% <0.00%> (+2.34%)` | :arrow_up: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/knative/serving/pull/9925?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/knative/serving/pull/9925?src=pr&el=footer). Last update [78b4162...be5b80a](https://codecov.io/gh/knative/serving/pull/9925?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

vagababov: /lgtm
/approve
/ok-to-test
knative-prow-robot: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/knative/serving/pull/9925#" title="Author self-approved">knative-automation</a>*, *<a href="https://github.com/knative/serving/pull/9925#issuecomment-715444840" title="Approved">vagababov</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=knative%2Fserving).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[third_party/OWNERS](https://github.com/knative/serving/blob/master/third_party/OWNERS)~~ [vagababov]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->
knative-prow-robot: [APPROVALNOTIFIER] This PR is **APPROVED**

This pull-request has been approved by: *<a href="https://github.com/knative/serving/pull/9925#" title="Author self-approved">knative-automation</a>*, *<a href="https://github.com/knative/serving/pull/9925#pullrequestreview-515825139" title="LGTM">tcnghia</a>*, *<a href="https://github.com/knative/serving/pull/9925#issuecomment-715444840" title="Approved">vagababov</a>*

The full list of commands accepted by this bot can be found [here](https://go.k8s.io/bot-commands?repo=knative%2Fserving).

The pull request process is described [here](https://git.k8s.io/community/contributors/guide/owners.md#the-code-review-process)

<details >
Needs approval from an approver in each of these files:

- ~~[third_party/OWNERS](https://github.com/knative/serving/blob/master/third_party/OWNERS)~~ [tcnghia,vagababov]

Approvers can indicate their approval by writing `/approve` in a comment
Approvers can cancel approval by writing `/approve cancel` in a comment
</details>
<!-- META={"approvers":[]} -->

Patch:
diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md
index 38c750d85..babb6a9f8 100644
--- a/DEVELOPMENT.md
+++ b/DEVELOPMENT.md
@@ -139,36 +139,6 @@ Kubernetes installation. Please go back to
 [your cluster setup](https://www.knative.dev/docs/install/) to reconfigure your
 Kubernetes cluster in your designated environment, if necessary.
 
-### Deploy Istio
-
-```shell
-kubectl apply -f "https://raw.githubusercontent.com/knative-sandbox/net-istio/master/third_party/istio-stable/istio-crds.yaml"
-while [[ $(kubectl get crd gateways.networking.istio.io -o jsonpath='{.status.conditions[?(@.type=="Established")].status}') != 'True' ]]; do
-  echo "Waiting on Istio CRDs"; sleep 1
-done
-kubectl apply -f "https://raw.githubusercontent.com/knative-sandbox/net-istio/master/third_party/istio-stable/istio-minimal.yaml"
-kubectl apply -f ./third_party/net-istio.yaml
-```
-
-Follow the
-[instructions](https://www.knative.dev/docs/serving/gke-assigning-static-ip-address/)
-if you need to set up static IP for Ingresses in the cluster.
-
-If you want to adopt preinstalled Istio, please check whether the
-`cluster-local-gateway` Service is deployed in namespace `istio-system` or not
-(you can check by running
-`kubectl get service cluster-local-gateway -n istio-system`). If it's not
-installed, please install it with the following command. You could also adjust
-parameters if needed.
-
-```shell
-kubectl apply -f "https://raw.githubusercontent.com/knative-sandbox/net-istio/master/third_party/istio-stable/istio-knative-extras.yaml"
-```
-
-> If you want to customize the `istio*.yaml` files you can refer to the
-> [Istio installation doc](https://github.com/knative/docs/blob/master/docs/install/installing-istio.md)
-> for more information.
-
 ### Deploy cert-manager
 
 1. Deploy `cert-manager` CRDs
@@ -207,7 +177,6 @@ while [[ $(kubectl get crd images.caching.internal.knative.dev -o jsonpath='{.st
 done
 
 ko apply -Rf config/core/
-kubectl apply -f ./third_party/net-istio.yaml
 
 # Optional steps
 
@@ -219,8 +188,7 @@ ko apply -f config/post-install/default-domain.yaml
 
 The above step is equivalent to applying the `serving-crds.yaml`,
 `serving-core.yaml`, `serving-hpa.yaml` and `serving-nscert.yaml` for released
-versions of Knative Serving and additionally applying **net-istio** as the
-ingress implementation.
+versions of Knative Serving.
 
 You can see things running with:
 
@@ -231,8 +199,6 @@ activator-7454cd659f-rrz86            1/1     Running   0          105s
 autoscaler-58cbfd4985-fl5h7           1/1     Running   0          105s
 autoscaler-hpa-77964b9b8c-9sbgq       1/1     Running   0          105s
 controller-847b7cc977-5mvvq           1/1     Running   0          105s
-istio-webhook-69bf66f869-cgc4l        1/1     Running   0          105s
-networking-istio-dcf7944fb-5m25h      1/1     Running   0          105s
 networking-ns-cert-56c58544db-sgstd   1/1     Running   0          105s
 webhook-6b6c77567f-flr59              1/1     Running   0          105s
 ```
@@ -249,6 +215,25 @@ check the
 page to ensure that all services are up and running (and not blocked by a quota
 issue, for example).
 
+### Deploy Knative Ingress
+
+Knative supports a variety of Ingress solutions.
+
+For simplicity, you can just run the following command to install Kourier.
+
+```
+kubectl apply -f https://github.com/knative/net-kourier/releases/download/v0.18.0/kourier.yaml
+
+kubectl patch configmap/config-network \
+  -n knative-serving \
+  --type merge \
+  -p '{"data":{"ingress.class":"kourier.ingress.networking.knative.dev"}}'
+```
+
+If you want to choose another Ingress solution, you can follow step 3 in the
+[Knative installation doc](https://knative.dev/docs/install/any-kubernetes-cluster/#installing-the-serving-component)
+to pick up an alternative Ingress solution and install it.
+
 ## Iterating
 
 As you make changes to the code-base, there are two special cases to be aware
@@ -300,9 +285,7 @@ You can delete all of the service components with:
 ```shell
 ko delete --ignore-not-found=true \
   -Rf config/core/ \
-  -f ./third_party/net-istio.yaml \
-  -f "https://raw.githubusercontent.com/knative-sandbox/net-istio/master/third_party/istio-stable/istio-minimal.yaml" \
-  -f "https://raw.githubusercontent.com/knative-sandbox/net-istio/master/third_party/istio-stable/istio-crds.yaml" \
+  -f https://github.com/knative/net-kourier/releases/download/v0.18.0/kourier.yaml \
   -f ./third_party/cert-manager-0.12.0/cert-manager-crds.yaml \
   -f ./third_party/cert-manager-0.12.0/cert-manager.yaml
 ```
diff --git a/cmd/queue/main.go b/cmd/queue/main.go
index 7b8df5417..205bf2729 100644
--- a/cmd/queue/main.go
+++ b/cmd/queue/main.go
@@ -133,10 +133,10 @@ func main() {
 	defer flush(logger)
 
 	logger = logger.Named("queueproxy").With(
-		zap.Object(logkey.Key, pkglogging.NamespacedName(types.NamespacedName{
+		zap.String(logkey.Key, types.NamespacedName{
 			Namespace: env.ServingNamespace,
 			Name:      env.ServingRevision,
-		})),
+		}.String()),
 		zap.String(logkey.Pod, env.ServingPod))
 
 	// Report stats on Go memory usage every 30 seconds.
diff --git a/pkg/activator/net/revision_backends.go b/pkg/activator/net/revision_backends.go
index ab58fb200..1dc4431a8 100644
--- a/pkg/activator/net/revision_backends.go
+++ b/pkg/activator/net/revision_backends.go
@@ -129,7 +129,7 @@ func newRevisionWatcher(ctx context.Context, rev types.NamespacedName, protocol
 		destsCh:         destsCh,
 		serviceLister:   serviceLister,
 		podsAddressable: true, // By default we presume we can talk to pods directly.
-		logger:          logger.With(zap.Object(logkey.Key, logging.NamespacedName(rev))),
+		logger:          logger.With(zap.String(logkey.Key, rev.String())),
 	}
 }
 
@@ -480,7 +480,7 @@ func (rbm *revisionBackendsManager) endpointsUpdated(newObj interface{}) {
 	}
 	endpoints := newObj.(*corev1.Endpoints)
 	revID := types.NamespacedName{Namespace: endpoints.Namespace, Name: endpoints.Labels[serving.RevisionLabelKey]}
-	logger := rbm.logger.With(zap.Object(logkey.Key, logging.NamespacedName(revID)))
+	logger := rbm.logger.With(zap.String(logkey.Key, revID.String()))
 
 	logger.Debugf("Endpoints updated: %#v", newObj)
 
@@ -517,7 +517,7 @@ func (rbm *revisionBackendsManager) endpointsDeleted(obj interface{}) {
 	ep := obj.(*corev1.Endpoints)
 	revID := types.NamespacedName{Namespace: ep.Namespace, Name: ep.Labels[serving.RevisionLabelKey]}
 
-	rbm.logger.Debugw("Deleting endpoint", zap.Object(logkey.Key, logging.NamespacedName(revID)))
+	rbm.logger.Debugw("Deleting endpoint", zap.String(logkey.Key, revID.String()))
 	rbm.revisionWatchersMux.Lock()
 	defer rbm.revisionWatchersMux.Unlock()
 	rbm.deleteRevisionWatcher(revID)
diff --git a/pkg/activator/net/throttler.go b/pkg/activator/net/throttler.go
index df040630d..75ac8a45b 100644
--- a/pkg/activator/net/throttler.go
+++ b/pkg/activator/net/throttler.go
@@ -171,7 +171,7 @@ func newRevisionThrottler(revID types.NamespacedName,
 	containerConcurrency int, proto string,
 	breakerParams queue.BreakerParams,
 	logger *zap.SugaredLogger) *revisionThrottler {
-	logger = logger.With(zap.Object(logkey.Key, logging.NamespacedName(revID)))
+	logger = logger.With(zap.String(logkey.Key, revID.String()))
 	var (
 		revBreaker breaker
 		lbp        lbPolicy
@@ -563,11 +563,11 @@ func (t *Throttler) revisionUpdated(obj interface{}) {
 	rev := obj.(*v1.Revision)
 	revID := types.NamespacedName{Namespace: rev.Namespace, Name: rev.Name}
 
-	t.logger.Debug("Revision update", zap.Object(logkey.Key, logging.NamespacedName(revID)))
+	t.logger.Debug("Revision update", zap.String(logkey.Key, revID.String()))
 
 	if _, err := t.getOrCreateRevisionThrottler(revID); err != nil {
 		t.logger.Errorw("Failed to get revision throttler for revision",
-			zap.Error(err), zap.Object(logkey.Key, logging.NamespacedName(revID)))
+			zap.Error(err), zap.String(logkey.Key, revID.String()))
 	}
 }
 
@@ -577,7 +577,7 @@ func (t *Throttler) revisionDeleted(obj interface{}) {
 	rev := obj.(*v1.Revision)
 	revID := types.NamespacedName{Namespace: rev.Namespace, Name: rev.Name}
 
-	t.logger.Debugw("Revision delete", zap.Object(logkey.Key, logging.NamespacedName(revID)))
+	t.logger.Debugw("Revision delete", zap.String(logkey.Key, revID.String()))
 
 	t.revisionThrottlersMutex.Lock()
 	defer t.revisionThrottlersMutex.Unlock()
@@ -586,12 +586,11 @@ func (t *Throttler) revisionDeleted(obj interface{}) {
 
 func (t *Throttler) handleUpdate(update revisionDestsUpdate) {
 	if rt, err := t.getOrCreateRevisionThrottler(update.Rev); err != nil {
+		logger := t.logger.With(zap.String(logkey.Key, update.Rev.String()))
 		if k8serrors.IsNotFound(err) {
-			t.logger.Debugw("Revision not found. It was probably removed",
-				zap.Object(logkey.Key, logging.NamespacedName(update.Rev)))
+			logger.Debug("Revision not found. It was probably removed")
 		} else {
-			t.logger.Errorw("Failed to get revision throttler", zap.Error(err),
-				zap.Object(logkey.Key, logging.NamespacedName(update.Rev)))
+			logger.Errorw("Failed to get revision throttler", zap.Error(err))
 		}
 	} else {
 		rt.handleUpdate(update)
@@ -609,7 +608,7 @@ func (t *Throttler) handlePubEpsUpdate(eps *corev1.Endpoints) {
 	}
 	rev := types.NamespacedName{Name: revN, Namespace: eps.Namespace}
 	if rt, err := t.getOrCreateRevisionThrottler(rev); err != nil {
-		logger := t.logger.With(zap.Object(logkey.Key, logging.NamespacedName(rev)))
+		logger := t.logger.With(zap.String(logkey.Key, rev.String()))
 		if k8serrors.IsNotFound(err) {
 			logger.Debug("Revision not found. It was probably removed")
 		} else {
diff --git a/pkg/apis/serving/v1/route_defaults.go b/pkg/apis/serving/v1/route_defaults.go
index 55bcc825f..652eef568 100644
--- a/pkg/apis/serving/v1/route_defaults.go
+++ b/pkg/apis/serving/v1/route_defaults.go
@@ -55,4 +55,11 @@ func (tt *TrafficTarget) SetDefaults(ctx context.Context) {
 	if tt.LatestRevision == nil {
 		tt.LatestRevision = ptr.Bool(tt.RevisionName == "")
 	}
+	// Despite the fact that we have the field percent
+	// as required, historically we were lenient about checking this.
+	// But by setting explicit `0` we can eliminate lots of checking
+	// downstream in validation and controllers.
+	if tt.Percent == nil {
+		tt.Percent = ptr.Int64(0)
+	}
 }
diff --git a/pkg/autoscaler/metrics/collector.go b/pkg/autoscaler/metrics/collector.go
index f16aa720d..ef9d3c7d0 100644
--- a/pkg/autoscaler/metrics/collector.go
+++ b/pkg/autoscaler/metrics/collector.go
@@ -24,7 +24,6 @@ import (
 	"go.uber.org/zap"
 	"k8s.io/apimachinery/pkg/types"
 	"k8s.io/apimachinery/pkg/util/clock"
-	"knative.dev/pkg/logging"
 	"knative.dev/pkg/logging/logkey"
 	av1alpha1 "knative.dev/serving/pkg/apis/autoscaling/v1alpha1"
 	"knative.dev/serving/pkg/autoscaler/aggregation"
@@ -112,10 +111,10 @@ func NewMetricCollector(statsScraperFactory StatsScraperFactory, logger *zap.Sug
 // CreateOrUpdate either creates a collection for the given metric or update it, should
 // it already exist.
 func (c *MetricCollector) CreateOrUpdate(metric *av1alpha1.Metric) error {
-	logger := c.logger.With(zap.Object(logkey.Key, logging.NamespacedName(types.NamespacedName{
+	logger := c.logger.With(zap.String(logkey.Key, types.NamespacedName{
 		Namespace: metric.Namespace,
 		Name:      metric.Name,
-	})))
+	}.String()))
 	scraper, err := c.statsScraperFactory(metric, logger)
 	if err != nil {
 		return err
diff --git a/pkg/reconciler/revision/controller.go b/pkg/reconciler/revision/controller.go
index 6ec0e9a33..043adb94e 100644
--- a/pkg/reconciler/revision/controller.go
+++ b/pkg/reconciler/revision/controller.go
@@ -20,6 +20,7 @@ import (
 	"context"
 	"net/http"
 
+	"go.uber.org/zap"
 	cachingclient "knative.dev/caching/pkg/client/injection/client"
 	imageinformer "knative.dev/caching/pkg/client/injection/informers/caching/v1alpha1/image"
 	kubeclient "knative.dev/pkg/client/injection/kube/client"
@@ -105,7 +106,7 @@ func newControllerWithOptions(
 
 	transport := http.DefaultTransport
 	if rt, err := newResolverTransport(k8sCertPath, digestResolutionWorkers, digestResolutionWorkers); err != nil {
-		logging.FromContext(ctx).Error("Failed to create resolver transport: ", err)
+		logging.FromContext(ctx).Errorw("Failed to create resolver transport", zap.Error(err))
 	} else {
 		transport = rt
 	}
diff --git a/pkg/reconciler/route/traffic/rollout.go b/pkg/reconciler/route/traffic/rollout.go
index aef33dcde..32e4afcde 100644
--- a/pkg/reconciler/route/traffic/rollout.go
+++ b/pkg/reconciler/route/traffic/rollout.go
@@ -43,6 +43,11 @@ type ConfigurationRollout struct {
 	ConfigurationName string `json:"configurationName"`
 	Tag               string `json:"tag,omitempty"`
 
+	// Percent denotes the total percentage for this configuration.
+	// The individual percentages of the Revisions below will sum to this
+	// number.
+	Percent int `json:"percent"`
+
 	// The revisions in the rollout. In steady state this should
 	// contain 0 (no revision is ready) or 1 (rollout done).
 	// During the actual rollout it will contain N revisions
diff --git a/pkg/reconciler/route/traffic/traffic.go b/pkg/reconciler/route/traffic/traffic.go
index 88906cf1b..649765c57 100644
--- a/pkg/reconciler/route/traffic/traffic.go
+++ b/pkg/reconciler/route/traffic/traffic.go
@@ -36,11 +36,10 @@ import (
 // DefaultTarget is the unnamed default target for the traffic.
 const DefaultTarget = ""
 
-// A RevisionTarget adds the Active/Inactive state and the transport protocol of a
+// A RevisionTarget adds the transport protocol and the service name of a
 // Revision to a flattened TrafficTarget.
 type RevisionTarget struct {
 	v1.TrafficTarget
-	Active      bool
 	Protocol    net.ProtocolType
 	ServiceName string // Revision service name.
 }
@@ -167,6 +166,8 @@ func newBuilder(
 
 // BuildRollout builds the current rollout state.
 // It is expected to be invoked after applySpecTraffic.
+// Returned Rollout will be sorted by tag and within tag by configuration
+// (only default tag can have more than configuration object attached).
 // TODO(vagababov): actually deal with rollouts, vs just report desired state.
 func (cfg *Config) BuildRollout() *Rollout {
 	rollout := &Rollout{}
@@ -205,9 +206,12 @@ func buildRolloutForTag(r *Rollout, tag string, rts RevisionTargets) {
 		r.Configurations = append(r.Configurations, ConfigurationRollout{
 			ConfigurationName: rt.ConfigurationName,
 			Tag:               tag,
+			Percent:           int(zeroIfNil(rt.Percent)),
 			Revisions: []RevisionRollout{{
 				RevisionName: rt.RevisionName,
-				Percent:      int(valIfNil(0, rt.Percent)),
+				// Note: this will match config value in steady state, but
+				// during rollout it will be overridden by the rollout logic.
+				Percent: int(zeroIfNil(rt.Percent)),
 			}},
 		})
 	}
@@ -306,7 +310,6 @@ func (cb *configBuilder) addConfigurationTarget(tt *v1.TrafficTarget) error {
 	ntt := tt.DeepCopy()
 	target := RevisionTarget{
 		TrafficTarget: *ntt,
-		Active:        !rev.Status.IsActivationRequired(),
 		Protocol:      rev.GetProtocol(),
 		ServiceName:   rev.Status.ServiceName,
 	}
@@ -326,7 +329,6 @@ func (cb *configBuilder) addRevisionTarget(tt *v1.TrafficTarget) error {
 	ntt := tt.DeepCopy()
 	target := RevisionTarget{
 		TrafficTarget: *ntt,
-		Active:        !rev.Status.IsActivationRequired(),
 		Protocol:      rev.GetProtocol(),
 		ServiceName:   rev.Status.ServiceName,
 	}
@@ -340,10 +342,10 @@ func (cb *configBuilder) addRevisionTarget(tt *v1.TrafficTarget) error {
 	return nil
 }
 
-// valIfNil returns `val` if `ptr==nil`, or `*ptr` otherwise.
-func valIfNil(val int64, ptr *int64) int64 {
+// zeroIfNil returns `0` if `ptr==nil`, or `*ptr` otherwise.
+func zeroIfNil(ptr *int64) int64 {
 	if ptr == nil {
-		return val
+		return 0
 	}
 	return *ptr
 }
@@ -354,7 +356,7 @@ func mergeIfNecessary(rts RevisionTargets, rt RevisionTarget) RevisionTargets {
 	for i := range rts {
 		if rts[i].Tag == rt.Tag && rts[i].RevisionName == rt.RevisionName &&
 			*rt.LatestRevision == *rts[i].LatestRevision {
-			rts[i].Percent = ptr.Int64(valIfNil(0, rts[i].Percent) + valIfNil(0, rt.Percent))
+			rts[i].Percent = ptr.Int64(zeroIfNil(rts[i].Percent) + zeroIfNil(rt.Percent))
 			return rts
 		}
 	}
diff --git a/third_party/net-istio.yaml b/third_party/net-istio.yaml
index 6a2bb8b87..521b65fe5 100644
--- a/third_party/net-istio.yaml
+++ b/third_party/net-istio.yaml
@@ -18,7 +18,7 @@ metadata:
   # These are the permissions needed by the Istio Ingress implementation.
   name: knative-serving-istio
   labels:
-    serving.knative.dev/release: "v20201022-7bda3d56"
+    serving.knative.dev/release: "v20201023-3b6e0d50"
     serving.knative.dev/controller: "true"
     networking.knative.dev/ingress-provider: istio
 rules:
@@ -48,7 +48,7 @@ metadata:
   name: knative-ingress-gateway
   namespace: knative-serving
   labels:
-    serving.knative.dev/release: "v20201022-7bda3d56"
+    serving.knative.dev/release: "v20201023-3b6e0d50"
     networking.knative.dev/ingress-provider: istio
 spec:
   selector:
@@ -85,7 +85,7 @@ metadata:
   name: cluster-local-gateway
   namespace: knative-serving
   labels:
-    serving.knative.dev/release: "v20201022-7bda3d56"
+    serving.knative.dev/release: "v20201023-3b6e0d50"
     networking.knative.dev/ingress-provider: istio
 spec:
   selector:
@@ -104,7 +104,7 @@ metadata:
   name: knative-local-gateway
   namespace: knative-serving
   labels:
-    serving.knative.dev/release: "v20201022-7bda3d56"
+    serving.knative.dev/release: "v20201023-3b6e0d50"
     networking.knative.dev/ingress-provider: istio
 spec:
   selector:
@@ -123,7 +123,7 @@ metadata:
   name: knative-local-gateway
   namespace: knative-serving
   labels:
-    serving.knative.dev/release: "v20201022-7bda3d56"
+    serving.knative.dev/release: "v20201023-3b6e0d50"
     networking.knative.dev/ingress-provider: istio
 spec:
   type: ClusterIP
@@ -181,7 +181,7 @@ kind: MutatingWebhookConfiguration
 metadata:
   name: webhook.istio.networking.internal.knative.dev
   labels:
-    serving.knative.dev/release: "v20201022-7bda3d56"
+    serving.knative.dev/release: "v20201023-3b6e0d50"
     networking.knative.dev/ingress-provider: istio
 webhooks:
   - admissionReviewVersions:
@@ -217,7 +217,7 @@ kind: ValidatingWebhookConfiguration
 metadata:
   name: config.webhook.istio.networking.internal.knative.dev
   labels:
-    serving.knative.dev/release: "v20201022-7bda3d56"
+    serving.knative.dev/release: "v20201023-3b6e0d50"
     networking.knative.dev/ingress-provider: istio
 webhooks:
   - admissionReviewVersions:
@@ -255,7 +255,7 @@ metadata:
   name: istio-webhook-certs
   namespace: knative-serving
   labels:
-    serving.knative.dev/release: "v20201022-7bda3d56"
+    serving.knative.dev/release: "v20201023-3b6e0d50"
     networking.knative.dev/ingress-provider: istio
 
 ---
@@ -279,7 +279,7 @@ metadata:
   name: config-istio
   namespace: knative-serving
   labels:
-    serving.knative.dev/release: "v20201022-7bda3d56"
+    serving.knative.dev/release: "v20201023-3b6e0d50"
     networking.knative.dev/ingress-provider: istio
 data:
   _example: |
@@ -349,7 +349,7 @@ metadata:
   name: networking-istio
   namespace: knative-serving
   labels:
-    serving.knative.dev/release: "v20201022-7bda3d56"
+    serving.knative.dev/release: "v20201023-3b6e0d50"
     networking.knative.dev/ingress-provider: istio
 spec:
   selector:
@@ -365,14 +365,14 @@ spec:
         sidecar.istio.io/inject: "false"
       labels:
         app: networking-istio
-        serving.knative.dev/release: "v20201022-7bda3d56"
+        serving.knative.dev/release: "v20201023-3b6e0d50"
     spec:
       serviceAccountName: controller
       containers:
         - name: networking-istio
           # This is the Go import path for the binary that is containerized
           # and substituted here.
-          image: gcr.io/knative-nightly/knative.dev/net-istio/cmd/controller@sha256:b4750acde7a10a1a91f91884dfd5083b4bdac8bda4da8d1f1ddb3ff235793544
+          image: gcr.io/knative-nightly/knative.dev/net-istio/cmd/controller@sha256:b7d30876d7f9a5d476667cf92c62fb66977a7e7724509d8940eafee62bacc433
           resources:
             requests:
               cpu: 30m
@@ -424,7 +424,7 @@ metadata:
   name: istio-webhook
   namespace: knative-serving
   labels:
-    serving.knative.dev/release: "v20201022-7bda3d56"
+    serving.knative.dev/release: "v20201023-3b6e0d50"
     networking.knative.dev/ingress-provider: istio
 spec:
   selector:
@@ -438,14 +438,14 @@ spec:
       labels:
         app: istio-webhook
         role: istio-webhook
-        serving.knative.dev/release: "v20201022-7bda3d56"
+        serving.knative.dev/release: "v20201023-3b6e0d50"
     spec:
       serviceAccountName: controller
       containers:
         - name: webhook
           # This is the Go import path for the binary that is containerized
           # and substituted here.
-          image: gcr.io/knative-nightly/knative.dev/net-istio/cmd/webhook@sha256:8bc42e9af355c20d6fa0db45f7eb0e34e169d0528288cac8f8e70e7e9955a4ae
+          image: gcr.io/knative-nightly/knative.dev/net-istio/cmd/webhook@sha256:50842889b16c4a44444d9ef3f396c4557ae005a809e648e2e8dc01c4b495b1c8
           resources:
             requests:
               cpu: 20m
@@ -499,7 +499,7 @@ metadata:
   namespace: knative-serving
   labels:
     role: istio-webhook
-    serving.knative.dev/release: "v20201022-7bda3d56"
+    serving.knative.dev/release: "v20201023-3b6e0d50"
     networking.knative.dev/ingress-provider: istio
 spec:
   ports:


Test patch:
diff --git a/pkg/apis/serving/v1/route_defaults_test.go b/pkg/apis/serving/v1/route_defaults_test.go
index 7773c305e..9f409cb43 100644
--- a/pkg/apis/serving/v1/route_defaults_test.go
+++ b/pkg/apis/serving/v1/route_defaults_test.go
@@ -51,7 +51,7 @@ func TestRouteDefaulting(t *testing.T) {
 		},
 		wc: WithDefaultConfigurationName,
 	}, {
-		// Make sure it keeps a 'nil' as a 'nil' and not 'zero'
+		// Make sure it replaces a 'nil' as a '0'.
 		name: "implied zero percent",
 		in: &Route{
 			Spec: RouteSpec{
@@ -70,8 +70,8 @@ func TestRouteDefaulting(t *testing.T) {
 					LatestRevision: ptr.Bool(true),
 				}, {
 					RevisionName:   "bar",
-					Percent:        nil,
 					LatestRevision: ptr.Bool(false),
+					Percent:        ptr.Int64(0),
 				}},
 			},
 		},
diff --git a/pkg/apis/serving/v1/service_defaults_test.go b/pkg/apis/serving/v1/service_defaults_test.go
index 31b88e5ba..01547042a 100644
--- a/pkg/apis/serving/v1/service_defaults_test.go
+++ b/pkg/apis/serving/v1/service_defaults_test.go
@@ -253,6 +253,7 @@ func TestServiceDefaulting(t *testing.T) {
 						LatestRevision: ptr.Bool(false),
 					}, {
 						Tag:            "latest",
+						Percent:        ptr.Int64(0),
 						LatestRevision: ptr.Bool(true),
 					}},
 				},
diff --git a/pkg/reconciler/route/reconcile_resources_test.go b/pkg/reconciler/route/reconcile_resources_test.go
index fa5d8a328..2df0af8b8 100644
--- a/pkg/reconciler/route/reconcile_resources_test.go
+++ b/pkg/reconciler/route/reconcile_resources_test.go
@@ -123,7 +123,6 @@ func TestReconcileTargetValidRevision(t *testing.T) {
 				RevisionName: "revision",
 				Percent:      ptr.Int64(100),
 			},
-			Active: true,
 		}}}}
 
 	ctx = config.ToContext(ctx, &config.Config{
@@ -175,7 +174,6 @@ func TestReconcileRevisionTargetDoesNotExist(t *testing.T) {
 				RevisionName: "invalid-revision",
 				Percent:      ptr.Int64(100),
 			},
-			Active: true,
 		}}}}
 	ctx = config.ToContext(ctx, &config.Config{
 		GC: &gc.Config{
@@ -219,7 +217,6 @@ func newTestIngress(t *testing.T, r *v1.Route, trafficOpts ...func(tc *traffic.C
 				RevisionName: "revision",
 				Percent:      ptr.Int64(100),
 			},
-			Active: true,
 		}}}}
 
 	for _, opt := range trafficOpts {
@@ -233,7 +230,7 @@ func newTestIngress(t *testing.T, r *v1.Route, trafficOpts ...func(tc *traffic.C
 	}}
 	ingress, err := resources.MakeIngress(getContext(), r, tc, tls, "foo-ingress")
 	if err != nil {
-		t.Error("Unexpected error", err)
+		t.Error("Unexpected error:", err)
 	}
 	return ingress
 }
@@ -252,7 +249,7 @@ func TestReconcileCertificatesInsert(t *testing.T) {
 	}
 	created := getCertificateFromClient(ctx, t, certificate)
 	if diff := cmp.Diff(certificate, created); diff != "" {
-		t.Error("Unexpected diff (-want +got):", diff)
+		t.Errorf("Unexpected diff (-want +got):\n%s", diff)
 	}
 }
 
diff --git a/pkg/reconciler/route/resources/ingress_test.go b/pkg/reconciler/route/resources/ingress_test.go
index d060cbe55..f9ef370cf 100644
--- a/pkg/reconciler/route/resources/ingress_test.go
+++ b/pkg/reconciler/route/resources/ingress_test.go
@@ -171,7 +171,6 @@ func TestMakeIngressSpecCorrectRules(t *testing.T) {
 				Percent:           ptr.Int64(100),
 			},
 			ServiceName: "gilberto",
-			Active:      true,
 		}},
 		"v1": {{
 			TrafficTarget: v1.TrafficTarget{
@@ -180,7 +179,6 @@ func TestMakeIngressSpecCorrectRules(t *testing.T) {
 				Percent:           ptr.Int64(100),
 			},
 			ServiceName: "jobim",
-			Active:      true,
 		}},
 	}
 
@@ -304,7 +302,6 @@ func TestMakeIngressSpecCorrectRuleVisibility(t *testing.T) {
 					Percent:           ptr.Int64(100),
 				},
 				ServiceName: "gilberto",
-				Active:      true,
 			}},
 		},
 		expectedVisibility: map[netv1alpha1.IngressVisibility][]string{
@@ -322,7 +319,6 @@ func TestMakeIngressSpecCorrectRuleVisibility(t *testing.T) {
 					Percent:           ptr.Int64(100),
 				},
 				ServiceName: "gilberto",
-				Active:      true,
 			}},
 		},
 		serviceVisibility: map[string]netv1alpha1.IngressVisibility{
@@ -342,7 +338,6 @@ func TestMakeIngressSpecCorrectRuleVisibility(t *testing.T) {
 					Percent:           ptr.Int64(100),
 				},
 				ServiceName: "gilberto",
-				Active:      true,
 			}},
 		},
 		expectedVisibility: map[netv1alpha1.IngressVisibility][]string{
@@ -381,7 +376,6 @@ func TestMakeIngressSpecCorrectRulesWithTagBasedRouting(t *testing.T) {
 				Percent:           ptr.Int64(100),
 			},
 			ServiceName: "gilberto",
-			Active:      true,
 		}},
 		"v1": {{
 			TrafficTarget: v1.TrafficTarget{
@@ -390,7 +384,6 @@ func TestMakeIngressSpecCorrectRulesWithTagBasedRouting(t *testing.T) {
 				Percent:           ptr.Int64(100),
 			},
 			ServiceName: "jobim",
-			Active:      true,
 		}},
 	}
 
@@ -556,7 +549,6 @@ func TestMakeIngressRuleVanilla(t *testing.T) {
 			Percent:           ptr.Int64(100),
 		},
 		ServiceName: "chocolate",
-		Active:      true,
 	}}
 	domains := []string{"a.com", "b.org"}
 	rule := makeIngressRule(domains, ns, netv1alpha1.IngressVisibilityExternalIP, targets)
@@ -598,14 +590,12 @@ func TestMakeIngressRuleZeroPercentTarget(t *testing.T) {
 			Percent:           ptr.Int64(100),
 		},
 		ServiceName: "active-target",
-		Active:      true,
 	}, {
 		TrafficTarget: v1.TrafficTarget{
 			ConfigurationName: "new-config",
 			RevisionName:      "new-revision",
 			Percent:           ptr.Int64(0),
 		},
-		Active: true,
 	}}
 	domains := []string{"test.org"}
 	rule := makeIngressRule(domains, ns, netv1alpha1.IngressVisibilityExternalIP, targets)
@@ -644,14 +634,11 @@ func TestMakeIngressRuleNilPercentTarget(t *testing.T) {
 			Percent:           ptr.Int64(100),
 		},
 		ServiceName: "active-target",
-		Active:      true,
 	}, {
 		TrafficTarget: v1.TrafficTarget{
 			ConfigurationName: "new-config",
 			RevisionName:      "new-revision",
-			Percent:           nil,
 		},
-		Active: true,
 	}}
 	domains := []string{"test.org"}
 	rule := makeIngressRule(domains, ns, netv1alpha1.IngressVisibilityExternalIP, targets)
@@ -690,7 +677,6 @@ func TestMakeIngressRuleTwoTargets(t *testing.T) {
 			Percent:           ptr.Int64(80),
 		},
 		ServiceName: "nigh",
-		Active:      true,
 	}, {
 		TrafficTarget: v1.TrafficTarget{
 			ConfigurationName: "new-config",
@@ -698,7 +684,6 @@ func TestMakeIngressRuleTwoTargets(t *testing.T) {
 			Percent:           ptr.Int64(20),
 		},
 		ServiceName: "death",
-		Active:      true,
 	}}
 	domains := []string{"test.org"}
 	rule := makeIngressRule(domains, ns, netv1alpha1.IngressVisibilityExternalIP, targets)
@@ -748,7 +733,6 @@ func TestMakeIngressRuleInactiveTarget(t *testing.T) {
 			Percent:           ptr.Int64(100),
 		},
 		ServiceName: "strange-quark",
-		Active:      false,
 	}}
 	domains := []string{"a.com", "b.org"}
 	rule := makeIngressRule(domains, ns, netv1alpha1.IngressVisibilityExternalIP, targets)
@@ -789,7 +773,6 @@ func TestMakeIngressRuleTwoInactiveTargets(t *testing.T) {
 			Percent:           ptr.Int64(80),
 		},
 		ServiceName: "up-quark",
-		Active:      false,
 	}, {
 		TrafficTarget: v1.TrafficTarget{
 			ConfigurationName: "new-config",
@@ -797,7 +780,6 @@ func TestMakeIngressRuleTwoInactiveTargets(t *testing.T) {
 			Percent:           ptr.Int64(20),
 		},
 		ServiceName: "down-quark",
-		Active:      false,
 	}}
 	domains := []string{"a.com", "b.org"}
 	rule := makeIngressRule(domains, ns, netv1alpha1.IngressVisibilityExternalIP, targets)
@@ -848,14 +830,12 @@ func TestMakeIngressRuleZeroPercentTargetInactive(t *testing.T) {
 			Percent:           ptr.Int64(100),
 		},
 		ServiceName: "apathy-sets-in",
-		Active:      true,
 	}, {
 		TrafficTarget: v1.TrafficTarget{
 			ConfigurationName: "new-config",
 			RevisionName:      "new-revision",
 			Percent:           ptr.Int64(0),
 		},
-		Active: false,
 	}}
 	domains := []string{"test.org"}
 	rule := makeIngressRule(domains, ns, netv1alpha1.IngressVisibilityExternalIP, targets)
@@ -893,14 +873,12 @@ func TestMakeIngressRuleNilPercentTargetInactive(t *testing.T) {
 			Percent:           ptr.Int64(100),
 		},
 		ServiceName: "apathy-sets-in",
-		Active:      true,
 	}, {
 		TrafficTarget: v1.TrafficTarget{
 			ConfigurationName: "new-config",
 			RevisionName:      "new-revision",
 			Percent:           nil,
 		},
-		Active: false,
 	}}
 	domains := []string{"test.org"}
 	rule := makeIngressRule(domains, ns, netv1alpha1.IngressVisibilityExternalIP, targets)
@@ -999,7 +977,6 @@ func TestMakeIngressACMEChallenges(t *testing.T) {
 				Percent:           ptr.Int64(100),
 			},
 			ServiceName: "gilberto",
-			Active:      true,
 		}},
 	}
 
@@ -1103,7 +1080,6 @@ func TestMakeIngressFailToGenerateDomain(t *testing.T) {
 				Percent:           ptr.Int64(100),
 			},
 			ServiceName: "gilberto",
-			Active:      true,
 		}},
 	}
 
@@ -1135,7 +1111,6 @@ func TestMakeIngressFailToGenerateTagHost(t *testing.T) {
 				Percent:           ptr.Int64(100),
 			},
 			ServiceName: "gilberto",
-			Active:      true,
 		}},
 		"v1": {{
 			TrafficTarget: v1.TrafficTarget{
@@ -1144,7 +1119,6 @@ func TestMakeIngressFailToGenerateTagHost(t *testing.T) {
 				Percent:           ptr.Int64(100),
 			},
 			ServiceName: "jobim",
-			Active:      true,
 		}},
 	}
 
diff --git a/pkg/reconciler/route/table_test.go b/pkg/reconciler/route/table_test.go
index daf07354f..5ba5edbdb 100644
--- a/pkg/reconciler/route/table_test.go
+++ b/pkg/reconciler/route/table_test.go
@@ -151,7 +151,6 @@ func TestReconcile(t *testing.T) {
 								RevisionName:      "ing-unknown-00001",
 							},
 							ServiceName: "mcd",
-							Active:      true,
 						}},
 					},
 				},
@@ -199,7 +198,6 @@ func TestReconcile(t *testing.T) {
 								LatestRevision:    ptr.Bool(true),
 							},
 							ServiceName: "mcd",
-							Active:      true,
 						}},
 					},
 				}, WithLoadbalancerFailed("TestFailure", "failure"),
@@ -250,7 +248,6 @@ func TestReconcile(t *testing.T) {
 								LatestRevision:    ptr.Bool(true),
 							},
 							ServiceName: "bk",
-							Active:      true,
 						}},
 					},
 				},
@@ -306,7 +303,6 @@ func TestReconcile(t *testing.T) {
 								Percent:           ptr.Int64(100),
 							},
 							ServiceName: "tb",
-							Active:      true,
 						}},
 					},
 					Visibility: map[string]netv1alpha1.IngressVisibility{
@@ -358,7 +354,6 @@ func TestReconcile(t *testing.T) {
 								Percent:           ptr.Int64(100),
 								LatestRevision:    ptr.Bool(true),
 							},
-							Active: true,
 						}},
 					},
 				},
@@ -459,7 +454,6 @@ func TestReconcile(t *testing.T) {
 								LatestRevision:    ptr.Bool(true),
 							},
 							ServiceName: "astrid",
-							Active:      true,
 						}},
 					},
 				},
@@ -519,7 +513,6 @@ func TestReconcile(t *testing.T) {
 								RevisionName:      "config-00001",
 								Percent:           ptr.Int64(100),
 							},
-							Active: true,
 						}},
 					},
 				},
@@ -597,7 +590,6 @@ func TestReconcile(t *testing.T) {
 								RevisionName:      "config-00001",
 								Percent:           ptr.Int64(100),
 							},
-							Active:      true,
 							ServiceName: "my-service",
 						}},
 					},
@@ -618,7 +610,6 @@ func TestReconcile(t *testing.T) {
 								LatestRevision:    ptr.Bool(true),
 								Percent:           ptr.Int64(100),
 							},
-							Active:      true,
 							ServiceName: "my-service",
 						}},
 					},
@@ -660,7 +651,6 @@ func TestReconcile(t *testing.T) {
 								Percent:           ptr.Int64(100),
 							},
 							ServiceName: "daisy",
-							Active:      true,
 						}},
 					},
 				},
@@ -699,7 +689,6 @@ func TestReconcile(t *testing.T) {
 								Percent:           ptr.Int64(100),
 							},
 							ServiceName: "magnolia",
-							Active:      true,
 						}},
 					},
 				},
@@ -721,7 +710,6 @@ func TestReconcile(t *testing.T) {
 								Percent:      ptr.Int64(100),
 							},
 							ServiceName: "belltown",
-							Active:      true,
 						}},
 					},
 				},
@@ -759,7 +747,6 @@ func TestReconcile(t *testing.T) {
 								LatestRevision:    ptr.Bool(true),
 							},
 							ServiceName: "tb",
-							Active:      true,
 						}},
 					},
 				},
@@ -783,7 +770,6 @@ func TestReconcile(t *testing.T) {
 								LatestRevision:    ptr.Bool(true),
 							},
 							ServiceName: "tb",
-							Active:      true,
 						}},
 					},
 					Visibility: map[string]netv1alpha1.IngressVisibility{
@@ -827,7 +813,6 @@ func TestReconcile(t *testing.T) {
 								LatestRevision:    ptr.Bool(true),
 							},
 							ServiceName: "tb",
-							Active:      true,
 						}},
 					},
 					Visibility: map[string]netv1alpha1.IngressVisibility{
@@ -852,7 +837,6 @@ func TestReconcile(t *testing.T) {
 								LatestRevision:    ptr.Bool(true),
 							},
 							ServiceName: "tb",
-							Active:      true,
 						}},
 					},
 				},
@@ -906,7 +890,6 @@ func TestReconcile(t *testing.T) {
 								Percent:           ptr.Int64(100),
 							},
 							ServiceName: "fremont",
-							Active:      true,
 						}},
 					},
 				},
@@ -927,7 +910,6 @@ func TestReconcile(t *testing.T) {
 								Percent:      ptr.Int64(100),
 							},
 							ServiceName: "wallingford",
-							Active:      true,
 						}},
 					},
 				},
@@ -975,7 +957,6 @@ func TestReconcile(t *testing.T) {
 								LatestRevision:    ptr.Bool(true),
 								Percent:           ptr.Int64(100),
 							},
-							Active: true,
 						}},
 					},
 				},
@@ -1020,7 +1001,6 @@ func TestReconcile(t *testing.T) {
 								RevisionName:      "config-00001",
 								Percent:           ptr.Int64(100),
 							},
-							Active: true,
 						}},
 					},
 				},
@@ -1066,7 +1046,6 @@ func TestReconcile(t *testing.T) {
 								RevisionName:      "config-00001",
 								Percent:           ptr.Int64(100),
 							},
-							Active: true,
 						}},
 					},
 				},
@@ -1107,7 +1086,6 @@ func TestReconcile(t *testing.T) {
 								RevisionName:      "config-00001",
 								Percent:           ptr.Int64(100),
 							},
-							Active: true,
 						}},
 					},
 				},
@@ -1146,7 +1124,6 @@ func TestReconcile(t *testing.T) {
 								Percent:      ptr.Int64(100),
 							},
 							ServiceName: "magnusson-park",
-							Active:      true,
 						}},
 					},
 				},
@@ -1166,7 +1143,6 @@ func TestReconcile(t *testing.T) {
 								Percent:           ptr.Int64(100),
 							},
 							ServiceName: "windermere",
-							Active:      true,
 						}},
 					},
 				},
@@ -1239,7 +1215,6 @@ func TestReconcile(t *testing.T) {
 								RevisionName: "config-00001",
 								Percent:      ptr.Int64(100),
 							},
-							Active: true,
 						}},
 					},
 				},
@@ -1296,7 +1271,6 @@ func TestReconcile(t *testing.T) {
 								LatestRevision:    ptr.Bool(true),
 							},
 							ServiceName: "blue-ridge",
-							Active:      true,
 						}, {
 							TrafficTarget: v1.TrafficTarget{
 								ConfigurationName: "green",
@@ -1305,7 +1279,6 @@ func TestReconcile(t *testing.T) {
 								LatestRevision:    ptr.Bool(true),
 							},
 							ServiceName: "green-lake",
-							Active:      true,
 						}},
 					},
 				},
@@ -1394,7 +1367,6 @@ func TestReconcile(t *testing.T) {
 								LatestRevision:    ptr.Bool(true),
 							},
 							ServiceName: "shades",
-							Active:      true,
 						}},
 						"gray": {{
 							TrafficTarget: v1.TrafficTarget{
@@ -1404,7 +1376,6 @@ func TestReconcile(t *testing.T) {
 								LatestRevision:    ptr.Bool(true),
 							},
 							ServiceName: "shades",
-							Active:      true,
 						}},
 						"also-gray": {{
 							TrafficTarget: v1.TrafficTarget{
@@ -1412,7 +1383,6 @@ func TestReconcile(t *testing.T) {
 								Percent:      ptr.Int64(100),
 							},
 							ServiceName: "shades",
-							Active:      true,
 						}},
 					},
 				},
@@ -1545,7 +1515,6 @@ func TestReconcile(t *testing.T) {
 								LatestRevision:    ptr.Bool(true),
 							},
 							ServiceName: "alki-beach",
-							Active:      true,
 						}},
 					},
 				},
@@ -1565,7 +1534,6 @@ func TestReconcile(t *testing.T) {
 								Percent:           ptr.Int64(100),
 							},
 							ServiceName: "rainier-beach",
-							Active:      true,
 						}},
 					},
 				},
@@ -1667,7 +1635,6 @@ func TestReconcile(t *testing.T) {
 								RevisionName:      "config-00001",
 								Percent:           ptr.Int64(100),
 							},
-							Active: true,
 						}},
 					},
 				},
@@ -1781,7 +1748,6 @@ func TestReconcileResponsiveGC(t *testing.T) {
 								LatestRevision:    ptr.Bool(true),
 								Percent:           ptr.Int64(100),
 							},
-							Active: true,
 						}},
 					},
 				},
@@ -1825,7 +1791,6 @@ func TestReconcileResponsiveGC(t *testing.T) {
 								RevisionName: "config-00001",
 								Percent:      ptr.Int64(100),
 							},
-							Active: true,
 						}},
 					},
 				},
@@ -1880,7 +1845,6 @@ func TestReconcileEnableAutoTLS(t *testing.T) {
 								Percent:           ptr.Int64(100),
 							},
 							ServiceName: "mcd",
-							Active:      true,
 						}},
 					},
 				},
@@ -1937,7 +1901,6 @@ func TestReconcileEnableAutoTLS(t *testing.T) {
 								Percent:           ptr.Int64(100),
 							},
 							ServiceName: "mcd",
-							Active:      true,
 						}},
 					},
 				},
@@ -1991,7 +1954,6 @@ func TestReconcileEnableAutoTLS(t *testing.T) {
 								Percent:           ptr.Int64(100),
 							},
 							ServiceName: "mcd",
-							Active:      true,
 						}},
 					},
 				},
@@ -2068,7 +2030,6 @@ func TestReconcileEnableAutoTLS(t *testing.T) {
 								Percent:           ptr.Int64(100),
 							},
 							ServiceName: "mcd",
-							Active:      true,
 						}},
 					},
 				},
@@ -2160,7 +2121,6 @@ func TestReconcileEnableAutoTLS(t *testing.T) {
 								Percent:           ptr.Int64(100),
 							},
 							ServiceName: "mcd",
-							Active:      true,
 						}},
 					},
 				},
@@ -2292,13 +2252,9 @@ func TestReconcileEnableAutoTLS(t *testing.T) {
 								Percent:           ptr.Int64(100),
 							},
 							ServiceName: "mcd",
-							Active:      true,
 						}},
 					},
-				},
-				nil,
-				nil,
-			),
+				}, nil, nil),
 			simpleK8sService(
 				Route("default", "becomes-ready", WithConfigTarget("config"), WithRouteUID("12-34")),
 				WithExternalName("becomes-ready.default.example.com"),
@@ -2350,7 +2306,6 @@ func TestReconcileEnableAutoTLS(t *testing.T) {
 								Percent:           ptr.Int64(100),
 							},
 							ServiceName: "tb",
-							Active:      true,
 						}},
 					},
 				},
@@ -2374,7 +2329,6 @@ func TestReconcileEnableAutoTLS(t *testing.T) {
 								Percent:           ptr.Int64(100),
 							},
 							ServiceName: "tb",
-							Active:      true,
 						}},
 					},
 					Visibility: map[string]netv1alpha1.IngressVisibility{
@@ -2481,13 +2435,9 @@ func TestReconcileEnableAutoTLSHTTPDisabled(t *testing.T) {
 								Percent:           ptr.Int64(100),
 							},
 							ServiceName: "mcd",
-							Active:      true,
 						}},
 					},
-				},
-				nil,
-				nil,
-			),
+				}, nil, nil),
 			simpleK8sService(
 				Route("default", "becomes-ready", WithConfigTarget("config"), WithRouteUID("12-34")),
 				WithExternalName("becomes-ready.default.example.com"),
diff --git a/pkg/reconciler/route/traffic/traffic_test.go b/pkg/reconciler/route/traffic/traffic_test.go
index d2656f55a..863b2e870 100644
--- a/pkg/reconciler/route/traffic/traffic_test.go
+++ b/pkg/reconciler/route/traffic/traffic_test.go
@@ -147,7 +147,6 @@ func TestBuildTrafficConfigurationVanilla(t *testing.T) {
 					Percent:           ptr.Int64(100),
 					LatestRevision:    ptr.Bool(true),
 				},
-				Active:   true,
 				Protocol: net.ProtocolH2C,
 			}},
 		},
@@ -158,7 +157,6 @@ func TestBuildTrafficConfigurationVanilla(t *testing.T) {
 				Percent:           ptr.Int64(100),
 				LatestRevision:    ptr.Bool(true),
 			},
-			Active:   true,
 			Protocol: net.ProtocolH2C,
 		}},
 		Configurations: map[string]*v1.Configuration{
@@ -179,6 +177,7 @@ func TestBuildTrafficConfigurationVanilla(t *testing.T) {
 	wantR := &Rollout{
 		Configurations: []ConfigurationRollout{{
 			ConfigurationName: goodConfig.Name,
+			Percent:           100,
 			Revisions: []RevisionRollout{{
 				RevisionName: goodNewRev.Name,
 				Percent:      100,
@@ -209,7 +208,6 @@ func TestBuildTrafficConfigurationNoNameRevision(t *testing.T) {
 					Percent:           ptr.Int64(100),
 					LatestRevision:    ptr.Bool(false),
 				},
-				Active:   true,
 				Protocol: net.ProtocolH2C,
 			}},
 		},
@@ -220,7 +218,6 @@ func TestBuildTrafficConfigurationNoNameRevision(t *testing.T) {
 				Percent:           ptr.Int64(100),
 				LatestRevision:    ptr.Bool(false),
 			},
-			Active:   true,
 			Protocol: net.ProtocolH2C,
 		}},
 		Configurations: map[string]*v1.Configuration{goodConfig.Name: goodConfig},
@@ -248,7 +245,6 @@ func TestBuildTrafficConfigurationVanillaScaledToZero(t *testing.T) {
 					Percent:           ptr.Int64(100),
 					LatestRevision:    ptr.Bool(true),
 				},
-				Active:   false,
 				Protocol: net.ProtocolHTTP1,
 			}},
 		},
@@ -259,7 +255,6 @@ func TestBuildTrafficConfigurationVanillaScaledToZero(t *testing.T) {
 				Percent:           ptr.Int64(100),
 				LatestRevision:    ptr.Bool(true),
 			},
-			Active:   false,
 			Protocol: net.ProtocolHTTP1,
 		}},
 		Configurations: map[string]*v1.Configuration{
@@ -282,6 +277,7 @@ func TestBuildTrafficConfigurationVanillaScaledToZero(t *testing.T) {
 	wantR := &Rollout{
 		Configurations: []ConfigurationRollout{{
 			ConfigurationName: inactiveConfig.Name,
+			Percent:           100,
 			Revisions: []RevisionRollout{{
 				RevisionName: inactiveRev.Name,
 				Percent:      100,
@@ -304,7 +300,6 @@ func TestBuildTrafficConfigurationTwoConfigs(t *testing.T) {
 					Percent:           ptr.Int64(90),
 					LatestRevision:    ptr.Bool(true),
 				},
-				Active:   true,
 				Protocol: net.ProtocolH2C,
 			}, {
 				TrafficTarget: v1.TrafficTarget{
@@ -313,7 +308,6 @@ func TestBuildTrafficConfigurationTwoConfigs(t *testing.T) {
 					Percent:           ptr.Int64(10),
 					LatestRevision:    ptr.Bool(true),
 				},
-				Active:   true,
 				Protocol: net.ProtocolH2C,
 			}},
 		},
@@ -324,7 +318,6 @@ func TestBuildTrafficConfigurationTwoConfigs(t *testing.T) {
 				Percent:           ptr.Int64(90),
 				LatestRevision:    ptr.Bool(true),
 			},
-			Active:   true,
 			Protocol: net.ProtocolH2C,
 		}, {
 			TrafficTarget: v1.TrafficTarget{
@@ -333,7 +326,6 @@ func TestBuildTrafficConfigurationTwoConfigs(t *testing.T) {
 				Percent:           ptr.Int64(10),
 				LatestRevision:    ptr.Bool(true),
 			},
-			Active:   true,
 			Protocol: net.ProtocolH2C,
 		}},
 		Configurations: map[string]*v1.Configuration{
@@ -368,7 +360,6 @@ func TestBuildTrafficConfigurationTwoEntriesSameConfig(t *testing.T) {
 					Percent:           ptr.Int64(100),
 					LatestRevision:    ptr.Bool(true),
 				},
-				Active:   true,
 				Protocol: net.ProtocolH2C,
 			}},
 		},
@@ -379,7 +370,6 @@ func TestBuildTrafficConfigurationTwoEntriesSameConfig(t *testing.T) {
 				Percent:           ptr.Int64(100),
 				LatestRevision:    ptr.Bool(true),
 			},
-			Active:   true,
 			Protocol: net.ProtocolH2C,
 		}},
 		Configurations: map[string]*v1.Configuration{
@@ -432,6 +422,7 @@ func TestBuildTrafficConfigurationTwoEntriesSameConfig(t *testing.T) {
 	wantR := &Rollout{
 		Configurations: []ConfigurationRollout{{
 			ConfigurationName: niceConfig.Name,
+			Percent:           100,
 			Revisions: []RevisionRollout{{
 				RevisionName: niceNewRev.Name,
 				Percent:      100,
@@ -454,7 +445,6 @@ func TestBuildTrafficConfigThreeConfigs(t *testing.T) {
 					Percent:           ptr.Int64(30),
 					LatestRevision:    ptr.Bool(true),
 				},
-				Active:   true,
 				Protocol: net.ProtocolH2C,
 			}, {
 				TrafficTarget: v1.TrafficTarget{
@@ -464,7 +454,6 @@ func TestBuildTrafficConfigThreeConfigs(t *testing.T) {
 					LatestRevision:    ptr.Bool(true),
 					Tag:               "robert",
 				},
-				Active:   true,
 				Protocol: net.ProtocolH2C,
 			}, {
 				TrafficTarget: v1.TrafficTarget{
@@ -474,7 +463,6 @@ func TestBuildTrafficConfigThreeConfigs(t *testing.T) {
 					LatestRevision:    ptr.Bool(true),
 					Tag:               "jackson",
 				},
-				Active:   false,
 				Protocol: net.ProtocolHTTP1,
 			}},
 			"robert": {{
@@ -485,7 +473,6 @@ func TestBuildTrafficConfigThreeConfigs(t *testing.T) {
 					Tag:               "robert",
 					LatestRevision:    ptr.Bool(true),
 				},
-				Active:   true,
 				Protocol: net.ProtocolH2C,
 			}},
 			"jackson": {{
@@ -496,7 +483,6 @@ func TestBuildTrafficConfigThreeConfigs(t *testing.T) {
 					Tag:               "jackson",
 					LatestRevision:    ptr.Bool(true),
 				},
-				Active:   false,
 				Protocol: net.ProtocolHTTP1,
 			}},
 		},
@@ -507,7 +493,6 @@ func TestBuildTrafficConfigThreeConfigs(t *testing.T) {
 				Percent:           ptr.Int64(30),
 				LatestRevision:    ptr.Bool(true),
 			},
-			Active:   true,
 			Protocol: net.ProtocolH2C,
 		}, {
 			TrafficTarget: v1.TrafficTarget{
@@ -517,7 +502,6 @@ func TestBuildTrafficConfigThreeConfigs(t *testing.T) {
 				LatestRevision:    ptr.Bool(true),
 				Tag:               "robert",
 			},
-			Active:   true,
 			Protocol: net.ProtocolH2C,
 		}, {
 			TrafficTarget: v1.TrafficTarget{
@@ -527,7 +511,6 @@ func TestBuildTrafficConfigThreeConfigs(t *testing.T) {
 				LatestRevision:    ptr.Bool(true),
 				Tag:               "jackson",
 			},
-			Active:   false,
 			Protocol: net.ProtocolHTTP1,
 		}},
 		Configurations: map[string]*v1.Configuration{
@@ -566,18 +549,21 @@ func TestBuildTrafficConfigThreeConfigs(t *testing.T) {
 		// Default tag configs are sorted as well.
 		Configurations: []ConfigurationRollout{{
 			ConfigurationName: goodConfig.Name,
+			Percent:           35,
 			Revisions: []RevisionRollout{{
 				RevisionName: goodNewRev.Name,
 				Percent:      35,
 			}},
 		}, {
 			ConfigurationName: inactiveConfig.Name,
+			Percent:           35,
 			Revisions: []RevisionRollout{{
 				RevisionName: inactiveRev.Name,
 				Percent:      35,
 			}},
 		}, {
 			ConfigurationName: niceConfig.Name,
+			Percent:           30,
 			Revisions: []RevisionRollout{{
 				RevisionName: niceNewRev.Name,
 				Percent:      30,
@@ -586,6 +572,7 @@ func TestBuildTrafficConfigThreeConfigs(t *testing.T) {
 			// Note sorting flipped these two.
 			ConfigurationName: inactiveConfig.Name,
 			Tag:               "jackson",
+			Percent:           100,
 			Revisions: []RevisionRollout{{
 				RevisionName: inactiveRev.Name,
 				Percent:      100,
@@ -593,6 +580,7 @@ func TestBuildTrafficConfigThreeConfigs(t *testing.T) {
 		}, {
 			ConfigurationName: goodConfig.Name,
 			Tag:               "robert",
+			Percent:           100,
 			Revisions: []RevisionRollout{{
 				RevisionName: goodNewRev.Name,
 				Percent:      100,
@@ -613,7 +601,6 @@ func TestBuildTrafficConfigurationTwoEntriesSameConfigDifferentTags(t *testing.T
 					Percent:           ptr.Int64(100),
 					LatestRevision:    ptr.Bool(true),
 				},
-				Active:   true,
 				Protocol: net.ProtocolH2C,
 			}},
 			"robert": {{
@@ -624,7 +611,6 @@ func TestBuildTrafficConfigurationTwoEntriesSameConfigDifferentTags(t *testing.T
 					Tag:               "robert",
 					LatestRevision:    ptr.Bool(true),
 				},
-				Active:   true,
 				Protocol: net.ProtocolH2C,
 			}},
 		},
@@ -635,7 +621,6 @@ func TestBuildTrafficConfigurationTwoEntriesSameConfigDifferentTags(t *testing.T
 				Percent:           ptr.Int64(90),
 				LatestRevision:    ptr.Bool(true),
 			},
-			Active:   true,
 			Protocol: net.ProtocolH2C,
 		}, {
 			TrafficTarget: v1.TrafficTarget{
@@ -645,7 +630,6 @@ func TestBuildTrafficConfigurationTwoEntriesSameConfigDifferentTags(t *testing.T
 				LatestRevision:    ptr.Bool(true),
 				Tag:               "robert",
 			},
-			Active:   true,
 			Protocol: net.ProtocolH2C,
 		}},
 		Configurations: map[string]*v1.Configuration{
@@ -675,6 +659,7 @@ func TestBuildTrafficConfigurationTwoEntriesSameConfigDifferentTags(t *testing.T
 	wantR := &Rollout{
 		Configurations: []ConfigurationRollout{{
 			ConfigurationName: niceConfig.Name,
+			Percent:           100,
 			Revisions: []RevisionRollout{{
 				RevisionName: niceNewRev.Name,
 				Percent:      100,
@@ -682,6 +667,7 @@ func TestBuildTrafficConfigurationTwoEntriesSameConfigDifferentTags(t *testing.T
 		}, {
 			ConfigurationName: niceConfig.Name,
 			Tag:               "robert",
+			Percent:           100,
 			Revisions: []RevisionRollout{{
 				RevisionName: niceNewRev.Name,
 				Percent:      100,
@@ -704,7 +690,6 @@ func TestBuildTrafficConfigurationCanary(t *testing.T) {
 					Percent:           ptr.Int64(90),
 					LatestRevision:    ptr.Bool(false),
 				},
-				Active:   true,
 				Protocol: net.ProtocolHTTP1,
 			}, {
 				TrafficTarget: v1.TrafficTarget{
@@ -713,7 +698,6 @@ func TestBuildTrafficConfigurationCanary(t *testing.T) {
 					Percent:           ptr.Int64(10),
 					LatestRevision:    ptr.Bool(true),
 				},
-				Active:   true,
 				Protocol: net.ProtocolH2C,
 			}},
 		},
@@ -724,7 +708,6 @@ func TestBuildTrafficConfigurationCanary(t *testing.T) {
 				Percent:           ptr.Int64(90),
 				LatestRevision:    ptr.Bool(false),
 			},
-			Active:   true,
 			Protocol: net.ProtocolHTTP1,
 		}, {
 			TrafficTarget: v1.TrafficTarget{
@@ -733,7 +716,6 @@ func TestBuildTrafficConfigurationCanary(t *testing.T) {
 				Percent:           ptr.Int64(10),
 				LatestRevision:    ptr.Bool(true),
 			},
-			Active:   true,
 			Protocol: net.ProtocolH2C,
 		}},
 		Configurations: map[string]*v1.Configuration{
@@ -769,7 +751,6 @@ func TestBuildTrafficConfigurationConsolidated(t *testing.T) {
 					Percent:           ptr.Int64(49),
 					LatestRevision:    ptr.Bool(false),
 				},
-				Active:   true,
 				Protocol: net.ProtocolHTTP1,
 			}, {
 				TrafficTarget: v1.TrafficTarget{
@@ -779,7 +760,6 @@ func TestBuildTrafficConfigurationConsolidated(t *testing.T) {
 					Percent:           ptr.Int64(51),
 					LatestRevision:    ptr.Bool(false),
 				},
-				Active:   true,
 				Protocol: net.ProtocolH2C,
 			}},
 			"one": {{
@@ -790,7 +770,6 @@ func TestBuildTrafficConfigurationConsolidated(t *testing.T) {
 					Percent:           ptr.Int64(100),
 					LatestRevision:    ptr.Bool(false),
 				},
-				Active:   true,
 				Protocol: net.ProtocolHTTP1,
 			}},
 			"two": {{
@@ -801,7 +780,6 @@ func TestBuildTrafficConfigurationConsolidated(t *testing.T) {
 					Percent:           ptr.Int64(100),
 					LatestRevision:    ptr.Bool(false),
 				},
-				Active:   true,
 				Protocol: net.ProtocolH2C,
 			}},
 			"also-two": {{
@@ -812,7 +790,6 @@ func TestBuildTrafficConfigurationConsolidated(t *testing.T) {
 					Percent:           ptr.Int64(100),
 					LatestRevision:    ptr.Bool(true),
 				},
-				Active:   true,
 				Protocol: net.ProtocolH2C,
 			}},
 		},
@@ -824,7 +801,6 @@ func TestBuildTrafficConfigurationConsolidated(t *testing.T) {
 				Percent:           ptr.Int64(49),
 				LatestRevision:    ptr.Bool(false),
 			},
-			Active:   true,
 			Protocol: net.ProtocolHTTP1,
 		}, {
 			TrafficTarget: v1.TrafficTarget{
@@ -834,7 +810,6 @@ func TestBuildTrafficConfigurationConsolidated(t *testing.T) {
 				Percent:           ptr.Int64(50),
 				LatestRevision:    ptr.Bool(false),
 			},
-			Active:   true,
 			Protocol: net.ProtocolH2C,
 		}, {
 			TrafficTarget: v1.TrafficTarget{
@@ -844,7 +819,6 @@ func TestBuildTrafficConfigurationConsolidated(t *testing.T) {
 				Percent:           ptr.Int64(1),
 				LatestRevision:    ptr.Bool(true),
 			},
-			Active:   true,
 			Protocol: net.ProtocolH2C,
 		}},
 		Configurations: map[string]*v1.Configuration{
@@ -885,7 +859,6 @@ func TestBuildTrafficConfigurationTwoFixedRevisions(t *testing.T) {
 					Percent:           ptr.Int64(90),
 					LatestRevision:    ptr.Bool(false),
 				},
-				Active:   true,
 				Protocol: net.ProtocolHTTP1,
 			}, {
 				TrafficTarget: v1.TrafficTarget{
@@ -894,7 +867,6 @@ func TestBuildTrafficConfigurationTwoFixedRevisions(t *testing.T) {
 					Percent:           ptr.Int64(10),
 					LatestRevision:    ptr.Bool(false),
 				},
-				Active:   true,
 				Protocol: net.ProtocolH2C,
 			}},
 		},
@@ -905,7 +877,6 @@ func TestBuildTrafficConfigurationTwoFixedRevisions(t *testing.T) {
 				Percent:           ptr.Int64(90),
 				LatestRevision:    ptr.Bool(false),
 			},
-			Active:   true,
 			Protocol: net.ProtocolHTTP1,
 		}, {
 			TrafficTarget: v1.TrafficTarget{
@@ -914,7 +885,6 @@ func TestBuildTrafficConfigurationTwoFixedRevisions(t *testing.T) {
 				Percent:           ptr.Int64(10),
 				LatestRevision:    ptr.Bool(false),
 			},
-			Active:   true,
 			Protocol: net.ProtocolH2C,
 		}},
 		Configurations: map[string]*v1.Configuration{
@@ -957,7 +927,6 @@ func TestBuildTrafficConfigurationTwoFixedRevisionsFromTwoConfigurations(t *test
 					Percent:           ptr.Int64(40),
 					LatestRevision:    ptr.Bool(false),
 				},
-				Active:   true,
 				Protocol: net.ProtocolH2C,
 			}, {
 				TrafficTarget: v1.TrafficTarget{
@@ -966,7 +935,6 @@ func TestBuildTrafficConfigurationTwoFixedRevisionsFromTwoConfigurations(t *test
 					Percent:           ptr.Int64(60),
 					LatestRevision:    ptr.Bool(false),
 				},
-				Active:   true,
 				Protocol: net.ProtocolH2C,
 			}},
 		},
@@ -977,7 +945,6 @@ func TestBuildTrafficConfigurationTwoFixedRevisionsFromTwoConfigurations(t *test
 				Percent:           ptr.Int64(40),
 				LatestRevision:    ptr.Bool(false),
 			},
-			Active:   true,
 			Protocol: net.ProtocolH2C,
 		}, {
 			TrafficTarget: v1.TrafficTarget{
@@ -986,7 +953,6 @@ func TestBuildTrafficConfigurationTwoFixedRevisionsFromTwoConfigurations(t *test
 				Percent:           ptr.Int64(60),
 				LatestRevision:    ptr.Bool(false),
 			},
-			Active:   true,
 			Protocol: net.ProtocolH2C,
 		}},
 		Configurations: map[string]*v1.Configuration{
@@ -1022,7 +988,6 @@ func TestBuildTrafficConfigurationPreliminary(t *testing.T) {
 					Percent:           ptr.Int64(100),
 					LatestRevision:    ptr.Bool(false),
 				},
-				Active:   true,
 				Protocol: net.ProtocolHTTP1,
 			}, {
 				TrafficTarget: v1.TrafficTarget{
@@ -1030,17 +995,17 @@ func TestBuildTrafficConfigurationPreliminary(t *testing.T) {
 					ConfigurationName: goodConfig.Name,
 					RevisionName:      goodNewRev.Name,
 					LatestRevision:    ptr.Bool(false),
+					Percent:           ptr.Int64(0),
 				},
-				Active:   true,
 				Protocol: net.ProtocolH2C,
 			}, {
 				TrafficTarget: v1.TrafficTarget{
 					Tag:               "alpha",
 					ConfigurationName: niceConfig.Name,
 					RevisionName:      niceNewRev.Name,
+					Percent:           ptr.Int64(0),
 					LatestRevision:    ptr.Bool(true),
 				},
-				Active:   true,
 				Protocol: net.ProtocolH2C,
 			}},
 			"beta": {{
@@ -1051,7 +1016,6 @@ func TestBuildTrafficConfigurationPreliminary(t *testing.T) {
 					Percent:           ptr.Int64(100),
 					LatestRevision:    ptr.Bool(false),
 				},
-				Active:   true,
 				Protocol: net.ProtocolH2C,
 			}},
 			"alpha": {{
@@ -1062,7 +1026,6 @@ func TestBuildTrafficConfigurationPreliminary(t *testing.T) {
 					Percent:           ptr.Int64(100),
 					LatestRevision:    ptr.Bool(true),
 				},
-				Active:   true,
 				Protocol: net.ProtocolH2C,
 			}},
 		},
@@ -1073,7 +1036,6 @@ func TestBuildTrafficConfigurationPreliminary(t *testing.T) {
 				Percent:           ptr.Int64(100),
 				LatestRevision:    ptr.Bool(false),
 			},
-			Active:   true,
 			Protocol: net.ProtocolHTTP1,
 		}, {
 			TrafficTarget: v1.TrafficTarget{
@@ -1081,8 +1043,8 @@ func TestBuildTrafficConfigurationPreliminary(t *testing.T) {
 				ConfigurationName: goodConfig.Name,
 				RevisionName:      goodNewRev.Name,
 				LatestRevision:    ptr.Bool(false),
+				Percent:           ptr.Int64(0),
 			},
-			Active:   true,
 			Protocol: net.ProtocolH2C,
 		}, {
 			TrafficTarget: v1.TrafficTarget{
@@ -1090,8 +1052,8 @@ func TestBuildTrafficConfigurationPreliminary(t *testing.T) {
 				ConfigurationName: niceConfig.Name,
 				RevisionName:      niceNewRev.Name,
 				LatestRevision:    ptr.Bool(true),
+				Percent:           ptr.Int64(0),
 			},
-			Active:   true,
 			Protocol: net.ProtocolH2C,
 		}},
 		Configurations: map[string]*v1.Configuration{
@@ -1318,11 +1280,13 @@ func TestRoundTripping(t *testing.T) {
 		RevisionName:   goodNewRev.Name,
 		URL:            domains.URL(domains.HTTPScheme, "beta-test-route.test.example.com"),
 		LatestRevision: ptr.Bool(false),
+		Percent:        ptr.Int64(0),
 	}, {
 		Tag:            "alpha",
 		RevisionName:   niceNewRev.Name,
 		URL:            domains.URL(domains.HTTPScheme, "alpha-test-route.test.example.com"),
 		LatestRevision: ptr.Bool(true),
+		Percent:        ptr.Int64(0),
 	}}
 	route := testRouteWithTrafficTargets(WithSpecTraffic(v1.TrafficTarget{
 		RevisionName: goodOldRev.Name,
diff --git a/test/conformance/api/v1/service_test.go b/test/conformance/api/v1/service_test.go
index 718ba3aeb..2d9b8f5df 100644
--- a/test/conformance/api/v1/service_test.go
+++ b/test/conformance/api/v1/service_test.go
@@ -24,6 +24,7 @@ import (
 
 	"github.com/google/go-cmp/cmp"
 	"github.com/google/go-cmp/cmp/cmpopts"
+
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	"knative.dev/pkg/ptr"
 	pkgTest "knative.dev/pkg/test"
@@ -305,6 +306,7 @@ func TestServiceWithTrafficSplit(t *testing.T) {
 			Tag:            "latest",
 			RevisionName:   objects.Config.Status.LatestReadyRevisionName,
 			LatestRevision: ptr.Bool(true),
+			Percent:        ptr.Int64(0),
 		},
 	}
 	t.Log("Waiting for Service to become ready with the new shape.")
@@ -338,6 +340,7 @@ func TestServiceWithTrafficSplit(t *testing.T) {
 		Tag:            "latest",
 		RevisionName:   secondRevision,
 		LatestRevision: ptr.Bool(true),
+		Percent:        ptr.Int64(0),
 	}
 	t.Log("Waiting for Service to become ready with the new shape.")
 	if err := waitForDesiredTrafficShape(t, names.Service, desiredTrafficShape, clients); err != nil {
@@ -365,8 +368,7 @@ func TestServiceWithTrafficSplit(t *testing.T) {
 			RevisionName: secondRevision,
 			Percent:      ptr.Int64(50),
 		}, {
-			Tag:     "latest",
-			Percent: nil,
+			Tag: "latest",
 		}},
 	})
 	if err != nil {
@@ -390,6 +392,7 @@ func TestServiceWithTrafficSplit(t *testing.T) {
 			Tag:            "latest",
 			RevisionName:   secondRevision,
 			LatestRevision: ptr.Bool(true),
+			Percent:        ptr.Int64(0),
 		},
 	}
 	t.Log("Waiting for Service to become ready with the new shape.")
@@ -421,6 +424,7 @@ func TestServiceWithTrafficSplit(t *testing.T) {
 		Tag:            "latest",
 		RevisionName:   thirdRevision,
 		LatestRevision: ptr.Bool(true),
+		Percent:        ptr.Int64(0),
 	}
 	t.Log("Waiting for Service to become ready with the new shape.")
 	if err := waitForDesiredTrafficShape(t, names.Service, desiredTrafficShape, clients); err != nil {
diff --git a/test/e2e-tests.sh b/test/e2e-tests.sh
index 4414e6b86..b22de1b4c 100755
--- a/test/e2e-tests.sh
+++ b/test/e2e-tests.sh
@@ -132,7 +132,7 @@ go_test_e2e -timeout=20m -parallel=300 ./test/scale || failed=1
 
 # Run HA tests separately as they're stopping core Knative Serving pods
 # Define short -spoofinterval to ensure frequent probing while stopping pods
-go_test_e2e -timeout=15m -failfast -parallel=1 ./test/ha \
+go_test_e2e -timeout=25m -failfast -parallel=1 ./test/ha \
 	    -replicas="${REPLICAS:-1}" -buckets="${BUCKETS:-1}" -spoofinterval="10ms" || failed=1
 
 (( failed )) && fail_test
diff --git a/third_party/cert-manager-latest/net-certmanager.yaml b/third_party/cert-manager-latest/net-certmanager.yaml
index b7b627541..0dfd5db86 100644
--- a/third_party/cert-manager-latest/net-certmanager.yaml
+++ b/third_party/cert-manager-latest/net-certmanager.yaml
@@ -18,7 +18,7 @@ metadata:
   # These are the permissions needed by the `cert-manager` `Certificate` implementation.
   name: knative-serving-certmanager
   labels:
-    serving.knative.dev/release: "v20201022-49d24d5"
+    serving.knative.dev/release: "v20201023-b976324"
     serving.knative.dev/controller: "true"
     networking.knative.dev/certificate-provider: cert-manager
 rules:
@@ -49,7 +49,7 @@ kind: ValidatingWebhookConfiguration
 metadata:
   name: config.webhook.net-certmanager.networking.internal.knative.dev
   labels:
-    serving.knative.dev/release: "v20201022-49d24d5"
+    serving.knative.dev/release: "v20201023-b976324"
 webhooks:
   - admissionReviewVersions:
       - v1beta1
@@ -86,7 +86,7 @@ metadata:
   name: net-certmanager-webhook-certs
   namespace: knative-serving
   labels:
-    serving.knative.dev/release: "v20201022-49d24d5"
+    serving.knative.dev/release: "v20201023-b976324"
 
 ---
 # Copyright 2020 The Knative Authors
@@ -109,7 +109,7 @@ metadata:
   name: config-certmanager
   namespace: knative-serving
   labels:
-    serving.knative.dev/release: "v20201022-49d24d5"
+    serving.knative.dev/release: "v20201023-b976324"
     networking.knative.dev/certificate-provider: cert-manager
 data:
   _example: |
@@ -156,7 +156,7 @@ metadata:
   name: networking-certmanager
   namespace: knative-serving
   labels:
-    serving.knative.dev/release: "v20201022-49d24d5"
+    serving.knative.dev/release: "v20201023-b976324"
     networking.knative.dev/certificate-provider: cert-manager
 spec:
   selector:
@@ -168,14 +168,14 @@ spec:
         cluster-autoscaler.kubernetes.io/safe-to-evict: "true"
       labels:
         app: networking-certmanager
-        serving.knative.dev/release: "v20201022-49d24d5"
+        serving.knative.dev/release: "v20201023-b976324"
     spec:
       serviceAccountName: controller
       containers:
         - name: networking-certmanager
           # This is the Go import path for the binary that is containerized
           # and substituted here.
-          image: gcr.io/knative-nightly/knative.dev/net-certmanager/cmd/controller@sha256:7bac4ea2dd54040b3ddc16b040446dd177af9b0bd7f7454797ca69327fd0ab1b
+          image: gcr.io/knative-nightly/knative.dev/net-certmanager/cmd/controller@sha256:7f903b7d362a61918602403d40f3711a8c94f595e505dfbeb2053d3f589317fb
           resources:
             requests:
               cpu: 30m
@@ -208,7 +208,7 @@ kind: Service
 metadata:
   labels:
     app: networking-certmanager
-    serving.knative.dev/release: "v20201022-49d24d5"
+    serving.knative.dev/release: "v20201023-b976324"
     networking.knative.dev/certificate-provider: cert-manager
   name: networking-certmanager
   namespace: knative-serving
@@ -245,7 +245,7 @@ metadata:
   name: net-certmanager-webhook
   namespace: knative-serving
   labels:
-    serving.knative.dev/release: "v20201022-49d24d5"
+    serving.knative.dev/release: "v20201023-b976324"
 spec:
   selector:
     matchLabels:
@@ -258,14 +258,14 @@ spec:
       labels:
         app: net-certmanager-webhook
         role: net-certmanager-webhook
-        serving.knative.dev/release: "v20201022-49d24d5"
+        serving.knative.dev/release: "v20201023-b976324"
     spec:
       serviceAccountName: controller
       containers:
         - name: webhook
           # This is the Go import path for the binary that is containerized
           # and substituted here.
-          image: gcr.io/knative-nightly/knative.dev/net-certmanager/cmd/webhook@sha256:82c1310231b75477514d969f9c51fb83f0696190110db4baafaf93a1127fd46c
+          image: gcr.io/knative-nightly/knative.dev/net-certmanager/cmd/webhook@sha256:b13f20704cddda9dc2761ae64c9fa8067106b6b2772dfc8c2e93d482a7b6ae08
           resources:
             requests:
               cpu: 20m
@@ -319,7 +319,7 @@ metadata:
   namespace: knative-serving
   labels:
     role: net-certmanager-webhook
-    serving.knative.dev/release: "v20201022-49d24d5"
+    serving.knative.dev/release: "v20201023-b976324"
 spec:
   ports:
     # Define metrics and profiling for them to be accessible within service meshes.