mirror of https://github.com/knative/serving.git
Add v1beta1 version of DomainMapping crd (#11682)
* Add v1beta1 version of DomainMapping crd * Keep v1alpha1 as storage version for a release * Update copyright year * Rerun codegen after rebase * Regenerate with new boilerplate
This commit is contained in:
parent
644798277d
commit
5a51323d83
|
@ -31,11 +31,13 @@ import (
|
|||
"knative.dev/pkg/webhook/resourcesemantics/defaulting"
|
||||
"knative.dev/pkg/webhook/resourcesemantics/validation"
|
||||
servingv1alpha1 "knative.dev/serving/pkg/apis/serving/v1alpha1"
|
||||
servingv1beta1 "knative.dev/serving/pkg/apis/serving/v1beta1"
|
||||
"knative.dev/serving/pkg/reconciler/domainmapping/config"
|
||||
)
|
||||
|
||||
var types = map[schema.GroupVersionKind]resourcesemantics.GenericCRD{
|
||||
servingv1alpha1.SchemeGroupVersion.WithKind("DomainMapping"): &servingv1alpha1.DomainMapping{},
|
||||
servingv1beta1.SchemeGroupVersion.WithKind("DomainMapping"): &servingv1beta1.DomainMapping{},
|
||||
}
|
||||
|
||||
func newDefaultingAdmissionController(ctx context.Context, cmw configmap.Watcher) *controller.Impl {
|
||||
|
|
|
@ -22,6 +22,122 @@ metadata:
|
|||
spec:
|
||||
group: serving.knative.dev
|
||||
versions:
|
||||
- name: v1beta1
|
||||
served: true
|
||||
storage: false
|
||||
subresources:
|
||||
status: {}
|
||||
additionalPrinterColumns:
|
||||
- name: URL
|
||||
type: string
|
||||
jsonPath: .status.url
|
||||
- name: Ready
|
||||
type: string
|
||||
jsonPath: ".status.conditions[?(@.type=='Ready')].status"
|
||||
- name: Reason
|
||||
type: string
|
||||
jsonPath: ".status.conditions[?(@.type=='Ready')].reason"
|
||||
"schema":
|
||||
"openAPIV3Schema":
|
||||
description: DomainMapping is a mapping from a custom hostname to an Addressable.
|
||||
type: object
|
||||
properties:
|
||||
apiVersion:
|
||||
description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: 'Spec is the desired state of the DomainMapping. More info: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status'
|
||||
type: object
|
||||
required:
|
||||
- ref
|
||||
properties:
|
||||
ref:
|
||||
description: "Ref specifies the target of the Domain Mapping. \n The object identified by the Ref must be an Addressable with a URL of the form `{name}.{namespace}.{domain}` where `{domain}` is the cluster domain, and `{name}` and `{namespace}` are the name and namespace of a Kubernetes Service. \n This contract is satisfied by Knative types such as Knative Services and Knative Routes, and by Kubernetes Services."
|
||||
type: object
|
||||
required:
|
||||
- kind
|
||||
- name
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
group:
|
||||
description: 'Group of the API, without the version of the group. This can be used as an alternative to the APIVersion, and then resolved using ResolveGroup. Note: This API is EXPERIMENTAL and might break anytime. For more details: https://github.com/knative/eventing/issues/5086'
|
||||
type: string
|
||||
kind:
|
||||
description: 'Kind of the referent. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
|
||||
type: string
|
||||
name:
|
||||
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
|
||||
type: string
|
||||
namespace:
|
||||
description: 'Namespace of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/ This is optional field, it gets defaulted to the object holding it if left out.'
|
||||
type: string
|
||||
tls:
|
||||
description: TLS allows the DomainMapping to terminate TLS traffic with an existing secret.
|
||||
type: object
|
||||
required:
|
||||
- secretName
|
||||
properties:
|
||||
secretName:
|
||||
description: SecretName is the name of the existing secret used to terminate TLS traffic.
|
||||
type: string
|
||||
status:
|
||||
description: 'Status is the current state of the DomainMapping. More info: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status'
|
||||
type: object
|
||||
properties:
|
||||
address:
|
||||
description: Address holds the information needed for a DomainMapping to be the target of an event.
|
||||
type: object
|
||||
properties:
|
||||
url:
|
||||
type: string
|
||||
annotations:
|
||||
description: Annotations is additional Status fields for the Resource to save some additional State as well as convey more information to the user. This is roughly akin to Annotations on any k8s resource, just the reconciler conveying richer information outwards.
|
||||
type: object
|
||||
additionalProperties:
|
||||
type: string
|
||||
conditions:
|
||||
description: Conditions the latest available observations of a resource's current state.
|
||||
type: array
|
||||
items:
|
||||
description: 'Condition defines a readiness condition for a Knative resource. See: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#typical-status-properties'
|
||||
type: object
|
||||
required:
|
||||
- status
|
||||
- type
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: LastTransitionTime is the last time the condition transitioned from one status to another. We use VolatileTime in place of metav1.Time to exclude this from creating equality.Semantic differences (all other things held constant).
|
||||
type: string
|
||||
format: date-time
|
||||
message:
|
||||
description: A human readable message indicating details about the transition.
|
||||
type: string
|
||||
reason:
|
||||
description: The reason for the condition's last transition.
|
||||
type: string
|
||||
severity:
|
||||
description: Severity with which to treat failures of this type of condition. When this is not specified, it defaults to Error.
|
||||
type: string
|
||||
status:
|
||||
description: Status of the condition, one of True, False, Unknown.
|
||||
type: string
|
||||
type:
|
||||
description: Type of condition.
|
||||
type: string
|
||||
observedGeneration:
|
||||
description: ObservedGeneration is the 'Generation' of the Service that was last processed by the controller.
|
||||
type: integer
|
||||
format: int64
|
||||
url:
|
||||
description: URL is the URL of this DomainMapping.
|
||||
type: string
|
||||
- name: v1alpha1
|
||||
served: true
|
||||
storage: true
|
||||
|
|
|
@ -33,6 +33,7 @@ webhooks:
|
|||
- serving.knative.dev
|
||||
apiVersions:
|
||||
- v1alpha1
|
||||
- v1beta1
|
||||
operations:
|
||||
- CREATE
|
||||
- UPDATE
|
||||
|
|
|
@ -36,6 +36,7 @@ webhooks:
|
|||
- serving.knative.dev
|
||||
apiVersions:
|
||||
- v1alpha1
|
||||
- v1beta1
|
||||
operations:
|
||||
- CREATE
|
||||
- UPDATE
|
||||
|
|
|
@ -9,6 +9,9 @@
|
|||
<li>
|
||||
<a href="#serving.knative.dev%2fv1alpha1">serving.knative.dev/v1alpha1</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="#serving.knative.dev%2fv1beta1">serving.knative.dev/v1beta1</a>
|
||||
</li>
|
||||
</ul>
|
||||
<h2 id="autoscaling.internal.knative.dev/v1alpha1">autoscaling.internal.knative.dev/v1alpha1</h2>
|
||||
<div>
|
||||
|
@ -2321,6 +2324,310 @@ string
|
|||
</tbody>
|
||||
</table>
|
||||
<hr/>
|
||||
<h2 id="serving.knative.dev/v1beta1">serving.knative.dev/v1beta1</h2>
|
||||
<div>
|
||||
<p>Package v1beta1 contains the v1beta1 versions of the serving apis.
|
||||
Api versions allow the api contract for a resource to be changed while keeping
|
||||
backward compatibility by support multiple concurrent versions
|
||||
of the same resource</p>
|
||||
</div>
|
||||
Resource Types:
|
||||
<ul><li>
|
||||
<a href="#serving.knative.dev/v1beta1.DomainMapping">DomainMapping</a>
|
||||
</li></ul>
|
||||
<h3 id="serving.knative.dev/v1beta1.DomainMapping">DomainMapping
|
||||
</h3>
|
||||
<div>
|
||||
<p>DomainMapping is a mapping from a custom hostname to an Addressable.</p>
|
||||
</div>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Field</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<code>apiVersion</code><br/>
|
||||
string</td>
|
||||
<td>
|
||||
<code>
|
||||
serving.knative.dev/v1beta1
|
||||
</code>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>kind</code><br/>
|
||||
string
|
||||
</td>
|
||||
<td><code>DomainMapping</code></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>metadata</code><br/>
|
||||
<em>
|
||||
<a href="https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.18/#objectmeta-v1-meta">
|
||||
Kubernetes meta/v1.ObjectMeta
|
||||
</a>
|
||||
</em>
|
||||
</td>
|
||||
<td>
|
||||
<em>(Optional)</em>
|
||||
<p>Standard object’s metadata.
|
||||
More info: <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#metadata">https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#metadata</a></p>
|
||||
Refer to the Kubernetes API documentation for the fields of the
|
||||
<code>metadata</code> field.
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>spec</code><br/>
|
||||
<em>
|
||||
<a href="#serving.knative.dev/v1beta1.DomainMappingSpec">
|
||||
DomainMappingSpec
|
||||
</a>
|
||||
</em>
|
||||
</td>
|
||||
<td>
|
||||
<em>(Optional)</em>
|
||||
<p>Spec is the desired state of the DomainMapping.
|
||||
More info: <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status">https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status</a></p>
|
||||
<br/>
|
||||
<br/>
|
||||
<table>
|
||||
<tr>
|
||||
<td>
|
||||
<code>ref</code><br/>
|
||||
<em>
|
||||
<a href="https://pkg.go.dev/knative.dev/pkg/apis/duck/v1#KReference">
|
||||
knative.dev/pkg/apis/duck/v1.KReference
|
||||
</a>
|
||||
</em>
|
||||
</td>
|
||||
<td>
|
||||
<p>Ref specifies the target of the Domain Mapping.</p>
|
||||
<p>The object identified by the Ref must be an Addressable with a URL of the
|
||||
form <code>{name}.{namespace}.{domain}</code> where <code>{domain}</code> is the cluster domain,
|
||||
and <code>{name}</code> and <code>{namespace}</code> are the name and namespace of a Kubernetes
|
||||
Service.</p>
|
||||
<p>This contract is satisfied by Knative types such as Knative Services and
|
||||
Knative Routes, and by Kubernetes Services.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>tls</code><br/>
|
||||
<em>
|
||||
<a href="#serving.knative.dev/v1beta1.SecretTLS">
|
||||
SecretTLS
|
||||
</a>
|
||||
</em>
|
||||
</td>
|
||||
<td>
|
||||
<em>(Optional)</em>
|
||||
<p>TLS allows the DomainMapping to terminate TLS traffic with an existing secret.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>status</code><br/>
|
||||
<em>
|
||||
<a href="#serving.knative.dev/v1beta1.DomainMappingStatus">
|
||||
DomainMappingStatus
|
||||
</a>
|
||||
</em>
|
||||
</td>
|
||||
<td>
|
||||
<em>(Optional)</em>
|
||||
<p>Status is the current state of the DomainMapping.
|
||||
More info: <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status">https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status</a></p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h3 id="serving.knative.dev/v1beta1.CannotConvertError">CannotConvertError
|
||||
</h3>
|
||||
<div>
|
||||
<p>CannotConvertError is returned when a field cannot be converted.</p>
|
||||
</div>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Field</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<code>Message</code><br/>
|
||||
<em>
|
||||
string
|
||||
</em>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>Field</code><br/>
|
||||
<em>
|
||||
string
|
||||
</em>
|
||||
</td>
|
||||
<td>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h3 id="serving.knative.dev/v1beta1.DomainMappingSpec">DomainMappingSpec
|
||||
</h3>
|
||||
<p>
|
||||
(<em>Appears on:</em><a href="#serving.knative.dev/v1beta1.DomainMapping">DomainMapping</a>)
|
||||
</p>
|
||||
<div>
|
||||
<p>DomainMappingSpec describes the DomainMapping the user wishes to exist.</p>
|
||||
</div>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Field</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<code>ref</code><br/>
|
||||
<em>
|
||||
<a href="https://pkg.go.dev/knative.dev/pkg/apis/duck/v1#KReference">
|
||||
knative.dev/pkg/apis/duck/v1.KReference
|
||||
</a>
|
||||
</em>
|
||||
</td>
|
||||
<td>
|
||||
<p>Ref specifies the target of the Domain Mapping.</p>
|
||||
<p>The object identified by the Ref must be an Addressable with a URL of the
|
||||
form <code>{name}.{namespace}.{domain}</code> where <code>{domain}</code> is the cluster domain,
|
||||
and <code>{name}</code> and <code>{namespace}</code> are the name and namespace of a Kubernetes
|
||||
Service.</p>
|
||||
<p>This contract is satisfied by Knative types such as Knative Services and
|
||||
Knative Routes, and by Kubernetes Services.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>tls</code><br/>
|
||||
<em>
|
||||
<a href="#serving.knative.dev/v1beta1.SecretTLS">
|
||||
SecretTLS
|
||||
</a>
|
||||
</em>
|
||||
</td>
|
||||
<td>
|
||||
<em>(Optional)</em>
|
||||
<p>TLS allows the DomainMapping to terminate TLS traffic with an existing secret.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h3 id="serving.knative.dev/v1beta1.DomainMappingStatus">DomainMappingStatus
|
||||
</h3>
|
||||
<p>
|
||||
(<em>Appears on:</em><a href="#serving.knative.dev/v1beta1.DomainMapping">DomainMapping</a>)
|
||||
</p>
|
||||
<div>
|
||||
<p>DomainMappingStatus describes the current state of the DomainMapping.</p>
|
||||
</div>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Field</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<code>Status</code><br/>
|
||||
<em>
|
||||
<a href="https://pkg.go.dev/knative.dev/pkg/apis/duck/v1#Status">
|
||||
knative.dev/pkg/apis/duck/v1.Status
|
||||
</a>
|
||||
</em>
|
||||
</td>
|
||||
<td>
|
||||
<p>
|
||||
(Members of <code>Status</code> are embedded into this type.)
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>url</code><br/>
|
||||
<em>
|
||||
<a href="https://pkg.go.dev/knative.dev/pkg/apis#URL">
|
||||
knative.dev/pkg/apis.URL
|
||||
</a>
|
||||
</em>
|
||||
</td>
|
||||
<td>
|
||||
<em>(Optional)</em>
|
||||
<p>URL is the URL of this DomainMapping.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>address</code><br/>
|
||||
<em>
|
||||
<a href="https://pkg.go.dev/knative.dev/pkg/apis/duck/v1#Addressable">
|
||||
knative.dev/pkg/apis/duck/v1.Addressable
|
||||
</a>
|
||||
</em>
|
||||
</td>
|
||||
<td>
|
||||
<em>(Optional)</em>
|
||||
<p>Address holds the information needed for a DomainMapping to be the target of an event.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<h3 id="serving.knative.dev/v1beta1.SecretTLS">SecretTLS
|
||||
</h3>
|
||||
<p>
|
||||
(<em>Appears on:</em><a href="#serving.knative.dev/v1beta1.DomainMappingSpec">DomainMappingSpec</a>)
|
||||
</p>
|
||||
<div>
|
||||
<p>SecretTLS wrapper for TLS SecretName.</p>
|
||||
</div>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Field</th>
|
||||
<th>Description</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>
|
||||
<code>secretName</code><br/>
|
||||
<em>
|
||||
string
|
||||
</em>
|
||||
</td>
|
||||
<td>
|
||||
<p>SecretName is the name of the existing secret used to terminate TLS traffic.</p>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<hr/>
|
||||
<p><em>
|
||||
Generated with <code>gen-crd-api-reference-docs</code>
|
||||
.
|
||||
|
|
|
@ -66,7 +66,7 @@ group "Kubernetes Codegen"
|
|||
# instead of the $GOPATH directly. For normal projects this can be dropped.
|
||||
${CODEGEN_PKG}/generate-groups.sh "deepcopy,client,informer,lister" \
|
||||
knative.dev/serving/pkg/client knative.dev/serving/pkg/apis \
|
||||
"serving:v1 serving:v1alpha1 autoscaling:v1alpha1" \
|
||||
"serving:v1 serving:v1beta1 serving:v1alpha1 autoscaling:v1alpha1" \
|
||||
--go-header-file "${boilerplate}"
|
||||
|
||||
group "Knative Codegen"
|
||||
|
@ -74,7 +74,7 @@ group "Knative Codegen"
|
|||
# Knative Injection
|
||||
${KNATIVE_CODEGEN_PKG}/hack/generate-knative.sh "injection" \
|
||||
knative.dev/serving/pkg/client knative.dev/serving/pkg/apis \
|
||||
"serving:v1 serving:v1alpha1 autoscaling:v1alpha1" \
|
||||
"serving:v1 serving:v1beta1 serving:v1alpha1 autoscaling:v1alpha1" \
|
||||
--go-header-file "${boilerplate}"
|
||||
|
||||
group "Deepcopy Gen"
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
# Knative Serving API v1beta1
|
||||
|
||||
This is the implementation of the Knative Serving API, which is specified in
|
||||
[`docs/spec/spec.md`](/docs/spec/spec.md) and verified via
|
||||
[the conformance tests](/test/conformance).
|
||||
|
||||
**Updates to this implementation should include a corresponding change to
|
||||
[the spec](/docs/spec/spec.md) and [the conformance tests](/test/conformance).**
|
||||
([#780](https://github.com/knative/serving/issues/780))
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
Copyright 2021 The Knative Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"knative.dev/pkg/apis"
|
||||
)
|
||||
|
||||
const (
|
||||
// ConditionTypeConvertible is a Warning condition that is set on
|
||||
// resources when they cannot be converted to warn of a forthcoming
|
||||
// breakage.
|
||||
ConditionTypeConvertible apis.ConditionType = "Convertible"
|
||||
)
|
||||
|
||||
// CannotConvertError is returned when a field cannot be converted.
|
||||
type CannotConvertError struct {
|
||||
Message string
|
||||
Field string
|
||||
}
|
||||
|
||||
var _ error = (*CannotConvertError)(nil)
|
||||
|
||||
// Error implements error
|
||||
func (cce *CannotConvertError) Error() string {
|
||||
return cce.Message
|
||||
}
|
||||
|
||||
// ConvertErrorf creates a CannotConvertError from the field name and format string.
|
||||
func ConvertErrorf(field, msg string, args ...interface{}) error {
|
||||
return &CannotConvertError{
|
||||
Message: fmt.Sprintf(msg, args...),
|
||||
Field: field,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
Copyright 2021 The Knative Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1beta1
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestConvertError(t *testing.T) {
|
||||
ce := ConvertErrorf("field", "foo %v %v %v", "bar", true, 42)
|
||||
|
||||
if got, want := ce.Error(), "foo bar true 42"; got != want {
|
||||
t.Errorf("Error() = %s, wanted %s", got, want)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
Copyright 2021 The Knative Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// +k8s:deepcopy-gen=package
|
||||
// +groupName=serving.knative.dev
|
||||
|
||||
// Package v1beta1 contains the v1beta1 versions of the serving apis.
|
||||
// Api versions allow the api contract for a resource to be changed while keeping
|
||||
// backward compatibility by support multiple concurrent versions
|
||||
// of the same resource
|
||||
package v1beta1
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
Copyright 2021 The Knative Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"knative.dev/pkg/apis"
|
||||
"knative.dev/serving/pkg/apis/serving"
|
||||
)
|
||||
|
||||
// SetDefaults implements apis.Defaultable.
|
||||
func (dm *DomainMapping) SetDefaults(ctx context.Context) {
|
||||
ctx = apis.WithinParent(ctx, dm.ObjectMeta)
|
||||
dm.Spec.Ref.SetDefaults(apis.WithinSpec(ctx))
|
||||
|
||||
if apis.IsInUpdate(ctx) {
|
||||
serving.SetUserInfo(ctx, apis.GetBaseline(ctx).(*DomainMapping).Spec, dm.Spec, dm)
|
||||
} else {
|
||||
serving.SetUserInfo(ctx, nil, dm.Spec, dm)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,187 @@
|
|||
/*
|
||||
Copyright 2021 The Knative Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
authv1 "k8s.io/api/authentication/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"knative.dev/pkg/apis"
|
||||
duckv1 "knative.dev/pkg/apis/duck/v1"
|
||||
"knative.dev/serving/pkg/apis/serving"
|
||||
)
|
||||
|
||||
func TestDomainMappingDefaulting(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
in, out *DomainMapping
|
||||
}{{
|
||||
name: "empty",
|
||||
in: &DomainMapping{},
|
||||
out: &DomainMapping{},
|
||||
}, {
|
||||
name: "empty ref namespace",
|
||||
in: &DomainMapping{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "some-namespace",
|
||||
},
|
||||
},
|
||||
out: &DomainMapping{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "some-namespace",
|
||||
},
|
||||
Spec: DomainMappingSpec{
|
||||
Ref: duckv1.KReference{
|
||||
Namespace: "some-namespace",
|
||||
},
|
||||
},
|
||||
},
|
||||
}, {
|
||||
name: "explicit ref namespace",
|
||||
in: &DomainMapping{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "some-namespace",
|
||||
},
|
||||
Spec: DomainMappingSpec{
|
||||
Ref: duckv1.KReference{
|
||||
Namespace: "explicit-namespace",
|
||||
},
|
||||
},
|
||||
},
|
||||
out: &DomainMapping{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: "some-namespace",
|
||||
},
|
||||
Spec: DomainMappingSpec{
|
||||
Ref: duckv1.KReference{
|
||||
Namespace: "explicit-namespace",
|
||||
},
|
||||
},
|
||||
},
|
||||
}}
|
||||
|
||||
for _, test := range tests {
|
||||
ctx := context.Background()
|
||||
|
||||
test.in.SetDefaults(ctx)
|
||||
if !cmp.Equal(test.out, test.in) {
|
||||
t.Errorf("SetDefaults (-want, +got):\n%s", cmp.Diff(test.out, test.in))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDomainMappingUserInfo(t *testing.T) {
|
||||
const (
|
||||
u1 = "oveja@knative.dev"
|
||||
u2 = "cabra@knative.dev"
|
||||
u3 = "vaca@knative.dev"
|
||||
)
|
||||
withUserAnns := func(u1, u2 string, s *DomainMapping) *DomainMapping {
|
||||
a := s.GetAnnotations()
|
||||
if a == nil {
|
||||
a = map[string]string{}
|
||||
s.SetAnnotations(a)
|
||||
}
|
||||
a[serving.CreatorAnnotation] = u1
|
||||
a[serving.UpdaterAnnotation] = u2
|
||||
return s
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
user string
|
||||
this *DomainMapping
|
||||
prev *DomainMapping
|
||||
wantAnns map[string]string
|
||||
}{{
|
||||
name: "create-new",
|
||||
user: u1,
|
||||
this: &DomainMapping{},
|
||||
prev: nil,
|
||||
wantAnns: map[string]string{
|
||||
serving.CreatorAnnotation: u1,
|
||||
serving.UpdaterAnnotation: u1,
|
||||
},
|
||||
}, {
|
||||
name: "update-no-diff-new-object",
|
||||
user: u2,
|
||||
this: withUserAnns(u1, u1, &DomainMapping{}),
|
||||
prev: withUserAnns(u1, u1, &DomainMapping{}),
|
||||
wantAnns: map[string]string{
|
||||
serving.CreatorAnnotation: u1,
|
||||
serving.UpdaterAnnotation: u1,
|
||||
},
|
||||
}, {
|
||||
name: "update-diff-old-object",
|
||||
user: u2,
|
||||
this: &DomainMapping{
|
||||
Spec: DomainMappingSpec{
|
||||
Ref: duckv1.KReference{
|
||||
Name: "new",
|
||||
},
|
||||
},
|
||||
},
|
||||
prev: &DomainMapping{
|
||||
Spec: DomainMappingSpec{
|
||||
Ref: duckv1.KReference{
|
||||
Name: "old",
|
||||
},
|
||||
},
|
||||
},
|
||||
wantAnns: map[string]string{
|
||||
serving.UpdaterAnnotation: u2,
|
||||
},
|
||||
}, {
|
||||
name: "update-diff-new-object",
|
||||
user: u3,
|
||||
this: withUserAnns(u1, u2, &DomainMapping{
|
||||
Spec: DomainMappingSpec{
|
||||
Ref: duckv1.KReference{
|
||||
Name: "new",
|
||||
},
|
||||
},
|
||||
}),
|
||||
prev: withUserAnns(u1, u2, &DomainMapping{
|
||||
Spec: DomainMappingSpec{
|
||||
Ref: duckv1.KReference{
|
||||
Name: "old",
|
||||
},
|
||||
},
|
||||
}),
|
||||
wantAnns: map[string]string{
|
||||
serving.CreatorAnnotation: u1,
|
||||
serving.UpdaterAnnotation: u3,
|
||||
},
|
||||
}}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
ctx := apis.WithUserInfo(context.Background(), &authv1.UserInfo{
|
||||
Username: test.user,
|
||||
})
|
||||
if test.prev != nil {
|
||||
ctx = apis.WithinUpdate(ctx, test.prev)
|
||||
test.prev.SetDefaults(ctx)
|
||||
}
|
||||
test.this.SetDefaults(ctx)
|
||||
if got, want := test.this.GetAnnotations(), test.wantAnns; !cmp.Equal(got, want) {
|
||||
t.Errorf("Annotations = %v, want: %v, diff (-got, +want): %s", got, want, cmp.Diff(got, want))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
Copyright 2021 The Knative Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
netv1alpha1 "knative.dev/networking/pkg/apis/networking/v1alpha1"
|
||||
"knative.dev/pkg/apis"
|
||||
)
|
||||
|
||||
var domainMappingCondSet = apis.NewLivingConditionSet(
|
||||
DomainMappingConditionDomainClaimed,
|
||||
DomainMappingConditionReferenceResolved,
|
||||
DomainMappingConditionIngressReady,
|
||||
DomainMappingConditionCertificateProvisioned,
|
||||
)
|
||||
|
||||
// GetConditionSet retrieves the condition set for this resource. Implements the KRShaped interface.
|
||||
func (*DomainMapping) GetConditionSet() apis.ConditionSet {
|
||||
return domainMappingCondSet
|
||||
}
|
||||
|
||||
// GetGroupVersionKind returns the GroupVersionKind.
|
||||
func (dm *DomainMapping) GetGroupVersionKind() schema.GroupVersionKind {
|
||||
return SchemeGroupVersion.WithKind("DomainMapping")
|
||||
}
|
||||
|
||||
// IsReady returns true if the DomainMapping is ready.
|
||||
func (dms *DomainMappingStatus) IsReady() bool {
|
||||
return domainMappingCondSet.Manage(dms).IsHappy()
|
||||
}
|
||||
|
||||
// IsReady returns true if the Status condition DomainMappingConditionReady
|
||||
// is true and the latest spec has been observed.
|
||||
func (dm *DomainMapping) IsReady() bool {
|
||||
dms := dm.Status
|
||||
return dms.ObservedGeneration == dm.Generation &&
|
||||
dms.GetCondition(DomainMappingConditionReady).IsTrue()
|
||||
}
|
||||
|
||||
// InitializeConditions sets the initial values to the conditions.
|
||||
func (dms *DomainMappingStatus) InitializeConditions() {
|
||||
domainMappingCondSet.Manage(dms).InitializeConditions()
|
||||
}
|
||||
|
||||
const (
|
||||
// AutoTLSNotEnabledMessage is the message which is set on the
|
||||
// DomainMappingConditionCertificateProvisioned condition when it is set to True
|
||||
// because AutoTLS was not enabled.
|
||||
AutoTLSNotEnabledMessage = "autoTLS is not enabled"
|
||||
// TLSCertificateProvidedExternally indicates that a TLS secret won't be created or managed
|
||||
// instead a reference to an existing TLS secret should have been provided in the DomainMapping spec
|
||||
TLSCertificateProvidedExternally = "TLS certificate was provided externally"
|
||||
)
|
||||
|
||||
// MarkTLSNotEnabled sets DomainMappingConditionCertificateProvisioned to true when
|
||||
// certificate provisioning was skipped because TLS was not enabled.
|
||||
func (dms *DomainMappingStatus) MarkTLSNotEnabled(msg string) {
|
||||
domainMappingCondSet.Manage(dms).MarkTrueWithReason(DomainMappingConditionCertificateProvisioned,
|
||||
"TLSNotEnabled", msg)
|
||||
}
|
||||
|
||||
func (dms *DomainMappingStatus) MarkCertificateNotRequired(msg string) {
|
||||
domainMappingCondSet.Manage(dms).MarkTrueWithReason(DomainMappingConditionCertificateProvisioned,
|
||||
"CertificateExternallyProvided", msg)
|
||||
}
|
||||
|
||||
// MarkCertificateReady marks the DomainMappingConditionCertificateProvisioned
|
||||
// condition to indicate that the Certificate is ready.
|
||||
func (dms *DomainMappingStatus) MarkCertificateReady(name string) {
|
||||
domainMappingCondSet.Manage(dms).MarkTrue(DomainMappingConditionCertificateProvisioned)
|
||||
}
|
||||
|
||||
// MarkCertificateNotReady marks the DomainMappingConditionCertificateProvisioned
|
||||
// condition to indicate that the Certificate is not ready.
|
||||
func (dms *DomainMappingStatus) MarkCertificateNotReady(name string) {
|
||||
domainMappingCondSet.Manage(dms).MarkUnknown(DomainMappingConditionCertificateProvisioned,
|
||||
"CertificateNotReady",
|
||||
"Certificate %s is not ready.", name)
|
||||
}
|
||||
|
||||
// MarkCertificateNotOwned changes the DomainMappingConditionCertificateProvisioned
|
||||
// status to be false with the reason being that there is an existing
|
||||
// certificate with the name we wanted to use.
|
||||
func (dms *DomainMappingStatus) MarkCertificateNotOwned(name string) {
|
||||
domainMappingCondSet.Manage(dms).MarkFalse(DomainMappingConditionCertificateProvisioned,
|
||||
"CertificateNotOwned",
|
||||
"There is an existing certificate %s that we don't own.", name)
|
||||
}
|
||||
|
||||
// MarkCertificateProvisionFailed marks the
|
||||
// DomainMappingConditionCertificateProvisioned condition to indicate that the
|
||||
// Certificate provisioning failed.
|
||||
func (dms *DomainMappingStatus) MarkCertificateProvisionFailed(name string) {
|
||||
domainMappingCondSet.Manage(dms).MarkFalse(DomainMappingConditionCertificateProvisioned,
|
||||
"CertificateProvisionFailed",
|
||||
"Certificate %s failed to be provisioned.", name)
|
||||
}
|
||||
|
||||
// MarkHTTPDowngrade sets DomainMappingConditionCertificateProvisioned to true when plain
|
||||
// HTTP is enabled even when Certificate is not ready.
|
||||
func (dms *DomainMappingStatus) MarkHTTPDowngrade(name string) {
|
||||
domainMappingCondSet.Manage(dms).MarkTrueWithReason(DomainMappingConditionCertificateProvisioned,
|
||||
"HTTPDowngrade",
|
||||
"Certificate %s is not ready downgrade HTTP.", name)
|
||||
}
|
||||
|
||||
// MarkIngressNotConfigured changes the IngressReady condition to be unknown to reflect
|
||||
// that the Ingress does not yet have a Status.
|
||||
func (dms *DomainMappingStatus) MarkIngressNotConfigured() {
|
||||
domainMappingCondSet.Manage(dms).MarkUnknown(DomainMappingConditionIngressReady,
|
||||
"IngressNotConfigured", "Ingress has not yet been reconciled.")
|
||||
}
|
||||
|
||||
// MarkDomainClaimed updates the DomainMappingConditionDomainClaimed condition
|
||||
// to indicate that the domain was successfully claimed.
|
||||
func (dms *DomainMappingStatus) MarkDomainClaimed() {
|
||||
domainMappingCondSet.Manage(dms).MarkTrue(DomainMappingConditionDomainClaimed)
|
||||
}
|
||||
|
||||
// MarkDomainClaimNotOwned updates the DomainMappingConditionDomainClaimed
|
||||
// condition to indicate that the domain is already in use by another
|
||||
// DomainMapping.
|
||||
func (dms *DomainMappingStatus) MarkDomainClaimNotOwned() {
|
||||
domainMappingCondSet.Manage(dms).MarkFalse(DomainMappingConditionDomainClaimed, "DomainAlreadyClaimed",
|
||||
"The domain name is already in use by another DomainMapping")
|
||||
}
|
||||
|
||||
// MarkDomainClaimFailed updates the DomainMappingConditionDomainClaimed
|
||||
// condition to indicate that creating the ClusterDomainClaim failed.
|
||||
func (dms *DomainMappingStatus) MarkDomainClaimFailed(reason string) {
|
||||
domainMappingCondSet.Manage(dms).MarkFalse(DomainMappingConditionDomainClaimed, "DomainClaimFailed", reason)
|
||||
}
|
||||
|
||||
// MarkReferenceResolved sets the DomainMappingConditionReferenceResolved
|
||||
// condition to true.
|
||||
func (dms *DomainMappingStatus) MarkReferenceResolved() {
|
||||
domainMappingCondSet.Manage(dms).MarkTrue(DomainMappingConditionReferenceResolved)
|
||||
}
|
||||
|
||||
// MarkReferenceNotResolved sets the DomainMappingConditionReferenceResolved
|
||||
// condition to false.
|
||||
func (dms *DomainMappingStatus) MarkReferenceNotResolved(reason string) {
|
||||
domainMappingCondSet.Manage(dms).MarkFalse(DomainMappingConditionReferenceResolved, "ResolveFailed", reason)
|
||||
}
|
||||
|
||||
// PropagateIngressStatus updates the DomainMappingConditionIngressReady
|
||||
// condition according to the underlying Ingress's status.
|
||||
func (dms *DomainMappingStatus) PropagateIngressStatus(cs netv1alpha1.IngressStatus) {
|
||||
cc := cs.GetCondition(netv1alpha1.IngressConditionReady)
|
||||
if cc == nil {
|
||||
dms.MarkIngressNotConfigured()
|
||||
return
|
||||
}
|
||||
|
||||
m := domainMappingCondSet.Manage(dms)
|
||||
switch cc.Status {
|
||||
case corev1.ConditionTrue:
|
||||
m.MarkTrue(DomainMappingConditionIngressReady)
|
||||
case corev1.ConditionFalse:
|
||||
m.MarkFalse(DomainMappingConditionIngressReady, cc.Reason, cc.Message)
|
||||
case corev1.ConditionUnknown:
|
||||
m.MarkUnknown(DomainMappingConditionIngressReady, cc.Reason, cc.Message)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,337 @@
|
|||
/*
|
||||
Copyright 2021 The Knative Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
netv1alpha1 "knative.dev/networking/pkg/apis/networking/v1alpha1"
|
||||
"knative.dev/pkg/apis"
|
||||
"knative.dev/pkg/apis/duck"
|
||||
duckv1 "knative.dev/pkg/apis/duck/v1"
|
||||
apistest "knative.dev/pkg/apis/testing"
|
||||
)
|
||||
|
||||
func TestDomainMappingDuckTypes(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
t duck.Implementable
|
||||
}{{
|
||||
name: "conditions",
|
||||
t: &duckv1.Conditions{},
|
||||
}}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
err := duck.VerifyType(&DomainMapping{}, test.t)
|
||||
if err != nil {
|
||||
t.Errorf("VerifyType(DomainMapping, %T) = %v", test.t, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDomainMappingGetConditionSet(t *testing.T) {
|
||||
r := &DomainMapping{}
|
||||
|
||||
if got, want := r.GetConditionSet().GetTopLevelConditionType(), apis.ConditionReady; got != want {
|
||||
t.Errorf("GetTopLevelCondition=%v, want=%v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDomainMappingGetGroupVersionKind(t *testing.T) {
|
||||
r := &DomainMapping{}
|
||||
want := schema.GroupVersionKind{
|
||||
Group: "serving.knative.dev",
|
||||
Version: "v1beta1",
|
||||
Kind: "DomainMapping",
|
||||
}
|
||||
if got := r.GetGroupVersionKind(); got != want {
|
||||
t.Errorf("got: %v, want: %v", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDomainClaimConditions(t *testing.T) {
|
||||
dms := &DomainMappingStatus{}
|
||||
|
||||
dms.InitializeConditions()
|
||||
dms.MarkTLSNotEnabled("AutoTLS not yet available for DomainMapping")
|
||||
apistest.CheckConditionOngoing(dms, DomainMappingConditionDomainClaimed, t)
|
||||
apistest.CheckConditionOngoing(dms, DomainMappingConditionReady, t)
|
||||
|
||||
dms.MarkDomainClaimFailed("rejected")
|
||||
apistest.CheckConditionFailed(dms, DomainMappingConditionDomainClaimed, t)
|
||||
apistest.CheckConditionFailed(dms, DomainMappingConditionReady, t)
|
||||
|
||||
dms.MarkDomainClaimed()
|
||||
apistest.CheckConditionSucceeded(dms, DomainMappingConditionDomainClaimed, t)
|
||||
apistest.CheckConditionOngoing(dms, DomainMappingConditionReady, t)
|
||||
|
||||
dms.MarkReferenceResolved()
|
||||
dms.PropagateIngressStatus(netv1alpha1.IngressStatus{
|
||||
Status: duckv1.Status{
|
||||
Conditions: duckv1.Conditions{{
|
||||
Type: netv1alpha1.IngressConditionReady,
|
||||
Status: corev1.ConditionTrue,
|
||||
}},
|
||||
},
|
||||
})
|
||||
apistest.CheckConditionSucceeded(dms, DomainMappingConditionReady, t)
|
||||
|
||||
dms.MarkDomainClaimNotOwned()
|
||||
apistest.CheckConditionFailed(dms, DomainMappingConditionDomainClaimed, t)
|
||||
apistest.CheckConditionFailed(dms, DomainMappingConditionReady, t)
|
||||
}
|
||||
|
||||
func TestReferenceResolvedCondition(t *testing.T) {
|
||||
dms := &DomainMappingStatus{}
|
||||
|
||||
dms.InitializeConditions()
|
||||
dms.MarkTLSNotEnabled("AutoTLS not yet available for DomainMapping")
|
||||
apistest.CheckConditionOngoing(dms, DomainMappingConditionReferenceResolved, t)
|
||||
apistest.CheckConditionOngoing(dms, DomainMappingConditionReady, t)
|
||||
|
||||
dms.MarkReferenceNotResolved("can't get no resolution")
|
||||
apistest.CheckConditionFailed(dms, DomainMappingConditionReferenceResolved, t)
|
||||
apistest.CheckConditionFailed(dms, DomainMappingConditionReady, t)
|
||||
|
||||
dms.MarkReferenceResolved()
|
||||
apistest.CheckConditionSucceeded(dms, DomainMappingConditionReferenceResolved, t)
|
||||
apistest.CheckConditionOngoing(dms, DomainMappingConditionReady, t)
|
||||
|
||||
dms.MarkDomainClaimed()
|
||||
dms.PropagateIngressStatus(netv1alpha1.IngressStatus{
|
||||
Status: duckv1.Status{
|
||||
Conditions: duckv1.Conditions{{
|
||||
Type: netv1alpha1.IngressConditionReady,
|
||||
Status: corev1.ConditionTrue,
|
||||
}},
|
||||
},
|
||||
})
|
||||
apistest.CheckConditionSucceeded(dms, DomainMappingConditionReady, t)
|
||||
|
||||
dms.MarkReferenceNotResolved("still can't get no resolution")
|
||||
apistest.CheckConditionFailed(dms, DomainMappingConditionReferenceResolved, t)
|
||||
apistest.CheckConditionFailed(dms, DomainMappingConditionReady, t)
|
||||
}
|
||||
|
||||
func TestCertificateNotReady(t *testing.T) {
|
||||
dms := &DomainMappingStatus{}
|
||||
|
||||
dms.InitializeConditions()
|
||||
dms.MarkCertificateNotReady("cert pending")
|
||||
|
||||
apistest.CheckConditionOngoing(dms, DomainMappingConditionCertificateProvisioned, t)
|
||||
}
|
||||
|
||||
func TestCertificateProvisionFailed(t *testing.T) {
|
||||
dms := &DomainMappingStatus{}
|
||||
|
||||
dms.InitializeConditions()
|
||||
dms.MarkCertificateProvisionFailed("cert failed")
|
||||
|
||||
apistest.CheckConditionFailed(dms, DomainMappingConditionCertificateProvisioned, t)
|
||||
}
|
||||
|
||||
func TestDomainMappingNotOwnCertificate(t *testing.T) {
|
||||
dms := &DomainMappingStatus{}
|
||||
dms.InitializeConditions()
|
||||
dms.MarkCertificateNotOwned("cert not owned")
|
||||
|
||||
apistest.CheckConditionFailed(dms, DomainMappingConditionCertificateProvisioned, t)
|
||||
}
|
||||
|
||||
func TestDomainMappingAutoTLSNotEnabled(t *testing.T) {
|
||||
dms := &DomainMappingStatus{}
|
||||
dms.InitializeConditions()
|
||||
dms.MarkTLSNotEnabled(AutoTLSNotEnabledMessage)
|
||||
|
||||
apistest.CheckConditionSucceeded(dms, DomainMappingConditionCertificateProvisioned, t)
|
||||
}
|
||||
|
||||
func TestDomainMappingHTTPDowngrade(t *testing.T) {
|
||||
dms := &DomainMappingStatus{}
|
||||
dms.InitializeConditions()
|
||||
dms.MarkHTTPDowngrade("downgraded to HTTP because we can't obtain cert")
|
||||
|
||||
apistest.CheckConditionSucceeded(dms, DomainMappingConditionCertificateProvisioned, t)
|
||||
}
|
||||
|
||||
func TestPropagateIngressStatus(t *testing.T) {
|
||||
dms := &DomainMappingStatus{}
|
||||
|
||||
dms.InitializeConditions()
|
||||
dms.MarkTLSNotEnabled("AutoTLS not yet available for DomainMapping")
|
||||
apistest.CheckConditionOngoing(dms, DomainMappingConditionIngressReady, t)
|
||||
apistest.CheckConditionOngoing(dms, DomainMappingConditionReady, t)
|
||||
|
||||
dms.PropagateIngressStatus(netv1alpha1.IngressStatus{
|
||||
Status: duckv1.Status{
|
||||
Conditions: duckv1.Conditions{{
|
||||
Type: netv1alpha1.IngressConditionReady,
|
||||
Status: corev1.ConditionFalse,
|
||||
}},
|
||||
},
|
||||
})
|
||||
|
||||
apistest.CheckConditionFailed(dms, DomainMappingConditionIngressReady, t)
|
||||
apistest.CheckConditionFailed(dms, DomainMappingConditionReady, t)
|
||||
|
||||
dms.PropagateIngressStatus(netv1alpha1.IngressStatus{
|
||||
Status: duckv1.Status{
|
||||
Conditions: duckv1.Conditions{{
|
||||
Type: netv1alpha1.IngressConditionReady,
|
||||
Status: corev1.ConditionTrue,
|
||||
}},
|
||||
},
|
||||
})
|
||||
|
||||
apistest.CheckConditionSucceeded(dms, DomainMappingConditionIngressReady, t)
|
||||
apistest.CheckConditionOngoing(dms, DomainMappingConditionReady, t)
|
||||
|
||||
dms.MarkDomainClaimed()
|
||||
dms.MarkReferenceResolved()
|
||||
apistest.CheckConditionSucceeded(dms, DomainMappingConditionReady, t)
|
||||
|
||||
dms.PropagateIngressStatus(netv1alpha1.IngressStatus{
|
||||
Status: duckv1.Status{
|
||||
Conditions: duckv1.Conditions{{
|
||||
Type: netv1alpha1.IngressConditionReady,
|
||||
Status: corev1.ConditionUnknown,
|
||||
}},
|
||||
},
|
||||
})
|
||||
|
||||
apistest.CheckConditionOngoing(dms, DomainMappingConditionIngressReady, t)
|
||||
apistest.CheckConditionOngoing(dms, DomainMappingConditionReady, t)
|
||||
}
|
||||
|
||||
func TestDomainMappingIsReady(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
status DomainMappingStatus
|
||||
isReady bool
|
||||
}{{
|
||||
name: "empty status should not be ready",
|
||||
status: DomainMappingStatus{},
|
||||
isReady: false,
|
||||
}, {
|
||||
name: "Different condition type should not be ready",
|
||||
status: DomainMappingStatus{
|
||||
Status: duckv1.Status{
|
||||
Conditions: duckv1.Conditions{{
|
||||
Type: DomainMappingConditionIngressReady,
|
||||
Status: corev1.ConditionTrue,
|
||||
}},
|
||||
},
|
||||
},
|
||||
isReady: false,
|
||||
}, {
|
||||
name: "False condition status should not be ready",
|
||||
status: DomainMappingStatus{
|
||||
Status: duckv1.Status{
|
||||
Conditions: duckv1.Conditions{{
|
||||
Type: DomainMappingConditionReady,
|
||||
Status: corev1.ConditionFalse,
|
||||
}},
|
||||
},
|
||||
},
|
||||
isReady: false,
|
||||
}, {
|
||||
name: "Unknown condition status should not be ready",
|
||||
status: DomainMappingStatus{
|
||||
Status: duckv1.Status{
|
||||
Conditions: duckv1.Conditions{{
|
||||
Type: DomainMappingConditionReady,
|
||||
Status: corev1.ConditionUnknown,
|
||||
}},
|
||||
},
|
||||
},
|
||||
isReady: false,
|
||||
}, {
|
||||
name: "Missing condition status should not be ready",
|
||||
status: DomainMappingStatus{
|
||||
Status: duckv1.Status{
|
||||
Conditions: duckv1.Conditions{{
|
||||
Type: DomainMappingConditionReady,
|
||||
}},
|
||||
},
|
||||
},
|
||||
isReady: false,
|
||||
}, {
|
||||
name: "True condition status should be ready",
|
||||
status: DomainMappingStatus{
|
||||
Status: duckv1.Status{
|
||||
Conditions: duckv1.Conditions{{
|
||||
Type: DomainMappingConditionReady,
|
||||
Status: corev1.ConditionTrue,
|
||||
}},
|
||||
},
|
||||
},
|
||||
isReady: true,
|
||||
}, {
|
||||
name: "Multiple conditions with ready status should be ready",
|
||||
status: DomainMappingStatus{
|
||||
Status: duckv1.Status{
|
||||
Conditions: duckv1.Conditions{{
|
||||
Type: DomainMappingConditionIngressReady,
|
||||
Status: corev1.ConditionTrue,
|
||||
}, {
|
||||
Type: DomainMappingConditionReady,
|
||||
Status: corev1.ConditionTrue,
|
||||
}},
|
||||
},
|
||||
},
|
||||
isReady: true,
|
||||
}, {
|
||||
name: "Multiple conditions with ready status false should not be ready",
|
||||
status: DomainMappingStatus{
|
||||
Status: duckv1.Status{
|
||||
Conditions: duckv1.Conditions{{
|
||||
Type: DomainMappingConditionIngressReady,
|
||||
Status: corev1.ConditionTrue,
|
||||
}, {
|
||||
Type: DomainMappingConditionReady,
|
||||
Status: corev1.ConditionFalse,
|
||||
}},
|
||||
},
|
||||
},
|
||||
isReady: false,
|
||||
}}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
if e, a := tc.isReady, tc.status.IsReady(); e != a {
|
||||
t.Errorf("%q expected: %v got: %v", tc.name, e, a)
|
||||
}
|
||||
|
||||
dm := &DomainMapping{}
|
||||
dm.Status = tc.status
|
||||
if e, a := tc.isReady, dm.IsReady(); e != a {
|
||||
t.Errorf("%q expected: %v got: %v", tc.name, e, a)
|
||||
}
|
||||
|
||||
dm.Generation = 2
|
||||
dm.Status.ObservedGeneration = 1
|
||||
if dm.IsReady() {
|
||||
t.Error("Expected DomainMapping not to be Ready when ObservedGeneration != Generation")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
Copyright 2021 The Knative Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
"knative.dev/pkg/apis"
|
||||
duckv1 "knative.dev/pkg/apis/duck/v1"
|
||||
)
|
||||
|
||||
// +genclient
|
||||
// +genreconciler
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// DomainMapping is a mapping from a custom hostname to an Addressable.
|
||||
type DomainMapping struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
// Standard object's metadata.
|
||||
// More info: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||
// +optional
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Spec is the desired state of the DomainMapping.
|
||||
// More info: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
|
||||
// +optional
|
||||
Spec DomainMappingSpec `json:"spec,omitempty"`
|
||||
|
||||
// Status is the current state of the DomainMapping.
|
||||
// More info: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
|
||||
// +optional
|
||||
Status DomainMappingStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// Verify that DomainMapping adheres to the appropriate interfaces.
|
||||
var (
|
||||
// Check that DomainMapping may be validated and defaulted.
|
||||
_ apis.Validatable = (*DomainMapping)(nil)
|
||||
_ apis.Defaultable = (*DomainMapping)(nil)
|
||||
|
||||
// Check that the type conforms to the duck Knative Resource shape.
|
||||
_ duckv1.KRShaped = (*DomainMapping)(nil)
|
||||
)
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// DomainMappingList is a collection of DomainMapping objects.
|
||||
type DomainMappingList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
// Standard object metadata.
|
||||
// More info: https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md#metadata
|
||||
// +optional
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
|
||||
// Items is the list of DomainMapping objects.
|
||||
Items []DomainMapping `json:"items"`
|
||||
}
|
||||
|
||||
// SecretTLS wrapper for TLS SecretName.
|
||||
type SecretTLS struct {
|
||||
// SecretName is the name of the existing secret used to terminate TLS traffic.
|
||||
SecretName string `json:"secretName"`
|
||||
}
|
||||
|
||||
// DomainMappingSpec describes the DomainMapping the user wishes to exist.
|
||||
type DomainMappingSpec struct {
|
||||
// Ref specifies the target of the Domain Mapping.
|
||||
//
|
||||
// The object identified by the Ref must be an Addressable with a URL of the
|
||||
// form `{name}.{namespace}.{domain}` where `{domain}` is the cluster domain,
|
||||
// and `{name}` and `{namespace}` are the name and namespace of a Kubernetes
|
||||
// Service.
|
||||
//
|
||||
// This contract is satisfied by Knative types such as Knative Services and
|
||||
// Knative Routes, and by Kubernetes Services.
|
||||
Ref duckv1.KReference `json:"ref"`
|
||||
|
||||
// TLS allows the DomainMapping to terminate TLS traffic with an existing secret.
|
||||
// +optional
|
||||
TLS *SecretTLS `json:"tls,omitempty"`
|
||||
}
|
||||
|
||||
// DomainMappingStatus describes the current state of the DomainMapping.
|
||||
type DomainMappingStatus struct {
|
||||
duckv1.Status `json:",inline"`
|
||||
|
||||
// URL is the URL of this DomainMapping.
|
||||
// +optional
|
||||
URL *apis.URL `json:"url,omitempty"`
|
||||
|
||||
// Address holds the information needed for a DomainMapping to be the target of an event.
|
||||
// +optional
|
||||
Address *duckv1.Addressable `json:"address,omitempty"`
|
||||
}
|
||||
|
||||
const (
|
||||
// DomainMappingConditionReady is set when the DomainMapping is configured
|
||||
// and the Ingress is ready.
|
||||
DomainMappingConditionReady = apis.ConditionReady
|
||||
|
||||
// DomainMappingConditionReferenceResolved reflects whether the Ref
|
||||
// has been successfully resolved to an existing object.
|
||||
DomainMappingConditionReferenceResolved apis.ConditionType = "ReferenceResolved"
|
||||
|
||||
// DomainMappingConditionIngressReady reflects the readiness of the
|
||||
// underlying Ingress resource.
|
||||
DomainMappingConditionIngressReady apis.ConditionType = "IngressReady"
|
||||
|
||||
// DomainMappingConditionDomainClaimed reflects that the ClusterDomainClaim
|
||||
// for this DomainMapping exists, and is owned by this DomainMapping.
|
||||
DomainMappingConditionDomainClaimed apis.ConditionType = "DomainClaimed"
|
||||
|
||||
// DomainMappingConditionCertificateProvisioned is set to False when the
|
||||
// Knative Certificates fail to be provisioned for the DomainMapping.
|
||||
DomainMappingConditionCertificateProvisioned apis.ConditionType = "CertificateProvisioned"
|
||||
)
|
||||
|
||||
// GetStatus retrieves the status of the DomainMapping. Implements the KRShaped interface.
|
||||
func (dm *DomainMapping) GetStatus() *duckv1.Status {
|
||||
return &dm.Status.Status
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
Copyright 2021 The Knative Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
duckv1 "knative.dev/pkg/apis/duck/v1"
|
||||
)
|
||||
|
||||
func TestDomainMappingGetStatus(t *testing.T) {
|
||||
status := &duckv1.Status{}
|
||||
config := DomainMapping{
|
||||
Status: DomainMappingStatus{
|
||||
Status: *status,
|
||||
},
|
||||
}
|
||||
|
||||
if !cmp.Equal(config.GetStatus(), status) {
|
||||
t.Errorf("GetStatus did not retrieve status. Got=%v Want=%v", config.GetStatus(), status)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
Copyright 2021 The Knative Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"k8s.io/apimachinery/pkg/util/validation"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
"knative.dev/pkg/apis"
|
||||
"knative.dev/pkg/network"
|
||||
"knative.dev/serving/pkg/apis/serving"
|
||||
)
|
||||
|
||||
// Validate makes sure that DomainMapping is properly configured.
|
||||
func (dm *DomainMapping) Validate(ctx context.Context) *apis.FieldError {
|
||||
errs := dm.validateMetadata(ctx).ViaField("metadata")
|
||||
|
||||
ctx = apis.WithinParent(ctx, dm.ObjectMeta)
|
||||
errs = errs.Also(dm.Spec.Validate(apis.WithinSpec(ctx)).ViaField("spec"))
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
// validateMetadata validates the metadata section of a DomainMapping.
|
||||
func (dm *DomainMapping) validateMetadata(ctx context.Context) (errs *apis.FieldError) {
|
||||
if dm.GenerateName != "" {
|
||||
errs = errs.Also(apis.ErrDisallowedFields("generateName"))
|
||||
}
|
||||
|
||||
err := validation.IsFullyQualifiedDomainName(field.NewPath("name"), dm.Name)
|
||||
if err != nil {
|
||||
errs = errs.Also(apis.ErrGeneric(fmt.Sprintf(
|
||||
"invalid name %q: %s", dm.Name, err.ToAggregate()), "name"))
|
||||
}
|
||||
|
||||
clusterLocalDomain := network.GetClusterDomainName()
|
||||
if strings.HasSuffix(dm.Name, "."+clusterLocalDomain) {
|
||||
errs = errs.Also(apis.ErrGeneric(
|
||||
fmt.Sprintf("invalid name %q: must not be a subdomain of cluster local domain %q", dm.Name, clusterLocalDomain), "name"))
|
||||
}
|
||||
|
||||
if apis.IsInUpdate(ctx) {
|
||||
original := apis.GetBaseline(ctx).(*DomainMapping)
|
||||
errs = errs.Also(
|
||||
apis.ValidateCreatorAndModifier(original.Spec, dm.Spec,
|
||||
original.GetAnnotations(), dm.GetAnnotations(), serving.GroupName).ViaField("annotations"),
|
||||
)
|
||||
}
|
||||
|
||||
return errs
|
||||
}
|
||||
|
||||
// Validate makes sure the DomainMappingSpec is properly configured.
|
||||
func (spec *DomainMappingSpec) Validate(ctx context.Context) *apis.FieldError {
|
||||
return spec.Ref.Validate(ctx).ViaField("ref")
|
||||
}
|
|
@ -0,0 +1,287 @@
|
|||
/*
|
||||
Copyright 2021 The Knative Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"knative.dev/pkg/apis"
|
||||
duckv1 "knative.dev/pkg/apis/duck/v1"
|
||||
"knative.dev/serving/pkg/apis/serving"
|
||||
)
|
||||
|
||||
func TestDomainMappingValidation(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
dm *DomainMapping
|
||||
want *apis.FieldError
|
||||
}{{
|
||||
name: "invalid name",
|
||||
want: apis.ErrGeneric("invalid name \"invalid\": name: Invalid value: \"invalid\": should be a domain with at least two segments separated by dots", "metadata.name"),
|
||||
dm: &DomainMapping{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "invalid",
|
||||
Namespace: "ns",
|
||||
},
|
||||
Spec: DomainMappingSpec{
|
||||
Ref: duckv1.KReference{
|
||||
Name: "some-name.example.com",
|
||||
APIVersion: "serving.knative.dev/v1",
|
||||
Kind: "Service",
|
||||
Namespace: "ns",
|
||||
},
|
||||
},
|
||||
},
|
||||
}, {
|
||||
name: "uses GenerateName rather than Name",
|
||||
want: apis.ErrDisallowedFields("metadata.generateName").Also(
|
||||
apis.ErrGeneric("invalid name \"\": name: Required value", "metadata.name")),
|
||||
dm: &DomainMapping{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
GenerateName: "cant-use-this",
|
||||
Namespace: "ns",
|
||||
},
|
||||
Spec: DomainMappingSpec{
|
||||
Ref: duckv1.KReference{
|
||||
Name: "some-name.example.com",
|
||||
APIVersion: "serving.knative.dev/v1",
|
||||
Kind: "Service",
|
||||
Namespace: "ns",
|
||||
},
|
||||
},
|
||||
},
|
||||
}, {
|
||||
name: "ref in wrong namespace",
|
||||
want: &apis.FieldError{
|
||||
Paths: []string{"spec.ref.namespace"},
|
||||
Details: `parent namespace: "good-namespace" does not match ref: "bad-namespace"`,
|
||||
Message: `mismatched namespaces`,
|
||||
},
|
||||
dm: &DomainMapping{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "wrong-ref-ns.example.com",
|
||||
Namespace: "good-namespace",
|
||||
},
|
||||
Spec: DomainMappingSpec{
|
||||
Ref: duckv1.KReference{
|
||||
Name: "some-name",
|
||||
Namespace: "bad-namespace",
|
||||
APIVersion: "serving.knative.dev/v1",
|
||||
Kind: "Service",
|
||||
},
|
||||
},
|
||||
},
|
||||
}, {
|
||||
name: "ref missing Kind",
|
||||
want: apis.ErrMissingField("spec.ref.kind"),
|
||||
dm: &DomainMapping{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "wrong-kind.example.com",
|
||||
Namespace: "ns",
|
||||
},
|
||||
Spec: DomainMappingSpec{
|
||||
Ref: duckv1.KReference{
|
||||
Name: "some-name",
|
||||
Namespace: "ns",
|
||||
APIVersion: "serving.knative.dev/v1",
|
||||
},
|
||||
},
|
||||
},
|
||||
}, {
|
||||
name: "ref missing ApiVersion",
|
||||
want: apis.ErrMissingField("spec.ref.apiVersion"),
|
||||
dm: &DomainMapping{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "wrong-version.example.com",
|
||||
Namespace: "ns",
|
||||
},
|
||||
Spec: DomainMappingSpec{
|
||||
Ref: duckv1.KReference{
|
||||
Name: "some-name",
|
||||
Namespace: "ns",
|
||||
Kind: "Service",
|
||||
},
|
||||
},
|
||||
},
|
||||
}, {
|
||||
name: "cluster local domain name",
|
||||
want: apis.ErrGeneric("invalid name \"notallowed.svc.cluster.local\": must not be a subdomain of cluster local domain \"cluster.local\"", "metadata.name"),
|
||||
dm: &DomainMapping{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "notallowed.svc.cluster.local",
|
||||
Namespace: "ns",
|
||||
},
|
||||
Spec: DomainMappingSpec{
|
||||
Ref: duckv1.KReference{
|
||||
Name: "some-name",
|
||||
Namespace: "ns",
|
||||
Kind: "Service",
|
||||
APIVersion: "serving.knative.dev/v1",
|
||||
},
|
||||
},
|
||||
},
|
||||
}}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
got := test.dm.Validate(ctx)
|
||||
|
||||
if !cmp.Equal(test.want.Error(), got.Error()) {
|
||||
t.Errorf("Validate (-want, +got):\n%s", cmp.Diff(test.want.Error(), got.Error()))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDomainMappingAnnotationUpdate(t *testing.T) {
|
||||
const (
|
||||
u1 = "oveja@knative.dev"
|
||||
u2 = "cabra@knative.dev"
|
||||
u3 = "vaca@knative.dev"
|
||||
)
|
||||
spec := func(name string) DomainMappingSpec {
|
||||
return DomainMappingSpec{
|
||||
Ref: duckv1.KReference{
|
||||
Name: name,
|
||||
Namespace: "ns",
|
||||
Kind: "Service",
|
||||
APIVersion: "serving.knative.dev/v1",
|
||||
},
|
||||
}
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
prev *DomainMapping
|
||||
this *DomainMapping
|
||||
want *apis.FieldError
|
||||
}{{
|
||||
name: "update creator annotation",
|
||||
this: &DomainMapping{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "valid.example.com",
|
||||
Namespace: "ns",
|
||||
Annotations: map[string]string{
|
||||
serving.CreatorAnnotation: u2,
|
||||
serving.UpdaterAnnotation: u1,
|
||||
},
|
||||
},
|
||||
Spec: spec("old"),
|
||||
},
|
||||
prev: &DomainMapping{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "valid.example.com",
|
||||
Namespace: "ns",
|
||||
Annotations: map[string]string{
|
||||
serving.CreatorAnnotation: u1,
|
||||
serving.UpdaterAnnotation: u1,
|
||||
},
|
||||
},
|
||||
Spec: spec("old"),
|
||||
},
|
||||
want: (&apis.FieldError{Message: "annotation value is immutable",
|
||||
Paths: []string{serving.CreatorAnnotation}}).ViaField("metadata.annotations"),
|
||||
}, {
|
||||
name: "update creator annotation with spec changes",
|
||||
this: &DomainMapping{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "valid.example.com",
|
||||
Namespace: "ns",
|
||||
Annotations: map[string]string{
|
||||
serving.CreatorAnnotation: u2,
|
||||
serving.UpdaterAnnotation: u1,
|
||||
},
|
||||
},
|
||||
Spec: spec("new"),
|
||||
},
|
||||
prev: &DomainMapping{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "valid.example.com",
|
||||
Namespace: "ns",
|
||||
Annotations: map[string]string{
|
||||
serving.CreatorAnnotation: u1,
|
||||
serving.UpdaterAnnotation: u1,
|
||||
},
|
||||
},
|
||||
Spec: spec("old"),
|
||||
},
|
||||
want: (&apis.FieldError{Message: "annotation value is immutable",
|
||||
Paths: []string{serving.CreatorAnnotation}}).ViaField("metadata.annotations"),
|
||||
}, {
|
||||
name: "update lastModifier annotation without spec changes",
|
||||
this: &DomainMapping{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "valid.example.com",
|
||||
Namespace: "ns",
|
||||
Annotations: map[string]string{
|
||||
serving.CreatorAnnotation: u1,
|
||||
serving.UpdaterAnnotation: u2,
|
||||
},
|
||||
},
|
||||
Spec: spec("old"),
|
||||
},
|
||||
prev: &DomainMapping{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "valid.example.com",
|
||||
Namespace: "ns",
|
||||
Annotations: map[string]string{
|
||||
serving.CreatorAnnotation: u1,
|
||||
serving.UpdaterAnnotation: u1,
|
||||
},
|
||||
},
|
||||
Spec: spec("old"),
|
||||
},
|
||||
want: apis.ErrInvalidValue(u2, serving.UpdaterAnnotation).ViaField("metadata.annotations"),
|
||||
}, {
|
||||
name: "update lastModifier annotation with spec changes",
|
||||
this: &DomainMapping{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "valid.example.com",
|
||||
Namespace: "ns",
|
||||
Annotations: map[string]string{
|
||||
serving.CreatorAnnotation: u1,
|
||||
serving.UpdaterAnnotation: u3,
|
||||
},
|
||||
},
|
||||
Spec: spec("new"),
|
||||
},
|
||||
prev: &DomainMapping{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "valid.example.com",
|
||||
Namespace: "ns",
|
||||
Annotations: map[string]string{
|
||||
serving.CreatorAnnotation: u1,
|
||||
serving.UpdaterAnnotation: u1,
|
||||
},
|
||||
},
|
||||
Spec: spec("old"),
|
||||
},
|
||||
want: nil,
|
||||
}}
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
ctx = apis.WithinUpdate(ctx, test.prev)
|
||||
if diff := cmp.Diff(test.want.Error(), test.this.Validate(ctx).Error()); diff != "" {
|
||||
t.Error("Validate (-want, +got) =", diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
Copyright 2021 The Knative Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
"knative.dev/serving/pkg/apis/serving"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
)
|
||||
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: serving.GroupName, Version: "v1beta1"}
|
||||
|
||||
// Kind takes an unqualified kind and returns back a Group qualified GroupKind
|
||||
func Kind(kind string) schema.GroupKind {
|
||||
return SchemeGroupVersion.WithKind(kind).GroupKind()
|
||||
}
|
||||
|
||||
// Resource takes an unqualified resource and returns a Group qualified GroupResource
|
||||
func Resource(resource string) schema.GroupResource {
|
||||
return SchemeGroupVersion.WithResource(resource).GroupResource()
|
||||
}
|
||||
|
||||
var (
|
||||
// SchemeBuilder registers the addKnownTypes function.
|
||||
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)
|
||||
// AddToScheme applies all the stored functions to the scheme.
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
// Adds the list of known types to Scheme.
|
||||
func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&DomainMapping{},
|
||||
&DomainMappingList{},
|
||||
)
|
||||
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
Copyright 2021 The Knative Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
func TestRegisterHelpers(t *testing.T) {
|
||||
if got, want := Kind("Revision"), "Revision.serving.knative.dev"; got.String() != want {
|
||||
t.Errorf("Kind(Revision) = %v, want %v", got.String(), want)
|
||||
}
|
||||
|
||||
if got, want := Resource("Revision"), "Revision.serving.knative.dev"; got.String() != want {
|
||||
t.Errorf("Resource(Revision) = %v, want %v", got.String(), want)
|
||||
}
|
||||
|
||||
if got, want := SchemeGroupVersion.String(), "serving.knative.dev/v1beta1"; got != want {
|
||||
t.Errorf("SchemeGroupVersion() = %v, want %v", got, want)
|
||||
}
|
||||
|
||||
scheme := runtime.NewScheme()
|
||||
if err := addKnownTypes(scheme); err != nil {
|
||||
t.Error("addKnownTypes() =", err)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,169 @@
|
|||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright 2021 The Knative Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by deepcopy-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
apis "knative.dev/pkg/apis"
|
||||
v1 "knative.dev/pkg/apis/duck/v1"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *CannotConvertError) DeepCopyInto(out *CannotConvertError) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CannotConvertError.
|
||||
func (in *CannotConvertError) DeepCopy() *CannotConvertError {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(CannotConvertError)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *DomainMapping) DeepCopyInto(out *DomainMapping) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DomainMapping.
|
||||
func (in *DomainMapping) DeepCopy() *DomainMapping {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DomainMapping)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *DomainMapping) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *DomainMappingList) DeepCopyInto(out *DomainMappingList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]DomainMapping, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DomainMappingList.
|
||||
func (in *DomainMappingList) DeepCopy() *DomainMappingList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DomainMappingList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *DomainMappingList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *DomainMappingSpec) DeepCopyInto(out *DomainMappingSpec) {
|
||||
*out = *in
|
||||
out.Ref = in.Ref
|
||||
if in.TLS != nil {
|
||||
in, out := &in.TLS, &out.TLS
|
||||
*out = new(SecretTLS)
|
||||
**out = **in
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DomainMappingSpec.
|
||||
func (in *DomainMappingSpec) DeepCopy() *DomainMappingSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DomainMappingSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *DomainMappingStatus) DeepCopyInto(out *DomainMappingStatus) {
|
||||
*out = *in
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
if in.URL != nil {
|
||||
in, out := &in.URL, &out.URL
|
||||
*out = new(apis.URL)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.Address != nil {
|
||||
in, out := &in.Address, &out.Address
|
||||
*out = new(v1.Addressable)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DomainMappingStatus.
|
||||
func (in *DomainMappingStatus) DeepCopy() *DomainMappingStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DomainMappingStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *SecretTLS) DeepCopyInto(out *SecretTLS) {
|
||||
*out = *in
|
||||
return
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretTLS.
|
||||
func (in *SecretTLS) DeepCopy() *SecretTLS {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(SecretTLS)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
|
@ -27,12 +27,14 @@ import (
|
|||
autoscalingv1alpha1 "knative.dev/serving/pkg/client/clientset/versioned/typed/autoscaling/v1alpha1"
|
||||
servingv1 "knative.dev/serving/pkg/client/clientset/versioned/typed/serving/v1"
|
||||
servingv1alpha1 "knative.dev/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1"
|
||||
servingv1beta1 "knative.dev/serving/pkg/client/clientset/versioned/typed/serving/v1beta1"
|
||||
)
|
||||
|
||||
type Interface interface {
|
||||
Discovery() discovery.DiscoveryInterface
|
||||
AutoscalingV1alpha1() autoscalingv1alpha1.AutoscalingV1alpha1Interface
|
||||
ServingV1() servingv1.ServingV1Interface
|
||||
ServingV1beta1() servingv1beta1.ServingV1beta1Interface
|
||||
ServingV1alpha1() servingv1alpha1.ServingV1alpha1Interface
|
||||
}
|
||||
|
||||
|
@ -42,6 +44,7 @@ type Clientset struct {
|
|||
*discovery.DiscoveryClient
|
||||
autoscalingV1alpha1 *autoscalingv1alpha1.AutoscalingV1alpha1Client
|
||||
servingV1 *servingv1.ServingV1Client
|
||||
servingV1beta1 *servingv1beta1.ServingV1beta1Client
|
||||
servingV1alpha1 *servingv1alpha1.ServingV1alpha1Client
|
||||
}
|
||||
|
||||
|
@ -55,6 +58,11 @@ func (c *Clientset) ServingV1() servingv1.ServingV1Interface {
|
|||
return c.servingV1
|
||||
}
|
||||
|
||||
// ServingV1beta1 retrieves the ServingV1beta1Client
|
||||
func (c *Clientset) ServingV1beta1() servingv1beta1.ServingV1beta1Interface {
|
||||
return c.servingV1beta1
|
||||
}
|
||||
|
||||
// ServingV1alpha1 retrieves the ServingV1alpha1Client
|
||||
func (c *Clientset) ServingV1alpha1() servingv1alpha1.ServingV1alpha1Interface {
|
||||
return c.servingV1alpha1
|
||||
|
@ -89,6 +97,10 @@ func NewForConfig(c *rest.Config) (*Clientset, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cs.servingV1beta1, err = servingv1beta1.NewForConfig(&configShallowCopy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cs.servingV1alpha1, err = servingv1alpha1.NewForConfig(&configShallowCopy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -107,6 +119,7 @@ func NewForConfigOrDie(c *rest.Config) *Clientset {
|
|||
var cs Clientset
|
||||
cs.autoscalingV1alpha1 = autoscalingv1alpha1.NewForConfigOrDie(c)
|
||||
cs.servingV1 = servingv1.NewForConfigOrDie(c)
|
||||
cs.servingV1beta1 = servingv1beta1.NewForConfigOrDie(c)
|
||||
cs.servingV1alpha1 = servingv1alpha1.NewForConfigOrDie(c)
|
||||
|
||||
cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c)
|
||||
|
@ -118,6 +131,7 @@ func New(c rest.Interface) *Clientset {
|
|||
var cs Clientset
|
||||
cs.autoscalingV1alpha1 = autoscalingv1alpha1.New(c)
|
||||
cs.servingV1 = servingv1.New(c)
|
||||
cs.servingV1beta1 = servingv1beta1.New(c)
|
||||
cs.servingV1alpha1 = servingv1alpha1.New(c)
|
||||
|
||||
cs.DiscoveryClient = discovery.NewDiscoveryClient(c)
|
||||
|
|
|
@ -31,6 +31,8 @@ import (
|
|||
fakeservingv1 "knative.dev/serving/pkg/client/clientset/versioned/typed/serving/v1/fake"
|
||||
servingv1alpha1 "knative.dev/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1"
|
||||
fakeservingv1alpha1 "knative.dev/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1/fake"
|
||||
servingv1beta1 "knative.dev/serving/pkg/client/clientset/versioned/typed/serving/v1beta1"
|
||||
fakeservingv1beta1 "knative.dev/serving/pkg/client/clientset/versioned/typed/serving/v1beta1/fake"
|
||||
)
|
||||
|
||||
// NewSimpleClientset returns a clientset that will respond with the provided objects.
|
||||
|
@ -90,6 +92,11 @@ func (c *Clientset) ServingV1() servingv1.ServingV1Interface {
|
|||
return &fakeservingv1.FakeServingV1{Fake: &c.Fake}
|
||||
}
|
||||
|
||||
// ServingV1beta1 retrieves the ServingV1beta1Client
|
||||
func (c *Clientset) ServingV1beta1() servingv1beta1.ServingV1beta1Interface {
|
||||
return &fakeservingv1beta1.FakeServingV1beta1{Fake: &c.Fake}
|
||||
}
|
||||
|
||||
// ServingV1alpha1 retrieves the ServingV1alpha1Client
|
||||
func (c *Clientset) ServingV1alpha1() servingv1alpha1.ServingV1alpha1Interface {
|
||||
return &fakeservingv1alpha1.FakeServingV1alpha1{Fake: &c.Fake}
|
||||
|
|
|
@ -27,6 +27,7 @@ import (
|
|||
autoscalingv1alpha1 "knative.dev/serving/pkg/apis/autoscaling/v1alpha1"
|
||||
servingv1 "knative.dev/serving/pkg/apis/serving/v1"
|
||||
servingv1alpha1 "knative.dev/serving/pkg/apis/serving/v1alpha1"
|
||||
servingv1beta1 "knative.dev/serving/pkg/apis/serving/v1beta1"
|
||||
)
|
||||
|
||||
var scheme = runtime.NewScheme()
|
||||
|
@ -35,6 +36,7 @@ var codecs = serializer.NewCodecFactory(scheme)
|
|||
var localSchemeBuilder = runtime.SchemeBuilder{
|
||||
autoscalingv1alpha1.AddToScheme,
|
||||
servingv1.AddToScheme,
|
||||
servingv1beta1.AddToScheme,
|
||||
servingv1alpha1.AddToScheme,
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ import (
|
|||
autoscalingv1alpha1 "knative.dev/serving/pkg/apis/autoscaling/v1alpha1"
|
||||
servingv1 "knative.dev/serving/pkg/apis/serving/v1"
|
||||
servingv1alpha1 "knative.dev/serving/pkg/apis/serving/v1alpha1"
|
||||
servingv1beta1 "knative.dev/serving/pkg/apis/serving/v1beta1"
|
||||
)
|
||||
|
||||
var Scheme = runtime.NewScheme()
|
||||
|
@ -35,6 +36,7 @@ var ParameterCodec = runtime.NewParameterCodec(Scheme)
|
|||
var localSchemeBuilder = runtime.SchemeBuilder{
|
||||
autoscalingv1alpha1.AddToScheme,
|
||||
servingv1.AddToScheme,
|
||||
servingv1beta1.AddToScheme,
|
||||
servingv1alpha1.AddToScheme,
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
Copyright 2021 The Knative Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
// This package has the automatically generated typed clients.
|
||||
package v1beta1
|
|
@ -0,0 +1,195 @@
|
|||
/*
|
||||
Copyright 2021 The Knative Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
rest "k8s.io/client-go/rest"
|
||||
v1beta1 "knative.dev/serving/pkg/apis/serving/v1beta1"
|
||||
scheme "knative.dev/serving/pkg/client/clientset/versioned/scheme"
|
||||
)
|
||||
|
||||
// DomainMappingsGetter has a method to return a DomainMappingInterface.
|
||||
// A group's client should implement this interface.
|
||||
type DomainMappingsGetter interface {
|
||||
DomainMappings(namespace string) DomainMappingInterface
|
||||
}
|
||||
|
||||
// DomainMappingInterface has methods to work with DomainMapping resources.
|
||||
type DomainMappingInterface interface {
|
||||
Create(ctx context.Context, domainMapping *v1beta1.DomainMapping, opts v1.CreateOptions) (*v1beta1.DomainMapping, error)
|
||||
Update(ctx context.Context, domainMapping *v1beta1.DomainMapping, opts v1.UpdateOptions) (*v1beta1.DomainMapping, error)
|
||||
UpdateStatus(ctx context.Context, domainMapping *v1beta1.DomainMapping, opts v1.UpdateOptions) (*v1beta1.DomainMapping, error)
|
||||
Delete(ctx context.Context, name string, opts v1.DeleteOptions) error
|
||||
DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error
|
||||
Get(ctx context.Context, name string, opts v1.GetOptions) (*v1beta1.DomainMapping, error)
|
||||
List(ctx context.Context, opts v1.ListOptions) (*v1beta1.DomainMappingList, error)
|
||||
Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error)
|
||||
Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.DomainMapping, err error)
|
||||
DomainMappingExpansion
|
||||
}
|
||||
|
||||
// domainMappings implements DomainMappingInterface
|
||||
type domainMappings struct {
|
||||
client rest.Interface
|
||||
ns string
|
||||
}
|
||||
|
||||
// newDomainMappings returns a DomainMappings
|
||||
func newDomainMappings(c *ServingV1beta1Client, namespace string) *domainMappings {
|
||||
return &domainMappings{
|
||||
client: c.RESTClient(),
|
||||
ns: namespace,
|
||||
}
|
||||
}
|
||||
|
||||
// Get takes name of the domainMapping, and returns the corresponding domainMapping object, and an error if there is any.
|
||||
func (c *domainMappings) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.DomainMapping, err error) {
|
||||
result = &v1beta1.DomainMapping{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("domainmappings").
|
||||
Name(name).
|
||||
VersionedParams(&options, scheme.ParameterCodec).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of DomainMappings that match those selectors.
|
||||
func (c *domainMappings) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.DomainMappingList, err error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
result = &v1beta1.DomainMappingList{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("domainmappings").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested domainMappings.
|
||||
func (c *domainMappings) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
opts.Watch = true
|
||||
return c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("domainmappings").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Watch(ctx)
|
||||
}
|
||||
|
||||
// Create takes the representation of a domainMapping and creates it. Returns the server's representation of the domainMapping, and an error, if there is any.
|
||||
func (c *domainMappings) Create(ctx context.Context, domainMapping *v1beta1.DomainMapping, opts v1.CreateOptions) (result *v1beta1.DomainMapping, err error) {
|
||||
result = &v1beta1.DomainMapping{}
|
||||
err = c.client.Post().
|
||||
Namespace(c.ns).
|
||||
Resource("domainmappings").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(domainMapping).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a domainMapping and updates it. Returns the server's representation of the domainMapping, and an error, if there is any.
|
||||
func (c *domainMappings) Update(ctx context.Context, domainMapping *v1beta1.DomainMapping, opts v1.UpdateOptions) (result *v1beta1.DomainMapping, err error) {
|
||||
result = &v1beta1.DomainMapping{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("domainmappings").
|
||||
Name(domainMapping.Name).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(domainMapping).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
func (c *domainMappings) UpdateStatus(ctx context.Context, domainMapping *v1beta1.DomainMapping, opts v1.UpdateOptions) (result *v1beta1.DomainMapping, err error) {
|
||||
result = &v1beta1.DomainMapping{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("domainmappings").
|
||||
Name(domainMapping.Name).
|
||||
SubResource("status").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(domainMapping).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the domainMapping and deletes it. Returns an error if one occurs.
|
||||
func (c *domainMappings) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("domainmappings").
|
||||
Name(name).
|
||||
Body(&opts).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *domainMappings) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
var timeout time.Duration
|
||||
if listOpts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("domainmappings").
|
||||
VersionedParams(&listOpts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Body(&opts).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched domainMapping.
|
||||
func (c *domainMappings) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.DomainMapping, err error) {
|
||||
result = &v1beta1.DomainMapping{}
|
||||
err = c.client.Patch(pt).
|
||||
Namespace(c.ns).
|
||||
Resource("domainmappings").
|
||||
Name(name).
|
||||
SubResource(subresources...).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(data).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
Copyright 2021 The Knative Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
// Package fake has the automatically generated clients.
|
||||
package fake
|
142
pkg/client/clientset/versioned/typed/serving/v1beta1/fake/fake_domainmapping.go
generated
Normal file
142
pkg/client/clientset/versioned/typed/serving/v1beta1/fake/fake_domainmapping.go
generated
Normal file
|
@ -0,0 +1,142 @@
|
|||
/*
|
||||
Copyright 2021 The Knative Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
labels "k8s.io/apimachinery/pkg/labels"
|
||||
schema "k8s.io/apimachinery/pkg/runtime/schema"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
testing "k8s.io/client-go/testing"
|
||||
v1beta1 "knative.dev/serving/pkg/apis/serving/v1beta1"
|
||||
)
|
||||
|
||||
// FakeDomainMappings implements DomainMappingInterface
|
||||
type FakeDomainMappings struct {
|
||||
Fake *FakeServingV1beta1
|
||||
ns string
|
||||
}
|
||||
|
||||
var domainmappingsResource = schema.GroupVersionResource{Group: "serving.knative.dev", Version: "v1beta1", Resource: "domainmappings"}
|
||||
|
||||
var domainmappingsKind = schema.GroupVersionKind{Group: "serving.knative.dev", Version: "v1beta1", Kind: "DomainMapping"}
|
||||
|
||||
// Get takes name of the domainMapping, and returns the corresponding domainMapping object, and an error if there is any.
|
||||
func (c *FakeDomainMappings) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.DomainMapping, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewGetAction(domainmappingsResource, c.ns, name), &v1beta1.DomainMapping{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.DomainMapping), err
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of DomainMappings that match those selectors.
|
||||
func (c *FakeDomainMappings) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.DomainMappingList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewListAction(domainmappingsResource, domainmappingsKind, c.ns, opts), &v1beta1.DomainMappingList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label, _, _ := testing.ExtractFromListOptions(opts)
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &v1beta1.DomainMappingList{ListMeta: obj.(*v1beta1.DomainMappingList).ListMeta}
|
||||
for _, item := range obj.(*v1beta1.DomainMappingList).Items {
|
||||
if label.Matches(labels.Set(item.Labels)) {
|
||||
list.Items = append(list.Items, item)
|
||||
}
|
||||
}
|
||||
return list, err
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested domainMappings.
|
||||
func (c *FakeDomainMappings) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewWatchAction(domainmappingsResource, c.ns, opts))
|
||||
|
||||
}
|
||||
|
||||
// Create takes the representation of a domainMapping and creates it. Returns the server's representation of the domainMapping, and an error, if there is any.
|
||||
func (c *FakeDomainMappings) Create(ctx context.Context, domainMapping *v1beta1.DomainMapping, opts v1.CreateOptions) (result *v1beta1.DomainMapping, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewCreateAction(domainmappingsResource, c.ns, domainMapping), &v1beta1.DomainMapping{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.DomainMapping), err
|
||||
}
|
||||
|
||||
// Update takes the representation of a domainMapping and updates it. Returns the server's representation of the domainMapping, and an error, if there is any.
|
||||
func (c *FakeDomainMappings) Update(ctx context.Context, domainMapping *v1beta1.DomainMapping, opts v1.UpdateOptions) (result *v1beta1.DomainMapping, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateAction(domainmappingsResource, c.ns, domainMapping), &v1beta1.DomainMapping{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.DomainMapping), err
|
||||
}
|
||||
|
||||
// UpdateStatus was generated because the type contains a Status member.
|
||||
// Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus().
|
||||
func (c *FakeDomainMappings) UpdateStatus(ctx context.Context, domainMapping *v1beta1.DomainMapping, opts v1.UpdateOptions) (*v1beta1.DomainMapping, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateSubresourceAction(domainmappingsResource, "status", c.ns, domainMapping), &v1beta1.DomainMapping{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.DomainMapping), err
|
||||
}
|
||||
|
||||
// Delete takes name of the domainMapping and deletes it. Returns an error if one occurs.
|
||||
func (c *FakeDomainMappings) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewDeleteAction(domainmappingsResource, c.ns, name), &v1beta1.DomainMapping{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *FakeDomainMappings) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
action := testing.NewDeleteCollectionAction(domainmappingsResource, c.ns, listOpts)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &v1beta1.DomainMappingList{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched domainMapping.
|
||||
func (c *FakeDomainMappings) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.DomainMapping, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewPatchSubresourceAction(domainmappingsResource, c.ns, name, pt, data, subresources...), &v1beta1.DomainMapping{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta1.DomainMapping), err
|
||||
}
|
40
pkg/client/clientset/versioned/typed/serving/v1beta1/fake/fake_serving_client.go
generated
Normal file
40
pkg/client/clientset/versioned/typed/serving/v1beta1/fake/fake_serving_client.go
generated
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
Copyright 2021 The Knative Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
rest "k8s.io/client-go/rest"
|
||||
testing "k8s.io/client-go/testing"
|
||||
v1beta1 "knative.dev/serving/pkg/client/clientset/versioned/typed/serving/v1beta1"
|
||||
)
|
||||
|
||||
type FakeServingV1beta1 struct {
|
||||
*testing.Fake
|
||||
}
|
||||
|
||||
func (c *FakeServingV1beta1) DomainMappings(namespace string) v1beta1.DomainMappingInterface {
|
||||
return &FakeDomainMappings{c, namespace}
|
||||
}
|
||||
|
||||
// RESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *FakeServingV1beta1) RESTClient() rest.Interface {
|
||||
var ret *rest.RESTClient
|
||||
return ret
|
||||
}
|
21
pkg/client/clientset/versioned/typed/serving/v1beta1/generated_expansion.go
generated
Normal file
21
pkg/client/clientset/versioned/typed/serving/v1beta1/generated_expansion.go
generated
Normal file
|
@ -0,0 +1,21 @@
|
|||
/*
|
||||
Copyright 2021 The Knative Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
type DomainMappingExpansion interface{}
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
Copyright 2021 The Knative Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by client-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
rest "k8s.io/client-go/rest"
|
||||
v1beta1 "knative.dev/serving/pkg/apis/serving/v1beta1"
|
||||
"knative.dev/serving/pkg/client/clientset/versioned/scheme"
|
||||
)
|
||||
|
||||
type ServingV1beta1Interface interface {
|
||||
RESTClient() rest.Interface
|
||||
DomainMappingsGetter
|
||||
}
|
||||
|
||||
// ServingV1beta1Client is used to interact with features provided by the serving.knative.dev group.
|
||||
type ServingV1beta1Client struct {
|
||||
restClient rest.Interface
|
||||
}
|
||||
|
||||
func (c *ServingV1beta1Client) DomainMappings(namespace string) DomainMappingInterface {
|
||||
return newDomainMappings(c, namespace)
|
||||
}
|
||||
|
||||
// NewForConfig creates a new ServingV1beta1Client for the given config.
|
||||
func NewForConfig(c *rest.Config) (*ServingV1beta1Client, error) {
|
||||
config := *c
|
||||
if err := setConfigDefaults(&config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client, err := rest.RESTClientFor(&config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &ServingV1beta1Client{client}, nil
|
||||
}
|
||||
|
||||
// NewForConfigOrDie creates a new ServingV1beta1Client for the given config and
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *rest.Config) *ServingV1beta1Client {
|
||||
client, err := NewForConfig(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// New creates a new ServingV1beta1Client for the given RESTClient.
|
||||
func New(c rest.Interface) *ServingV1beta1Client {
|
||||
return &ServingV1beta1Client{c}
|
||||
}
|
||||
|
||||
func setConfigDefaults(config *rest.Config) error {
|
||||
gv := v1beta1.SchemeGroupVersion
|
||||
config.GroupVersion = &gv
|
||||
config.APIPath = "/apis"
|
||||
config.NegotiatedSerializer = scheme.Codecs.WithoutConversion()
|
||||
|
||||
if config.UserAgent == "" {
|
||||
config.UserAgent = rest.DefaultKubernetesUserAgent()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// RESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *ServingV1beta1Client) RESTClient() rest.Interface {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.restClient
|
||||
}
|
|
@ -26,6 +26,7 @@ import (
|
|||
v1alpha1 "knative.dev/serving/pkg/apis/autoscaling/v1alpha1"
|
||||
v1 "knative.dev/serving/pkg/apis/serving/v1"
|
||||
servingv1alpha1 "knative.dev/serving/pkg/apis/serving/v1alpha1"
|
||||
v1beta1 "knative.dev/serving/pkg/apis/serving/v1beta1"
|
||||
)
|
||||
|
||||
// GenericInformer is type of SharedIndexInformer which will locate and delegate to other
|
||||
|
@ -74,6 +75,10 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource
|
|||
case servingv1alpha1.SchemeGroupVersion.WithResource("domainmappings"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Serving().V1alpha1().DomainMappings().Informer()}, nil
|
||||
|
||||
// Group=serving.knative.dev, Version=v1beta1
|
||||
case v1beta1.SchemeGroupVersion.WithResource("domainmappings"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Serving().V1beta1().DomainMappings().Informer()}, nil
|
||||
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("no informer found for %v", resource)
|
||||
|
|
|
@ -22,12 +22,15 @@ import (
|
|||
internalinterfaces "knative.dev/serving/pkg/client/informers/externalversions/internalinterfaces"
|
||||
v1 "knative.dev/serving/pkg/client/informers/externalversions/serving/v1"
|
||||
v1alpha1 "knative.dev/serving/pkg/client/informers/externalversions/serving/v1alpha1"
|
||||
v1beta1 "knative.dev/serving/pkg/client/informers/externalversions/serving/v1beta1"
|
||||
)
|
||||
|
||||
// Interface provides access to each of this group's versions.
|
||||
type Interface interface {
|
||||
// V1 provides access to shared informers for resources in V1.
|
||||
V1() v1.Interface
|
||||
// V1beta1 provides access to shared informers for resources in V1beta1.
|
||||
V1beta1() v1beta1.Interface
|
||||
// V1alpha1 provides access to shared informers for resources in V1alpha1.
|
||||
V1alpha1() v1alpha1.Interface
|
||||
}
|
||||
|
@ -48,6 +51,11 @@ func (g *group) V1() v1.Interface {
|
|||
return v1.New(g.factory, g.namespace, g.tweakListOptions)
|
||||
}
|
||||
|
||||
// V1beta1 returns a new v1beta1.Interface.
|
||||
func (g *group) V1beta1() v1beta1.Interface {
|
||||
return v1beta1.New(g.factory, g.namespace, g.tweakListOptions)
|
||||
}
|
||||
|
||||
// V1alpha1 returns a new v1alpha1.Interface.
|
||||
func (g *group) V1alpha1() v1alpha1.Interface {
|
||||
return v1alpha1.New(g.factory, g.namespace, g.tweakListOptions)
|
||||
|
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
Copyright 2021 The Knative Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
"context"
|
||||
time "time"
|
||||
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
servingv1beta1 "knative.dev/serving/pkg/apis/serving/v1beta1"
|
||||
versioned "knative.dev/serving/pkg/client/clientset/versioned"
|
||||
internalinterfaces "knative.dev/serving/pkg/client/informers/externalversions/internalinterfaces"
|
||||
v1beta1 "knative.dev/serving/pkg/client/listers/serving/v1beta1"
|
||||
)
|
||||
|
||||
// DomainMappingInformer provides access to a shared informer and lister for
|
||||
// DomainMappings.
|
||||
type DomainMappingInformer interface {
|
||||
Informer() cache.SharedIndexInformer
|
||||
Lister() v1beta1.DomainMappingLister
|
||||
}
|
||||
|
||||
type domainMappingInformer struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
namespace string
|
||||
}
|
||||
|
||||
// NewDomainMappingInformer constructs a new informer for DomainMapping type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewDomainMappingInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||
return NewFilteredDomainMappingInformer(client, namespace, resyncPeriod, indexers, nil)
|
||||
}
|
||||
|
||||
// NewFilteredDomainMappingInformer constructs a new informer for DomainMapping type.
|
||||
// Always prefer using an informer factory to get a shared informer instead of getting an independent
|
||||
// one. This reduces memory footprint and number of connections to the server.
|
||||
func NewFilteredDomainMappingInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer {
|
||||
return cache.NewSharedIndexInformer(
|
||||
&cache.ListWatch{
|
||||
ListFunc: func(options v1.ListOptions) (runtime.Object, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.ServingV1beta1().DomainMappings(namespace).List(context.TODO(), options)
|
||||
},
|
||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.ServingV1beta1().DomainMappings(namespace).Watch(context.TODO(), options)
|
||||
},
|
||||
},
|
||||
&servingv1beta1.DomainMapping{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
}
|
||||
|
||||
func (f *domainMappingInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
||||
return NewFilteredDomainMappingInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *domainMappingInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&servingv1beta1.DomainMapping{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *domainMappingInformer) Lister() v1beta1.DomainMappingLister {
|
||||
return v1beta1.NewDomainMappingLister(f.Informer().GetIndexer())
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
Copyright 2021 The Knative Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by informer-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
internalinterfaces "knative.dev/serving/pkg/client/informers/externalversions/internalinterfaces"
|
||||
)
|
||||
|
||||
// Interface provides access to all the informers in this group version.
|
||||
type Interface interface {
|
||||
// DomainMappings returns a DomainMappingInformer.
|
||||
DomainMappings() DomainMappingInformer
|
||||
}
|
||||
|
||||
type version struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
namespace string
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
}
|
||||
|
||||
// New returns a new Interface.
|
||||
func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface {
|
||||
return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
|
||||
}
|
||||
|
||||
// DomainMappings returns a DomainMappingInformer.
|
||||
func (v *version) DomainMappings() DomainMappingInformer {
|
||||
return &domainMappingInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
|
||||
}
|
52
pkg/client/injection/informers/serving/v1beta1/domainmapping/domainmapping.go
generated
Normal file
52
pkg/client/injection/informers/serving/v1beta1/domainmapping/domainmapping.go
generated
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
Copyright 2021 The Knative Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by injection-gen. DO NOT EDIT.
|
||||
|
||||
package domainmapping
|
||||
|
||||
import (
|
||||
context "context"
|
||||
|
||||
controller "knative.dev/pkg/controller"
|
||||
injection "knative.dev/pkg/injection"
|
||||
logging "knative.dev/pkg/logging"
|
||||
v1beta1 "knative.dev/serving/pkg/client/informers/externalversions/serving/v1beta1"
|
||||
factory "knative.dev/serving/pkg/client/injection/informers/factory"
|
||||
)
|
||||
|
||||
func init() {
|
||||
injection.Default.RegisterInformer(withInformer)
|
||||
}
|
||||
|
||||
// Key is used for associating the Informer inside the context.Context.
|
||||
type Key struct{}
|
||||
|
||||
func withInformer(ctx context.Context) (context.Context, controller.Informer) {
|
||||
f := factory.Get(ctx)
|
||||
inf := f.Serving().V1beta1().DomainMappings()
|
||||
return context.WithValue(ctx, Key{}, inf), inf.Informer()
|
||||
}
|
||||
|
||||
// Get extracts the typed informer from the context.
|
||||
func Get(ctx context.Context) v1beta1.DomainMappingInformer {
|
||||
untyped := ctx.Value(Key{})
|
||||
if untyped == nil {
|
||||
logging.FromContext(ctx).Panic(
|
||||
"Unable to fetch knative.dev/serving/pkg/client/informers/externalversions/serving/v1beta1.DomainMappingInformer from context.")
|
||||
}
|
||||
return untyped.(v1beta1.DomainMappingInformer)
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
Copyright 2021 The Knative Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by injection-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
context "context"
|
||||
|
||||
controller "knative.dev/pkg/controller"
|
||||
injection "knative.dev/pkg/injection"
|
||||
fake "knative.dev/serving/pkg/client/injection/informers/factory/fake"
|
||||
domainmapping "knative.dev/serving/pkg/client/injection/informers/serving/v1beta1/domainmapping"
|
||||
)
|
||||
|
||||
var Get = domainmapping.Get
|
||||
|
||||
func init() {
|
||||
injection.Fake.RegisterInformer(withInformer)
|
||||
}
|
||||
|
||||
func withInformer(ctx context.Context) (context.Context, controller.Informer) {
|
||||
f := fake.Get(ctx)
|
||||
inf := f.Serving().V1beta1().DomainMappings()
|
||||
return context.WithValue(ctx, domainmapping.Key{}, inf), inf.Informer()
|
||||
}
|
65
pkg/client/injection/informers/serving/v1beta1/domainmapping/filtered/domainmapping.go
generated
Normal file
65
pkg/client/injection/informers/serving/v1beta1/domainmapping/filtered/domainmapping.go
generated
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
Copyright 2021 The Knative Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by injection-gen. DO NOT EDIT.
|
||||
|
||||
package filtered
|
||||
|
||||
import (
|
||||
context "context"
|
||||
|
||||
controller "knative.dev/pkg/controller"
|
||||
injection "knative.dev/pkg/injection"
|
||||
logging "knative.dev/pkg/logging"
|
||||
v1beta1 "knative.dev/serving/pkg/client/informers/externalversions/serving/v1beta1"
|
||||
filtered "knative.dev/serving/pkg/client/injection/informers/factory/filtered"
|
||||
)
|
||||
|
||||
func init() {
|
||||
injection.Default.RegisterFilteredInformers(withInformer)
|
||||
}
|
||||
|
||||
// Key is used for associating the Informer inside the context.Context.
|
||||
type Key struct {
|
||||
Selector string
|
||||
}
|
||||
|
||||
func withInformer(ctx context.Context) (context.Context, []controller.Informer) {
|
||||
untyped := ctx.Value(filtered.LabelKey{})
|
||||
if untyped == nil {
|
||||
logging.FromContext(ctx).Panic(
|
||||
"Unable to fetch labelkey from context.")
|
||||
}
|
||||
labelSelectors := untyped.([]string)
|
||||
infs := []controller.Informer{}
|
||||
for _, selector := range labelSelectors {
|
||||
f := filtered.Get(ctx, selector)
|
||||
inf := f.Serving().V1beta1().DomainMappings()
|
||||
ctx = context.WithValue(ctx, Key{Selector: selector}, inf)
|
||||
infs = append(infs, inf.Informer())
|
||||
}
|
||||
return ctx, infs
|
||||
}
|
||||
|
||||
// Get extracts the typed informer from the context.
|
||||
func Get(ctx context.Context, selector string) v1beta1.DomainMappingInformer {
|
||||
untyped := ctx.Value(Key{Selector: selector})
|
||||
if untyped == nil {
|
||||
logging.FromContext(ctx).Panicf(
|
||||
"Unable to fetch knative.dev/serving/pkg/client/informers/externalversions/serving/v1beta1.DomainMappingInformer with selector %s from context.", selector)
|
||||
}
|
||||
return untyped.(v1beta1.DomainMappingInformer)
|
||||
}
|
52
pkg/client/injection/informers/serving/v1beta1/domainmapping/filtered/fake/fake.go
generated
Normal file
52
pkg/client/injection/informers/serving/v1beta1/domainmapping/filtered/fake/fake.go
generated
Normal file
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
Copyright 2021 The Knative Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by injection-gen. DO NOT EDIT.
|
||||
|
||||
package fake
|
||||
|
||||
import (
|
||||
context "context"
|
||||
|
||||
controller "knative.dev/pkg/controller"
|
||||
injection "knative.dev/pkg/injection"
|
||||
logging "knative.dev/pkg/logging"
|
||||
factoryfiltered "knative.dev/serving/pkg/client/injection/informers/factory/filtered"
|
||||
filtered "knative.dev/serving/pkg/client/injection/informers/serving/v1beta1/domainmapping/filtered"
|
||||
)
|
||||
|
||||
var Get = filtered.Get
|
||||
|
||||
func init() {
|
||||
injection.Fake.RegisterFilteredInformers(withInformer)
|
||||
}
|
||||
|
||||
func withInformer(ctx context.Context) (context.Context, []controller.Informer) {
|
||||
untyped := ctx.Value(factoryfiltered.LabelKey{})
|
||||
if untyped == nil {
|
||||
logging.FromContext(ctx).Panic(
|
||||
"Unable to fetch labelkey from context.")
|
||||
}
|
||||
labelSelectors := untyped.([]string)
|
||||
infs := []controller.Informer{}
|
||||
for _, selector := range labelSelectors {
|
||||
f := factoryfiltered.Get(ctx, selector)
|
||||
inf := f.Serving().V1beta1().DomainMappings()
|
||||
ctx = context.WithValue(ctx, filtered.Key{Selector: selector}, inf)
|
||||
infs = append(infs, inf.Informer())
|
||||
}
|
||||
return ctx, infs
|
||||
}
|
162
pkg/client/injection/reconciler/serving/v1beta1/domainmapping/controller.go
generated
Normal file
162
pkg/client/injection/reconciler/serving/v1beta1/domainmapping/controller.go
generated
Normal file
|
@ -0,0 +1,162 @@
|
|||
/*
|
||||
Copyright 2021 The Knative Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by injection-gen. DO NOT EDIT.
|
||||
|
||||
package domainmapping
|
||||
|
||||
import (
|
||||
context "context"
|
||||
fmt "fmt"
|
||||
reflect "reflect"
|
||||
strings "strings"
|
||||
|
||||
zap "go.uber.org/zap"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
labels "k8s.io/apimachinery/pkg/labels"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
watch "k8s.io/apimachinery/pkg/watch"
|
||||
scheme "k8s.io/client-go/kubernetes/scheme"
|
||||
v1 "k8s.io/client-go/kubernetes/typed/core/v1"
|
||||
record "k8s.io/client-go/tools/record"
|
||||
kubeclient "knative.dev/pkg/client/injection/kube/client"
|
||||
controller "knative.dev/pkg/controller"
|
||||
logging "knative.dev/pkg/logging"
|
||||
logkey "knative.dev/pkg/logging/logkey"
|
||||
reconciler "knative.dev/pkg/reconciler"
|
||||
versionedscheme "knative.dev/serving/pkg/client/clientset/versioned/scheme"
|
||||
client "knative.dev/serving/pkg/client/injection/client"
|
||||
domainmapping "knative.dev/serving/pkg/client/injection/informers/serving/v1beta1/domainmapping"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultControllerAgentName = "domainmapping-controller"
|
||||
defaultFinalizerName = "domainmappings.serving.knative.dev"
|
||||
)
|
||||
|
||||
// NewImpl returns a controller.Impl that handles queuing and feeding work from
|
||||
// the queue through an implementation of controller.Reconciler, delegating to
|
||||
// the provided Interface and optional Finalizer methods. OptionsFn is used to return
|
||||
// controller.Options to be used by the internal reconciler.
|
||||
func NewImpl(ctx context.Context, r Interface, optionsFns ...controller.OptionsFn) *controller.Impl {
|
||||
logger := logging.FromContext(ctx)
|
||||
|
||||
// Check the options function input. It should be 0 or 1.
|
||||
if len(optionsFns) > 1 {
|
||||
logger.Fatal("Up to one options function is supported, found: ", len(optionsFns))
|
||||
}
|
||||
|
||||
domainmappingInformer := domainmapping.Get(ctx)
|
||||
|
||||
lister := domainmappingInformer.Lister()
|
||||
|
||||
var promoteFilterFunc func(obj interface{}) bool
|
||||
|
||||
rec := &reconcilerImpl{
|
||||
LeaderAwareFuncs: reconciler.LeaderAwareFuncs{
|
||||
PromoteFunc: func(bkt reconciler.Bucket, enq func(reconciler.Bucket, types.NamespacedName)) error {
|
||||
all, err := lister.List(labels.Everything())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, elt := range all {
|
||||
if promoteFilterFunc != nil {
|
||||
if ok := promoteFilterFunc(elt); !ok {
|
||||
continue
|
||||
}
|
||||
}
|
||||
enq(bkt, types.NamespacedName{
|
||||
Namespace: elt.GetNamespace(),
|
||||
Name: elt.GetName(),
|
||||
})
|
||||
}
|
||||
return nil
|
||||
},
|
||||
},
|
||||
Client: client.Get(ctx),
|
||||
Lister: lister,
|
||||
reconciler: r,
|
||||
finalizerName: defaultFinalizerName,
|
||||
}
|
||||
|
||||
ctrType := reflect.TypeOf(r).Elem()
|
||||
ctrTypeName := fmt.Sprintf("%s.%s", ctrType.PkgPath(), ctrType.Name())
|
||||
ctrTypeName = strings.ReplaceAll(ctrTypeName, "/", ".")
|
||||
|
||||
logger = logger.With(
|
||||
zap.String(logkey.ControllerType, ctrTypeName),
|
||||
zap.String(logkey.Kind, "serving.knative.dev.DomainMapping"),
|
||||
)
|
||||
|
||||
impl := controller.NewImpl(rec, logger, ctrTypeName)
|
||||
agentName := defaultControllerAgentName
|
||||
|
||||
// Pass impl to the options. Save any optional results.
|
||||
for _, fn := range optionsFns {
|
||||
opts := fn(impl)
|
||||
if opts.ConfigStore != nil {
|
||||
rec.configStore = opts.ConfigStore
|
||||
}
|
||||
if opts.FinalizerName != "" {
|
||||
rec.finalizerName = opts.FinalizerName
|
||||
}
|
||||
if opts.AgentName != "" {
|
||||
agentName = opts.AgentName
|
||||
}
|
||||
if opts.SkipStatusUpdates {
|
||||
rec.skipStatusUpdates = true
|
||||
}
|
||||
if opts.DemoteFunc != nil {
|
||||
rec.DemoteFunc = opts.DemoteFunc
|
||||
}
|
||||
if opts.PromoteFilterFunc != nil {
|
||||
promoteFilterFunc = opts.PromoteFilterFunc
|
||||
}
|
||||
}
|
||||
|
||||
rec.Recorder = createRecorder(ctx, agentName)
|
||||
|
||||
return impl
|
||||
}
|
||||
|
||||
func createRecorder(ctx context.Context, agentName string) record.EventRecorder {
|
||||
logger := logging.FromContext(ctx)
|
||||
|
||||
recorder := controller.GetEventRecorder(ctx)
|
||||
if recorder == nil {
|
||||
// Create event broadcaster
|
||||
logger.Debug("Creating event broadcaster")
|
||||
eventBroadcaster := record.NewBroadcaster()
|
||||
watches := []watch.Interface{
|
||||
eventBroadcaster.StartLogging(logger.Named("event-broadcaster").Infof),
|
||||
eventBroadcaster.StartRecordingToSink(
|
||||
&v1.EventSinkImpl{Interface: kubeclient.Get(ctx).CoreV1().Events("")}),
|
||||
}
|
||||
recorder = eventBroadcaster.NewRecorder(scheme.Scheme, corev1.EventSource{Component: agentName})
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
for _, w := range watches {
|
||||
w.Stop()
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
return recorder
|
||||
}
|
||||
|
||||
func init() {
|
||||
versionedscheme.AddToScheme(scheme.Scheme)
|
||||
}
|
455
pkg/client/injection/reconciler/serving/v1beta1/domainmapping/reconciler.go
generated
Normal file
455
pkg/client/injection/reconciler/serving/v1beta1/domainmapping/reconciler.go
generated
Normal file
|
@ -0,0 +1,455 @@
|
|||
/*
|
||||
Copyright 2021 The Knative Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by injection-gen. DO NOT EDIT.
|
||||
|
||||
package domainmapping
|
||||
|
||||
import (
|
||||
context "context"
|
||||
json "encoding/json"
|
||||
fmt "fmt"
|
||||
|
||||
zap "go.uber.org/zap"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
equality "k8s.io/apimachinery/pkg/api/equality"
|
||||
errors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
labels "k8s.io/apimachinery/pkg/labels"
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
sets "k8s.io/apimachinery/pkg/util/sets"
|
||||
record "k8s.io/client-go/tools/record"
|
||||
controller "knative.dev/pkg/controller"
|
||||
kmp "knative.dev/pkg/kmp"
|
||||
logging "knative.dev/pkg/logging"
|
||||
reconciler "knative.dev/pkg/reconciler"
|
||||
v1beta1 "knative.dev/serving/pkg/apis/serving/v1beta1"
|
||||
versioned "knative.dev/serving/pkg/client/clientset/versioned"
|
||||
servingv1beta1 "knative.dev/serving/pkg/client/listers/serving/v1beta1"
|
||||
)
|
||||
|
||||
// Interface defines the strongly typed interfaces to be implemented by a
|
||||
// controller reconciling v1beta1.DomainMapping.
|
||||
type Interface interface {
|
||||
// ReconcileKind implements custom logic to reconcile v1beta1.DomainMapping. Any changes
|
||||
// to the objects .Status or .Finalizers will be propagated to the stored
|
||||
// object. It is recommended that implementors do not call any update calls
|
||||
// for the Kind inside of ReconcileKind, it is the responsibility of the calling
|
||||
// controller to propagate those properties. The resource passed to ReconcileKind
|
||||
// will always have an empty deletion timestamp.
|
||||
ReconcileKind(ctx context.Context, o *v1beta1.DomainMapping) reconciler.Event
|
||||
}
|
||||
|
||||
// Finalizer defines the strongly typed interfaces to be implemented by a
|
||||
// controller finalizing v1beta1.DomainMapping.
|
||||
type Finalizer interface {
|
||||
// FinalizeKind implements custom logic to finalize v1beta1.DomainMapping. Any changes
|
||||
// to the objects .Status or .Finalizers will be ignored. Returning a nil or
|
||||
// Normal type reconciler.Event will allow the finalizer to be deleted on
|
||||
// the resource. The resource passed to FinalizeKind will always have a set
|
||||
// deletion timestamp.
|
||||
FinalizeKind(ctx context.Context, o *v1beta1.DomainMapping) reconciler.Event
|
||||
}
|
||||
|
||||
// ReadOnlyInterface defines the strongly typed interfaces to be implemented by a
|
||||
// controller reconciling v1beta1.DomainMapping if they want to process resources for which
|
||||
// they are not the leader.
|
||||
type ReadOnlyInterface interface {
|
||||
// ObserveKind implements logic to observe v1beta1.DomainMapping.
|
||||
// This method should not write to the API.
|
||||
ObserveKind(ctx context.Context, o *v1beta1.DomainMapping) reconciler.Event
|
||||
}
|
||||
|
||||
// ReadOnlyFinalizer defines the strongly typed interfaces to be implemented by a
|
||||
// controller finalizing v1beta1.DomainMapping if they want to process tombstoned resources
|
||||
// even when they are not the leader. Due to the nature of how finalizers are handled
|
||||
// there are no guarantees that this will be called.
|
||||
type ReadOnlyFinalizer interface {
|
||||
// ObserveFinalizeKind implements custom logic to observe the final state of v1beta1.DomainMapping.
|
||||
// This method should not write to the API.
|
||||
ObserveFinalizeKind(ctx context.Context, o *v1beta1.DomainMapping) reconciler.Event
|
||||
}
|
||||
|
||||
type doReconcile func(ctx context.Context, o *v1beta1.DomainMapping) reconciler.Event
|
||||
|
||||
// reconcilerImpl implements controller.Reconciler for v1beta1.DomainMapping resources.
|
||||
type reconcilerImpl struct {
|
||||
// LeaderAwareFuncs is inlined to help us implement reconciler.LeaderAware.
|
||||
reconciler.LeaderAwareFuncs
|
||||
|
||||
// Client is used to write back status updates.
|
||||
Client versioned.Interface
|
||||
|
||||
// Listers index properties about resources.
|
||||
Lister servingv1beta1.DomainMappingLister
|
||||
|
||||
// Recorder is an event recorder for recording Event resources to the
|
||||
// Kubernetes API.
|
||||
Recorder record.EventRecorder
|
||||
|
||||
// configStore allows for decorating a context with config maps.
|
||||
// +optional
|
||||
configStore reconciler.ConfigStore
|
||||
|
||||
// reconciler is the implementation of the business logic of the resource.
|
||||
reconciler Interface
|
||||
|
||||
// finalizerName is the name of the finalizer to reconcile.
|
||||
finalizerName string
|
||||
|
||||
// skipStatusUpdates configures whether or not this reconciler automatically updates
|
||||
// the status of the reconciled resource.
|
||||
skipStatusUpdates bool
|
||||
}
|
||||
|
||||
// Check that our Reconciler implements controller.Reconciler.
|
||||
var _ controller.Reconciler = (*reconcilerImpl)(nil)
|
||||
|
||||
// Check that our generated Reconciler is always LeaderAware.
|
||||
var _ reconciler.LeaderAware = (*reconcilerImpl)(nil)
|
||||
|
||||
func NewReconciler(ctx context.Context, logger *zap.SugaredLogger, client versioned.Interface, lister servingv1beta1.DomainMappingLister, recorder record.EventRecorder, r Interface, options ...controller.Options) controller.Reconciler {
|
||||
// Check the options function input. It should be 0 or 1.
|
||||
if len(options) > 1 {
|
||||
logger.Fatal("Up to one options struct is supported, found: ", len(options))
|
||||
}
|
||||
|
||||
// Fail fast when users inadvertently implement the other LeaderAware interface.
|
||||
// For the typed reconcilers, Promote shouldn't take any arguments.
|
||||
if _, ok := r.(reconciler.LeaderAware); ok {
|
||||
logger.Fatalf("%T implements the incorrect LeaderAware interface. Promote() should not take an argument as genreconciler handles the enqueuing automatically.", r)
|
||||
}
|
||||
// TODO: Consider validating when folks implement ReadOnlyFinalizer, but not Finalizer.
|
||||
|
||||
rec := &reconcilerImpl{
|
||||
LeaderAwareFuncs: reconciler.LeaderAwareFuncs{
|
||||
PromoteFunc: func(bkt reconciler.Bucket, enq func(reconciler.Bucket, types.NamespacedName)) error {
|
||||
all, err := lister.List(labels.Everything())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for _, elt := range all {
|
||||
// TODO: Consider letting users specify a filter in options.
|
||||
enq(bkt, types.NamespacedName{
|
||||
Namespace: elt.GetNamespace(),
|
||||
Name: elt.GetName(),
|
||||
})
|
||||
}
|
||||
return nil
|
||||
},
|
||||
},
|
||||
Client: client,
|
||||
Lister: lister,
|
||||
Recorder: recorder,
|
||||
reconciler: r,
|
||||
finalizerName: defaultFinalizerName,
|
||||
}
|
||||
|
||||
for _, opts := range options {
|
||||
if opts.ConfigStore != nil {
|
||||
rec.configStore = opts.ConfigStore
|
||||
}
|
||||
if opts.FinalizerName != "" {
|
||||
rec.finalizerName = opts.FinalizerName
|
||||
}
|
||||
if opts.SkipStatusUpdates {
|
||||
rec.skipStatusUpdates = true
|
||||
}
|
||||
if opts.DemoteFunc != nil {
|
||||
rec.DemoteFunc = opts.DemoteFunc
|
||||
}
|
||||
}
|
||||
|
||||
return rec
|
||||
}
|
||||
|
||||
// Reconcile implements controller.Reconciler
|
||||
func (r *reconcilerImpl) Reconcile(ctx context.Context, key string) error {
|
||||
logger := logging.FromContext(ctx)
|
||||
|
||||
// Initialize the reconciler state. This will convert the namespace/name
|
||||
// string into a distinct namespace and name, determine if this instance of
|
||||
// the reconciler is the leader, and any additional interfaces implemented
|
||||
// by the reconciler. Returns an error is the resource key is invalid.
|
||||
s, err := newState(key, r)
|
||||
if err != nil {
|
||||
logger.Error("Invalid resource key: ", key)
|
||||
return nil
|
||||
}
|
||||
|
||||
// If we are not the leader, and we don't implement either ReadOnly
|
||||
// observer interfaces, then take a fast-path out.
|
||||
if s.isNotLeaderNorObserver() {
|
||||
return controller.NewSkipKey(key)
|
||||
}
|
||||
|
||||
// If configStore is set, attach the frozen configuration to the context.
|
||||
if r.configStore != nil {
|
||||
ctx = r.configStore.ToContext(ctx)
|
||||
}
|
||||
|
||||
// Add the recorder to context.
|
||||
ctx = controller.WithEventRecorder(ctx, r.Recorder)
|
||||
|
||||
// Get the resource with this namespace/name.
|
||||
|
||||
getter := r.Lister.DomainMappings(s.namespace)
|
||||
|
||||
original, err := getter.Get(s.name)
|
||||
|
||||
if errors.IsNotFound(err) {
|
||||
// The resource may no longer exist, in which case we stop processing and call
|
||||
// the ObserveDeletion handler if appropriate.
|
||||
logger.Debugf("Resource %q no longer exists", key)
|
||||
if del, ok := r.reconciler.(reconciler.OnDeletionInterface); ok {
|
||||
return del.ObserveDeletion(ctx, types.NamespacedName{
|
||||
Namespace: s.namespace,
|
||||
Name: s.name,
|
||||
})
|
||||
}
|
||||
return nil
|
||||
} else if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Don't modify the informers copy.
|
||||
resource := original.DeepCopy()
|
||||
|
||||
var reconcileEvent reconciler.Event
|
||||
|
||||
name, do := s.reconcileMethodFor(resource)
|
||||
// Append the target method to the logger.
|
||||
logger = logger.With(zap.String("targetMethod", name))
|
||||
switch name {
|
||||
case reconciler.DoReconcileKind:
|
||||
// Set and update the finalizer on resource if r.reconciler
|
||||
// implements Finalizer.
|
||||
if resource, err = r.setFinalizerIfFinalizer(ctx, resource); err != nil {
|
||||
return fmt.Errorf("failed to set finalizers: %w", err)
|
||||
}
|
||||
|
||||
if !r.skipStatusUpdates {
|
||||
reconciler.PreProcessReconcile(ctx, resource)
|
||||
}
|
||||
|
||||
// Reconcile this copy of the resource and then write back any status
|
||||
// updates regardless of whether the reconciliation errored out.
|
||||
reconcileEvent = do(ctx, resource)
|
||||
|
||||
if !r.skipStatusUpdates {
|
||||
reconciler.PostProcessReconcile(ctx, resource, original)
|
||||
}
|
||||
|
||||
case reconciler.DoFinalizeKind:
|
||||
// For finalizing reconcilers, if this resource being marked for deletion
|
||||
// and reconciled cleanly (nil or normal event), remove the finalizer.
|
||||
reconcileEvent = do(ctx, resource)
|
||||
|
||||
if resource, err = r.clearFinalizer(ctx, resource, reconcileEvent); err != nil {
|
||||
return fmt.Errorf("failed to clear finalizers: %w", err)
|
||||
}
|
||||
|
||||
case reconciler.DoObserveKind, reconciler.DoObserveFinalizeKind:
|
||||
// Observe any changes to this resource, since we are not the leader.
|
||||
reconcileEvent = do(ctx, resource)
|
||||
|
||||
}
|
||||
|
||||
// Synchronize the status.
|
||||
switch {
|
||||
case r.skipStatusUpdates:
|
||||
// This reconciler implementation is configured to skip resource updates.
|
||||
// This may mean this reconciler does not observe spec, but reconciles external changes.
|
||||
case equality.Semantic.DeepEqual(original.Status, resource.Status):
|
||||
// If we didn't change anything then don't call updateStatus.
|
||||
// This is important because the copy we loaded from the injectionInformer's
|
||||
// cache may be stale and we don't want to overwrite a prior update
|
||||
// to status with this stale state.
|
||||
case !s.isLeader:
|
||||
// High-availability reconcilers may have many replicas watching the resource, but only
|
||||
// the elected leader is expected to write modifications.
|
||||
logger.Warn("Saw status changes when we aren't the leader!")
|
||||
default:
|
||||
if err = r.updateStatus(ctx, original, resource); err != nil {
|
||||
logger.Warnw("Failed to update resource status", zap.Error(err))
|
||||
r.Recorder.Eventf(resource, v1.EventTypeWarning, "UpdateFailed",
|
||||
"Failed to update status for %q: %v", resource.Name, err)
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// Report the reconciler event, if any.
|
||||
if reconcileEvent != nil {
|
||||
var event *reconciler.ReconcilerEvent
|
||||
if reconciler.EventAs(reconcileEvent, &event) {
|
||||
logger.Infow("Returned an event", zap.Any("event", reconcileEvent))
|
||||
r.Recorder.Event(resource, event.EventType, event.Reason, event.Error())
|
||||
|
||||
// the event was wrapped inside an error, consider the reconciliation as failed
|
||||
if _, isEvent := reconcileEvent.(*reconciler.ReconcilerEvent); !isEvent {
|
||||
return reconcileEvent
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
logger.Errorw("Returned an error", zap.Error(reconcileEvent))
|
||||
r.Recorder.Event(resource, v1.EventTypeWarning, "InternalError", reconcileEvent.Error())
|
||||
return reconcileEvent
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *reconcilerImpl) updateStatus(ctx context.Context, existing *v1beta1.DomainMapping, desired *v1beta1.DomainMapping) error {
|
||||
existing = existing.DeepCopy()
|
||||
return reconciler.RetryUpdateConflicts(func(attempts int) (err error) {
|
||||
// The first iteration tries to use the injectionInformer's state, subsequent attempts fetch the latest state via API.
|
||||
if attempts > 0 {
|
||||
|
||||
getter := r.Client.ServingV1beta1().DomainMappings(desired.Namespace)
|
||||
|
||||
existing, err = getter.Get(ctx, desired.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// If there's nothing to update, just return.
|
||||
if equality.Semantic.DeepEqual(existing.Status, desired.Status) {
|
||||
return nil
|
||||
}
|
||||
|
||||
if diff, err := kmp.SafeDiff(existing.Status, desired.Status); err == nil && diff != "" {
|
||||
logging.FromContext(ctx).Debug("Updating status with: ", diff)
|
||||
}
|
||||
|
||||
existing.Status = desired.Status
|
||||
|
||||
updater := r.Client.ServingV1beta1().DomainMappings(existing.Namespace)
|
||||
|
||||
_, err = updater.UpdateStatus(ctx, existing, metav1.UpdateOptions{})
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
// updateFinalizersFiltered will update the Finalizers of the resource.
|
||||
// TODO: this method could be generic and sync all finalizers. For now it only
|
||||
// updates defaultFinalizerName or its override.
|
||||
func (r *reconcilerImpl) updateFinalizersFiltered(ctx context.Context, resource *v1beta1.DomainMapping) (*v1beta1.DomainMapping, error) {
|
||||
|
||||
getter := r.Lister.DomainMappings(resource.Namespace)
|
||||
|
||||
actual, err := getter.Get(resource.Name)
|
||||
if err != nil {
|
||||
return resource, err
|
||||
}
|
||||
|
||||
// Don't modify the informers copy.
|
||||
existing := actual.DeepCopy()
|
||||
|
||||
var finalizers []string
|
||||
|
||||
// If there's nothing to update, just return.
|
||||
existingFinalizers := sets.NewString(existing.Finalizers...)
|
||||
desiredFinalizers := sets.NewString(resource.Finalizers...)
|
||||
|
||||
if desiredFinalizers.Has(r.finalizerName) {
|
||||
if existingFinalizers.Has(r.finalizerName) {
|
||||
// Nothing to do.
|
||||
return resource, nil
|
||||
}
|
||||
// Add the finalizer.
|
||||
finalizers = append(existing.Finalizers, r.finalizerName)
|
||||
} else {
|
||||
if !existingFinalizers.Has(r.finalizerName) {
|
||||
// Nothing to do.
|
||||
return resource, nil
|
||||
}
|
||||
// Remove the finalizer.
|
||||
existingFinalizers.Delete(r.finalizerName)
|
||||
finalizers = existingFinalizers.List()
|
||||
}
|
||||
|
||||
mergePatch := map[string]interface{}{
|
||||
"metadata": map[string]interface{}{
|
||||
"finalizers": finalizers,
|
||||
"resourceVersion": existing.ResourceVersion,
|
||||
},
|
||||
}
|
||||
|
||||
patch, err := json.Marshal(mergePatch)
|
||||
if err != nil {
|
||||
return resource, err
|
||||
}
|
||||
|
||||
patcher := r.Client.ServingV1beta1().DomainMappings(resource.Namespace)
|
||||
|
||||
resourceName := resource.Name
|
||||
updated, err := patcher.Patch(ctx, resourceName, types.MergePatchType, patch, metav1.PatchOptions{})
|
||||
if err != nil {
|
||||
r.Recorder.Eventf(existing, v1.EventTypeWarning, "FinalizerUpdateFailed",
|
||||
"Failed to update finalizers for %q: %v", resourceName, err)
|
||||
} else {
|
||||
r.Recorder.Eventf(updated, v1.EventTypeNormal, "FinalizerUpdate",
|
||||
"Updated %q finalizers", resource.GetName())
|
||||
}
|
||||
return updated, err
|
||||
}
|
||||
|
||||
func (r *reconcilerImpl) setFinalizerIfFinalizer(ctx context.Context, resource *v1beta1.DomainMapping) (*v1beta1.DomainMapping, error) {
|
||||
if _, ok := r.reconciler.(Finalizer); !ok {
|
||||
return resource, nil
|
||||
}
|
||||
|
||||
finalizers := sets.NewString(resource.Finalizers...)
|
||||
|
||||
// If this resource is not being deleted, mark the finalizer.
|
||||
if resource.GetDeletionTimestamp().IsZero() {
|
||||
finalizers.Insert(r.finalizerName)
|
||||
}
|
||||
|
||||
resource.Finalizers = finalizers.List()
|
||||
|
||||
// Synchronize the finalizers filtered by r.finalizerName.
|
||||
return r.updateFinalizersFiltered(ctx, resource)
|
||||
}
|
||||
|
||||
func (r *reconcilerImpl) clearFinalizer(ctx context.Context, resource *v1beta1.DomainMapping, reconcileEvent reconciler.Event) (*v1beta1.DomainMapping, error) {
|
||||
if _, ok := r.reconciler.(Finalizer); !ok {
|
||||
return resource, nil
|
||||
}
|
||||
if resource.GetDeletionTimestamp().IsZero() {
|
||||
return resource, nil
|
||||
}
|
||||
|
||||
finalizers := sets.NewString(resource.Finalizers...)
|
||||
|
||||
if reconcileEvent != nil {
|
||||
var event *reconciler.ReconcilerEvent
|
||||
if reconciler.EventAs(reconcileEvent, &event) {
|
||||
if event.EventType == v1.EventTypeNormal {
|
||||
finalizers.Delete(r.finalizerName)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
finalizers.Delete(r.finalizerName)
|
||||
}
|
||||
|
||||
resource.Finalizers = finalizers.List()
|
||||
|
||||
// Synchronize the finalizers filtered by r.finalizerName.
|
||||
return r.updateFinalizersFiltered(ctx, resource)
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
Copyright 2021 The Knative Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by injection-gen. DO NOT EDIT.
|
||||
|
||||
package domainmapping
|
||||
|
||||
import (
|
||||
fmt "fmt"
|
||||
|
||||
types "k8s.io/apimachinery/pkg/types"
|
||||
cache "k8s.io/client-go/tools/cache"
|
||||
reconciler "knative.dev/pkg/reconciler"
|
||||
v1beta1 "knative.dev/serving/pkg/apis/serving/v1beta1"
|
||||
)
|
||||
|
||||
// state is used to track the state of a reconciler in a single run.
|
||||
type state struct {
|
||||
// key is the original reconciliation key from the queue.
|
||||
key string
|
||||
// namespace is the namespace split from the reconciliation key.
|
||||
namespace string
|
||||
// name is the name split from the reconciliation key.
|
||||
name string
|
||||
// reconciler is the reconciler.
|
||||
reconciler Interface
|
||||
// roi is the read only interface cast of the reconciler.
|
||||
roi ReadOnlyInterface
|
||||
// isROI (Read Only Interface) the reconciler only observes reconciliation.
|
||||
isROI bool
|
||||
// rof is the read only finalizer cast of the reconciler.
|
||||
rof ReadOnlyFinalizer
|
||||
// isROF (Read Only Finalizer) the reconciler only observes finalize.
|
||||
isROF bool
|
||||
// isLeader the instance of the reconciler is the elected leader.
|
||||
isLeader bool
|
||||
}
|
||||
|
||||
func newState(key string, r *reconcilerImpl) (*state, error) {
|
||||
// Convert the namespace/name string into a distinct namespace and name.
|
||||
namespace, name, err := cache.SplitMetaNamespaceKey(key)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid resource key: %s", key)
|
||||
}
|
||||
|
||||
roi, isROI := r.reconciler.(ReadOnlyInterface)
|
||||
rof, isROF := r.reconciler.(ReadOnlyFinalizer)
|
||||
|
||||
isLeader := r.IsLeaderFor(types.NamespacedName{
|
||||
Namespace: namespace,
|
||||
Name: name,
|
||||
})
|
||||
|
||||
return &state{
|
||||
key: key,
|
||||
namespace: namespace,
|
||||
name: name,
|
||||
reconciler: r.reconciler,
|
||||
roi: roi,
|
||||
isROI: isROI,
|
||||
rof: rof,
|
||||
isROF: isROF,
|
||||
isLeader: isLeader,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// isNotLeaderNorObserver checks to see if this reconciler with the current
|
||||
// state is enabled to do any work or not.
|
||||
// isNotLeaderNorObserver returns true when there is no work possible for the
|
||||
// reconciler.
|
||||
func (s *state) isNotLeaderNorObserver() bool {
|
||||
if !s.isLeader && !s.isROI && !s.isROF {
|
||||
// If we are not the leader, and we don't implement either ReadOnly
|
||||
// interface, then take a fast-path out.
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *state) reconcileMethodFor(o *v1beta1.DomainMapping) (string, doReconcile) {
|
||||
if o.GetDeletionTimestamp().IsZero() {
|
||||
if s.isLeader {
|
||||
return reconciler.DoReconcileKind, s.reconciler.ReconcileKind
|
||||
} else if s.isROI {
|
||||
return reconciler.DoObserveKind, s.roi.ObserveKind
|
||||
}
|
||||
} else if fin, ok := s.reconciler.(Finalizer); s.isLeader && ok {
|
||||
return reconciler.DoFinalizeKind, fin.FinalizeKind
|
||||
} else if !s.isLeader && s.isROF {
|
||||
return reconciler.DoObserveFinalizeKind, s.rof.ObserveFinalizeKind
|
||||
}
|
||||
return "unknown", nil
|
||||
}
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
Copyright 2021 The Knative Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by lister-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
v1beta1 "knative.dev/serving/pkg/apis/serving/v1beta1"
|
||||
)
|
||||
|
||||
// DomainMappingLister helps list DomainMappings.
|
||||
// All objects returned here must be treated as read-only.
|
||||
type DomainMappingLister interface {
|
||||
// List lists all DomainMappings in the indexer.
|
||||
// Objects returned here must be treated as read-only.
|
||||
List(selector labels.Selector) (ret []*v1beta1.DomainMapping, err error)
|
||||
// DomainMappings returns an object that can list and get DomainMappings.
|
||||
DomainMappings(namespace string) DomainMappingNamespaceLister
|
||||
DomainMappingListerExpansion
|
||||
}
|
||||
|
||||
// domainMappingLister implements the DomainMappingLister interface.
|
||||
type domainMappingLister struct {
|
||||
indexer cache.Indexer
|
||||
}
|
||||
|
||||
// NewDomainMappingLister returns a new DomainMappingLister.
|
||||
func NewDomainMappingLister(indexer cache.Indexer) DomainMappingLister {
|
||||
return &domainMappingLister{indexer: indexer}
|
||||
}
|
||||
|
||||
// List lists all DomainMappings in the indexer.
|
||||
func (s *domainMappingLister) List(selector labels.Selector) (ret []*v1beta1.DomainMapping, err error) {
|
||||
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1beta1.DomainMapping))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// DomainMappings returns an object that can list and get DomainMappings.
|
||||
func (s *domainMappingLister) DomainMappings(namespace string) DomainMappingNamespaceLister {
|
||||
return domainMappingNamespaceLister{indexer: s.indexer, namespace: namespace}
|
||||
}
|
||||
|
||||
// DomainMappingNamespaceLister helps list and get DomainMappings.
|
||||
// All objects returned here must be treated as read-only.
|
||||
type DomainMappingNamespaceLister interface {
|
||||
// List lists all DomainMappings in the indexer for a given namespace.
|
||||
// Objects returned here must be treated as read-only.
|
||||
List(selector labels.Selector) (ret []*v1beta1.DomainMapping, err error)
|
||||
// Get retrieves the DomainMapping from the indexer for a given namespace and name.
|
||||
// Objects returned here must be treated as read-only.
|
||||
Get(name string) (*v1beta1.DomainMapping, error)
|
||||
DomainMappingNamespaceListerExpansion
|
||||
}
|
||||
|
||||
// domainMappingNamespaceLister implements the DomainMappingNamespaceLister
|
||||
// interface.
|
||||
type domainMappingNamespaceLister struct {
|
||||
indexer cache.Indexer
|
||||
namespace string
|
||||
}
|
||||
|
||||
// List lists all DomainMappings in the indexer for a given namespace.
|
||||
func (s domainMappingNamespaceLister) List(selector labels.Selector) (ret []*v1beta1.DomainMapping, err error) {
|
||||
err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1beta1.DomainMapping))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get retrieves the DomainMapping from the indexer for a given namespace and name.
|
||||
func (s domainMappingNamespaceLister) Get(name string) (*v1beta1.DomainMapping, error) {
|
||||
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return nil, errors.NewNotFound(v1beta1.Resource("domainmapping"), name)
|
||||
}
|
||||
return obj.(*v1beta1.DomainMapping), nil
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
Copyright 2021 The Knative Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by lister-gen. DO NOT EDIT.
|
||||
|
||||
package v1beta1
|
||||
|
||||
// DomainMappingListerExpansion allows custom methods to be added to
|
||||
// DomainMappingLister.
|
||||
type DomainMappingListerExpansion interface{}
|
||||
|
||||
// DomainMappingNamespaceListerExpansion allows custom methods to be added to
|
||||
// DomainMappingNamespaceLister.
|
||||
type DomainMappingNamespaceListerExpansion interface{}
|
|
@ -34,6 +34,7 @@ import (
|
|||
"knative.dev/serving/pkg/client/clientset/versioned"
|
||||
servingv1 "knative.dev/serving/pkg/client/clientset/versioned/typed/serving/v1"
|
||||
servingv1alpha1 "knative.dev/serving/pkg/client/clientset/versioned/typed/serving/v1alpha1"
|
||||
servingv1beta1 "knative.dev/serving/pkg/client/clientset/versioned/typed/serving/v1beta1"
|
||||
|
||||
// Every E2E test requires this, so add it here.
|
||||
_ "knative.dev/pkg/metrics/testing"
|
||||
|
@ -43,6 +44,7 @@ import (
|
|||
type Clients struct {
|
||||
KubeClient kubernetes.Interface
|
||||
ServingAlphaClient *ServingAlphaClients
|
||||
ServingBetaClient *ServingBetaClients
|
||||
ServingClient *ServingClients
|
||||
NetworkingClient *NetworkingClients
|
||||
Dynamic dynamic.Interface
|
||||
|
@ -53,6 +55,11 @@ type ServingAlphaClients struct {
|
|||
DomainMappings servingv1alpha1.DomainMappingInterface
|
||||
}
|
||||
|
||||
// ServingBetaClients holds instances of interfaces for making requests to knative serving clients.
|
||||
type ServingBetaClients struct {
|
||||
DomainMappings servingv1beta1.DomainMappingInterface
|
||||
}
|
||||
|
||||
// ServingClients holds instances of interfaces for making requests to knative serving clients.
|
||||
type ServingClients struct {
|
||||
Routes servingv1.RouteInterface
|
||||
|
@ -96,6 +103,11 @@ func NewClients(cfg *rest.Config, namespace string) (*Clients, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
clients.ServingBetaClient, err = newServingBetaClients(cfg, namespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
clients.Dynamic, err = dynamic.NewForConfig(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -136,6 +148,19 @@ func newServingAlphaClients(cfg *rest.Config, namespace string) (*ServingAlphaCl
|
|||
}, nil
|
||||
}
|
||||
|
||||
// newServingBetaClients instantiates and returns the serving clientset required to make requests to the
|
||||
// knative serving cluster.
|
||||
func newServingBetaClients(cfg *rest.Config, namespace string) (*ServingBetaClients, error) {
|
||||
cs, err := versioned.NewForConfig(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &ServingBetaClients{
|
||||
DomainMappings: cs.ServingV1beta1().DomainMappings(namespace),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// newServingClients instantiates and returns the serving clientset required to make requests to the
|
||||
// knative serving cluster.
|
||||
func newServingClients(cfg *rest.Config, namespace string) (*ServingClients, error) {
|
||||
|
|
|
@ -0,0 +1,222 @@
|
|||
// +build e2e
|
||||
|
||||
/*
|
||||
Copyright 2021 The Knative Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
duckv1 "knative.dev/pkg/apis/duck/v1"
|
||||
"knative.dev/pkg/reconciler"
|
||||
pkgtest "knative.dev/pkg/test"
|
||||
"knative.dev/pkg/test/spoof"
|
||||
"knative.dev/serving/pkg/apis/serving/v1beta1"
|
||||
"knative.dev/serving/test"
|
||||
"knative.dev/serving/test/e2e"
|
||||
v1test "knative.dev/serving/test/v1"
|
||||
)
|
||||
|
||||
func TestDomainMapping(t *testing.T) {
|
||||
if !test.ServingFlags.EnableBetaFeatures {
|
||||
t.Skip("Beta features not enabled")
|
||||
}
|
||||
|
||||
t.Parallel()
|
||||
ctx, clients := context.Background(), test.Setup(t)
|
||||
|
||||
names := test.ResourceNames{
|
||||
Service: test.ObjectNameForTest(t),
|
||||
Image: test.PizzaPlanet1,
|
||||
}
|
||||
|
||||
// Clean up on test failure or interrupt.
|
||||
test.EnsureTearDown(t, clients, &names)
|
||||
|
||||
// Set up initial Service.
|
||||
svc, err := v1test.CreateServiceReady(t, clients, &names)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create initial Service %v: %v", names.Service, err)
|
||||
}
|
||||
|
||||
// Using fixed hostnames can lead to conflicts when multiple tests run at
|
||||
// once, so include the svc name to avoid collisions.
|
||||
host := svc.Service.Name + ".example.org"
|
||||
// Set resolvabledomain for custom domain to false by default.
|
||||
resolvableCustomDomain := false
|
||||
|
||||
if test.ServingFlags.CustomDomain != "" {
|
||||
host = svc.Service.Name + "." + test.ServingFlags.CustomDomain
|
||||
resolvableCustomDomain = true
|
||||
}
|
||||
// Point DomainMapping at our service.
|
||||
var dm *v1beta1.DomainMapping
|
||||
if err := reconciler.RetryTestErrors(func(int) error {
|
||||
dm, err = clients.ServingBetaClient.DomainMappings.Create(ctx, &v1beta1.DomainMapping{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: host,
|
||||
Namespace: svc.Service.Namespace,
|
||||
},
|
||||
Spec: v1beta1.DomainMappingSpec{
|
||||
Ref: duckv1.KReference{
|
||||
Namespace: svc.Service.Namespace,
|
||||
Name: svc.Service.Name,
|
||||
APIVersion: "serving.knative.dev/v1",
|
||||
Kind: "Service",
|
||||
},
|
||||
},
|
||||
}, metav1.CreateOptions{})
|
||||
return err
|
||||
}); err != nil {
|
||||
t.Fatalf("Create(DomainMapping) = %v, expected no error", err)
|
||||
}
|
||||
|
||||
t.Cleanup(func() {
|
||||
clients.ServingAlphaClient.DomainMappings.Delete(ctx, dm.Name, metav1.DeleteOptions{})
|
||||
})
|
||||
|
||||
// Wait for DomainMapping to go Ready.
|
||||
waitErr := wait.PollImmediate(test.PollInterval, test.PollTimeout, func() (bool, error) {
|
||||
var err error
|
||||
dm, err = clients.ServingBetaClient.DomainMappings.Get(context.Background(), dm.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
|
||||
return dm.IsReady(), nil
|
||||
})
|
||||
if waitErr != nil {
|
||||
t.Fatalf("The DomainMapping %s was not marked as Ready: %v", dm.Name, waitErr)
|
||||
}
|
||||
|
||||
endpoint := dm.Status.URL.URL()
|
||||
t.Log("Probing", endpoint)
|
||||
if _, err := pkgtest.WaitForEndpointState(
|
||||
context.Background(),
|
||||
clients.KubeClient,
|
||||
t.Logf,
|
||||
endpoint,
|
||||
v1test.RetryingRouteInconsistency(spoof.MatchesAllOf(spoof.IsStatusOK, spoof.MatchesBody(test.PizzaPlanetText1))),
|
||||
"WaitForSuccessfulResponse",
|
||||
resolvableCustomDomain,
|
||||
test.AddRootCAtoTransport(context.Background(), t.Logf, clients, test.ServingFlags.HTTPS)); err != nil {
|
||||
t.Fatalf("Error probing %s: %v", endpoint, err)
|
||||
}
|
||||
|
||||
altClients := e2e.SetupAlternativeNamespace(t)
|
||||
altNames := test.ResourceNames{
|
||||
Service: test.ObjectNameForTest(t),
|
||||
Image: test.PizzaPlanet2,
|
||||
}
|
||||
test.EnsureTearDown(t, altClients, &altNames)
|
||||
|
||||
// Set up second Service in alt namespace.
|
||||
altSvc, err := v1test.CreateServiceReady(t, altClients, &altNames)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to create initial Service %v: %v", altNames.Service, err)
|
||||
}
|
||||
|
||||
// Create second domain mapping with same name in alt namespace - this will collide with the existing mapping.
|
||||
var altDm *v1beta1.DomainMapping
|
||||
if err := reconciler.RetryTestErrors(func(int) error {
|
||||
altDm, err = altClients.ServingBetaClient.DomainMappings.Create(ctx, &v1beta1.DomainMapping{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: host,
|
||||
Namespace: altSvc.Service.Namespace,
|
||||
},
|
||||
Spec: v1beta1.DomainMappingSpec{
|
||||
Ref: duckv1.KReference{
|
||||
Namespace: altSvc.Service.Namespace,
|
||||
Name: altSvc.Service.Name,
|
||||
APIVersion: "serving.knative.dev/v1",
|
||||
Kind: "Service",
|
||||
},
|
||||
},
|
||||
}, metav1.CreateOptions{})
|
||||
return err
|
||||
}); err != nil {
|
||||
t.Fatalf("Create(DomainMapping) = %v, expected no error", err)
|
||||
}
|
||||
|
||||
t.Cleanup(func() {
|
||||
altClients.ServingAlphaClient.DomainMappings.Delete(ctx, altDm.Name, metav1.DeleteOptions{})
|
||||
})
|
||||
|
||||
// Second domain mapping should go to DomainMappingConditionDomainClaimed=false state.
|
||||
waitErr = wait.PollImmediate(test.PollInterval, test.PollTimeout, func() (bool, error) {
|
||||
state, err := altClients.ServingAlphaClient.DomainMappings.Get(context.Background(), dm.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
|
||||
return state.Generation == state.Status.ObservedGeneration &&
|
||||
state.Status.GetCondition(v1beta1.DomainMappingConditionDomainClaimed).IsFalse(), nil
|
||||
})
|
||||
if waitErr != nil {
|
||||
t.Fatalf("The second DomainMapping %s did not enter DomainMappingConditionDomainClaimed=false state: %v", altDm.Name, waitErr)
|
||||
}
|
||||
|
||||
// Because the second DomainMapping collided with the first, it should not have taken effect.
|
||||
t.Log("Probing", endpoint)
|
||||
if _, err := pkgtest.WaitForEndpointState(
|
||||
context.Background(),
|
||||
clients.KubeClient,
|
||||
t.Logf,
|
||||
endpoint,
|
||||
v1test.RetryingRouteInconsistency(spoof.MatchesAllOf(spoof.IsStatusOK, spoof.MatchesBody(test.PizzaPlanetText1))),
|
||||
"WaitForSuccessfulResponse",
|
||||
resolvableCustomDomain,
|
||||
test.AddRootCAtoTransport(context.Background(), t.Logf, clients, test.ServingFlags.HTTPS)); err != nil {
|
||||
t.Fatalf("Error probing %s: %v", endpoint, err)
|
||||
}
|
||||
|
||||
// Delete the first DomainMapping.
|
||||
if err := clients.ServingAlphaClient.DomainMappings.Delete(ctx, dm.Name, metav1.DeleteOptions{}); err != nil {
|
||||
t.Fatalf("Delete=%v, expected no error", err)
|
||||
}
|
||||
|
||||
// The second DomainMapping should now be able to claim the domain.
|
||||
waitErr = wait.PollImmediate(test.PollInterval, test.PollTimeout, func() (bool, error) {
|
||||
var err error
|
||||
altDm, err = altClients.ServingBetaClient.DomainMappings.Get(context.Background(), altDm.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return true, err
|
||||
}
|
||||
|
||||
return altDm.IsReady(), nil
|
||||
})
|
||||
if waitErr != nil {
|
||||
t.Fatalf("The second DomainMapping %s was not marked as Ready: %v", dm.Name, waitErr)
|
||||
}
|
||||
|
||||
endpoint = altDm.Status.URL.URL()
|
||||
t.Log("Probing", endpoint)
|
||||
if _, err := pkgtest.WaitForEndpointState(
|
||||
context.Background(),
|
||||
clients.KubeClient,
|
||||
t.Logf,
|
||||
endpoint,
|
||||
v1test.RetryingRouteInconsistency(spoof.MatchesAllOf(spoof.IsStatusOK, spoof.MatchesBody(test.PizzaPlanetText2))),
|
||||
"WaitForSuccessfulResponse",
|
||||
resolvableCustomDomain,
|
||||
test.AddRootCAtoTransport(context.Background(), t.Logf, clients, test.ServingFlags.HTTPS)); err != nil {
|
||||
t.Fatalf("Error probing %s: %v", endpoint, err)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue