mirror of
https://github.com/fluxcd/flagger.git
synced 2026-08-29 02:37:31 +00:00
Merge pull request #584 from weaveworks/appmesh-v1beta2
Implement AppMesh v1beta2 router
This commit is contained in:
@@ -110,6 +110,8 @@ rules:
|
||||
resources:
|
||||
- virtualnodes
|
||||
- virtualnodes/finalizers
|
||||
- virtualrouters
|
||||
- virtualrouters/finalizers
|
||||
- virtualservices
|
||||
- virtualservices/finalizers
|
||||
verbs:
|
||||
|
||||
@@ -106,6 +106,8 @@ rules:
|
||||
resources:
|
||||
- virtualnodes
|
||||
- virtualnodes/finalizers
|
||||
- virtualrouters
|
||||
- virtualrouters/finalizers
|
||||
- virtualservices
|
||||
- virtualservices/finalizers
|
||||
verbs:
|
||||
|
||||
@@ -51,17 +51,6 @@ helm upgrade -i flagger flagger/flagger \
|
||||
--set meshProvider=smi:crossover
|
||||
```
|
||||
|
||||
Optionally you can enable Slack notifications:
|
||||
|
||||
```bash
|
||||
helm upgrade -i flagger flagger/flagger \
|
||||
--reuse-values \
|
||||
--namespace test \
|
||||
--set slack.url=https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK \
|
||||
--set slack.channel=general \
|
||||
--set slack.user=flagger
|
||||
```
|
||||
|
||||
## Bootstrap
|
||||
|
||||
Flagger takes a Kubernetes deployment and optionally a horizontal pod autoscaler (HPA),
|
||||
@@ -82,6 +71,59 @@ helm upgrade -i flagger-loadtester flagger/loadtester \
|
||||
--namespace=test
|
||||
```
|
||||
|
||||
Create a metric template to measure the HTTP requests error rate:
|
||||
|
||||
```yaml
|
||||
apiVersion: flagger.app/v1beta1
|
||||
kind: MetricTemplate
|
||||
metadata:
|
||||
name: error-rate
|
||||
namespace: test
|
||||
spec:
|
||||
provider:
|
||||
address: http://flagger-prometheus:9090
|
||||
type: prometheus
|
||||
query: |
|
||||
100 - rate(
|
||||
envoy_cluster_upstream_rq{
|
||||
kubernetes_namespace="{{ namespace }}",
|
||||
envoy_cluster_name="{{ target }}-canary",
|
||||
envoy_response_code!~"5.*"
|
||||
}[{{ interval }}])
|
||||
/
|
||||
rate(
|
||||
envoy_cluster_upstream_rq{
|
||||
kubernetes_namespace="{{ namespace }}",
|
||||
envoy_cluster_name="{{ target }}-canary"
|
||||
}[{{ interval }}]
|
||||
) * 100
|
||||
```
|
||||
|
||||
Create a metric template to measure the HTTP requests average duration:
|
||||
|
||||
```yaml
|
||||
apiVersion: flagger.app/v1beta1
|
||||
kind: MetricTemplate
|
||||
metadata:
|
||||
name: latency
|
||||
namespace: test
|
||||
spec:
|
||||
provider:
|
||||
address: http://flagger-prometheus:9090
|
||||
type: prometheus
|
||||
query: |
|
||||
histogram_quantile(0.99,
|
||||
sum(
|
||||
rate(
|
||||
envoy_cluster_upstream_rq_time_bucket{
|
||||
kubernetes_namespace="{{ namespace }}",
|
||||
envoy_cluster_name="{{ target }}-canary"
|
||||
}[{{ interval }}]
|
||||
)
|
||||
) by (le)
|
||||
)
|
||||
```
|
||||
|
||||
Create a canary custom resource:
|
||||
|
||||
```yaml
|
||||
@@ -91,15 +133,12 @@ metadata:
|
||||
name: podinfo
|
||||
namespace: test
|
||||
spec:
|
||||
# specify mesh provider if it isn't the default one
|
||||
# provider: "smi:crossover"
|
||||
provider: "smi:crossover"
|
||||
# deployment reference
|
||||
targetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: podinfo
|
||||
# the maximum time in seconds for the canary deployment
|
||||
# to make progress before it is rollback (default 600s)
|
||||
progressDeadlineSeconds: 60
|
||||
# HPA reference (optional)
|
||||
autoscalerRef:
|
||||
@@ -107,10 +146,7 @@ spec:
|
||||
kind: HorizontalPodAutoscaler
|
||||
name: podinfo
|
||||
service:
|
||||
# ClusterIP port number
|
||||
port: 9898
|
||||
# container port number or name (optional)
|
||||
targetPort: 9898
|
||||
# define the canary analysis timing and KPIs
|
||||
analysis:
|
||||
# schedule interval (default 60s)
|
||||
@@ -123,21 +159,19 @@ spec:
|
||||
# canary increment step
|
||||
# percentage (0-100)
|
||||
stepWeight: 5
|
||||
# App Mesh Prometheus checks
|
||||
metrics:
|
||||
- name: request-success-rate
|
||||
# minimum req success rate (non 5xx responses)
|
||||
# percentage (0-100)
|
||||
- name: error-rate
|
||||
templateRef:
|
||||
name: error-rate
|
||||
thresholdRange:
|
||||
min: 99
|
||||
interval: 1m
|
||||
- name: request-duration
|
||||
# maximum req duration P99
|
||||
# milliseconds
|
||||
max: 1
|
||||
interval: 30s
|
||||
- name: latency
|
||||
templateRef:
|
||||
name: latency
|
||||
thresholdRange:
|
||||
max: 500
|
||||
max: 0.5
|
||||
interval: 30s
|
||||
# testing (optional)
|
||||
webhooks:
|
||||
- name: acceptance-test
|
||||
type: pre-rollout
|
||||
|
||||
@@ -118,7 +118,7 @@ spec:
|
||||
) * 100
|
||||
```
|
||||
|
||||
Amd a metric template to measure the HTTP requests average duration:
|
||||
Create a metric template to measure the HTTP requests average duration:
|
||||
|
||||
```yaml
|
||||
apiVersion: flagger.app/v1beta1
|
||||
|
||||
@@ -30,7 +30,7 @@ chmod +x ${CODEGEN_PKG}/generate-groups.sh
|
||||
|
||||
${CODEGEN_PKG}/generate-groups.sh all \
|
||||
github.com/weaveworks/flagger/pkg/client github.com/weaveworks/flagger/pkg/apis \
|
||||
"flagger:v1beta1 appmesh:v1beta1 istio:v1alpha3 smi:v1alpha1 smi:v1alpha2 gloo:v1 projectcontour:v1" \
|
||||
"flagger:v1beta1 appmesh:v1beta2 appmesh:v1beta1 istio:v1alpha3 smi:v1alpha1 smi:v1alpha2 gloo:v1 projectcontour:v1" \
|
||||
--output-base "${TEMP_DIR}" \
|
||||
--go-header-file ${SCRIPT_ROOT}/hack/boilerplate.go.txt
|
||||
|
||||
|
||||
@@ -100,6 +100,8 @@ rules:
|
||||
resources:
|
||||
- virtualnodes
|
||||
- virtualnodes/finalizers
|
||||
- virtualrouters
|
||||
- virtualrouters/finalizers
|
||||
- virtualservices
|
||||
- virtualservices/finalizers
|
||||
verbs:
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
// +k8s:deepcopy-gen=package
|
||||
|
||||
// Package v1beta2 is the v1beta2 version of the API.
|
||||
// +groupName=appmesh.k8s.aws
|
||||
package v1beta2
|
||||
@@ -0,0 +1,41 @@
|
||||
package v1beta2
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
|
||||
"github.com/weaveworks/flagger/pkg/apis/appmesh"
|
||||
)
|
||||
|
||||
// SchemeGroupVersion is group version used to register these objects
|
||||
var SchemeGroupVersion = schema.GroupVersion{Group: appmesh.GroupName, Version: "v1beta2"}
|
||||
|
||||
// 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 = runtime.NewSchemeBuilder(addKnownTypes)
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
)
|
||||
|
||||
// Adds the list of known types to api.Scheme.
|
||||
func addKnownTypes(scheme *runtime.Scheme) error {
|
||||
scheme.AddKnownTypes(SchemeGroupVersion,
|
||||
&VirtualService{},
|
||||
&VirtualServiceList{},
|
||||
&VirtualRouter{},
|
||||
&VirtualRouterList{},
|
||||
&VirtualNode{},
|
||||
&VirtualNodeList{},
|
||||
)
|
||||
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
package v1beta2
|
||||
|
||||
import "k8s.io/apimachinery/pkg/types"
|
||||
|
||||
// +kubebuilder:validation:Enum=s;ms
|
||||
type DurationUnit string
|
||||
|
||||
const (
|
||||
DurationUnitS DurationUnit = "s"
|
||||
DurationUnitMS DurationUnit = "ms"
|
||||
)
|
||||
|
||||
type Duration struct {
|
||||
// A unit of time.
|
||||
Unit DurationUnit `json:"unit"`
|
||||
// A number of time units.
|
||||
// +kubebuilder:validation:Minimum=0
|
||||
Value int64 `json:"value"`
|
||||
}
|
||||
|
||||
// +kubebuilder:validation:Minimum=1
|
||||
// +kubebuilder:validation:Maximum=65535
|
||||
type PortNumber int64
|
||||
|
||||
// +kubebuilder:validation:Enum=grpc;http;http2;tcp
|
||||
type PortProtocol string
|
||||
|
||||
const (
|
||||
PortProtocolGRPC PortProtocol = "grpc"
|
||||
PortProtocolHTTP PortProtocol = "http"
|
||||
PortProtocolHTTP2 PortProtocol = "http2"
|
||||
PortProtocolTCP PortProtocol = "tcp"
|
||||
)
|
||||
|
||||
// PortMapping refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_PortMapping.html
|
||||
type PortMapping struct {
|
||||
// The port used for the port mapping.
|
||||
Port PortNumber `json:"port"`
|
||||
// The protocol used for the port mapping.
|
||||
Protocol PortProtocol `json:"protocol"`
|
||||
}
|
||||
|
||||
// VirtualNodeReference holds a reference to VirtualNode.appmesh.k8s.aws
|
||||
type VirtualNodeReference struct {
|
||||
// Namespace is the namespace of VirtualNode CR.
|
||||
// If unspecified, defaults to the referencing object's namespace
|
||||
// +optional
|
||||
Namespace *string `json:"namespace,omitempty"`
|
||||
// Name is the name of VirtualNode CR
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// VirtualServiceReference holds a reference to VirtualService.appmesh.k8s.aws
|
||||
type VirtualServiceReference struct {
|
||||
// Namespace is the namespace of VirtualService CR.
|
||||
// If unspecified, defaults to the referencing object's namespace
|
||||
// +optional
|
||||
Namespace *string `json:"namespace,omitempty"`
|
||||
// Name is the name of VirtualService CR
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// VirtualRouterReference holds a reference to VirtualRouter.appmesh.k8s.aws
|
||||
type VirtualRouterReference struct {
|
||||
// Namespace is the namespace of VirtualRouter CR.
|
||||
// If unspecified, defaults to the referencing object's namespace
|
||||
// +optional
|
||||
Namespace *string `json:"namespace,omitempty"`
|
||||
// Name is the name of VirtualRouter CR
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// MeshReference holds a reference to Mesh.appmesh.k8s.aws
|
||||
type MeshReference struct {
|
||||
// Name is the name of Mesh CR
|
||||
Name string `json:"name"`
|
||||
// UID is the UID of Mesh CR
|
||||
UID types.UID `json:"uid"`
|
||||
}
|
||||
|
||||
// VirtualGatewayReference holds a reference to VirtualGateway.appmesh.k8s.aws
|
||||
type VirtualGatewayReference struct {
|
||||
// Namespace is the namespace of VirtualGateway CR.
|
||||
// If unspecified, defaults to the referencing object's namespace
|
||||
// +optional
|
||||
Namespace *string `json:"namespace,omitempty"`
|
||||
// Name is the name of VirtualGateway CR
|
||||
Name string `json:"name"`
|
||||
// UID is the UID of VirtualGateway CR
|
||||
UID types.UID `json:"uid"`
|
||||
}
|
||||
@@ -0,0 +1,347 @@
|
||||
package v1beta2
|
||||
|
||||
import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// TLSValidationContextACMTrust refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_TlsValidationContextAcmTrust.html
|
||||
type TLSValidationContextACMTrust struct {
|
||||
// One or more ACM Amazon Resource Name (ARN)s.
|
||||
// +kubebuilder:validation:MinItems=1
|
||||
// +kubebuilder:validation:MaxItems=3
|
||||
CertificateAuthorityARNs []string `json:"certificateAuthorityARNs"`
|
||||
}
|
||||
|
||||
// TLSValidationContextFileTrust refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_TlsValidationContextFileTrust.html
|
||||
type TLSValidationContextFileTrust struct {
|
||||
// The certificate trust chain for a certificate stored on the file system of the virtual node that the proxy is running on.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=255
|
||||
CertificateChain string `json:"certificateChain"`
|
||||
}
|
||||
|
||||
// TLSValidationContextTrust refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_TlsValidationContextTrust.html
|
||||
type TLSValidationContextTrust struct {
|
||||
// A reference to an object that represents a TLS validation context trust for an AWS Certicate Manager (ACM) certificate.
|
||||
// +optional
|
||||
ACM *TLSValidationContextACMTrust `json:"acm,omitempty"`
|
||||
// An object that represents a TLS validation context trust for a local file.
|
||||
// +optional
|
||||
File *TLSValidationContextFileTrust `json:"file,omitempty"`
|
||||
}
|
||||
|
||||
// TLSValidationContext refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_TlsValidationContext.html
|
||||
type TLSValidationContext struct {
|
||||
// A reference to an object that represents a TLS validation context trust
|
||||
Trust TLSValidationContextTrust `json:"trust"`
|
||||
}
|
||||
|
||||
// ClientPolicyTLS refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_ClientPolicyTls.html
|
||||
type ClientPolicyTLS struct {
|
||||
// Whether the policy is enforced.
|
||||
// If unspecified, default settings from AWS API will be applied. Refer to AWS Docs for default settings.
|
||||
// +optional
|
||||
Enforce *bool `json:"enforce,omitempty"`
|
||||
// The range of ports that the policy is enforced for.
|
||||
// +optional
|
||||
Ports []PortNumber `json:"ports,omitempty"`
|
||||
// A reference to an object that represents a TLS validation context.
|
||||
Validation TLSValidationContext `json:"validation"`
|
||||
}
|
||||
|
||||
// ClientPolicy refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_ClientPolicy.html
|
||||
type ClientPolicy struct {
|
||||
// A reference to an object that represents a Transport Layer Security (TLS) client policy.
|
||||
// +optional
|
||||
TLS *ClientPolicyTLS `json:"tls,omitempty"`
|
||||
}
|
||||
|
||||
// VirtualServiceBackend refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_VirtualServiceBackend.html
|
||||
type VirtualServiceBackend struct {
|
||||
// The VirtualService that is acting as a virtual node backend.
|
||||
VirtualServiceRef VirtualServiceReference `json:"virtualServiceRef"`
|
||||
// A reference to an object that represents the client policy for a backend.
|
||||
// +optional
|
||||
ClientPolicy *ClientPolicy `json:"clientPolicy,omitempty"`
|
||||
}
|
||||
|
||||
// Backend refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_Backend.html
|
||||
type Backend struct {
|
||||
// Specifies a virtual service to use as a backend for a virtual node.
|
||||
VirtualService VirtualServiceBackend `json:"virtualService"`
|
||||
}
|
||||
|
||||
// BackendDefaults refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_BackendDefaults.html
|
||||
type BackendDefaults struct {
|
||||
// A reference to an object that represents a client policy.
|
||||
// +optional
|
||||
ClientPolicy *ClientPolicy `json:"clientPolicy,omitempty"`
|
||||
}
|
||||
|
||||
// HealthCheckPolicy refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_HealthCheckPolicy.html
|
||||
type HealthCheckPolicy struct {
|
||||
// The number of consecutive successful health checks that must occur before declaring listener healthy.
|
||||
// If unspecified, defaults to be 10
|
||||
// +kubebuilder:validation:Minimum=2
|
||||
// +kubebuilder:validation:Maximum=10
|
||||
// +optional
|
||||
HealthyThreshold *int64 `json:"healthyThreshold,omitempty"`
|
||||
// The time period in milliseconds between each health check execution.
|
||||
// If unspecified, defaults to be 30000
|
||||
// +kubebuilder:validation:Minimum=5000
|
||||
// +kubebuilder:validation:Maximum=300000
|
||||
// +optional
|
||||
IntervalMillis *int64 `json:"intervalMillis,omitempty"`
|
||||
// The destination path for the health check request.
|
||||
// This value is only used if the specified protocol is http or http2. For any other protocol, this value is ignored.
|
||||
// +optional
|
||||
Path *string `json:"path,omitempty"`
|
||||
// The destination port for the health check request.
|
||||
// If unspecified, defaults to be same as port defined in the PortMapping for the listener.
|
||||
// +optional
|
||||
Port *PortNumber `json:"port,omitempty"`
|
||||
// The protocol for the health check request
|
||||
// If unspecified, defaults to be same as protocol defined in the PortMapping for the listener.
|
||||
// +optional
|
||||
Protocol *PortProtocol `json:"protocol,omitempty"`
|
||||
// The amount of time to wait when receiving a response from the health check, in milliseconds.
|
||||
// If unspecified, defaults to be 5000
|
||||
// +kubebuilder:validation:Minimum=2000
|
||||
// +kubebuilder:validation:Maximum=60000
|
||||
// +optional
|
||||
TimeoutMillis *int64 `json:"timeoutMillis,omitempty"`
|
||||
// The number of consecutive failed health checks that must occur before declaring a virtual node unhealthy.
|
||||
// If unspecified, defaults to be 2
|
||||
// +kubebuilder:validation:Minimum=2
|
||||
// +kubebuilder:validation:Maximum=10
|
||||
// +optional
|
||||
UnhealthyThreshold *int64 `json:"unhealthyThreshold,omitempty"`
|
||||
}
|
||||
|
||||
// ListenerTLSACMCertificate refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_ListenerTlsAcmCertificate.html
|
||||
type ListenerTLSACMCertificate struct {
|
||||
// The Amazon Resource Name (ARN) for the certificate.
|
||||
CertificateARN string `json:"certificateARN"`
|
||||
}
|
||||
|
||||
// ListenerTLSFileCertificate refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_ListenerTlsFileCertificate.html
|
||||
type ListenerTLSFileCertificate struct {
|
||||
// The certificate chain for the certificate.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=255
|
||||
CertificateChain string `json:"certificateChain"`
|
||||
// The private key for a certificate stored on the file system of the virtual node that the proxy is running on.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=255
|
||||
PrivateKey string `json:"privateKey"`
|
||||
}
|
||||
|
||||
// ListenerTLSCertificate refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_ListenerTlsCertificate.html
|
||||
type ListenerTLSCertificate struct {
|
||||
// A reference to an object that represents an AWS Certificate Manager (ACM) certificate.
|
||||
// +optional
|
||||
ACM *ListenerTLSACMCertificate `json:"acm,omitempty"`
|
||||
// A reference to an object that represents a local file certificate.
|
||||
// +optional
|
||||
File *ListenerTLSFileCertificate `json:"file,omitempty"`
|
||||
}
|
||||
|
||||
const (
|
||||
ListenerTLSModeDisabled ListenerTLSMode = "DISABLED"
|
||||
ListenerTLSModePermissive ListenerTLSMode = "PERMISSIVE"
|
||||
ListenerTLSModeStrict ListenerTLSMode = "STRICT"
|
||||
)
|
||||
|
||||
// +kubebuilder:validation:Enum=DISABLED;PERMISSIVE;STRICT
|
||||
type ListenerTLSMode string
|
||||
|
||||
// ListenerTLS refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_ListenerTls.html
|
||||
type ListenerTLS struct {
|
||||
// A reference to an object that represents a listener's TLS certificate.
|
||||
Certificate ListenerTLSCertificate `json:"certificate"`
|
||||
// ListenerTLS mode
|
||||
Mode ListenerTLSMode `json:"mode"`
|
||||
}
|
||||
|
||||
// Listener refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_Listener.html
|
||||
type Listener struct {
|
||||
// The port mapping information for the listener.
|
||||
PortMapping PortMapping `json:"portMapping"`
|
||||
// The health check information for the listener.
|
||||
// +optional
|
||||
HealthCheck *HealthCheckPolicy `json:"healthCheck,omitempty"`
|
||||
// A reference to an object that represents the Transport Layer Security (TLS) properties for a listener.
|
||||
// +optional
|
||||
TLS *ListenerTLS `json:"tls,omitempty"`
|
||||
}
|
||||
|
||||
// AWSCloudMapInstanceAttribute refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_AwsCloudMapInstanceAttribute.html
|
||||
type AWSCloudMapInstanceAttribute struct {
|
||||
// The name of an AWS Cloud Map service instance attribute key.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=255
|
||||
Key string `json:"key"`
|
||||
// The value of an AWS Cloud Map service instance attribute key.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=1024
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
// AWSCloudMapServiceDiscovery refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_AwsCloudMapServiceDiscovery.html
|
||||
type AWSCloudMapServiceDiscovery struct {
|
||||
// The name of the AWS Cloud Map namespace to use.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=1024
|
||||
NamespaceName string `json:"namespaceName"`
|
||||
// The name of the AWS Cloud Map service to use.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=1024
|
||||
ServiceName string `json:"serviceName"`
|
||||
// A string map that contains attributes with values that you can use to filter instances by any custom attribute that you specified when you registered the instance
|
||||
// +optional
|
||||
Attributes []AWSCloudMapInstanceAttribute `json:"attributes,omitempty"`
|
||||
}
|
||||
|
||||
// DNSServiceDiscovery refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_DnsServiceDiscovery.html
|
||||
type DNSServiceDiscovery struct {
|
||||
// Specifies the DNS service discovery hostname for the virtual node.
|
||||
Hostname string `json:"hostname"`
|
||||
}
|
||||
|
||||
// ServiceDiscovery refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_ServiceDiscovery.html
|
||||
type ServiceDiscovery struct {
|
||||
// Specifies any AWS Cloud Map information for the virtual node.
|
||||
// +optional
|
||||
AWSCloudMap *AWSCloudMapServiceDiscovery `json:"awsCloudMap,omitempty"`
|
||||
// Specifies the DNS information for the virtual node.
|
||||
// +optional
|
||||
DNS *DNSServiceDiscovery `json:"dns,omitempty"`
|
||||
}
|
||||
|
||||
// FileAccessLog refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_FileAccessLog.html
|
||||
type FileAccessLog struct {
|
||||
// The file path to write access logs to.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=255
|
||||
Path string `json:"path"`
|
||||
}
|
||||
|
||||
// AccessLog refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_AccessLog.html
|
||||
type AccessLog struct {
|
||||
// The file object to send virtual node access logs to.
|
||||
// +optional
|
||||
File *FileAccessLog `json:"file,omitempty"`
|
||||
}
|
||||
|
||||
// Logging refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_Logging.html
|
||||
type Logging struct {
|
||||
// The access log configuration for a virtual node.
|
||||
// +optional
|
||||
AccessLog *AccessLog `json:"accessLog,omitempty"`
|
||||
}
|
||||
|
||||
type VirtualNodeConditionType string
|
||||
|
||||
const (
|
||||
// VirtualNodeActive is True when the AppMesh VirtualNode has been created or found via the API
|
||||
VirtualNodeActive VirtualNodeConditionType = "VirtualNodeActive"
|
||||
)
|
||||
|
||||
type VirtualNodeCondition struct {
|
||||
// Type of VirtualNode condition.
|
||||
Type VirtualNodeConditionType `json:"type"`
|
||||
// Status of the condition, one of True, False, Unknown.
|
||||
Status corev1.ConditionStatus `json:"status"`
|
||||
// Last time the condition transitioned from one status to another.
|
||||
// +optional
|
||||
LastTransitionTime *metav1.Time `json:"lastTransitionTime,omitempty"`
|
||||
// The reason for the condition's last transition.
|
||||
// +optional
|
||||
Reason *string `json:"reason,omitempty"`
|
||||
// A human readable message indicating details about the transition.
|
||||
// +optional
|
||||
Message *string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
// AWSCloudMapServiceStatus is AWS CloudMap Service object's info
|
||||
type AWSCloudMapServiceStatus struct {
|
||||
// NamespaceID is AWS CloudMap Service object's namespace Id
|
||||
// +optional
|
||||
NamespaceID *string `json:"namespaceID,omitempty"`
|
||||
// ServiceID is AWS CloudMap Service object's Id
|
||||
// +optional
|
||||
ServiceID *string `json:"serviceID,omitempty"`
|
||||
}
|
||||
|
||||
// VirtualNodeSpec defines the desired state of VirtualNode
|
||||
// refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_VirtualServiceSpec.html
|
||||
type VirtualNodeSpec struct {
|
||||
// AWSName is the AppMesh VirtualNode object's name.
|
||||
// If unspecified or empty, it defaults to be "${name}_${namespace}" of k8s VirtualNode
|
||||
// +optional
|
||||
AWSName *string `json:"awsName,omitempty"`
|
||||
// PodSelector selects Pods using labels to designate VirtualNode membership.
|
||||
// if unspecified or empty, it selects no pods.
|
||||
// +optional
|
||||
PodSelector *metav1.LabelSelector `json:"podSelector,omitempty"`
|
||||
// The listener that the virtual node is expected to receive inbound traffic from
|
||||
// +kubebuilder:validation:MinItems=0
|
||||
// +kubebuilder:validation:MaxItems=1
|
||||
// +optional
|
||||
Listeners []Listener `json:"listeners,omitempty"`
|
||||
// The service discovery information for the virtual node.
|
||||
// +optional
|
||||
ServiceDiscovery *ServiceDiscovery `json:"serviceDiscovery,omitempty"`
|
||||
// The backends that the virtual node is expected to send outbound traffic to.
|
||||
// +optional
|
||||
Backends []Backend `json:"backends,omitempty"`
|
||||
// A reference to an object that represents the defaults for backends.
|
||||
// +optional
|
||||
BackendDefaults *BackendDefaults `json:"backendDefaults,omitempty"`
|
||||
// The inbound and outbound access logging information for the virtual node.
|
||||
// +optional
|
||||
Logging *Logging `json:"logging,omitempty"`
|
||||
|
||||
// A reference to k8s Mesh CR that this VirtualNode belongs to.
|
||||
// The admission controller populates it using Meshes's selector, and prevents users from setting this field.
|
||||
//
|
||||
// Populated by the system.
|
||||
// Read-only.
|
||||
// +optional
|
||||
MeshRef *MeshReference `json:"meshRef,omitempty"`
|
||||
}
|
||||
|
||||
// VirtualNodeStatus defines the observed state of VirtualNode
|
||||
type VirtualNodeStatus struct {
|
||||
// VirtualNodeARN is the AppMesh VirtualNode object's Amazon Resource Name
|
||||
// +optional
|
||||
VirtualNodeARN *string `json:"virtualNodeARN,omitempty"`
|
||||
// The current VirtualNode status.
|
||||
// +optional
|
||||
Conditions []VirtualNodeCondition `json:"conditions,omitempty"`
|
||||
// AWSCloudMapServiceStatus is AWS CloudMap Service object's info
|
||||
// +optional
|
||||
AWSCloudMapServiceStatus *AWSCloudMapServiceStatus `json:"awsCloudMapServiceStatus,omitempty"`
|
||||
}
|
||||
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// VirtualNode is the Schema for the virtualnodes API
|
||||
type VirtualNode struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec VirtualNodeSpec `json:"spec,omitempty"`
|
||||
Status VirtualNodeStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// VirtualNodeList contains a list of VirtualNode
|
||||
type VirtualNodeList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []VirtualNode `json:"items"`
|
||||
}
|
||||
@@ -0,0 +1,369 @@
|
||||
/*
|
||||
|
||||
|
||||
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 v1beta2
|
||||
|
||||
import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// VirtualRouterListener refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_VirtualRouterListener.html
|
||||
type VirtualRouterListener struct {
|
||||
// The port mapping information for the listener.
|
||||
PortMapping PortMapping `json:"portMapping"`
|
||||
}
|
||||
|
||||
// WeightedTarget refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_WeightedTarget.html
|
||||
type WeightedTarget struct {
|
||||
// The virtual node to associate with the weighted target.
|
||||
VirtualNodeRef VirtualNodeReference `json:"virtualNodeRef"`
|
||||
// The relative weight of the weighted target.
|
||||
// +kubebuilder:validation:Minimum=0
|
||||
// +kubebuilder:validation:Maximum=100
|
||||
Weight int64 `json:"weight"`
|
||||
}
|
||||
|
||||
type MatchRange struct {
|
||||
// The start of the range.
|
||||
// +optional
|
||||
Start int64 `json:"start"`
|
||||
// The end of the range.
|
||||
// +optional
|
||||
End int64 `json:"end"`
|
||||
}
|
||||
|
||||
// HeaderMatchMethod refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_HeaderMatchMethod.html
|
||||
type HeaderMatchMethod struct {
|
||||
// The value sent by the client must match the specified value exactly.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=255
|
||||
// +optional
|
||||
Exact *string `json:"exact,omitempty"`
|
||||
// The value sent by the client must begin with the specified characters.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=255
|
||||
// +optional
|
||||
Prefix *string `json:"prefix,omitempty"`
|
||||
// An object that represents the range of values to match on.
|
||||
// +optional
|
||||
Range *MatchRange `json:"range,omitempty"`
|
||||
// The value sent by the client must include the specified characters.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=255
|
||||
// +optional
|
||||
Regex *string `json:"regex,omitempty"`
|
||||
// The value sent by the client must end with the specified characters.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=255
|
||||
// +optional
|
||||
Suffix *string `json:"suffix,omitempty"`
|
||||
}
|
||||
|
||||
// HTTPRouteHeader refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_HttpRouteHeader.html
|
||||
type HTTPRouteHeader struct {
|
||||
// A name for the HTTP header in the client request that will be matched on.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=50
|
||||
Name string `json:"name"`
|
||||
// The HeaderMatchMethod object.
|
||||
// +optional
|
||||
Match *HeaderMatchMethod `json:"match,omitempty"`
|
||||
// Specify True to match anything except the match criteria. The default value is False.
|
||||
// +optional
|
||||
Invert *bool `json:"invert,omitempty"`
|
||||
}
|
||||
|
||||
// HTTPRouteMatch refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_HttpRouteMatch.html
|
||||
type HTTPRouteMatch struct {
|
||||
// An object that represents the client request headers to match on.
|
||||
// +kubebuilder:validation:MinItems=1
|
||||
// +kubebuilder:validation:MaxItems=10
|
||||
// +optional
|
||||
Headers []HTTPRouteHeader `json:"headers,omitempty"`
|
||||
// The client request method to match on.
|
||||
// +kubebuilder:validation:Enum=CONNECT;DELETE;GET;HEAD;OPTIONS;PATCH;POST;PUT;TRACE
|
||||
// +optional
|
||||
Method *string `json:"method,omitempty"`
|
||||
// Specifies the path to match requests with
|
||||
Prefix string `json:"prefix"`
|
||||
// The client request scheme to match on
|
||||
// +kubebuilder:validation:Enum=http;https
|
||||
// +optional
|
||||
Scheme *string `json:"scheme,omitempty"`
|
||||
}
|
||||
|
||||
// HTTPRouteAction refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_HttpRouteAction.html
|
||||
type HTTPRouteAction struct {
|
||||
// An object that represents the targets that traffic is routed to when a request matches the route.
|
||||
// +kubebuilder:validation:MinItems=1
|
||||
// +kubebuilder:validation:MaxItems=10
|
||||
WeightedTargets []WeightedTarget `json:"weightedTargets"`
|
||||
}
|
||||
|
||||
// +kubebuilder:validation:Enum=server-error;gateway-error;client-error;stream-error
|
||||
type HTTPRetryPolicyEvent string
|
||||
|
||||
// +kubebuilder:validation:Enum=connection-error
|
||||
type TCPRetryPolicyEvent string
|
||||
|
||||
// +kubebuilder:validation:Enum=cancelled;deadline-exceeded;internal;resource-exhausted;unavailable
|
||||
type GRPCRetryPolicyEvent string
|
||||
|
||||
// HTTPRetryPolicy refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_HttpRetryPolicy.html
|
||||
type HTTPRetryPolicy struct {
|
||||
// +kubebuilder:validation:MinItems=1
|
||||
// +kubebuilder:validation:MaxItems=25
|
||||
// +optional
|
||||
HTTPRetryEvents []HTTPRetryPolicyEvent `json:"httpRetryEvents,omitempty"`
|
||||
// +kubebuilder:validation:MinItems=1
|
||||
// +kubebuilder:validation:MaxItems=1
|
||||
// +optional
|
||||
TCPRetryEvents []TCPRetryPolicyEvent `json:"tcpRetryEvents,omitempty"`
|
||||
// The maximum number of retry attempts.
|
||||
// +kubebuilder:validation:Minimum=0
|
||||
MaxRetries int64 `json:"maxRetries"`
|
||||
// An object that represents a duration of time
|
||||
PerRetryTimeout Duration `json:"perRetryTimeout"`
|
||||
}
|
||||
|
||||
// HTTPRoute refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_HttpRoute.html
|
||||
type HTTPRoute struct {
|
||||
// An object that represents the criteria for determining a request match.
|
||||
Match HTTPRouteMatch `json:"match"`
|
||||
// An object that represents the action to take if a match is determined.
|
||||
Action HTTPRouteAction `json:"action"`
|
||||
// An object that represents a retry policy.
|
||||
// +optional
|
||||
RetryPolicy *HTTPRetryPolicy `json:"retryPolicy,omitempty"`
|
||||
}
|
||||
|
||||
// TCPRouteAction refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_TcpRouteAction.html
|
||||
type TCPRouteAction struct {
|
||||
// An object that represents the targets that traffic is routed to when a request matches the route.
|
||||
// +kubebuilder:validation:MinItems=1
|
||||
// +kubebuilder:validation:MaxItems=10
|
||||
WeightedTargets []WeightedTarget `json:"weightedTargets"`
|
||||
}
|
||||
|
||||
// TCPRoute refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_TcpRoute.html
|
||||
type TCPRoute struct {
|
||||
// The action to take if a match is determined.
|
||||
Action TCPRouteAction `json:"action"`
|
||||
}
|
||||
|
||||
// GRPCRouteMetadataMatchMethod refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_GrpcRouteMetadataMatchMethod.html
|
||||
type GRPCRouteMetadataMatchMethod struct {
|
||||
// The value sent by the client must match the specified value exactly.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=255
|
||||
// +optional
|
||||
Exact *string `json:"exact,omitempty"`
|
||||
// The value sent by the client must begin with the specified characters.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=255
|
||||
// +optional
|
||||
Prefix *string `json:"prefix,omitempty"`
|
||||
// An object that represents the range of values to match on
|
||||
// +optional
|
||||
Range *MatchRange `json:"range,omitempty"`
|
||||
// The value sent by the client must include the specified characters.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=255
|
||||
// +optional
|
||||
Regex *string `json:"regex,omitempty"`
|
||||
// The value sent by the client must end with the specified characters.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=255
|
||||
// +optional
|
||||
Suffix *string `json:"suffix,omitempty"`
|
||||
}
|
||||
|
||||
// GRPCRouteMetadata refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_GrpcRouteMetadata.html
|
||||
type GRPCRouteMetadata struct {
|
||||
// The name of the route.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=50
|
||||
Name string `json:"name"`
|
||||
// An object that represents the data to match from the request.
|
||||
// +optional
|
||||
Match *GRPCRouteMetadataMatchMethod `json:"match,omitempty"`
|
||||
// Specify True to match anything except the match criteria. The default value is False.
|
||||
// +optional
|
||||
Invert *bool `json:"invert,omitempty"`
|
||||
}
|
||||
|
||||
// GRPCRouteMatch refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_GrpcRouteMatch.html
|
||||
type GRPCRouteMatch struct {
|
||||
// The method name to match from the request. If you specify a name, you must also specify a serviceName.
|
||||
// +kubebuilder:validation:MinLength=1
|
||||
// +kubebuilder:validation:MaxLength=50
|
||||
// +optional
|
||||
MethodName *string `json:"methodName,omitempty"`
|
||||
// The fully qualified domain name for the service to match from the request.
|
||||
// +optional
|
||||
ServiceName *string `json:"serviceName,omitempty"`
|
||||
// An object that represents the data to match from the request.
|
||||
// +kubebuilder:validation:MinItems=1
|
||||
// +kubebuilder:validation:MaxItems=10
|
||||
// +optional
|
||||
Metadata []GRPCRouteMetadata `json:"metadata,omitempty"`
|
||||
}
|
||||
|
||||
// GRPCRouteAction refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_GrpcRouteAction.html
|
||||
type GRPCRouteAction struct {
|
||||
// An object that represents the targets that traffic is routed to when a request matches the route.
|
||||
// +kubebuilder:validation:MinItems=1
|
||||
// +kubebuilder:validation:MaxItems=10
|
||||
WeightedTargets []WeightedTarget `json:"weightedTargets"`
|
||||
}
|
||||
|
||||
// GRPCRetryPolicy refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_GrpcRetryPolicy.html
|
||||
type GRPCRetryPolicy struct {
|
||||
// +kubebuilder:validation:MinItems=1
|
||||
// +kubebuilder:validation:MaxItems=5
|
||||
// +optional
|
||||
GRPCRetryEvents []GRPCRetryPolicyEvent `json:"grpcRetryEvents,omitempty"`
|
||||
// +kubebuilder:validation:MinItems=1
|
||||
// +kubebuilder:validation:MaxItems=25
|
||||
// +optional
|
||||
HTTPRetryEvents []HTTPRetryPolicyEvent `json:"httpRetryEvents,omitempty"`
|
||||
// +kubebuilder:validation:MinItems=1
|
||||
// +kubebuilder:validation:MaxItems=1
|
||||
// +optional
|
||||
TCPRetryEvents []TCPRetryPolicyEvent `json:"tcpRetryEvents,omitempty"`
|
||||
// The maximum number of retry attempts.
|
||||
// +kubebuilder:validation:Minimum=0
|
||||
MaxRetries int64 `json:"maxRetries"`
|
||||
// An object that represents a duration of time.
|
||||
PerRetryTimeout Duration `json:"perRetryTimeout"`
|
||||
}
|
||||
|
||||
// GRPCRoute refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_GrpcRoute.html
|
||||
type GRPCRoute struct {
|
||||
// An object that represents the criteria for determining a request match.
|
||||
Match GRPCRouteMatch `json:"match"`
|
||||
// An object that represents the action to take if a match is determined.
|
||||
Action GRPCRouteAction `json:"action"`
|
||||
// An object that represents a retry policy.
|
||||
// +optional
|
||||
RetryPolicy *GRPCRetryPolicy `json:"retryPolicy,omitempty"`
|
||||
}
|
||||
|
||||
// Route refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_RouteSpec.html
|
||||
type Route struct {
|
||||
// Route's name
|
||||
Name string `json:"name"`
|
||||
// An object that represents the specification of a gRPC route.
|
||||
// +optional
|
||||
GRPCRoute *GRPCRoute `json:"grpcRoute,omitempty"`
|
||||
// An object that represents the specification of an HTTP route.
|
||||
// +optional
|
||||
HTTPRoute *HTTPRoute `json:"httpRoute,omitempty"`
|
||||
// An object that represents the specification of an HTTP/2 route.
|
||||
// +optional
|
||||
HTTP2Route *HTTPRoute `json:"http2Route,omitempty"`
|
||||
// An object that represents the specification of a TCP route.
|
||||
// +optional
|
||||
TCPRoute *TCPRoute `json:"tcpRoute,omitempty"`
|
||||
// The priority for the route.
|
||||
// +kubebuilder:validation:Minimum=0
|
||||
// +kubebuilder:validation:Maximum=1000
|
||||
// +optional
|
||||
Priority *int64 `json:"priority,omitempty"`
|
||||
}
|
||||
|
||||
type VirtualRouterConditionType string
|
||||
|
||||
const (
|
||||
// VirtualRouterActive is True when the AppMesh VirtualRouter has been created or found via the API
|
||||
VirtualRouterActive VirtualRouterConditionType = "VirtualRouterActive"
|
||||
)
|
||||
|
||||
type VirtualRouterCondition struct {
|
||||
// Type of VirtualRouter condition.
|
||||
Type VirtualRouterConditionType `json:"type"`
|
||||
// Status of the condition, one of True, False, Unknown.
|
||||
Status corev1.ConditionStatus `json:"status"`
|
||||
// Last time the condition transitioned from one status to another.
|
||||
// +optional
|
||||
LastTransitionTime *metav1.Time `json:"lastTransitionTime,omitempty"`
|
||||
// The reason for the condition's last transition.
|
||||
// +optional
|
||||
Reason *string `json:"reason,omitempty"`
|
||||
// A human readable message indicating details about the transition.
|
||||
// +optional
|
||||
Message *string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
// VirtualRouterSpec defines the desired state of VirtualRouter
|
||||
// refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_VirtualRouterSpec.html
|
||||
type VirtualRouterSpec struct {
|
||||
// AWSName is the AppMesh VirtualRouter object's name.
|
||||
// If unspecified or empty, it defaults to be "${name}_${namespace}" of k8s VirtualRouter
|
||||
// +optional
|
||||
AWSName *string `json:"awsName,omitempty"`
|
||||
// The listeners that the virtual router is expected to receive inbound traffic from
|
||||
// +kubebuilder:validation:MinItems=1
|
||||
// +kubebuilder:validation:MaxItems=1
|
||||
Listeners []VirtualRouterListener `json:"listeners,omitempty"`
|
||||
|
||||
// The routes associated with VirtualRouter
|
||||
// +optional
|
||||
Routes []Route `json:"routes,omitempty"`
|
||||
|
||||
// A reference to k8s Mesh CR that this VirtualRouter belongs to.
|
||||
// The admission controller populates it using Meshes's selector, and prevents users from setting this field.
|
||||
//
|
||||
// Populated by the system.
|
||||
// Read-only.
|
||||
// +optional
|
||||
MeshRef *MeshReference `json:"meshRef,omitempty"`
|
||||
}
|
||||
|
||||
// VirtualRouterStatus defines the observed state of VirtualRouter
|
||||
type VirtualRouterStatus struct {
|
||||
// VirtualRouterARN is the AppMesh VirtualRouter object's Amazon Resource Name.
|
||||
// +optional
|
||||
VirtualRouterARN *string `json:"virtualRouterARN,omitempty"`
|
||||
// RouteARNs is a map of AppMesh Route objects' Amazon Resource Names, indexed by route name.
|
||||
// +optional
|
||||
RouteARNs map[string]string `json:"routeARNs,omitempty"`
|
||||
// The current VirtualRouter status.
|
||||
// +optional
|
||||
Conditions []VirtualRouterCondition `json:"conditions,omitempty"`
|
||||
}
|
||||
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// VirtualRouter is the Schema for the virtualrouters API
|
||||
type VirtualRouter struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec VirtualRouterSpec `json:"spec,omitempty"`
|
||||
Status VirtualRouterStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// VirtualRouterList contains a list of VirtualRouter
|
||||
type VirtualRouterList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []VirtualRouter `json:"items"`
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
|
||||
|
||||
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 v1beta2
|
||||
|
||||
import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// VirtualNodeServiceProvider refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_VirtualNodeServiceProvider.html
|
||||
type VirtualNodeServiceProvider struct {
|
||||
// The virtual node that is acting as a service provider.
|
||||
VirtualNodeRef VirtualNodeReference `json:"virtualNodeRef"`
|
||||
}
|
||||
|
||||
// VirtualRouterServiceProvider refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_VirtualRouterServiceProvider.html
|
||||
type VirtualRouterServiceProvider struct {
|
||||
// The virtual router that is acting as a service provider.
|
||||
VirtualRouterRef VirtualRouterReference `json:"virtualRouterRef"`
|
||||
}
|
||||
|
||||
// VirtualServiceProvider refers to https://docs.aws.amazon.com/app-mesh/latest/APIReference/API_VirtualServiceProvider.html
|
||||
type VirtualServiceProvider struct {
|
||||
// The virtual node associated with a virtual service.
|
||||
// +optional
|
||||
VirtualNode *VirtualNodeServiceProvider `json:"virtualNode,omitempty"`
|
||||
// The virtual router associated with a virtual service.
|
||||
// +optional
|
||||
VirtualRouter *VirtualRouterServiceProvider `json:"virtualRouter,omitempty"`
|
||||
}
|
||||
|
||||
type VirtualServiceConditionType string
|
||||
|
||||
const (
|
||||
// VirtualServiceActive is True when the AppMesh VirtualService has been created or found via the API
|
||||
VirtualServiceActive VirtualServiceConditionType = "VirtualServiceActive"
|
||||
)
|
||||
|
||||
type VirtualServiceCondition struct {
|
||||
// Type of VirtualService condition.
|
||||
Type VirtualServiceConditionType `json:"type"`
|
||||
// Status of the condition, one of True, False, Unknown.
|
||||
Status corev1.ConditionStatus `json:"status"`
|
||||
// Last time the condition transitioned from one status to another.
|
||||
// +optional
|
||||
LastTransitionTime *metav1.Time `json:"lastTransitionTime,omitempty"`
|
||||
// The reason for the condition's last transition.
|
||||
// +optional
|
||||
Reason *string `json:"reason,omitempty"`
|
||||
// A human readable message indicating details about the transition.
|
||||
// +optional
|
||||
Message *string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
// VirtualServiceSpec defines the desired state of VirtualService
|
||||
type VirtualServiceSpec struct {
|
||||
// AWSName is the AppMesh VirtualService object's name.
|
||||
// If unspecified or empty, it defaults to be "${name}.${namespace}" of k8s VirtualService
|
||||
// +optional
|
||||
AWSName *string `json:"awsName,omitempty"`
|
||||
|
||||
// The provider for virtual services. You can specify a single virtual node or virtual router.
|
||||
// +optional
|
||||
Provider *VirtualServiceProvider `json:"provider,omitempty"`
|
||||
|
||||
// A reference to k8s Mesh CR that this VirtualService belongs to.
|
||||
// The admission controller populates it using Meshes's selector, and prevents users from setting this field.
|
||||
//
|
||||
// Populated by the system.
|
||||
// Read-only.
|
||||
// +optional
|
||||
MeshRef *MeshReference `json:"meshRef,omitempty"`
|
||||
}
|
||||
|
||||
// VirtualServiceStatus defines the observed state of VirtualService
|
||||
type VirtualServiceStatus struct {
|
||||
// VirtualServiceARN is the AppMesh VirtualService object's Amazon Resource Name.
|
||||
// +optional
|
||||
VirtualServiceARN *string `json:"virtualServiceARN,omitempty"`
|
||||
// The current VirtualService status.
|
||||
// +optional
|
||||
Conditions []VirtualServiceCondition `json:"conditions,omitempty"`
|
||||
}
|
||||
|
||||
// +genclient
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// VirtualService is the Schema for the virtualservices API
|
||||
type VirtualService struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec VirtualServiceSpec `json:"spec,omitempty"`
|
||||
Status VirtualServiceStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
|
||||
|
||||
// VirtualServiceList contains a list of VirtualService
|
||||
type VirtualServiceList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []VirtualService `json:"items"`
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,12 @@
|
||||
package v1beta1
|
||||
|
||||
const (
|
||||
AppMeshProvider string = "appmesh"
|
||||
LinkerdProvider string = "linkerd"
|
||||
IstioProvider string = "istio"
|
||||
SMIProvider string = "smi"
|
||||
ContourProvider string = "contour"
|
||||
GlooProvider string = "gloo"
|
||||
NGINXProvider string = "nginx"
|
||||
KubernetesProvider string = "kubernetes"
|
||||
)
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
appmeshv1beta1 "github.com/weaveworks/flagger/pkg/client/clientset/versioned/typed/appmesh/v1beta1"
|
||||
appmeshv1beta2 "github.com/weaveworks/flagger/pkg/client/clientset/versioned/typed/appmesh/v1beta2"
|
||||
flaggerv1beta1 "github.com/weaveworks/flagger/pkg/client/clientset/versioned/typed/flagger/v1beta1"
|
||||
gloov1 "github.com/weaveworks/flagger/pkg/client/clientset/versioned/typed/gloo/v1"
|
||||
networkingv1alpha3 "github.com/weaveworks/flagger/pkg/client/clientset/versioned/typed/istio/v1alpha3"
|
||||
@@ -35,6 +36,7 @@ import (
|
||||
|
||||
type Interface interface {
|
||||
Discovery() discovery.DiscoveryInterface
|
||||
AppmeshV1beta2() appmeshv1beta2.AppmeshV1beta2Interface
|
||||
AppmeshV1beta1() appmeshv1beta1.AppmeshV1beta1Interface
|
||||
FlaggerV1beta1() flaggerv1beta1.FlaggerV1beta1Interface
|
||||
GlooV1() gloov1.GlooV1Interface
|
||||
@@ -48,6 +50,7 @@ type Interface interface {
|
||||
// version included in a Clientset.
|
||||
type Clientset struct {
|
||||
*discovery.DiscoveryClient
|
||||
appmeshV1beta2 *appmeshv1beta2.AppmeshV1beta2Client
|
||||
appmeshV1beta1 *appmeshv1beta1.AppmeshV1beta1Client
|
||||
flaggerV1beta1 *flaggerv1beta1.FlaggerV1beta1Client
|
||||
glooV1 *gloov1.GlooV1Client
|
||||
@@ -57,6 +60,11 @@ type Clientset struct {
|
||||
splitV1alpha2 *splitv1alpha2.SplitV1alpha2Client
|
||||
}
|
||||
|
||||
// AppmeshV1beta2 retrieves the AppmeshV1beta2Client
|
||||
func (c *Clientset) AppmeshV1beta2() appmeshv1beta2.AppmeshV1beta2Interface {
|
||||
return c.appmeshV1beta2
|
||||
}
|
||||
|
||||
// AppmeshV1beta1 retrieves the AppmeshV1beta1Client
|
||||
func (c *Clientset) AppmeshV1beta1() appmeshv1beta1.AppmeshV1beta1Interface {
|
||||
return c.appmeshV1beta1
|
||||
@@ -113,6 +121,10 @@ func NewForConfig(c *rest.Config) (*Clientset, error) {
|
||||
}
|
||||
var cs Clientset
|
||||
var err error
|
||||
cs.appmeshV1beta2, err = appmeshv1beta2.NewForConfig(&configShallowCopy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cs.appmeshV1beta1, err = appmeshv1beta1.NewForConfig(&configShallowCopy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -153,6 +165,7 @@ func NewForConfig(c *rest.Config) (*Clientset, error) {
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *rest.Config) *Clientset {
|
||||
var cs Clientset
|
||||
cs.appmeshV1beta2 = appmeshv1beta2.NewForConfigOrDie(c)
|
||||
cs.appmeshV1beta1 = appmeshv1beta1.NewForConfigOrDie(c)
|
||||
cs.flaggerV1beta1 = flaggerv1beta1.NewForConfigOrDie(c)
|
||||
cs.glooV1 = gloov1.NewForConfigOrDie(c)
|
||||
@@ -168,6 +181,7 @@ func NewForConfigOrDie(c *rest.Config) *Clientset {
|
||||
// New creates a new Clientset for the given RESTClient.
|
||||
func New(c rest.Interface) *Clientset {
|
||||
var cs Clientset
|
||||
cs.appmeshV1beta2 = appmeshv1beta2.New(c)
|
||||
cs.appmeshV1beta1 = appmeshv1beta1.New(c)
|
||||
cs.flaggerV1beta1 = flaggerv1beta1.New(c)
|
||||
cs.glooV1 = gloov1.New(c)
|
||||
|
||||
@@ -22,6 +22,8 @@ import (
|
||||
clientset "github.com/weaveworks/flagger/pkg/client/clientset/versioned"
|
||||
appmeshv1beta1 "github.com/weaveworks/flagger/pkg/client/clientset/versioned/typed/appmesh/v1beta1"
|
||||
fakeappmeshv1beta1 "github.com/weaveworks/flagger/pkg/client/clientset/versioned/typed/appmesh/v1beta1/fake"
|
||||
appmeshv1beta2 "github.com/weaveworks/flagger/pkg/client/clientset/versioned/typed/appmesh/v1beta2"
|
||||
fakeappmeshv1beta2 "github.com/weaveworks/flagger/pkg/client/clientset/versioned/typed/appmesh/v1beta2/fake"
|
||||
flaggerv1beta1 "github.com/weaveworks/flagger/pkg/client/clientset/versioned/typed/flagger/v1beta1"
|
||||
fakeflaggerv1beta1 "github.com/weaveworks/flagger/pkg/client/clientset/versioned/typed/flagger/v1beta1/fake"
|
||||
gloov1 "github.com/weaveworks/flagger/pkg/client/clientset/versioned/typed/gloo/v1"
|
||||
@@ -88,6 +90,11 @@ func (c *Clientset) Tracker() testing.ObjectTracker {
|
||||
|
||||
var _ clientset.Interface = &Clientset{}
|
||||
|
||||
// AppmeshV1beta2 retrieves the AppmeshV1beta2Client
|
||||
func (c *Clientset) AppmeshV1beta2() appmeshv1beta2.AppmeshV1beta2Interface {
|
||||
return &fakeappmeshv1beta2.FakeAppmeshV1beta2{Fake: &c.Fake}
|
||||
}
|
||||
|
||||
// AppmeshV1beta1 retrieves the AppmeshV1beta1Client
|
||||
func (c *Clientset) AppmeshV1beta1() appmeshv1beta1.AppmeshV1beta1Interface {
|
||||
return &fakeappmeshv1beta1.FakeAppmeshV1beta1{Fake: &c.Fake}
|
||||
|
||||
@@ -20,6 +20,7 @@ package fake
|
||||
|
||||
import (
|
||||
appmeshv1beta1 "github.com/weaveworks/flagger/pkg/apis/appmesh/v1beta1"
|
||||
appmeshv1beta2 "github.com/weaveworks/flagger/pkg/apis/appmesh/v1beta2"
|
||||
flaggerv1beta1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
|
||||
gloov1 "github.com/weaveworks/flagger/pkg/apis/gloo/v1"
|
||||
networkingv1alpha3 "github.com/weaveworks/flagger/pkg/apis/istio/v1alpha3"
|
||||
@@ -37,6 +38,7 @@ var scheme = runtime.NewScheme()
|
||||
var codecs = serializer.NewCodecFactory(scheme)
|
||||
var parameterCodec = runtime.NewParameterCodec(scheme)
|
||||
var localSchemeBuilder = runtime.SchemeBuilder{
|
||||
appmeshv1beta2.AddToScheme,
|
||||
appmeshv1beta1.AddToScheme,
|
||||
flaggerv1beta1.AddToScheme,
|
||||
gloov1.AddToScheme,
|
||||
|
||||
@@ -20,6 +20,7 @@ package scheme
|
||||
|
||||
import (
|
||||
appmeshv1beta1 "github.com/weaveworks/flagger/pkg/apis/appmesh/v1beta1"
|
||||
appmeshv1beta2 "github.com/weaveworks/flagger/pkg/apis/appmesh/v1beta2"
|
||||
flaggerv1beta1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
|
||||
gloov1 "github.com/weaveworks/flagger/pkg/apis/gloo/v1"
|
||||
networkingv1alpha3 "github.com/weaveworks/flagger/pkg/apis/istio/v1alpha3"
|
||||
@@ -37,6 +38,7 @@ var Scheme = runtime.NewScheme()
|
||||
var Codecs = serializer.NewCodecFactory(Scheme)
|
||||
var ParameterCodec = runtime.NewParameterCodec(Scheme)
|
||||
var localSchemeBuilder = runtime.SchemeBuilder{
|
||||
appmeshv1beta2.AddToScheme,
|
||||
appmeshv1beta1.AddToScheme,
|
||||
flaggerv1beta1.AddToScheme,
|
||||
gloov1.AddToScheme,
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
Copyright The Flagger 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 v1beta2
|
||||
|
||||
import (
|
||||
v1beta2 "github.com/weaveworks/flagger/pkg/apis/appmesh/v1beta2"
|
||||
"github.com/weaveworks/flagger/pkg/client/clientset/versioned/scheme"
|
||||
rest "k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
type AppmeshV1beta2Interface interface {
|
||||
RESTClient() rest.Interface
|
||||
VirtualNodesGetter
|
||||
VirtualRoutersGetter
|
||||
VirtualServicesGetter
|
||||
}
|
||||
|
||||
// AppmeshV1beta2Client is used to interact with features provided by the appmesh.k8s.aws group.
|
||||
type AppmeshV1beta2Client struct {
|
||||
restClient rest.Interface
|
||||
}
|
||||
|
||||
func (c *AppmeshV1beta2Client) VirtualNodes(namespace string) VirtualNodeInterface {
|
||||
return newVirtualNodes(c, namespace)
|
||||
}
|
||||
|
||||
func (c *AppmeshV1beta2Client) VirtualRouters(namespace string) VirtualRouterInterface {
|
||||
return newVirtualRouters(c, namespace)
|
||||
}
|
||||
|
||||
func (c *AppmeshV1beta2Client) VirtualServices(namespace string) VirtualServiceInterface {
|
||||
return newVirtualServices(c, namespace)
|
||||
}
|
||||
|
||||
// NewForConfig creates a new AppmeshV1beta2Client for the given config.
|
||||
func NewForConfig(c *rest.Config) (*AppmeshV1beta2Client, error) {
|
||||
config := *c
|
||||
if err := setConfigDefaults(&config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client, err := rest.RESTClientFor(&config)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &AppmeshV1beta2Client{client}, nil
|
||||
}
|
||||
|
||||
// NewForConfigOrDie creates a new AppmeshV1beta2Client for the given config and
|
||||
// panics if there is an error in the config.
|
||||
func NewForConfigOrDie(c *rest.Config) *AppmeshV1beta2Client {
|
||||
client, err := NewForConfig(c)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// New creates a new AppmeshV1beta2Client for the given RESTClient.
|
||||
func New(c rest.Interface) *AppmeshV1beta2Client {
|
||||
return &AppmeshV1beta2Client{c}
|
||||
}
|
||||
|
||||
func setConfigDefaults(config *rest.Config) error {
|
||||
gv := v1beta2.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 *AppmeshV1beta2Client) RESTClient() rest.Interface {
|
||||
if c == nil {
|
||||
return nil
|
||||
}
|
||||
return c.restClient
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
Copyright The Flagger 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 v1beta2
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
Copyright The Flagger 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
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
Copyright The Flagger 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 (
|
||||
v1beta2 "github.com/weaveworks/flagger/pkg/client/clientset/versioned/typed/appmesh/v1beta2"
|
||||
rest "k8s.io/client-go/rest"
|
||||
testing "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
type FakeAppmeshV1beta2 struct {
|
||||
*testing.Fake
|
||||
}
|
||||
|
||||
func (c *FakeAppmeshV1beta2) VirtualNodes(namespace string) v1beta2.VirtualNodeInterface {
|
||||
return &FakeVirtualNodes{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeAppmeshV1beta2) VirtualRouters(namespace string) v1beta2.VirtualRouterInterface {
|
||||
return &FakeVirtualRouters{c, namespace}
|
||||
}
|
||||
|
||||
func (c *FakeAppmeshV1beta2) VirtualServices(namespace string) v1beta2.VirtualServiceInterface {
|
||||
return &FakeVirtualServices{c, namespace}
|
||||
}
|
||||
|
||||
// RESTClient returns a RESTClient that is used to communicate
|
||||
// with API server by this client implementation.
|
||||
func (c *FakeAppmeshV1beta2) RESTClient() rest.Interface {
|
||||
var ret *rest.RESTClient
|
||||
return ret
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
Copyright The Flagger 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"
|
||||
|
||||
v1beta2 "github.com/weaveworks/flagger/pkg/apis/appmesh/v1beta2"
|
||||
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"
|
||||
)
|
||||
|
||||
// FakeVirtualNodes implements VirtualNodeInterface
|
||||
type FakeVirtualNodes struct {
|
||||
Fake *FakeAppmeshV1beta2
|
||||
ns string
|
||||
}
|
||||
|
||||
var virtualnodesResource = schema.GroupVersionResource{Group: "appmesh.k8s.aws", Version: "v1beta2", Resource: "virtualnodes"}
|
||||
|
||||
var virtualnodesKind = schema.GroupVersionKind{Group: "appmesh.k8s.aws", Version: "v1beta2", Kind: "VirtualNode"}
|
||||
|
||||
// Get takes name of the virtualNode, and returns the corresponding virtualNode object, and an error if there is any.
|
||||
func (c *FakeVirtualNodes) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta2.VirtualNode, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewGetAction(virtualnodesResource, c.ns, name), &v1beta2.VirtualNode{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta2.VirtualNode), err
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of VirtualNodes that match those selectors.
|
||||
func (c *FakeVirtualNodes) List(ctx context.Context, opts v1.ListOptions) (result *v1beta2.VirtualNodeList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewListAction(virtualnodesResource, virtualnodesKind, c.ns, opts), &v1beta2.VirtualNodeList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label, _, _ := testing.ExtractFromListOptions(opts)
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &v1beta2.VirtualNodeList{ListMeta: obj.(*v1beta2.VirtualNodeList).ListMeta}
|
||||
for _, item := range obj.(*v1beta2.VirtualNodeList).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 virtualNodes.
|
||||
func (c *FakeVirtualNodes) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewWatchAction(virtualnodesResource, c.ns, opts))
|
||||
|
||||
}
|
||||
|
||||
// Create takes the representation of a virtualNode and creates it. Returns the server's representation of the virtualNode, and an error, if there is any.
|
||||
func (c *FakeVirtualNodes) Create(ctx context.Context, virtualNode *v1beta2.VirtualNode, opts v1.CreateOptions) (result *v1beta2.VirtualNode, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewCreateAction(virtualnodesResource, c.ns, virtualNode), &v1beta2.VirtualNode{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta2.VirtualNode), err
|
||||
}
|
||||
|
||||
// Update takes the representation of a virtualNode and updates it. Returns the server's representation of the virtualNode, and an error, if there is any.
|
||||
func (c *FakeVirtualNodes) Update(ctx context.Context, virtualNode *v1beta2.VirtualNode, opts v1.UpdateOptions) (result *v1beta2.VirtualNode, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateAction(virtualnodesResource, c.ns, virtualNode), &v1beta2.VirtualNode{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta2.VirtualNode), 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 *FakeVirtualNodes) UpdateStatus(ctx context.Context, virtualNode *v1beta2.VirtualNode, opts v1.UpdateOptions) (*v1beta2.VirtualNode, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateSubresourceAction(virtualnodesResource, "status", c.ns, virtualNode), &v1beta2.VirtualNode{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta2.VirtualNode), err
|
||||
}
|
||||
|
||||
// Delete takes name of the virtualNode and deletes it. Returns an error if one occurs.
|
||||
func (c *FakeVirtualNodes) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewDeleteAction(virtualnodesResource, c.ns, name), &v1beta2.VirtualNode{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *FakeVirtualNodes) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
action := testing.NewDeleteCollectionAction(virtualnodesResource, c.ns, listOpts)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &v1beta2.VirtualNodeList{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched virtualNode.
|
||||
func (c *FakeVirtualNodes) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta2.VirtualNode, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewPatchSubresourceAction(virtualnodesResource, c.ns, name, pt, data, subresources...), &v1beta2.VirtualNode{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta2.VirtualNode), err
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
Copyright The Flagger 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"
|
||||
|
||||
v1beta2 "github.com/weaveworks/flagger/pkg/apis/appmesh/v1beta2"
|
||||
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"
|
||||
)
|
||||
|
||||
// FakeVirtualRouters implements VirtualRouterInterface
|
||||
type FakeVirtualRouters struct {
|
||||
Fake *FakeAppmeshV1beta2
|
||||
ns string
|
||||
}
|
||||
|
||||
var virtualroutersResource = schema.GroupVersionResource{Group: "appmesh.k8s.aws", Version: "v1beta2", Resource: "virtualrouters"}
|
||||
|
||||
var virtualroutersKind = schema.GroupVersionKind{Group: "appmesh.k8s.aws", Version: "v1beta2", Kind: "VirtualRouter"}
|
||||
|
||||
// Get takes name of the virtualRouter, and returns the corresponding virtualRouter object, and an error if there is any.
|
||||
func (c *FakeVirtualRouters) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta2.VirtualRouter, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewGetAction(virtualroutersResource, c.ns, name), &v1beta2.VirtualRouter{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta2.VirtualRouter), err
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of VirtualRouters that match those selectors.
|
||||
func (c *FakeVirtualRouters) List(ctx context.Context, opts v1.ListOptions) (result *v1beta2.VirtualRouterList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewListAction(virtualroutersResource, virtualroutersKind, c.ns, opts), &v1beta2.VirtualRouterList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label, _, _ := testing.ExtractFromListOptions(opts)
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &v1beta2.VirtualRouterList{ListMeta: obj.(*v1beta2.VirtualRouterList).ListMeta}
|
||||
for _, item := range obj.(*v1beta2.VirtualRouterList).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 virtualRouters.
|
||||
func (c *FakeVirtualRouters) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewWatchAction(virtualroutersResource, c.ns, opts))
|
||||
|
||||
}
|
||||
|
||||
// Create takes the representation of a virtualRouter and creates it. Returns the server's representation of the virtualRouter, and an error, if there is any.
|
||||
func (c *FakeVirtualRouters) Create(ctx context.Context, virtualRouter *v1beta2.VirtualRouter, opts v1.CreateOptions) (result *v1beta2.VirtualRouter, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewCreateAction(virtualroutersResource, c.ns, virtualRouter), &v1beta2.VirtualRouter{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta2.VirtualRouter), err
|
||||
}
|
||||
|
||||
// Update takes the representation of a virtualRouter and updates it. Returns the server's representation of the virtualRouter, and an error, if there is any.
|
||||
func (c *FakeVirtualRouters) Update(ctx context.Context, virtualRouter *v1beta2.VirtualRouter, opts v1.UpdateOptions) (result *v1beta2.VirtualRouter, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateAction(virtualroutersResource, c.ns, virtualRouter), &v1beta2.VirtualRouter{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta2.VirtualRouter), 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 *FakeVirtualRouters) UpdateStatus(ctx context.Context, virtualRouter *v1beta2.VirtualRouter, opts v1.UpdateOptions) (*v1beta2.VirtualRouter, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateSubresourceAction(virtualroutersResource, "status", c.ns, virtualRouter), &v1beta2.VirtualRouter{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta2.VirtualRouter), err
|
||||
}
|
||||
|
||||
// Delete takes name of the virtualRouter and deletes it. Returns an error if one occurs.
|
||||
func (c *FakeVirtualRouters) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewDeleteAction(virtualroutersResource, c.ns, name), &v1beta2.VirtualRouter{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *FakeVirtualRouters) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
action := testing.NewDeleteCollectionAction(virtualroutersResource, c.ns, listOpts)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &v1beta2.VirtualRouterList{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched virtualRouter.
|
||||
func (c *FakeVirtualRouters) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta2.VirtualRouter, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewPatchSubresourceAction(virtualroutersResource, c.ns, name, pt, data, subresources...), &v1beta2.VirtualRouter{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta2.VirtualRouter), err
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
Copyright The Flagger 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"
|
||||
|
||||
v1beta2 "github.com/weaveworks/flagger/pkg/apis/appmesh/v1beta2"
|
||||
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"
|
||||
)
|
||||
|
||||
// FakeVirtualServices implements VirtualServiceInterface
|
||||
type FakeVirtualServices struct {
|
||||
Fake *FakeAppmeshV1beta2
|
||||
ns string
|
||||
}
|
||||
|
||||
var virtualservicesResource = schema.GroupVersionResource{Group: "appmesh.k8s.aws", Version: "v1beta2", Resource: "virtualservices"}
|
||||
|
||||
var virtualservicesKind = schema.GroupVersionKind{Group: "appmesh.k8s.aws", Version: "v1beta2", Kind: "VirtualService"}
|
||||
|
||||
// Get takes name of the virtualService, and returns the corresponding virtualService object, and an error if there is any.
|
||||
func (c *FakeVirtualServices) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta2.VirtualService, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewGetAction(virtualservicesResource, c.ns, name), &v1beta2.VirtualService{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta2.VirtualService), err
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of VirtualServices that match those selectors.
|
||||
func (c *FakeVirtualServices) List(ctx context.Context, opts v1.ListOptions) (result *v1beta2.VirtualServiceList, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewListAction(virtualservicesResource, virtualservicesKind, c.ns, opts), &v1beta2.VirtualServiceList{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label, _, _ := testing.ExtractFromListOptions(opts)
|
||||
if label == nil {
|
||||
label = labels.Everything()
|
||||
}
|
||||
list := &v1beta2.VirtualServiceList{ListMeta: obj.(*v1beta2.VirtualServiceList).ListMeta}
|
||||
for _, item := range obj.(*v1beta2.VirtualServiceList).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 virtualServices.
|
||||
func (c *FakeVirtualServices) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) {
|
||||
return c.Fake.
|
||||
InvokesWatch(testing.NewWatchAction(virtualservicesResource, c.ns, opts))
|
||||
|
||||
}
|
||||
|
||||
// Create takes the representation of a virtualService and creates it. Returns the server's representation of the virtualService, and an error, if there is any.
|
||||
func (c *FakeVirtualServices) Create(ctx context.Context, virtualService *v1beta2.VirtualService, opts v1.CreateOptions) (result *v1beta2.VirtualService, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewCreateAction(virtualservicesResource, c.ns, virtualService), &v1beta2.VirtualService{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta2.VirtualService), err
|
||||
}
|
||||
|
||||
// Update takes the representation of a virtualService and updates it. Returns the server's representation of the virtualService, and an error, if there is any.
|
||||
func (c *FakeVirtualServices) Update(ctx context.Context, virtualService *v1beta2.VirtualService, opts v1.UpdateOptions) (result *v1beta2.VirtualService, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateAction(virtualservicesResource, c.ns, virtualService), &v1beta2.VirtualService{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta2.VirtualService), 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 *FakeVirtualServices) UpdateStatus(ctx context.Context, virtualService *v1beta2.VirtualService, opts v1.UpdateOptions) (*v1beta2.VirtualService, error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewUpdateSubresourceAction(virtualservicesResource, "status", c.ns, virtualService), &v1beta2.VirtualService{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta2.VirtualService), err
|
||||
}
|
||||
|
||||
// Delete takes name of the virtualService and deletes it. Returns an error if one occurs.
|
||||
func (c *FakeVirtualServices) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
_, err := c.Fake.
|
||||
Invokes(testing.NewDeleteAction(virtualservicesResource, c.ns, name), &v1beta2.VirtualService{})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *FakeVirtualServices) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error {
|
||||
action := testing.NewDeleteCollectionAction(virtualservicesResource, c.ns, listOpts)
|
||||
|
||||
_, err := c.Fake.Invokes(action, &v1beta2.VirtualServiceList{})
|
||||
return err
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched virtualService.
|
||||
func (c *FakeVirtualServices) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta2.VirtualService, err error) {
|
||||
obj, err := c.Fake.
|
||||
Invokes(testing.NewPatchSubresourceAction(virtualservicesResource, c.ns, name, pt, data, subresources...), &v1beta2.VirtualService{})
|
||||
|
||||
if obj == nil {
|
||||
return nil, err
|
||||
}
|
||||
return obj.(*v1beta2.VirtualService), err
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
Copyright The Flagger 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 v1beta2
|
||||
|
||||
type VirtualNodeExpansion interface{}
|
||||
|
||||
type VirtualRouterExpansion interface{}
|
||||
|
||||
type VirtualServiceExpansion interface{}
|
||||
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
Copyright The Flagger 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 v1beta2
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
v1beta2 "github.com/weaveworks/flagger/pkg/apis/appmesh/v1beta2"
|
||||
scheme "github.com/weaveworks/flagger/pkg/client/clientset/versioned/scheme"
|
||||
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"
|
||||
)
|
||||
|
||||
// VirtualNodesGetter has a method to return a VirtualNodeInterface.
|
||||
// A group's client should implement this interface.
|
||||
type VirtualNodesGetter interface {
|
||||
VirtualNodes(namespace string) VirtualNodeInterface
|
||||
}
|
||||
|
||||
// VirtualNodeInterface has methods to work with VirtualNode resources.
|
||||
type VirtualNodeInterface interface {
|
||||
Create(ctx context.Context, virtualNode *v1beta2.VirtualNode, opts v1.CreateOptions) (*v1beta2.VirtualNode, error)
|
||||
Update(ctx context.Context, virtualNode *v1beta2.VirtualNode, opts v1.UpdateOptions) (*v1beta2.VirtualNode, error)
|
||||
UpdateStatus(ctx context.Context, virtualNode *v1beta2.VirtualNode, opts v1.UpdateOptions) (*v1beta2.VirtualNode, 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) (*v1beta2.VirtualNode, error)
|
||||
List(ctx context.Context, opts v1.ListOptions) (*v1beta2.VirtualNodeList, 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 *v1beta2.VirtualNode, err error)
|
||||
VirtualNodeExpansion
|
||||
}
|
||||
|
||||
// virtualNodes implements VirtualNodeInterface
|
||||
type virtualNodes struct {
|
||||
client rest.Interface
|
||||
ns string
|
||||
}
|
||||
|
||||
// newVirtualNodes returns a VirtualNodes
|
||||
func newVirtualNodes(c *AppmeshV1beta2Client, namespace string) *virtualNodes {
|
||||
return &virtualNodes{
|
||||
client: c.RESTClient(),
|
||||
ns: namespace,
|
||||
}
|
||||
}
|
||||
|
||||
// Get takes name of the virtualNode, and returns the corresponding virtualNode object, and an error if there is any.
|
||||
func (c *virtualNodes) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta2.VirtualNode, err error) {
|
||||
result = &v1beta2.VirtualNode{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("virtualnodes").
|
||||
Name(name).
|
||||
VersionedParams(&options, scheme.ParameterCodec).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of VirtualNodes that match those selectors.
|
||||
func (c *virtualNodes) List(ctx context.Context, opts v1.ListOptions) (result *v1beta2.VirtualNodeList, err error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
result = &v1beta2.VirtualNodeList{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("virtualnodes").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested virtualNodes.
|
||||
func (c *virtualNodes) 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("virtualnodes").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Watch(ctx)
|
||||
}
|
||||
|
||||
// Create takes the representation of a virtualNode and creates it. Returns the server's representation of the virtualNode, and an error, if there is any.
|
||||
func (c *virtualNodes) Create(ctx context.Context, virtualNode *v1beta2.VirtualNode, opts v1.CreateOptions) (result *v1beta2.VirtualNode, err error) {
|
||||
result = &v1beta2.VirtualNode{}
|
||||
err = c.client.Post().
|
||||
Namespace(c.ns).
|
||||
Resource("virtualnodes").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(virtualNode).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a virtualNode and updates it. Returns the server's representation of the virtualNode, and an error, if there is any.
|
||||
func (c *virtualNodes) Update(ctx context.Context, virtualNode *v1beta2.VirtualNode, opts v1.UpdateOptions) (result *v1beta2.VirtualNode, err error) {
|
||||
result = &v1beta2.VirtualNode{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("virtualnodes").
|
||||
Name(virtualNode.Name).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(virtualNode).
|
||||
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 *virtualNodes) UpdateStatus(ctx context.Context, virtualNode *v1beta2.VirtualNode, opts v1.UpdateOptions) (result *v1beta2.VirtualNode, err error) {
|
||||
result = &v1beta2.VirtualNode{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("virtualnodes").
|
||||
Name(virtualNode.Name).
|
||||
SubResource("status").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(virtualNode).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the virtualNode and deletes it. Returns an error if one occurs.
|
||||
func (c *virtualNodes) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("virtualnodes").
|
||||
Name(name).
|
||||
Body(&opts).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *virtualNodes) 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("virtualnodes").
|
||||
VersionedParams(&listOpts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Body(&opts).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched virtualNode.
|
||||
func (c *virtualNodes) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta2.VirtualNode, err error) {
|
||||
result = &v1beta2.VirtualNode{}
|
||||
err = c.client.Patch(pt).
|
||||
Namespace(c.ns).
|
||||
Resource("virtualnodes").
|
||||
Name(name).
|
||||
SubResource(subresources...).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(data).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
Copyright The Flagger 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 v1beta2
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
v1beta2 "github.com/weaveworks/flagger/pkg/apis/appmesh/v1beta2"
|
||||
scheme "github.com/weaveworks/flagger/pkg/client/clientset/versioned/scheme"
|
||||
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"
|
||||
)
|
||||
|
||||
// VirtualRoutersGetter has a method to return a VirtualRouterInterface.
|
||||
// A group's client should implement this interface.
|
||||
type VirtualRoutersGetter interface {
|
||||
VirtualRouters(namespace string) VirtualRouterInterface
|
||||
}
|
||||
|
||||
// VirtualRouterInterface has methods to work with VirtualRouter resources.
|
||||
type VirtualRouterInterface interface {
|
||||
Create(ctx context.Context, virtualRouter *v1beta2.VirtualRouter, opts v1.CreateOptions) (*v1beta2.VirtualRouter, error)
|
||||
Update(ctx context.Context, virtualRouter *v1beta2.VirtualRouter, opts v1.UpdateOptions) (*v1beta2.VirtualRouter, error)
|
||||
UpdateStatus(ctx context.Context, virtualRouter *v1beta2.VirtualRouter, opts v1.UpdateOptions) (*v1beta2.VirtualRouter, 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) (*v1beta2.VirtualRouter, error)
|
||||
List(ctx context.Context, opts v1.ListOptions) (*v1beta2.VirtualRouterList, 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 *v1beta2.VirtualRouter, err error)
|
||||
VirtualRouterExpansion
|
||||
}
|
||||
|
||||
// virtualRouters implements VirtualRouterInterface
|
||||
type virtualRouters struct {
|
||||
client rest.Interface
|
||||
ns string
|
||||
}
|
||||
|
||||
// newVirtualRouters returns a VirtualRouters
|
||||
func newVirtualRouters(c *AppmeshV1beta2Client, namespace string) *virtualRouters {
|
||||
return &virtualRouters{
|
||||
client: c.RESTClient(),
|
||||
ns: namespace,
|
||||
}
|
||||
}
|
||||
|
||||
// Get takes name of the virtualRouter, and returns the corresponding virtualRouter object, and an error if there is any.
|
||||
func (c *virtualRouters) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta2.VirtualRouter, err error) {
|
||||
result = &v1beta2.VirtualRouter{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("virtualrouters").
|
||||
Name(name).
|
||||
VersionedParams(&options, scheme.ParameterCodec).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of VirtualRouters that match those selectors.
|
||||
func (c *virtualRouters) List(ctx context.Context, opts v1.ListOptions) (result *v1beta2.VirtualRouterList, err error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
result = &v1beta2.VirtualRouterList{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("virtualrouters").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested virtualRouters.
|
||||
func (c *virtualRouters) 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("virtualrouters").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Watch(ctx)
|
||||
}
|
||||
|
||||
// Create takes the representation of a virtualRouter and creates it. Returns the server's representation of the virtualRouter, and an error, if there is any.
|
||||
func (c *virtualRouters) Create(ctx context.Context, virtualRouter *v1beta2.VirtualRouter, opts v1.CreateOptions) (result *v1beta2.VirtualRouter, err error) {
|
||||
result = &v1beta2.VirtualRouter{}
|
||||
err = c.client.Post().
|
||||
Namespace(c.ns).
|
||||
Resource("virtualrouters").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(virtualRouter).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a virtualRouter and updates it. Returns the server's representation of the virtualRouter, and an error, if there is any.
|
||||
func (c *virtualRouters) Update(ctx context.Context, virtualRouter *v1beta2.VirtualRouter, opts v1.UpdateOptions) (result *v1beta2.VirtualRouter, err error) {
|
||||
result = &v1beta2.VirtualRouter{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("virtualrouters").
|
||||
Name(virtualRouter.Name).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(virtualRouter).
|
||||
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 *virtualRouters) UpdateStatus(ctx context.Context, virtualRouter *v1beta2.VirtualRouter, opts v1.UpdateOptions) (result *v1beta2.VirtualRouter, err error) {
|
||||
result = &v1beta2.VirtualRouter{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("virtualrouters").
|
||||
Name(virtualRouter.Name).
|
||||
SubResource("status").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(virtualRouter).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the virtualRouter and deletes it. Returns an error if one occurs.
|
||||
func (c *virtualRouters) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("virtualrouters").
|
||||
Name(name).
|
||||
Body(&opts).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *virtualRouters) 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("virtualrouters").
|
||||
VersionedParams(&listOpts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Body(&opts).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched virtualRouter.
|
||||
func (c *virtualRouters) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta2.VirtualRouter, err error) {
|
||||
result = &v1beta2.VirtualRouter{}
|
||||
err = c.client.Patch(pt).
|
||||
Namespace(c.ns).
|
||||
Resource("virtualrouters").
|
||||
Name(name).
|
||||
SubResource(subresources...).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(data).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
Copyright The Flagger 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 v1beta2
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
v1beta2 "github.com/weaveworks/flagger/pkg/apis/appmesh/v1beta2"
|
||||
scheme "github.com/weaveworks/flagger/pkg/client/clientset/versioned/scheme"
|
||||
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"
|
||||
)
|
||||
|
||||
// VirtualServicesGetter has a method to return a VirtualServiceInterface.
|
||||
// A group's client should implement this interface.
|
||||
type VirtualServicesGetter interface {
|
||||
VirtualServices(namespace string) VirtualServiceInterface
|
||||
}
|
||||
|
||||
// VirtualServiceInterface has methods to work with VirtualService resources.
|
||||
type VirtualServiceInterface interface {
|
||||
Create(ctx context.Context, virtualService *v1beta2.VirtualService, opts v1.CreateOptions) (*v1beta2.VirtualService, error)
|
||||
Update(ctx context.Context, virtualService *v1beta2.VirtualService, opts v1.UpdateOptions) (*v1beta2.VirtualService, error)
|
||||
UpdateStatus(ctx context.Context, virtualService *v1beta2.VirtualService, opts v1.UpdateOptions) (*v1beta2.VirtualService, 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) (*v1beta2.VirtualService, error)
|
||||
List(ctx context.Context, opts v1.ListOptions) (*v1beta2.VirtualServiceList, 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 *v1beta2.VirtualService, err error)
|
||||
VirtualServiceExpansion
|
||||
}
|
||||
|
||||
// virtualServices implements VirtualServiceInterface
|
||||
type virtualServices struct {
|
||||
client rest.Interface
|
||||
ns string
|
||||
}
|
||||
|
||||
// newVirtualServices returns a VirtualServices
|
||||
func newVirtualServices(c *AppmeshV1beta2Client, namespace string) *virtualServices {
|
||||
return &virtualServices{
|
||||
client: c.RESTClient(),
|
||||
ns: namespace,
|
||||
}
|
||||
}
|
||||
|
||||
// Get takes name of the virtualService, and returns the corresponding virtualService object, and an error if there is any.
|
||||
func (c *virtualServices) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta2.VirtualService, err error) {
|
||||
result = &v1beta2.VirtualService{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("virtualservices").
|
||||
Name(name).
|
||||
VersionedParams(&options, scheme.ParameterCodec).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// List takes label and field selectors, and returns the list of VirtualServices that match those selectors.
|
||||
func (c *virtualServices) List(ctx context.Context, opts v1.ListOptions) (result *v1beta2.VirtualServiceList, err error) {
|
||||
var timeout time.Duration
|
||||
if opts.TimeoutSeconds != nil {
|
||||
timeout = time.Duration(*opts.TimeoutSeconds) * time.Second
|
||||
}
|
||||
result = &v1beta2.VirtualServiceList{}
|
||||
err = c.client.Get().
|
||||
Namespace(c.ns).
|
||||
Resource("virtualservices").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Watch returns a watch.Interface that watches the requested virtualServices.
|
||||
func (c *virtualServices) 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("virtualservices").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Watch(ctx)
|
||||
}
|
||||
|
||||
// Create takes the representation of a virtualService and creates it. Returns the server's representation of the virtualService, and an error, if there is any.
|
||||
func (c *virtualServices) Create(ctx context.Context, virtualService *v1beta2.VirtualService, opts v1.CreateOptions) (result *v1beta2.VirtualService, err error) {
|
||||
result = &v1beta2.VirtualService{}
|
||||
err = c.client.Post().
|
||||
Namespace(c.ns).
|
||||
Resource("virtualservices").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(virtualService).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Update takes the representation of a virtualService and updates it. Returns the server's representation of the virtualService, and an error, if there is any.
|
||||
func (c *virtualServices) Update(ctx context.Context, virtualService *v1beta2.VirtualService, opts v1.UpdateOptions) (result *v1beta2.VirtualService, err error) {
|
||||
result = &v1beta2.VirtualService{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("virtualservices").
|
||||
Name(virtualService.Name).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(virtualService).
|
||||
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 *virtualServices) UpdateStatus(ctx context.Context, virtualService *v1beta2.VirtualService, opts v1.UpdateOptions) (result *v1beta2.VirtualService, err error) {
|
||||
result = &v1beta2.VirtualService{}
|
||||
err = c.client.Put().
|
||||
Namespace(c.ns).
|
||||
Resource("virtualservices").
|
||||
Name(virtualService.Name).
|
||||
SubResource("status").
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(virtualService).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
|
||||
// Delete takes name of the virtualService and deletes it. Returns an error if one occurs.
|
||||
func (c *virtualServices) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error {
|
||||
return c.client.Delete().
|
||||
Namespace(c.ns).
|
||||
Resource("virtualservices").
|
||||
Name(name).
|
||||
Body(&opts).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// DeleteCollection deletes a collection of objects.
|
||||
func (c *virtualServices) 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("virtualservices").
|
||||
VersionedParams(&listOpts, scheme.ParameterCodec).
|
||||
Timeout(timeout).
|
||||
Body(&opts).
|
||||
Do(ctx).
|
||||
Error()
|
||||
}
|
||||
|
||||
// Patch applies the patch and returns the patched virtualService.
|
||||
func (c *virtualServices) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta2.VirtualService, err error) {
|
||||
result = &v1beta2.VirtualService{}
|
||||
err = c.client.Patch(pt).
|
||||
Namespace(c.ns).
|
||||
Resource("virtualservices").
|
||||
Name(name).
|
||||
SubResource(subresources...).
|
||||
VersionedParams(&opts, scheme.ParameterCodec).
|
||||
Body(data).
|
||||
Do(ctx).
|
||||
Into(result)
|
||||
return
|
||||
}
|
||||
@@ -20,11 +20,14 @@ package appmesh
|
||||
|
||||
import (
|
||||
v1beta1 "github.com/weaveworks/flagger/pkg/client/informers/externalversions/appmesh/v1beta1"
|
||||
v1beta2 "github.com/weaveworks/flagger/pkg/client/informers/externalversions/appmesh/v1beta2"
|
||||
internalinterfaces "github.com/weaveworks/flagger/pkg/client/informers/externalversions/internalinterfaces"
|
||||
)
|
||||
|
||||
// Interface provides access to each of this group's versions.
|
||||
type Interface interface {
|
||||
// V1beta2 provides access to shared informers for resources in V1beta2.
|
||||
V1beta2() v1beta2.Interface
|
||||
// V1beta1 provides access to shared informers for resources in V1beta1.
|
||||
V1beta1() v1beta1.Interface
|
||||
}
|
||||
@@ -40,6 +43,11 @@ func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakList
|
||||
return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions}
|
||||
}
|
||||
|
||||
// V1beta2 returns a new v1beta2.Interface.
|
||||
func (g *group) V1beta2() v1beta2.Interface {
|
||||
return v1beta2.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)
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
Copyright The Flagger 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 v1beta2
|
||||
|
||||
import (
|
||||
internalinterfaces "github.com/weaveworks/flagger/pkg/client/informers/externalversions/internalinterfaces"
|
||||
)
|
||||
|
||||
// Interface provides access to all the informers in this group version.
|
||||
type Interface interface {
|
||||
// VirtualNodes returns a VirtualNodeInformer.
|
||||
VirtualNodes() VirtualNodeInformer
|
||||
// VirtualRouters returns a VirtualRouterInformer.
|
||||
VirtualRouters() VirtualRouterInformer
|
||||
// VirtualServices returns a VirtualServiceInformer.
|
||||
VirtualServices() VirtualServiceInformer
|
||||
}
|
||||
|
||||
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}
|
||||
}
|
||||
|
||||
// VirtualNodes returns a VirtualNodeInformer.
|
||||
func (v *version) VirtualNodes() VirtualNodeInformer {
|
||||
return &virtualNodeInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
|
||||
}
|
||||
|
||||
// VirtualRouters returns a VirtualRouterInformer.
|
||||
func (v *version) VirtualRouters() VirtualRouterInformer {
|
||||
return &virtualRouterInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
|
||||
}
|
||||
|
||||
// VirtualServices returns a VirtualServiceInformer.
|
||||
func (v *version) VirtualServices() VirtualServiceInformer {
|
||||
return &virtualServiceInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
Copyright The Flagger 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 v1beta2
|
||||
|
||||
import (
|
||||
"context"
|
||||
time "time"
|
||||
|
||||
appmeshv1beta2 "github.com/weaveworks/flagger/pkg/apis/appmesh/v1beta2"
|
||||
versioned "github.com/weaveworks/flagger/pkg/client/clientset/versioned"
|
||||
internalinterfaces "github.com/weaveworks/flagger/pkg/client/informers/externalversions/internalinterfaces"
|
||||
v1beta2 "github.com/weaveworks/flagger/pkg/client/listers/appmesh/v1beta2"
|
||||
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"
|
||||
)
|
||||
|
||||
// VirtualNodeInformer provides access to a shared informer and lister for
|
||||
// VirtualNodes.
|
||||
type VirtualNodeInformer interface {
|
||||
Informer() cache.SharedIndexInformer
|
||||
Lister() v1beta2.VirtualNodeLister
|
||||
}
|
||||
|
||||
type virtualNodeInformer struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
namespace string
|
||||
}
|
||||
|
||||
// NewVirtualNodeInformer constructs a new informer for VirtualNode 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 NewVirtualNodeInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||
return NewFilteredVirtualNodeInformer(client, namespace, resyncPeriod, indexers, nil)
|
||||
}
|
||||
|
||||
// NewFilteredVirtualNodeInformer constructs a new informer for VirtualNode 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 NewFilteredVirtualNodeInformer(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.AppmeshV1beta2().VirtualNodes(namespace).List(context.TODO(), options)
|
||||
},
|
||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.AppmeshV1beta2().VirtualNodes(namespace).Watch(context.TODO(), options)
|
||||
},
|
||||
},
|
||||
&appmeshv1beta2.VirtualNode{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
}
|
||||
|
||||
func (f *virtualNodeInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
||||
return NewFilteredVirtualNodeInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *virtualNodeInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&appmeshv1beta2.VirtualNode{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *virtualNodeInformer) Lister() v1beta2.VirtualNodeLister {
|
||||
return v1beta2.NewVirtualNodeLister(f.Informer().GetIndexer())
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
Copyright The Flagger 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 v1beta2
|
||||
|
||||
import (
|
||||
"context"
|
||||
time "time"
|
||||
|
||||
appmeshv1beta2 "github.com/weaveworks/flagger/pkg/apis/appmesh/v1beta2"
|
||||
versioned "github.com/weaveworks/flagger/pkg/client/clientset/versioned"
|
||||
internalinterfaces "github.com/weaveworks/flagger/pkg/client/informers/externalversions/internalinterfaces"
|
||||
v1beta2 "github.com/weaveworks/flagger/pkg/client/listers/appmesh/v1beta2"
|
||||
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"
|
||||
)
|
||||
|
||||
// VirtualRouterInformer provides access to a shared informer and lister for
|
||||
// VirtualRouters.
|
||||
type VirtualRouterInformer interface {
|
||||
Informer() cache.SharedIndexInformer
|
||||
Lister() v1beta2.VirtualRouterLister
|
||||
}
|
||||
|
||||
type virtualRouterInformer struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
namespace string
|
||||
}
|
||||
|
||||
// NewVirtualRouterInformer constructs a new informer for VirtualRouter 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 NewVirtualRouterInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||
return NewFilteredVirtualRouterInformer(client, namespace, resyncPeriod, indexers, nil)
|
||||
}
|
||||
|
||||
// NewFilteredVirtualRouterInformer constructs a new informer for VirtualRouter 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 NewFilteredVirtualRouterInformer(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.AppmeshV1beta2().VirtualRouters(namespace).List(context.TODO(), options)
|
||||
},
|
||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.AppmeshV1beta2().VirtualRouters(namespace).Watch(context.TODO(), options)
|
||||
},
|
||||
},
|
||||
&appmeshv1beta2.VirtualRouter{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
}
|
||||
|
||||
func (f *virtualRouterInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
||||
return NewFilteredVirtualRouterInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *virtualRouterInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&appmeshv1beta2.VirtualRouter{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *virtualRouterInformer) Lister() v1beta2.VirtualRouterLister {
|
||||
return v1beta2.NewVirtualRouterLister(f.Informer().GetIndexer())
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
Copyright The Flagger 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 v1beta2
|
||||
|
||||
import (
|
||||
"context"
|
||||
time "time"
|
||||
|
||||
appmeshv1beta2 "github.com/weaveworks/flagger/pkg/apis/appmesh/v1beta2"
|
||||
versioned "github.com/weaveworks/flagger/pkg/client/clientset/versioned"
|
||||
internalinterfaces "github.com/weaveworks/flagger/pkg/client/informers/externalversions/internalinterfaces"
|
||||
v1beta2 "github.com/weaveworks/flagger/pkg/client/listers/appmesh/v1beta2"
|
||||
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"
|
||||
)
|
||||
|
||||
// VirtualServiceInformer provides access to a shared informer and lister for
|
||||
// VirtualServices.
|
||||
type VirtualServiceInformer interface {
|
||||
Informer() cache.SharedIndexInformer
|
||||
Lister() v1beta2.VirtualServiceLister
|
||||
}
|
||||
|
||||
type virtualServiceInformer struct {
|
||||
factory internalinterfaces.SharedInformerFactory
|
||||
tweakListOptions internalinterfaces.TweakListOptionsFunc
|
||||
namespace string
|
||||
}
|
||||
|
||||
// NewVirtualServiceInformer constructs a new informer for VirtualService 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 NewVirtualServiceInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer {
|
||||
return NewFilteredVirtualServiceInformer(client, namespace, resyncPeriod, indexers, nil)
|
||||
}
|
||||
|
||||
// NewFilteredVirtualServiceInformer constructs a new informer for VirtualService 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 NewFilteredVirtualServiceInformer(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.AppmeshV1beta2().VirtualServices(namespace).List(context.TODO(), options)
|
||||
},
|
||||
WatchFunc: func(options v1.ListOptions) (watch.Interface, error) {
|
||||
if tweakListOptions != nil {
|
||||
tweakListOptions(&options)
|
||||
}
|
||||
return client.AppmeshV1beta2().VirtualServices(namespace).Watch(context.TODO(), options)
|
||||
},
|
||||
},
|
||||
&appmeshv1beta2.VirtualService{},
|
||||
resyncPeriod,
|
||||
indexers,
|
||||
)
|
||||
}
|
||||
|
||||
func (f *virtualServiceInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer {
|
||||
return NewFilteredVirtualServiceInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions)
|
||||
}
|
||||
|
||||
func (f *virtualServiceInformer) Informer() cache.SharedIndexInformer {
|
||||
return f.factory.InformerFor(&appmeshv1beta2.VirtualService{}, f.defaultInformer)
|
||||
}
|
||||
|
||||
func (f *virtualServiceInformer) Lister() v1beta2.VirtualServiceLister {
|
||||
return v1beta2.NewVirtualServiceLister(f.Informer().GetIndexer())
|
||||
}
|
||||
@@ -22,6 +22,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
v1beta1 "github.com/weaveworks/flagger/pkg/apis/appmesh/v1beta1"
|
||||
v1beta2 "github.com/weaveworks/flagger/pkg/apis/appmesh/v1beta2"
|
||||
flaggerv1beta1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
|
||||
v1 "github.com/weaveworks/flagger/pkg/apis/gloo/v1"
|
||||
v1alpha3 "github.com/weaveworks/flagger/pkg/apis/istio/v1alpha3"
|
||||
@@ -66,6 +67,14 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource
|
||||
case v1beta1.SchemeGroupVersion.WithResource("virtualservices"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Appmesh().V1beta1().VirtualServices().Informer()}, nil
|
||||
|
||||
// Group=appmesh.k8s.aws, Version=v1beta2
|
||||
case v1beta2.SchemeGroupVersion.WithResource("virtualnodes"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Appmesh().V1beta2().VirtualNodes().Informer()}, nil
|
||||
case v1beta2.SchemeGroupVersion.WithResource("virtualrouters"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Appmesh().V1beta2().VirtualRouters().Informer()}, nil
|
||||
case v1beta2.SchemeGroupVersion.WithResource("virtualservices"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Appmesh().V1beta2().VirtualServices().Informer()}, nil
|
||||
|
||||
// Group=flagger.app, Version=v1beta1
|
||||
case flaggerv1beta1.SchemeGroupVersion.WithResource("alertproviders"):
|
||||
return &genericInformer{resource: resource.GroupResource(), informer: f.Flagger().V1beta1().AlertProviders().Informer()}, nil
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
Copyright The Flagger 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 v1beta2
|
||||
|
||||
// VirtualNodeListerExpansion allows custom methods to be added to
|
||||
// VirtualNodeLister.
|
||||
type VirtualNodeListerExpansion interface{}
|
||||
|
||||
// VirtualNodeNamespaceListerExpansion allows custom methods to be added to
|
||||
// VirtualNodeNamespaceLister.
|
||||
type VirtualNodeNamespaceListerExpansion interface{}
|
||||
|
||||
// VirtualRouterListerExpansion allows custom methods to be added to
|
||||
// VirtualRouterLister.
|
||||
type VirtualRouterListerExpansion interface{}
|
||||
|
||||
// VirtualRouterNamespaceListerExpansion allows custom methods to be added to
|
||||
// VirtualRouterNamespaceLister.
|
||||
type VirtualRouterNamespaceListerExpansion interface{}
|
||||
|
||||
// VirtualServiceListerExpansion allows custom methods to be added to
|
||||
// VirtualServiceLister.
|
||||
type VirtualServiceListerExpansion interface{}
|
||||
|
||||
// VirtualServiceNamespaceListerExpansion allows custom methods to be added to
|
||||
// VirtualServiceNamespaceLister.
|
||||
type VirtualServiceNamespaceListerExpansion interface{}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
Copyright The Flagger 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 v1beta2
|
||||
|
||||
import (
|
||||
v1beta2 "github.com/weaveworks/flagger/pkg/apis/appmesh/v1beta2"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// VirtualNodeLister helps list VirtualNodes.
|
||||
type VirtualNodeLister interface {
|
||||
// List lists all VirtualNodes in the indexer.
|
||||
List(selector labels.Selector) (ret []*v1beta2.VirtualNode, err error)
|
||||
// VirtualNodes returns an object that can list and get VirtualNodes.
|
||||
VirtualNodes(namespace string) VirtualNodeNamespaceLister
|
||||
VirtualNodeListerExpansion
|
||||
}
|
||||
|
||||
// virtualNodeLister implements the VirtualNodeLister interface.
|
||||
type virtualNodeLister struct {
|
||||
indexer cache.Indexer
|
||||
}
|
||||
|
||||
// NewVirtualNodeLister returns a new VirtualNodeLister.
|
||||
func NewVirtualNodeLister(indexer cache.Indexer) VirtualNodeLister {
|
||||
return &virtualNodeLister{indexer: indexer}
|
||||
}
|
||||
|
||||
// List lists all VirtualNodes in the indexer.
|
||||
func (s *virtualNodeLister) List(selector labels.Selector) (ret []*v1beta2.VirtualNode, err error) {
|
||||
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1beta2.VirtualNode))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// VirtualNodes returns an object that can list and get VirtualNodes.
|
||||
func (s *virtualNodeLister) VirtualNodes(namespace string) VirtualNodeNamespaceLister {
|
||||
return virtualNodeNamespaceLister{indexer: s.indexer, namespace: namespace}
|
||||
}
|
||||
|
||||
// VirtualNodeNamespaceLister helps list and get VirtualNodes.
|
||||
type VirtualNodeNamespaceLister interface {
|
||||
// List lists all VirtualNodes in the indexer for a given namespace.
|
||||
List(selector labels.Selector) (ret []*v1beta2.VirtualNode, err error)
|
||||
// Get retrieves the VirtualNode from the indexer for a given namespace and name.
|
||||
Get(name string) (*v1beta2.VirtualNode, error)
|
||||
VirtualNodeNamespaceListerExpansion
|
||||
}
|
||||
|
||||
// virtualNodeNamespaceLister implements the VirtualNodeNamespaceLister
|
||||
// interface.
|
||||
type virtualNodeNamespaceLister struct {
|
||||
indexer cache.Indexer
|
||||
namespace string
|
||||
}
|
||||
|
||||
// List lists all VirtualNodes in the indexer for a given namespace.
|
||||
func (s virtualNodeNamespaceLister) List(selector labels.Selector) (ret []*v1beta2.VirtualNode, err error) {
|
||||
err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1beta2.VirtualNode))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get retrieves the VirtualNode from the indexer for a given namespace and name.
|
||||
func (s virtualNodeNamespaceLister) Get(name string) (*v1beta2.VirtualNode, error) {
|
||||
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return nil, errors.NewNotFound(v1beta2.Resource("virtualnode"), name)
|
||||
}
|
||||
return obj.(*v1beta2.VirtualNode), nil
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
Copyright The Flagger 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 v1beta2
|
||||
|
||||
import (
|
||||
v1beta2 "github.com/weaveworks/flagger/pkg/apis/appmesh/v1beta2"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// VirtualRouterLister helps list VirtualRouters.
|
||||
type VirtualRouterLister interface {
|
||||
// List lists all VirtualRouters in the indexer.
|
||||
List(selector labels.Selector) (ret []*v1beta2.VirtualRouter, err error)
|
||||
// VirtualRouters returns an object that can list and get VirtualRouters.
|
||||
VirtualRouters(namespace string) VirtualRouterNamespaceLister
|
||||
VirtualRouterListerExpansion
|
||||
}
|
||||
|
||||
// virtualRouterLister implements the VirtualRouterLister interface.
|
||||
type virtualRouterLister struct {
|
||||
indexer cache.Indexer
|
||||
}
|
||||
|
||||
// NewVirtualRouterLister returns a new VirtualRouterLister.
|
||||
func NewVirtualRouterLister(indexer cache.Indexer) VirtualRouterLister {
|
||||
return &virtualRouterLister{indexer: indexer}
|
||||
}
|
||||
|
||||
// List lists all VirtualRouters in the indexer.
|
||||
func (s *virtualRouterLister) List(selector labels.Selector) (ret []*v1beta2.VirtualRouter, err error) {
|
||||
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1beta2.VirtualRouter))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// VirtualRouters returns an object that can list and get VirtualRouters.
|
||||
func (s *virtualRouterLister) VirtualRouters(namespace string) VirtualRouterNamespaceLister {
|
||||
return virtualRouterNamespaceLister{indexer: s.indexer, namespace: namespace}
|
||||
}
|
||||
|
||||
// VirtualRouterNamespaceLister helps list and get VirtualRouters.
|
||||
type VirtualRouterNamespaceLister interface {
|
||||
// List lists all VirtualRouters in the indexer for a given namespace.
|
||||
List(selector labels.Selector) (ret []*v1beta2.VirtualRouter, err error)
|
||||
// Get retrieves the VirtualRouter from the indexer for a given namespace and name.
|
||||
Get(name string) (*v1beta2.VirtualRouter, error)
|
||||
VirtualRouterNamespaceListerExpansion
|
||||
}
|
||||
|
||||
// virtualRouterNamespaceLister implements the VirtualRouterNamespaceLister
|
||||
// interface.
|
||||
type virtualRouterNamespaceLister struct {
|
||||
indexer cache.Indexer
|
||||
namespace string
|
||||
}
|
||||
|
||||
// List lists all VirtualRouters in the indexer for a given namespace.
|
||||
func (s virtualRouterNamespaceLister) List(selector labels.Selector) (ret []*v1beta2.VirtualRouter, err error) {
|
||||
err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1beta2.VirtualRouter))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get retrieves the VirtualRouter from the indexer for a given namespace and name.
|
||||
func (s virtualRouterNamespaceLister) Get(name string) (*v1beta2.VirtualRouter, error) {
|
||||
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return nil, errors.NewNotFound(v1beta2.Resource("virtualrouter"), name)
|
||||
}
|
||||
return obj.(*v1beta2.VirtualRouter), nil
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
Copyright The Flagger 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 v1beta2
|
||||
|
||||
import (
|
||||
v1beta2 "github.com/weaveworks/flagger/pkg/apis/appmesh/v1beta2"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/labels"
|
||||
"k8s.io/client-go/tools/cache"
|
||||
)
|
||||
|
||||
// VirtualServiceLister helps list VirtualServices.
|
||||
type VirtualServiceLister interface {
|
||||
// List lists all VirtualServices in the indexer.
|
||||
List(selector labels.Selector) (ret []*v1beta2.VirtualService, err error)
|
||||
// VirtualServices returns an object that can list and get VirtualServices.
|
||||
VirtualServices(namespace string) VirtualServiceNamespaceLister
|
||||
VirtualServiceListerExpansion
|
||||
}
|
||||
|
||||
// virtualServiceLister implements the VirtualServiceLister interface.
|
||||
type virtualServiceLister struct {
|
||||
indexer cache.Indexer
|
||||
}
|
||||
|
||||
// NewVirtualServiceLister returns a new VirtualServiceLister.
|
||||
func NewVirtualServiceLister(indexer cache.Indexer) VirtualServiceLister {
|
||||
return &virtualServiceLister{indexer: indexer}
|
||||
}
|
||||
|
||||
// List lists all VirtualServices in the indexer.
|
||||
func (s *virtualServiceLister) List(selector labels.Selector) (ret []*v1beta2.VirtualService, err error) {
|
||||
err = cache.ListAll(s.indexer, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1beta2.VirtualService))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// VirtualServices returns an object that can list and get VirtualServices.
|
||||
func (s *virtualServiceLister) VirtualServices(namespace string) VirtualServiceNamespaceLister {
|
||||
return virtualServiceNamespaceLister{indexer: s.indexer, namespace: namespace}
|
||||
}
|
||||
|
||||
// VirtualServiceNamespaceLister helps list and get VirtualServices.
|
||||
type VirtualServiceNamespaceLister interface {
|
||||
// List lists all VirtualServices in the indexer for a given namespace.
|
||||
List(selector labels.Selector) (ret []*v1beta2.VirtualService, err error)
|
||||
// Get retrieves the VirtualService from the indexer for a given namespace and name.
|
||||
Get(name string) (*v1beta2.VirtualService, error)
|
||||
VirtualServiceNamespaceListerExpansion
|
||||
}
|
||||
|
||||
// virtualServiceNamespaceLister implements the VirtualServiceNamespaceLister
|
||||
// interface.
|
||||
type virtualServiceNamespaceLister struct {
|
||||
indexer cache.Indexer
|
||||
namespace string
|
||||
}
|
||||
|
||||
// List lists all VirtualServices in the indexer for a given namespace.
|
||||
func (s virtualServiceNamespaceLister) List(selector labels.Selector) (ret []*v1beta2.VirtualService, err error) {
|
||||
err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) {
|
||||
ret = append(ret, m.(*v1beta2.VirtualService))
|
||||
})
|
||||
return ret, err
|
||||
}
|
||||
|
||||
// Get retrieves the VirtualService from the indexer for a given namespace and name.
|
||||
func (s virtualServiceNamespaceLister) Get(name string) (*v1beta2.VirtualService, error) {
|
||||
obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !exists {
|
||||
return nil, errors.NewNotFound(v1beta2.Resource("virtualservice"), name)
|
||||
}
|
||||
return obj.(*v1beta2.VirtualService), nil
|
||||
}
|
||||
@@ -79,7 +79,7 @@ func (c *Controller) revertMesh(r *flaggerv1.Canary) error {
|
||||
provider = r.Spec.Provider
|
||||
}
|
||||
|
||||
meshRouter := c.routerFactory.MeshRouter(provider)
|
||||
meshRouter := c.routerFactory.MeshRouter(provider, "")
|
||||
if err := meshRouter.Finalize(r); err != nil {
|
||||
return fmt.Errorf("meshRouter.Finlize failed: %w", err)
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package controller
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@@ -110,31 +111,45 @@ func (c *Controller) advanceCanary(name string, namespace string) {
|
||||
|
||||
// init Kubernetes router
|
||||
kubeRouter := c.routerFactory.KubernetesRouter(cd.Spec.TargetRef.Kind, labelSelector, ports)
|
||||
|
||||
// reconcile the canary/primary services
|
||||
if err := kubeRouter.Initialize(cd); err != nil {
|
||||
c.recordEventWarningf(cd, "%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// create primary
|
||||
// init mesh router
|
||||
meshRouter := c.routerFactory.MeshRouter(provider, labelSelector)
|
||||
|
||||
// register the AppMesh VirtualNodes before creating the primary deployment
|
||||
// otherwise the pods will not be injected with the Envoy proxy
|
||||
if strings.HasPrefix(provider, flaggerv1.AppMeshProvider) {
|
||||
if err := meshRouter.Reconcile(cd); err != nil {
|
||||
c.recordEventWarningf(cd, "%v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// create primary workload
|
||||
err = canaryController.Initialize(cd)
|
||||
if err != nil {
|
||||
c.recordEventWarningf(cd, "%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// init mesh router
|
||||
meshRouter := c.routerFactory.MeshRouter(provider)
|
||||
|
||||
// create or update svc
|
||||
// change the apex service pod selector to primary
|
||||
if err := kubeRouter.Reconcile(cd); err != nil {
|
||||
c.recordEventWarningf(cd, "%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
// create or update mesh routes
|
||||
if err := meshRouter.Reconcile(cd); err != nil {
|
||||
c.recordEventWarningf(cd, "%v", err)
|
||||
return
|
||||
// take over an existing virtual service or ingress
|
||||
// runs after the primary is ready to ensure zero downtime
|
||||
if !strings.HasPrefix(provider, flaggerv1.AppMeshProvider) {
|
||||
if err := meshRouter.Reconcile(cd); err != nil {
|
||||
c.recordEventWarningf(cd, "%v", err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// check for changes
|
||||
|
||||
@@ -110,7 +110,7 @@ func newDaemonSetFixture(c *flaggerv1.Canary) daemonSetFixture {
|
||||
ctrl.flaggerInformers.MetricInformer.Informer().GetIndexer().Add(newDaemonSetTestMetricTemplate())
|
||||
ctrl.flaggerInformers.AlertInformer.Informer().GetIndexer().Add(newDaemonSetTestAlertProvider())
|
||||
|
||||
meshRouter := rf.MeshRouter("istio")
|
||||
meshRouter := rf.MeshRouter("istio", "")
|
||||
|
||||
return daemonSetFixture{
|
||||
canary: c,
|
||||
|
||||
@@ -138,7 +138,7 @@ func newDeploymentFixture(c *flaggerv1.Canary) fixture {
|
||||
ctrl.flaggerInformers.MetricInformer.Informer().GetIndexer().Add(newDeploymentTestMetricTemplate())
|
||||
ctrl.flaggerInformers.AlertInformer.Informer().GetIndexer().Add(newDeploymentTestAlertProvider())
|
||||
|
||||
meshRouter := rf.MeshRouter("istio")
|
||||
meshRouter := rf.MeshRouter("istio", "")
|
||||
|
||||
return fixture{
|
||||
canary: c,
|
||||
|
||||
@@ -1,77 +0,0 @@
|
||||
package observers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
|
||||
"github.com/weaveworks/flagger/pkg/metrics/providers"
|
||||
)
|
||||
|
||||
var crossoverQueries = map[string]string{
|
||||
"request-success-rate": `
|
||||
sum(
|
||||
rate(
|
||||
envoy_cluster_upstream_rq{
|
||||
kubernetes_namespace="{{ namespace }}",
|
||||
envoy_cluster_name=~"{{ target }}-canary",
|
||||
envoy_response_code!~"5.*"
|
||||
}[{{ interval }}]
|
||||
)
|
||||
)
|
||||
/
|
||||
sum(
|
||||
rate(
|
||||
envoy_cluster_upstream_rq{
|
||||
kubernetes_namespace="{{ namespace }}",
|
||||
envoy_cluster_name=~"{{ target }}-canary"
|
||||
}[{{ interval }}]
|
||||
)
|
||||
)
|
||||
* 100`,
|
||||
"request-duration": `
|
||||
histogram_quantile(
|
||||
0.99,
|
||||
sum(
|
||||
rate(
|
||||
envoy_cluster_upstream_rq_time_bucket{
|
||||
kubernetes_namespace="{{ namespace }}",
|
||||
envoy_cluster_name=~"{{ target }}-canary"
|
||||
}[{{ interval }}]
|
||||
)
|
||||
) by (le)
|
||||
)`,
|
||||
}
|
||||
|
||||
type CrossoverObserver struct {
|
||||
client providers.Interface
|
||||
}
|
||||
|
||||
func (ob *CrossoverObserver) GetRequestSuccessRate(model flaggerv1.MetricTemplateModel) (float64, error) {
|
||||
query, err := RenderQuery(crossoverQueries["request-success-rate"], model)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
value, err := ob.client.RunQuery(query)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return value, nil
|
||||
}
|
||||
|
||||
func (ob *CrossoverObserver) GetRequestDuration(model flaggerv1.MetricTemplateModel) (time.Duration, error) {
|
||||
query, err := RenderQuery(crossoverQueries["request-duration"], model)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("rendering query failed: %w", err)
|
||||
}
|
||||
|
||||
value, err := ob.client.RunQuery(query)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("running query failed: %w", err)
|
||||
}
|
||||
|
||||
ms := time.Duration(int64(value)) * time.Millisecond
|
||||
return ms, nil
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
package observers
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
|
||||
"github.com/weaveworks/flagger/pkg/metrics/providers"
|
||||
)
|
||||
|
||||
var crossoverServiceQueries = map[string]string{
|
||||
"request-success-rate": `
|
||||
sum(
|
||||
rate(
|
||||
envoy_cluster_upstream_rq{
|
||||
kubernetes_namespace="{{ namespace }}",
|
||||
envoy_cluster_name="{{ target }}-canary",
|
||||
envoy_response_code!~"5.*"
|
||||
}[{{ interval }}]
|
||||
)
|
||||
)
|
||||
/
|
||||
sum(
|
||||
rate(
|
||||
envoy_cluster_upstream_rq{
|
||||
kubernetes_namespace="{{ namespace }}",
|
||||
envoy_cluster_name="{{ target }}-canary"
|
||||
}[{{ interval }}]
|
||||
)
|
||||
)
|
||||
* 100`,
|
||||
"request-duration": `
|
||||
histogram_quantile(
|
||||
0.99,
|
||||
sum(
|
||||
rate(
|
||||
envoy_cluster_upstream_rq_time_bucket{
|
||||
kubernetes_namespace="{{ namespace }}",
|
||||
envoy_cluster_name="{{ target }}-canary"
|
||||
}[{{ interval }}]
|
||||
)
|
||||
) by (le)
|
||||
)`,
|
||||
}
|
||||
|
||||
type CrossoverServiceObserver struct {
|
||||
client providers.Interface
|
||||
}
|
||||
|
||||
func (ob *CrossoverServiceObserver) GetRequestSuccessRate(model flaggerv1.MetricTemplateModel) (float64, error) {
|
||||
query, err := RenderQuery(crossoverServiceQueries["request-success-rate"], model)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("rendering query failed: %w", err)
|
||||
}
|
||||
|
||||
value, err := ob.client.RunQuery(query)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("running query failed: %w", err)
|
||||
}
|
||||
|
||||
return value, nil
|
||||
}
|
||||
|
||||
func (ob *CrossoverServiceObserver) GetRequestDuration(model flaggerv1.MetricTemplateModel) (time.Duration, error) {
|
||||
query, err := RenderQuery(crossoverServiceQueries["request-duration"], model)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("rendering query failed: %w", err)
|
||||
}
|
||||
|
||||
value, err := ob.client.RunQuery(query)
|
||||
if err != nil {
|
||||
return 0, fmt.Errorf("running query failed: %w", err)
|
||||
}
|
||||
|
||||
ms := time.Duration(int64(value)) * time.Millisecond
|
||||
return ms, nil
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
package observers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
|
||||
"github.com/weaveworks/flagger/pkg/metrics/providers"
|
||||
)
|
||||
|
||||
func TestCrossoverServiceObserver_GetRequestSuccessRate(t *testing.T) {
|
||||
expected := ` sum( rate( envoy_cluster_upstream_rq{ kubernetes_namespace="default", envoy_cluster_name="podinfo-canary", envoy_response_code!~"5.*" }[1m] ) ) / sum( rate( envoy_cluster_upstream_rq{ kubernetes_namespace="default", envoy_cluster_name="podinfo-canary" }[1m] ) ) * 100`
|
||||
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
promql := r.URL.Query()["query"][0]
|
||||
assert.Equal(t, expected, promql)
|
||||
|
||||
json := `{"status":"success","data":{"resultType":"vector","result":[{"metric":{},"value":[1,"100"]}]}}`
|
||||
w.Write([]byte(json))
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
client, err := providers.NewPrometheusProvider(flaggerv1.MetricTemplateProvider{
|
||||
Type: "prometheus",
|
||||
Address: ts.URL,
|
||||
SecretRef: nil,
|
||||
}, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
observer := &CrossoverServiceObserver{
|
||||
client: client,
|
||||
}
|
||||
|
||||
val, err := observer.GetRequestSuccessRate(flaggerv1.MetricTemplateModel{
|
||||
Name: "podinfo",
|
||||
Namespace: "default",
|
||||
Target: "podinfo",
|
||||
Service: "podinfo",
|
||||
Interval: "1m",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, float64(100), val)
|
||||
}
|
||||
|
||||
func TestCrossoverServiceObserver_GetRequestDuration(t *testing.T) {
|
||||
expected := ` histogram_quantile( 0.99, sum( rate( envoy_cluster_upstream_rq_time_bucket{ kubernetes_namespace="default", envoy_cluster_name="podinfo-canary" }[1m] ) ) by (le) )`
|
||||
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
promql := r.URL.Query()["query"][0]
|
||||
assert.Equal(t, expected, promql)
|
||||
|
||||
json := `{"status":"success","data":{"resultType":"vector","result":[{"metric":{},"value":[1,"100"]}]}}`
|
||||
w.Write([]byte(json))
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
client, err := providers.NewPrometheusProvider(flaggerv1.MetricTemplateProvider{
|
||||
Type: "prometheus",
|
||||
Address: ts.URL,
|
||||
SecretRef: nil,
|
||||
}, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
observer := &CrossoverServiceObserver{
|
||||
client: client,
|
||||
}
|
||||
|
||||
val, err := observer.GetRequestDuration(flaggerv1.MetricTemplateModel{
|
||||
Name: "podinfo",
|
||||
Namespace: "default",
|
||||
Target: "podinfo",
|
||||
Service: "podinfo",
|
||||
Interval: "1m",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, 100*time.Millisecond, val)
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
package observers
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
|
||||
"github.com/weaveworks/flagger/pkg/metrics/providers"
|
||||
)
|
||||
|
||||
func TestCrossoverObserver_GetRequestSuccessRate(t *testing.T) {
|
||||
expected := ` sum( rate( envoy_cluster_upstream_rq{ kubernetes_namespace="default", envoy_cluster_name=~"podinfo-canary", envoy_response_code!~"5.*" }[1m] ) ) / sum( rate( envoy_cluster_upstream_rq{ kubernetes_namespace="default", envoy_cluster_name=~"podinfo-canary" }[1m] ) ) * 100`
|
||||
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
promql := r.URL.Query()["query"][0]
|
||||
assert.Equal(t, expected, promql)
|
||||
|
||||
json := `{"status":"success","data":{"resultType":"vector","result":[{"metric":{},"value":[1,"100"]}]}}`
|
||||
w.Write([]byte(json))
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
client, err := providers.NewPrometheusProvider(flaggerv1.MetricTemplateProvider{
|
||||
Type: "prometheus",
|
||||
Address: ts.URL,
|
||||
SecretRef: nil,
|
||||
}, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
observer := &CrossoverObserver{
|
||||
client: client,
|
||||
}
|
||||
|
||||
val, err := observer.GetRequestSuccessRate(flaggerv1.MetricTemplateModel{
|
||||
Name: "podinfo",
|
||||
Namespace: "default",
|
||||
Target: "podinfo",
|
||||
Service: "podinfo",
|
||||
Interval: "1m",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, float64(100), val)
|
||||
}
|
||||
|
||||
func TestCrossoverObserver_GetRequestDuration(t *testing.T) {
|
||||
expected := ` histogram_quantile( 0.99, sum( rate( envoy_cluster_upstream_rq_time_bucket{ kubernetes_namespace="default", envoy_cluster_name=~"podinfo-canary" }[1m] ) ) by (le) )`
|
||||
|
||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
promql := r.URL.Query()["query"][0]
|
||||
assert.Equal(t, expected, promql)
|
||||
|
||||
json := `{"status":"success","data":{"resultType":"vector","result":[{"metric":{},"value":[1,"100"]}]}}`
|
||||
w.Write([]byte(json))
|
||||
}))
|
||||
defer ts.Close()
|
||||
|
||||
client, err := providers.NewPrometheusProvider(flaggerv1.MetricTemplateProvider{
|
||||
Type: "prometheus",
|
||||
Address: ts.URL,
|
||||
SecretRef: nil,
|
||||
}, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
observer := &CrossoverObserver{
|
||||
client: client,
|
||||
}
|
||||
|
||||
val, err := observer.GetRequestDuration(flaggerv1.MetricTemplateModel{
|
||||
Name: "podinfo",
|
||||
Namespace: "default",
|
||||
Target: "podinfo",
|
||||
Service: "podinfo",
|
||||
Interval: "1m",
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, 100*time.Millisecond, val)
|
||||
}
|
||||
@@ -28,44 +28,32 @@ func NewFactory(metricsServer string) (*Factory, error) {
|
||||
|
||||
func (factory Factory) Observer(provider string) Interface {
|
||||
switch {
|
||||
case provider == "none":
|
||||
return &HttpObserver{
|
||||
client: factory.Client,
|
||||
}
|
||||
case provider == "kubernetes":
|
||||
return &HttpObserver{
|
||||
client: factory.Client,
|
||||
}
|
||||
case provider == "appmesh":
|
||||
case strings.HasPrefix(provider, flaggerv1.AppMeshProvider):
|
||||
return &AppMeshObserver{
|
||||
client: factory.Client,
|
||||
}
|
||||
case provider == "crossover":
|
||||
return &CrossoverObserver{
|
||||
case provider == flaggerv1.LinkerdProvider:
|
||||
return &LinkerdObserver{
|
||||
client: factory.Client,
|
||||
}
|
||||
case provider == "nginx":
|
||||
return &NginxObserver{
|
||||
case provider == flaggerv1.IstioProvider:
|
||||
return &IstioObserver{
|
||||
client: factory.Client,
|
||||
}
|
||||
case strings.HasPrefix(provider, "gloo"):
|
||||
case provider == flaggerv1.ContourProvider:
|
||||
return &ContourObserver{
|
||||
client: factory.Client,
|
||||
}
|
||||
case strings.HasPrefix(provider, flaggerv1.GlooProvider):
|
||||
return &GlooObserver{
|
||||
client: factory.Client,
|
||||
}
|
||||
case provider == "smi:linkerd":
|
||||
return &LinkerdObserver{
|
||||
case provider == flaggerv1.NGINXProvider:
|
||||
return &NginxObserver{
|
||||
client: factory.Client,
|
||||
}
|
||||
case provider == "crossover:service":
|
||||
return &CrossoverServiceObserver{
|
||||
client: factory.Client,
|
||||
}
|
||||
case provider == "linkerd":
|
||||
return &LinkerdObserver{
|
||||
client: factory.Client,
|
||||
}
|
||||
case provider == "contour":
|
||||
return &ContourObserver{
|
||||
case provider == flaggerv1.KubernetesProvider:
|
||||
return &HttpObserver{
|
||||
client: factory.Client,
|
||||
}
|
||||
default:
|
||||
|
||||
@@ -0,0 +1,540 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/google/go-cmp/cmp/cmpopts"
|
||||
"go.uber.org/zap"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
|
||||
appmeshv1 "github.com/weaveworks/flagger/pkg/apis/appmesh/v1beta2"
|
||||
flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
|
||||
clientset "github.com/weaveworks/flagger/pkg/client/clientset/versioned"
|
||||
)
|
||||
|
||||
// AppMeshRouter is managing AppMesh virtual services
|
||||
type AppMeshv1beta2Router struct {
|
||||
kubeClient kubernetes.Interface
|
||||
appmeshClient clientset.Interface
|
||||
flaggerClient clientset.Interface
|
||||
logger *zap.SugaredLogger
|
||||
labelSelector string
|
||||
}
|
||||
|
||||
// Reconcile creates or updates App Mesh virtual nodes and virtual services
|
||||
func (ar *AppMeshv1beta2Router) Reconcile(canary *flaggerv1.Canary) error {
|
||||
svcSuffix := "svc.cluster.local."
|
||||
apexName, primaryName, canaryName := canary.GetServiceNames()
|
||||
primaryHost := fmt.Sprintf("%s.%s.%s", primaryName, canary.Namespace, svcSuffix)
|
||||
canaryHost := fmt.Sprintf("%s.%s.%s", canaryName, canary.Namespace, svcSuffix)
|
||||
|
||||
// sync virtual node e.g. app-namespace
|
||||
// DNS app.namespace
|
||||
//err := ar.reconcileVirtualNode(canary, apexName, fmt.Sprintf("%s-primary", canary.Spec.TargetRef.Name), primaryHost)
|
||||
//if err != nil {
|
||||
// return fmt.Errorf("reconcileVirtualNode failed: %w", err)
|
||||
//}
|
||||
|
||||
// sync virtual node e.g. app-primary-namespace
|
||||
// DNS app-primary.namespace
|
||||
err := ar.reconcileVirtualNode(canary, primaryName, fmt.Sprintf("%s-primary", canary.Spec.TargetRef.Name), primaryHost)
|
||||
if err != nil {
|
||||
return fmt.Errorf("reconcileVirtualNode failed: %w", err)
|
||||
}
|
||||
|
||||
// sync virtual node e.g. app-canary-namespace
|
||||
// DNS app-canary.namespace
|
||||
err = ar.reconcileVirtualNode(canary, canaryName, canary.Spec.TargetRef.Name, canaryHost)
|
||||
if err != nil {
|
||||
return fmt.Errorf("reconcileVirtualNode failed: %w", err)
|
||||
}
|
||||
|
||||
// sync main virtual router
|
||||
// DNS app.namespace
|
||||
err = ar.reconcileVirtualRouter(canary, apexName, 0)
|
||||
if err != nil {
|
||||
return fmt.Errorf("reconcileVirtualService failed: %w", err)
|
||||
}
|
||||
|
||||
// sync canary virtual router
|
||||
// DNS app-canary.namespace
|
||||
err = ar.reconcileVirtualRouter(canary, canaryName, 100)
|
||||
if err != nil {
|
||||
return fmt.Errorf("reconcileVirtualRouter failed: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// reconcileVirtualNode creates or updates a virtual node
|
||||
// the virtual node naming format is name-role-namespace
|
||||
func (ar *AppMeshv1beta2Router) reconcileVirtualNode(canary *flaggerv1.Canary, name string, podSelector string, host string) error {
|
||||
protocol := ar.getProtocol(canary)
|
||||
vnSpec := appmeshv1.VirtualNodeSpec{
|
||||
Listeners: []appmeshv1.Listener{
|
||||
{
|
||||
PortMapping: appmeshv1.PortMapping{
|
||||
Port: ar.getContainerPort(canary),
|
||||
Protocol: protocol,
|
||||
},
|
||||
},
|
||||
},
|
||||
ServiceDiscovery: &appmeshv1.ServiceDiscovery{
|
||||
DNS: &appmeshv1.DNSServiceDiscovery{
|
||||
Hostname: host,
|
||||
},
|
||||
},
|
||||
PodSelector: &metav1.LabelSelector{
|
||||
MatchLabels: map[string]string{
|
||||
ar.labelSelector: podSelector,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
backends := make([]appmeshv1.Backend, 0)
|
||||
for _, b := range canary.Spec.Service.Backends {
|
||||
bk := appmeshv1.Backend{
|
||||
VirtualService: appmeshv1.VirtualServiceBackend{
|
||||
VirtualServiceRef: appmeshv1.VirtualServiceReference{
|
||||
Name: b,
|
||||
},
|
||||
},
|
||||
}
|
||||
backends = append(backends, bk)
|
||||
}
|
||||
|
||||
if len(backends) > 0 {
|
||||
vnSpec.Backends = backends
|
||||
}
|
||||
|
||||
virtualnode, err := ar.appmeshClient.AppmeshV1beta2().VirtualNodes(canary.Namespace).Get(context.TODO(), name, metav1.GetOptions{})
|
||||
|
||||
// create virtual node
|
||||
if errors.IsNotFound(err) {
|
||||
virtualnode = &appmeshv1.VirtualNode{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: canary.Namespace,
|
||||
OwnerReferences: []metav1.OwnerReference{
|
||||
*metav1.NewControllerRef(canary, schema.GroupVersionKind{
|
||||
Group: flaggerv1.SchemeGroupVersion.Group,
|
||||
Version: flaggerv1.SchemeGroupVersion.Version,
|
||||
Kind: flaggerv1.CanaryKind,
|
||||
}),
|
||||
},
|
||||
},
|
||||
Spec: vnSpec,
|
||||
}
|
||||
_, err = ar.appmeshClient.AppmeshV1beta2().VirtualNodes(canary.Namespace).Create(context.TODO(), virtualnode, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("VirtualNode %s.%s create error %w", name, canary.Namespace, err)
|
||||
}
|
||||
ar.logger.With("canary", fmt.Sprintf("%s.%s", canary.Name, canary.Namespace)).
|
||||
Infof("VirtualNode %s.%s created", virtualnode.GetName(), canary.Namespace)
|
||||
return nil
|
||||
} else if err != nil {
|
||||
return fmt.Errorf("VirtualNode %s get query error %w", name, err)
|
||||
}
|
||||
|
||||
// update virtual node
|
||||
if virtualnode != nil {
|
||||
if diff := cmp.Diff(vnSpec, virtualnode.Spec,
|
||||
cmpopts.IgnoreFields(appmeshv1.VirtualNodeSpec{}, "AWSName", "MeshRef")); diff != "" {
|
||||
vnClone := virtualnode.DeepCopy()
|
||||
vnClone.Spec = vnSpec
|
||||
vnClone.Spec.AWSName = virtualnode.Spec.AWSName
|
||||
vnClone.Spec.MeshRef = virtualnode.Spec.MeshRef
|
||||
_, err = ar.appmeshClient.AppmeshV1beta2().VirtualNodes(canary.Namespace).Update(context.TODO(), vnClone, metav1.UpdateOptions{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("VirtualNode %s update error %w", name, err)
|
||||
}
|
||||
ar.logger.With("canary", fmt.Sprintf("%s.%s", canary.Name, canary.Namespace)).
|
||||
Infof("VirtualNode %s updated", virtualnode.GetName())
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// reconcileVirtualRouter creates or updates a virtual router
|
||||
func (ar *AppMeshv1beta2Router) reconcileVirtualRouter(canary *flaggerv1.Canary, name string, canaryWeight int64) error {
|
||||
apexName, _, _ := canary.GetServiceNames()
|
||||
canaryVirtualNode := fmt.Sprintf("%s-canary", apexName)
|
||||
primaryVirtualNode := fmt.Sprintf("%s-primary", apexName)
|
||||
protocol := ar.getProtocol(canary)
|
||||
|
||||
routerName := apexName
|
||||
if canaryWeight > 0 {
|
||||
routerName = fmt.Sprintf("%s-canary", apexName)
|
||||
}
|
||||
// App Mesh supports only URI prefix
|
||||
routePrefix := "/"
|
||||
if len(canary.Spec.Service.Match) > 0 &&
|
||||
canary.Spec.Service.Match[0].Uri != nil &&
|
||||
canary.Spec.Service.Match[0].Uri.Prefix != "" {
|
||||
routePrefix = canary.Spec.Service.Match[0].Uri.Prefix
|
||||
}
|
||||
|
||||
// Canary progressive traffic shift
|
||||
routes := []appmeshv1.Route{
|
||||
{
|
||||
Name: routerName,
|
||||
HTTPRoute: &appmeshv1.HTTPRoute{
|
||||
Match: appmeshv1.HTTPRouteMatch{
|
||||
Prefix: routePrefix,
|
||||
},
|
||||
RetryPolicy: ar.makeRetryPolicy(canary),
|
||||
Action: appmeshv1.HTTPRouteAction{
|
||||
WeightedTargets: []appmeshv1.WeightedTarget{
|
||||
{
|
||||
VirtualNodeRef: appmeshv1.VirtualNodeReference{
|
||||
Name: canaryVirtualNode,
|
||||
},
|
||||
Weight: canaryWeight,
|
||||
},
|
||||
{
|
||||
VirtualNodeRef: appmeshv1.VirtualNodeReference{
|
||||
Name: primaryVirtualNode,
|
||||
},
|
||||
Weight: 100 - canaryWeight,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// A/B testing - header based routing
|
||||
if len(canary.GetAnalysis().Match) > 0 && canaryWeight == 0 {
|
||||
routes = []appmeshv1.Route{
|
||||
{
|
||||
Name: fmt.Sprintf("%s-a", apexName),
|
||||
Priority: int64p(10),
|
||||
HTTPRoute: &appmeshv1.HTTPRoute{
|
||||
Match: appmeshv1.HTTPRouteMatch{
|
||||
Prefix: routePrefix,
|
||||
Headers: ar.makeHeaders(canary),
|
||||
},
|
||||
RetryPolicy: ar.makeRetryPolicy(canary),
|
||||
Action: appmeshv1.HTTPRouteAction{
|
||||
WeightedTargets: []appmeshv1.WeightedTarget{
|
||||
{
|
||||
VirtualNodeRef: appmeshv1.VirtualNodeReference{
|
||||
Name: canaryVirtualNode,
|
||||
},
|
||||
Weight: canaryWeight,
|
||||
},
|
||||
{
|
||||
VirtualNodeRef: appmeshv1.VirtualNodeReference{
|
||||
Name: primaryVirtualNode,
|
||||
},
|
||||
Weight: 100 - canaryWeight,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: fmt.Sprintf("%s-b", apexName),
|
||||
Priority: int64p(20),
|
||||
HTTPRoute: &appmeshv1.HTTPRoute{
|
||||
Match: appmeshv1.HTTPRouteMatch{
|
||||
Prefix: routePrefix,
|
||||
},
|
||||
RetryPolicy: ar.makeRetryPolicy(canary),
|
||||
Action: appmeshv1.HTTPRouteAction{
|
||||
WeightedTargets: []appmeshv1.WeightedTarget{
|
||||
{
|
||||
VirtualNodeRef: appmeshv1.VirtualNodeReference{
|
||||
Name: primaryVirtualNode,
|
||||
},
|
||||
Weight: 100,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
vrSpec := appmeshv1.VirtualRouterSpec{
|
||||
Listeners: []appmeshv1.VirtualRouterListener{
|
||||
{
|
||||
PortMapping: appmeshv1.PortMapping{
|
||||
Port: ar.getContainerPort(canary),
|
||||
Protocol: protocol,
|
||||
},
|
||||
},
|
||||
},
|
||||
Routes: routes,
|
||||
}
|
||||
|
||||
virtualRouter, err := ar.appmeshClient.AppmeshV1beta2().VirtualRouters(canary.Namespace).Get(context.TODO(), name, metav1.GetOptions{})
|
||||
|
||||
// create virtual router
|
||||
if errors.IsNotFound(err) {
|
||||
virtualRouter = &appmeshv1.VirtualRouter{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: canary.Namespace,
|
||||
OwnerReferences: []metav1.OwnerReference{
|
||||
*metav1.NewControllerRef(canary, schema.GroupVersionKind{
|
||||
Group: flaggerv1.SchemeGroupVersion.Group,
|
||||
Version: flaggerv1.SchemeGroupVersion.Version,
|
||||
Kind: flaggerv1.CanaryKind,
|
||||
}),
|
||||
},
|
||||
},
|
||||
Spec: vrSpec,
|
||||
}
|
||||
|
||||
_, err = ar.appmeshClient.AppmeshV1beta2().VirtualRouters(canary.Namespace).Create(context.TODO(), virtualRouter, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("VirtualRouter %s create error %w", name, err)
|
||||
}
|
||||
ar.logger.With("canary", fmt.Sprintf("%s.%s", canary.Name, canary.Namespace)).
|
||||
Infof("VirtualRouter %s created", virtualRouter.GetName())
|
||||
|
||||
virtualService := &appmeshv1.VirtualService{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: name,
|
||||
Namespace: canary.Namespace,
|
||||
OwnerReferences: []metav1.OwnerReference{
|
||||
*metav1.NewControllerRef(canary, schema.GroupVersionKind{
|
||||
Group: flaggerv1.SchemeGroupVersion.Group,
|
||||
Version: flaggerv1.SchemeGroupVersion.Version,
|
||||
Kind: flaggerv1.CanaryKind,
|
||||
}),
|
||||
},
|
||||
},
|
||||
Spec: appmeshv1.VirtualServiceSpec{
|
||||
Provider: &appmeshv1.VirtualServiceProvider{
|
||||
VirtualRouter: &appmeshv1.VirtualRouterServiceProvider{
|
||||
VirtualRouterRef: appmeshv1.VirtualRouterReference{
|
||||
Name: name,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// set App Mesh Gateway annotation on primary virtual service
|
||||
if canaryWeight == 0 {
|
||||
a := ar.gatewayAnnotations(canary)
|
||||
if len(a) > 0 {
|
||||
virtualService.ObjectMeta.Annotations = a
|
||||
}
|
||||
}
|
||||
|
||||
_, err = ar.appmeshClient.AppmeshV1beta2().VirtualServices(canary.Namespace).Create(context.TODO(), virtualService, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("VirtualService %s create error %w", name, err)
|
||||
}
|
||||
ar.logger.With("canary", fmt.Sprintf("%s.%s", canary.Name, canary.Namespace)).
|
||||
Infof("VirtualService %s created", virtualRouter.GetName())
|
||||
|
||||
return nil
|
||||
} else if err != nil {
|
||||
return fmt.Errorf("VirtualRouter %s get query error: %w", name, err)
|
||||
}
|
||||
|
||||
// update virtual router but keep the original target weights
|
||||
if virtualRouter != nil {
|
||||
if diff := cmp.Diff(vrSpec, virtualRouter.Spec,
|
||||
cmpopts.IgnoreFields(appmeshv1.VirtualRouterSpec{}, "AWSName", "MeshRef"),
|
||||
cmpopts.IgnoreTypes(appmeshv1.WeightedTarget{}, appmeshv1.MeshReference{})); diff != "" {
|
||||
vrClone := virtualRouter.DeepCopy()
|
||||
vrClone.Spec = vrSpec
|
||||
vrClone.Spec.Routes[0].HTTPRoute.Action = virtualRouter.Spec.Routes[0].HTTPRoute.Action
|
||||
vrClone.Spec.AWSName = virtualRouter.Spec.AWSName
|
||||
vrClone.Spec.MeshRef = virtualRouter.Spec.MeshRef
|
||||
_, err = ar.appmeshClient.AppmeshV1beta2().VirtualRouters(canary.Namespace).Update(context.TODO(), vrClone, metav1.UpdateOptions{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("VirtualRouter %s update error: %w", name, err)
|
||||
}
|
||||
ar.logger.With("canary", fmt.Sprintf("%s.%s", canary.Name, canary.Namespace)).
|
||||
Infof("VirtualRouter %s updated", virtualRouter.GetName())
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetRoutes returns the destinations weight for primary and canary
|
||||
func (ar *AppMeshv1beta2Router) GetRoutes(canary *flaggerv1.Canary) (
|
||||
primaryWeight int,
|
||||
canaryWeight int,
|
||||
mirrored bool,
|
||||
err error,
|
||||
) {
|
||||
apexName, primaryName, canaryName := canary.GetServiceNames()
|
||||
virtualRouter, err := ar.appmeshClient.AppmeshV1beta2().VirtualRouters(canary.Namespace).Get(context.TODO(), apexName, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
err = fmt.Errorf("VirtualRouter %s get query error: %w", apexName, err)
|
||||
return
|
||||
}
|
||||
|
||||
if len(virtualRouter.Spec.Routes) < 1 || len(virtualRouter.Spec.Routes[0].HTTPRoute.Action.WeightedTargets) != 2 {
|
||||
err = fmt.Errorf("VirtualRouter routes %s not found", apexName)
|
||||
return
|
||||
}
|
||||
|
||||
targets := virtualRouter.Spec.Routes[0].HTTPRoute.Action.WeightedTargets
|
||||
for _, t := range targets {
|
||||
if t.VirtualNodeRef.Name == canaryName {
|
||||
canaryWeight = int(t.Weight)
|
||||
}
|
||||
if t.VirtualNodeRef.Name == primaryName {
|
||||
primaryWeight = int(t.Weight)
|
||||
}
|
||||
}
|
||||
|
||||
if primaryWeight == 0 && canaryWeight == 0 {
|
||||
err = fmt.Errorf("VirtualRouter %s does not contain routes for %s-primary and %s-canary",
|
||||
apexName, apexName, apexName)
|
||||
}
|
||||
|
||||
mirrored = false
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// SetRoutes updates the destinations weight for primary and canary
|
||||
func (ar *AppMeshv1beta2Router) SetRoutes(
|
||||
canary *flaggerv1.Canary,
|
||||
primaryWeight int,
|
||||
canaryWeight int,
|
||||
_ bool,
|
||||
) error {
|
||||
apexName, primaryName, canaryName := canary.GetServiceNames()
|
||||
virtualRouter, err := ar.appmeshClient.AppmeshV1beta2().VirtualRouters(canary.Namespace).Get(context.TODO(), apexName, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("VirtualRouter %s get query error: %w", apexName, err)
|
||||
}
|
||||
|
||||
vrClone := virtualRouter.DeepCopy()
|
||||
vrClone.Spec.Routes[0].HTTPRoute.Action = appmeshv1.HTTPRouteAction{
|
||||
WeightedTargets: []appmeshv1.WeightedTarget{
|
||||
{
|
||||
VirtualNodeRef: appmeshv1.VirtualNodeReference{
|
||||
Name: canaryName,
|
||||
},
|
||||
Weight: int64(canaryWeight),
|
||||
},
|
||||
{
|
||||
VirtualNodeRef: appmeshv1.VirtualNodeReference{
|
||||
Name: primaryName,
|
||||
},
|
||||
Weight: int64(primaryWeight),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
_, err = ar.appmeshClient.AppmeshV1beta2().VirtualRouters(canary.Namespace).Update(context.TODO(), vrClone, metav1.UpdateOptions{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("VirtualRouter %s update error: %w", apexName, err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// makeRetryPolicy creates an AppMesh HTTPRetryPolicy from the Canary.Service.Retries
|
||||
// default: one retry on gateway error with a 250ms timeout
|
||||
func (ar *AppMeshv1beta2Router) makeRetryPolicy(canary *flaggerv1.Canary) *appmeshv1.HTTPRetryPolicy {
|
||||
if canary.Spec.Service.Retries != nil {
|
||||
timeout := int64(250)
|
||||
if d, err := time.ParseDuration(canary.Spec.Service.Retries.PerTryTimeout); err == nil {
|
||||
timeout = d.Milliseconds()
|
||||
}
|
||||
|
||||
attempts := 1
|
||||
if canary.Spec.Service.Retries.Attempts > 0 {
|
||||
attempts = canary.Spec.Service.Retries.Attempts
|
||||
}
|
||||
retryPolicy := &appmeshv1.HTTPRetryPolicy{
|
||||
PerRetryTimeout: appmeshv1.Duration{
|
||||
Unit: appmeshv1.DurationUnitMS,
|
||||
Value: timeout,
|
||||
},
|
||||
MaxRetries: int64(attempts),
|
||||
}
|
||||
|
||||
events := []string{"gateway-error"}
|
||||
if len(canary.Spec.Service.Retries.RetryOn) > 0 {
|
||||
events = strings.Split(canary.Spec.Service.Retries.RetryOn, ",")
|
||||
}
|
||||
for _, value := range events {
|
||||
retryPolicy.HTTPRetryEvents = append(retryPolicy.HTTPRetryEvents, appmeshv1.HTTPRetryPolicyEvent(value))
|
||||
}
|
||||
return retryPolicy
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// makeRetryPolicy creates an App Mesh HttpRouteHeader from the Canary.CanaryAnalysis.Match
|
||||
func (ar *AppMeshv1beta2Router) makeHeaders(canary *flaggerv1.Canary) []appmeshv1.HTTPRouteHeader {
|
||||
|
||||
var headers []appmeshv1.HTTPRouteHeader
|
||||
for _, m := range canary.GetAnalysis().Match {
|
||||
for key, value := range m.Headers {
|
||||
header := appmeshv1.HTTPRouteHeader{
|
||||
Name: key,
|
||||
Match: &appmeshv1.HeaderMatchMethod{
|
||||
Exact: stringp(value.Exact),
|
||||
Prefix: stringp(value.Prefix),
|
||||
Regex: stringp(value.Regex),
|
||||
Suffix: stringp(value.Suffix),
|
||||
},
|
||||
}
|
||||
headers = append(headers, header)
|
||||
}
|
||||
}
|
||||
|
||||
return headers
|
||||
}
|
||||
|
||||
func (ar *AppMeshv1beta2Router) getProtocol(canary *flaggerv1.Canary) appmeshv1.PortProtocol {
|
||||
if strings.Contains(canary.Spec.Service.PortName, "grpc") {
|
||||
return appmeshv1.PortProtocolGRPC
|
||||
}
|
||||
return appmeshv1.PortProtocolHTTP
|
||||
}
|
||||
|
||||
func (ar *AppMeshv1beta2Router) getContainerPort(canary *flaggerv1.Canary) appmeshv1.PortNumber {
|
||||
containerPort := canary.Spec.Service.Port
|
||||
if canary.Spec.Service.TargetPort.IntVal > 0 {
|
||||
containerPort = canary.Spec.Service.TargetPort.IntVal
|
||||
}
|
||||
return appmeshv1.PortNumber(containerPort)
|
||||
}
|
||||
|
||||
func (ar *AppMeshv1beta2Router) gatewayAnnotations(canary *flaggerv1.Canary) map[string]string {
|
||||
a := make(map[string]string)
|
||||
domains := ""
|
||||
for _, value := range canary.Spec.Service.Hosts {
|
||||
domains += value + ","
|
||||
}
|
||||
if domains != "" {
|
||||
a["gateway.appmesh.k8s.aws/expose"] = "true"
|
||||
a["gateway.appmesh.k8s.aws/domain"] = domains
|
||||
if canary.Spec.Service.Timeout != "" {
|
||||
a["gateway.appmesh.k8s.aws/timeout"] = canary.Spec.Service.Timeout
|
||||
}
|
||||
if canary.Spec.Service.Retries != nil && canary.Spec.Service.Retries.Attempts > 0 {
|
||||
a["gateway.appmesh.k8s.aws/retries"] = strconv.Itoa(canary.Spec.Service.Retries.Attempts)
|
||||
}
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
func (ar *AppMeshv1beta2Router) Finalize(_ *flaggerv1.Canary) error {
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,162 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
func TestAppmeshv1beta2Router_Reconcile(t *testing.T) {
|
||||
mocks := newFixture(nil)
|
||||
router := &AppMeshv1beta2Router{
|
||||
logger: mocks.logger,
|
||||
flaggerClient: mocks.flaggerClient,
|
||||
appmeshClient: mocks.meshClient,
|
||||
kubeClient: mocks.kubeClient,
|
||||
}
|
||||
|
||||
apexName, primaryName, canaryName := mocks.appmeshCanary.GetServiceNames()
|
||||
err := router.Reconcile(mocks.appmeshCanary)
|
||||
require.NoError(t, err)
|
||||
|
||||
// check apex virtual service
|
||||
_, err = router.appmeshClient.AppmeshV1beta2().VirtualServices("default").Get(context.TODO(), apexName, metav1.GetOptions{})
|
||||
require.NoError(t, err)
|
||||
|
||||
// check canary virtual service
|
||||
_, err = router.appmeshClient.AppmeshV1beta2().VirtualServices("default").Get(context.TODO(), canaryName, metav1.GetOptions{})
|
||||
require.NoError(t, err)
|
||||
|
||||
// check apex virtual router
|
||||
vrApex, err := router.appmeshClient.AppmeshV1beta2().VirtualRouters("default").Get(context.TODO(), apexName, metav1.GetOptions{})
|
||||
require.NoError(t, err)
|
||||
assert.Len(t, vrApex.Spec.Routes[0].HTTPRoute.Action.WeightedTargets, 2)
|
||||
|
||||
// check canary virtual router
|
||||
vrCanary, err := router.appmeshClient.AppmeshV1beta2().VirtualRouters("default").Get(context.TODO(), canaryName, metav1.GetOptions{})
|
||||
require.NoError(t, err)
|
||||
|
||||
// check if the canary virtual service routes all traffic to the canary virtual node
|
||||
target := vrCanary.Spec.Routes[0].HTTPRoute.Action.WeightedTargets[0]
|
||||
assert.Equal(t, canaryName, target.VirtualNodeRef.Name)
|
||||
assert.Equal(t, int64(100), target.Weight)
|
||||
|
||||
// check primary virtual node
|
||||
vnPrimary, err := router.appmeshClient.AppmeshV1beta2().VirtualNodes("default").Get(context.TODO(), primaryName, metav1.GetOptions{})
|
||||
require.NoError(t, err)
|
||||
|
||||
primaryDNS := fmt.Sprintf("%s.%s.svc.cluster.local.", primaryName, mocks.appmeshCanary.Namespace)
|
||||
assert.Equal(t, primaryDNS, vnPrimary.Spec.ServiceDiscovery.DNS.Hostname)
|
||||
|
||||
// test backends update
|
||||
cd, err := mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Get(context.TODO(), mocks.appmeshCanary.Name, metav1.GetOptions{})
|
||||
require.NoError(t, err)
|
||||
|
||||
cdClone := cd.DeepCopy()
|
||||
backends := cdClone.Spec.Service.Backends
|
||||
backends = append(backends, "test.example.com")
|
||||
cdClone.Spec.Service.Backends = backends
|
||||
canary, err := mocks.flaggerClient.FlaggerV1beta1().Canaries("default").Update(context.TODO(), cdClone, metav1.UpdateOptions{})
|
||||
require.NoError(t, err)
|
||||
|
||||
// apply change
|
||||
err = router.Reconcile(canary)
|
||||
require.NoError(t, err)
|
||||
|
||||
// verify
|
||||
vnPrimary, err = router.appmeshClient.AppmeshV1beta2().VirtualNodes("default").Get(context.TODO(), primaryName, metav1.GetOptions{})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, vnPrimary.Spec.Backends, 2)
|
||||
|
||||
// update URI
|
||||
vrClone := vrApex.DeepCopy()
|
||||
vrClone.Spec.Routes[0].HTTPRoute.Match.Prefix = "api"
|
||||
vrApex, err = mocks.meshClient.AppmeshV1beta2().VirtualRouters("default").Update(context.TODO(), vrClone, metav1.UpdateOptions{})
|
||||
require.NoError(t, err)
|
||||
|
||||
// undo URI change
|
||||
err = router.Reconcile(canary)
|
||||
require.NoError(t, err)
|
||||
vrApex, err = router.appmeshClient.AppmeshV1beta2().VirtualRouters("default").Get(context.TODO(), apexName, metav1.GetOptions{})
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "/", vrApex.Spec.Routes[0].HTTPRoute.Match.Prefix)
|
||||
}
|
||||
|
||||
func TestAppmeshv1beta2Router_GetSetRoutes(t *testing.T) {
|
||||
mocks := newFixture(nil)
|
||||
router := &AppMeshv1beta2Router{
|
||||
logger: mocks.logger,
|
||||
flaggerClient: mocks.flaggerClient,
|
||||
appmeshClient: mocks.meshClient,
|
||||
kubeClient: mocks.kubeClient,
|
||||
}
|
||||
|
||||
err := router.Reconcile(mocks.appmeshCanary)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = router.SetRoutes(mocks.appmeshCanary, 60, 40, false)
|
||||
require.NoError(t, err)
|
||||
|
||||
p, c, m, err := router.GetRoutes(mocks.appmeshCanary)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 60, p)
|
||||
assert.Equal(t, 40, c)
|
||||
assert.False(t, m)
|
||||
}
|
||||
|
||||
func TestAppmesv1beta2hRouter_ABTest(t *testing.T) {
|
||||
mocks := newFixture(nil)
|
||||
router := &AppMeshv1beta2Router{
|
||||
logger: mocks.logger,
|
||||
flaggerClient: mocks.flaggerClient,
|
||||
appmeshClient: mocks.meshClient,
|
||||
kubeClient: mocks.kubeClient,
|
||||
}
|
||||
|
||||
apexName, _, _ := mocks.abtest.GetServiceNames()
|
||||
err := router.Reconcile(mocks.abtest)
|
||||
require.NoError(t, err)
|
||||
|
||||
vrApex, err := router.appmeshClient.AppmeshV1beta2().VirtualRouters("default").Get(context.TODO(), apexName, metav1.GetOptions{})
|
||||
require.NoError(t, err)
|
||||
|
||||
// check routes
|
||||
assert.Len(t, vrApex.Spec.Routes, 2)
|
||||
|
||||
// check headers
|
||||
assert.GreaterOrEqual(t, len(vrApex.Spec.Routes[0].HTTPRoute.Match.Headers), 1, "Got no http match headers")
|
||||
assert.Equal(t, "x-user-type", vrApex.Spec.Routes[0].HTTPRoute.Match.Headers[0].Name)
|
||||
assert.Equal(t, "test", *vrApex.Spec.Routes[0].HTTPRoute.Match.Headers[0].Match.Exact)
|
||||
}
|
||||
|
||||
func TestAppmeshv1beta2Router_Gateway(t *testing.T) {
|
||||
mocks := newFixture(nil)
|
||||
router := &AppMeshv1beta2Router{
|
||||
logger: mocks.logger,
|
||||
flaggerClient: mocks.flaggerClient,
|
||||
appmeshClient: mocks.meshClient,
|
||||
kubeClient: mocks.kubeClient,
|
||||
}
|
||||
|
||||
apexName, _, _ := mocks.appmeshCanary.GetServiceNames()
|
||||
err := router.Reconcile(mocks.appmeshCanary)
|
||||
require.NoError(t, err)
|
||||
|
||||
vs, err := router.appmeshClient.AppmeshV1beta2().VirtualServices("default").Get(context.TODO(), apexName, metav1.GetOptions{})
|
||||
require.NoError(t, err)
|
||||
|
||||
// check Flagger's gateway annotations
|
||||
assert.Equal(t, "true", vs.Annotations["gateway.appmesh.k8s.aws/expose"])
|
||||
assert.True(t, strings.Contains(vs.Annotations["gateway.appmesh.k8s.aws/domain"], mocks.appmeshCanary.Spec.Service.Hosts[0]))
|
||||
assert.Equal(t, mocks.appmeshCanary.Spec.Service.Timeout, vs.Annotations["gateway.appmesh.k8s.aws/timeout"])
|
||||
|
||||
retries := vs.Annotations["gateway.appmesh.k8s.aws/retries"]
|
||||
assert.Equal(t, strconv.Itoa(mocks.appmeshCanary.Spec.Service.Retries.Attempts), retries)
|
||||
}
|
||||
+39
-47
@@ -7,6 +7,7 @@ import (
|
||||
"k8s.io/client-go/kubernetes"
|
||||
restclient "k8s.io/client-go/rest"
|
||||
|
||||
flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1beta1"
|
||||
clientset "github.com/weaveworks/flagger/pkg/client/clientset/versioned"
|
||||
)
|
||||
|
||||
@@ -51,27 +52,40 @@ func (factory *Factory) KubernetesRouter(kind string, labelSelector string, port
|
||||
}
|
||||
|
||||
// MeshRouter returns a service mesh router
|
||||
func (factory *Factory) MeshRouter(provider string) Interface {
|
||||
func (factory *Factory) MeshRouter(provider string, labelSelector string) Interface {
|
||||
switch {
|
||||
case provider == "none":
|
||||
return &NopRouter{}
|
||||
case provider == "kubernetes":
|
||||
return &NopRouter{}
|
||||
case provider == "nginx":
|
||||
return &IngressRouter{
|
||||
logger: factory.logger,
|
||||
kubeClient: factory.kubeClient,
|
||||
annotationsPrefix: factory.ingressAnnotationsPrefix,
|
||||
case strings.HasPrefix(provider, flaggerv1.AppMeshProvider+":v1beta2"):
|
||||
return &AppMeshv1beta2Router{
|
||||
logger: factory.logger,
|
||||
flaggerClient: factory.flaggerClient,
|
||||
kubeClient: factory.kubeClient,
|
||||
appmeshClient: factory.meshClient,
|
||||
labelSelector: labelSelector,
|
||||
}
|
||||
case provider == "appmesh":
|
||||
case provider == flaggerv1.AppMeshProvider:
|
||||
return &AppMeshRouter{
|
||||
logger: factory.logger,
|
||||
flaggerClient: factory.flaggerClient,
|
||||
kubeClient: factory.kubeClient,
|
||||
appmeshClient: factory.meshClient,
|
||||
}
|
||||
case strings.HasPrefix(provider, "smi:"):
|
||||
mesh := strings.TrimPrefix(provider, "smi:")
|
||||
case provider == flaggerv1.LinkerdProvider:
|
||||
return &SmiRouter{
|
||||
logger: factory.logger,
|
||||
flaggerClient: factory.flaggerClient,
|
||||
kubeClient: factory.kubeClient,
|
||||
smiClient: factory.meshClient,
|
||||
targetMesh: flaggerv1.LinkerdProvider,
|
||||
}
|
||||
case provider == flaggerv1.IstioProvider:
|
||||
return &IstioRouter{
|
||||
logger: factory.logger,
|
||||
flaggerClient: factory.flaggerClient,
|
||||
kubeClient: factory.kubeClient,
|
||||
istioClient: factory.meshClient,
|
||||
}
|
||||
case strings.HasPrefix(provider, flaggerv1.SMIProvider):
|
||||
mesh := strings.TrimPrefix(provider, flaggerv1.SMIProvider+":")
|
||||
return &SmiRouter{
|
||||
logger: factory.logger,
|
||||
flaggerClient: factory.flaggerClient,
|
||||
@@ -79,25 +93,17 @@ func (factory *Factory) MeshRouter(provider string) Interface {
|
||||
smiClient: factory.meshClient,
|
||||
targetMesh: mesh,
|
||||
}
|
||||
case provider == "linkerd":
|
||||
return &SmiRouter{
|
||||
logger: factory.logger,
|
||||
flaggerClient: factory.flaggerClient,
|
||||
kubeClient: factory.kubeClient,
|
||||
smiClient: factory.meshClient,
|
||||
targetMesh: "linkerd",
|
||||
}
|
||||
case provider == "contour":
|
||||
case provider == flaggerv1.ContourProvider:
|
||||
return &ContourRouter{
|
||||
logger: factory.logger,
|
||||
flaggerClient: factory.flaggerClient,
|
||||
kubeClient: factory.kubeClient,
|
||||
contourClient: factory.meshClient,
|
||||
}
|
||||
case strings.HasPrefix(provider, "gloo"):
|
||||
upstreamDiscoveryNs := "gloo-system"
|
||||
if strings.HasPrefix(provider, "gloo:") {
|
||||
upstreamDiscoveryNs = strings.TrimPrefix(provider, "gloo:")
|
||||
case strings.HasPrefix(provider, flaggerv1.GlooProvider):
|
||||
upstreamDiscoveryNs := flaggerv1.GlooProvider + "-system"
|
||||
if strings.HasPrefix(provider, flaggerv1.GlooProvider+":") {
|
||||
upstreamDiscoveryNs = strings.TrimPrefix(provider, flaggerv1.GlooProvider+":")
|
||||
}
|
||||
return &GlooRouter{
|
||||
logger: factory.logger,
|
||||
@@ -106,28 +112,14 @@ func (factory *Factory) MeshRouter(provider string) Interface {
|
||||
glooClient: factory.meshClient,
|
||||
upstreamDiscoveryNs: upstreamDiscoveryNs,
|
||||
}
|
||||
case strings.HasPrefix(provider, "supergloo:appmesh"):
|
||||
return &AppMeshRouter{
|
||||
logger: factory.logger,
|
||||
flaggerClient: factory.flaggerClient,
|
||||
kubeClient: factory.kubeClient,
|
||||
appmeshClient: factory.meshClient,
|
||||
}
|
||||
case strings.HasPrefix(provider, "supergloo:istio"):
|
||||
return &IstioRouter{
|
||||
logger: factory.logger,
|
||||
flaggerClient: factory.flaggerClient,
|
||||
kubeClient: factory.kubeClient,
|
||||
istioClient: factory.meshClient,
|
||||
}
|
||||
case strings.HasPrefix(provider, "supergloo:linkerd"):
|
||||
return &SmiRouter{
|
||||
logger: factory.logger,
|
||||
flaggerClient: factory.flaggerClient,
|
||||
kubeClient: factory.kubeClient,
|
||||
smiClient: factory.meshClient,
|
||||
targetMesh: "linkerd",
|
||||
case provider == flaggerv1.NGINXProvider:
|
||||
return &IngressRouter{
|
||||
logger: factory.logger,
|
||||
kubeClient: factory.kubeClient,
|
||||
annotationsPrefix: factory.ingressAnnotationsPrefix,
|
||||
}
|
||||
case provider == flaggerv1.KubernetesProvider:
|
||||
return &NopRouter{}
|
||||
default:
|
||||
return &IstioRouter{
|
||||
logger: factory.logger,
|
||||
|
||||
@@ -181,7 +181,6 @@ func (c *KubernetesDefaultRouter) reconcileService(canary *flaggerv1.Canary, nam
|
||||
|
||||
portsDiff := cmp.Diff(svcSpec.Ports, svc.Spec.Ports, cmpopts.SortSlices(sortPorts))
|
||||
selectorsDiff := cmp.Diff(svcSpec.Selector, svc.Spec.Selector)
|
||||
|
||||
if portsDiff != "" || selectorsDiff != "" {
|
||||
svcClone.Spec.Ports = svcSpec.Ports
|
||||
svcClone.Spec.Selector = svcSpec.Selector
|
||||
@@ -191,11 +190,14 @@ func (c *KubernetesDefaultRouter) reconcileService(canary *flaggerv1.Canary, nam
|
||||
|
||||
// update annotations and labels only if the service has been created by Flagger
|
||||
if _, owned := c.isOwnedByCanary(svc, canary.Name); owned {
|
||||
if cmp.Diff(metadata.Annotations, svc.ObjectMeta.Annotations) != "" {
|
||||
if svc.ObjectMeta.Annotations == nil {
|
||||
svc.ObjectMeta.Annotations = make(map[string]string)
|
||||
}
|
||||
if diff := cmp.Diff(metadata.Annotations, svc.ObjectMeta.Annotations); diff != "" {
|
||||
svcClone.ObjectMeta.Annotations = metadata.Annotations
|
||||
updateService = true
|
||||
}
|
||||
if cmp.Diff(metadata.Labels, svc.ObjectMeta.Labels) != "" {
|
||||
if diff := cmp.Diff(metadata.Labels, svc.ObjectMeta.Labels); diff != "" {
|
||||
svcClone.ObjectMeta.Labels = metadata.Labels
|
||||
updateService = true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user