Add NTH queue-processor mode

This commit is contained in:
Jason Haugen 2021-03-09 10:00:55 -06:00
parent bcf92d1fa5
commit d07b067249
42 changed files with 37637 additions and 580 deletions

View File

@ -3916,6 +3916,10 @@ spec:
handler drain nodes when spot interruption termination notice
is received. Default: true'
type: boolean
enableSqsTerminationDraining:
description: EnableSqsTerminationDraining enables queue-processor
mode which drains nodes when an SQS termination event is received.
type: boolean
enabled:
description: 'Enabled enables the node termination handler. Default:
true'

View File

@ -161,7 +161,7 @@ type ClusterSpec struct {
ExternalDNS *ExternalDNSConfig `json:"externalDns,omitempty"`
NTP *NTPConfig `json:"ntp,omitempty"`
// NodeTerminationHandler determines the cluster autoscaler configuration.
// NodeTerminationHandler determines the node termination handler configuration.
NodeTerminationHandler *NodeTerminationHandlerConfig `json:"nodeTerminationHandler,omitempty"`
// MetricsServer determines the metrics server configuration.
MetricsServer *MetricsServerConfig `json:"metricsServer,omitempty"`

View File

@ -854,6 +854,9 @@ type NodeTerminationHandlerConfig struct {
// EnablePrometheusMetrics enables the "/metrics" endpoint.
EnablePrometheusMetrics *bool `json:"prometheusEnable,omitempty"`
// EnableSqsTerminationDraining enables queue-processor mode which drains nodes when an SQS termination event is received.
EnableSqsTerminationDraining *bool `json:"enableSqsTerminationDraining,omitempty"`
}
// ClusterAutoscalerConfig determines the cluster autoscaler configuration.

View File

@ -853,6 +853,9 @@ type NodeTerminationHandlerConfig struct {
// EnablePrometheusMetrics enables the "/metrics" endpoint.
EnablePrometheusMetrics *bool `json:"prometheusEnable,omitempty"`
// EnableSqsTerminationDraining enables queue-processor mode which drains nodes when an SQS termination event is received.
EnableSqsTerminationDraining *bool `json:"enableSqsTerminationDraining,omitempty"`
}
// ClusterAutoscalerConfig determines the cluster autoscaler configuration.

View File

@ -5733,6 +5733,7 @@ func autoConvert_v1alpha2_NodeTerminationHandlerConfig_To_kops_NodeTerminationHa
out.EnableSpotInterruptionDraining = in.EnableSpotInterruptionDraining
out.EnableScheduledEventDraining = in.EnableScheduledEventDraining
out.EnablePrometheusMetrics = in.EnablePrometheusMetrics
out.EnableSqsTerminationDraining = in.EnableSqsTerminationDraining
return nil
}
@ -5746,6 +5747,7 @@ func autoConvert_kops_NodeTerminationHandlerConfig_To_v1alpha2_NodeTerminationHa
out.EnableSpotInterruptionDraining = in.EnableSpotInterruptionDraining
out.EnableScheduledEventDraining = in.EnableScheduledEventDraining
out.EnablePrometheusMetrics = in.EnablePrometheusMetrics
out.EnableSqsTerminationDraining = in.EnableSqsTerminationDraining
return nil
}

View File

@ -3889,6 +3889,11 @@ func (in *NodeTerminationHandlerConfig) DeepCopyInto(out *NodeTerminationHandler
*out = new(bool)
**out = **in
}
if in.EnableSqsTerminationDraining != nil {
in, out := &in.EnableSqsTerminationDraining, &out.EnableSqsTerminationDraining
*out = new(bool)
**out = **in
}
return
}

View File

@ -4087,6 +4087,11 @@ func (in *NodeTerminationHandlerConfig) DeepCopyInto(out *NodeTerminationHandler
*out = new(bool)
**out = **in
}
if in.EnableSqsTerminationDraining != nil {
in, out := &in.EnableSqsTerminationDraining, &out.EnableSqsTerminationDraining
*out = new(bool)
**out = **in
}
return
}

View File

@ -0,0 +1,176 @@
/*
Copyright 2019 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package awsmodel
import (
"strings"
"k8s.io/kops/pkg/model"
"k8s.io/kops/upup/pkg/fi/cloudup/awstasks"
"github.com/aws/aws-sdk-go/aws"
"k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/upup/pkg/fi"
)
const (
NTHTemplate = `{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"Service": ["events.amazonaws.com", "sqs.amazonaws.com"]
},
"Action": "sqs:SendMessage",
"Resource": [
"arn:aws:sqs:{{ AWS_REGION }}:{{ ACCOUNT_ID }}:{{ SQS_QUEUE_NAME }}"
]
}]
}`
DefaultMessageRetentionPeriod = 300
)
type event struct {
name string
pattern string
}
var (
_ fi.ModelBuilder = &NodeTerminationHandlerBuilder{}
events = []event{
{
name: "ASGLifecycle",
pattern: `{"source":["aws.autoscaling"],"detail-type":["EC2 Instance-terminate Lifecycle Action"]}`,
},
{
name: "SpotInterruption",
pattern: `{"source": ["aws.ec2"],"detail-type": ["EC2 Spot Instance Interruption Warning"]}`,
},
{
name: "RebalanceRecommendation",
pattern: `{"source": ["aws.ec2"],"detail-type": ["EC2 Instance Rebalance Recommendation"]}`,
},
}
)
type NodeTerminationHandlerBuilder struct {
*AWSModelContext
Lifecycle *fi.Lifecycle
}
func (b *NodeTerminationHandlerBuilder) Build(c *fi.ModelBuilderContext) error {
for _, ig := range b.InstanceGroups {
err := b.configureASG(c, ig)
if err != nil {
return err
}
}
err := b.buildSQSQueue(c)
if err != nil {
return err
}
err = b.buildEventBridgeRules(c)
if err != nil {
return err
}
return nil
}
func (b *NodeTerminationHandlerBuilder) configureASG(c *fi.ModelBuilderContext, ig *kops.InstanceGroup) error {
name := ig.Name + "-NTHLifecycleHook"
tags := b.CloudTags(name, false)
tags["aws-node-termination-handler/managed"] = ""
lifecyleTask := &awstasks.AutoscalingLifecycleHook{
ID: aws.String(name),
Name: aws.String(name),
Lifecycle: b.Lifecycle,
AutoscalingGroup: b.LinkToAutoscalingGroup(ig),
DefaultResult: aws.String("CONTINUE"),
HeartbeatTimeout: aws.Int64(DefaultMessageRetentionPeriod),
LifecycleTransition: aws.String("autoscaling:EC2_INSTANCE_TERMINATING"),
Tags: tags,
}
c.AddTask(lifecyleTask)
return nil
}
func (b *NodeTerminationHandlerBuilder) buildSQSQueue(c *fi.ModelBuilderContext) error {
queueName := model.QueueNamePrefix(b.ClusterName()) + "-nth"
policy := strings.ReplaceAll(NTHTemplate, "{{ AWS_REGION }}", b.Region)
policy = strings.ReplaceAll(policy, "{{ ACCOUNT_ID }}", b.AWSAccountID)
policy = strings.ReplaceAll(policy, "{{ SQS_QUEUE_NAME }}", queueName)
task := &awstasks.SQS{
Name: aws.String(queueName),
Lifecycle: b.Lifecycle,
Policy: fi.NewStringResource(policy),
MessageRetentionPeriod: DefaultMessageRetentionPeriod,
Tags: b.CloudTags(queueName, false),
}
c.AddTask(task)
return nil
}
func (b *NodeTerminationHandlerBuilder) buildEventBridgeRules(c *fi.ModelBuilderContext) error {
clusterName := b.ClusterName()
queueName := model.QueueNamePrefix(clusterName) + "-nth"
region := b.Region
accountID := b.AWSAccountID
targetArn := "arn:aws:sqs:" + region + ":" + accountID + ":" + queueName
for _, event := range events {
// build rule
ruleName := aws.String(clusterName + "-" + event.name)
ruleTask := &awstasks.EventBridgeRule{
Name: ruleName,
Lifecycle: b.Lifecycle,
Tags: b.CloudTags(*ruleName, false),
EventPattern: &event.pattern,
TargetArn: &targetArn,
}
c.AddTask(ruleTask)
// build target
targetTask := &awstasks.EventBridgeTarget{
Name: aws.String(*ruleName + "-Target"),
Lifecycle: b.Lifecycle,
Rule: ruleTask,
TargetArn: &targetArn,
}
c.AddTask(targetTask)
}
return nil
}

View File

@ -45,6 +45,10 @@ func (b *NodeTerminationHandlerOptionsBuilder) BuildOptions(o interface{}) error
nth.EnableScheduledEventDraining = fi.Bool(false)
}
if nth.EnableSqsTerminationDraining == nil {
nth.EnableSqsTerminationDraining = fi.Bool(false)
}
if nth.EnablePrometheusMetrics == nil {
nth.EnablePrometheusMetrics = fi.Bool(false)
}

View File

@ -143,6 +143,12 @@ func (m *KopsModelContext) CloudTagsForInstanceGroup(ig *kops.InstanceGroup) (ma
labels[k] = v
}
// Apply NTH Labels
nth := m.Cluster.Spec.NodeTerminationHandler
if nth != nil && fi.BoolValue(nth.Enabled) && fi.BoolValue(nth.EnableSqsTerminationDraining) {
labels["aws-node-termination-handler/managed"] = "true"
}
// Apply labels for cluster autoscaler node labels
for k, v := range nodelabels.BuildNodeLabels(m.Cluster, ig) {
labels[nodeidentityaws.ClusterAutoscalerNodeTemplateLabel+k] = v

View File

@ -377,6 +377,11 @@ func (r *NodeRoleNode) BuildAWSPolicy(b *PolicyBuilder) (*Policy, error) {
addCalicoSrcDstCheckPermissions(p)
}
nth := b.Cluster.Spec.NodeTerminationHandler
if nth != nil && fi.BoolValue(nth.Enabled) && fi.BoolValue(nth.EnableSqsTerminationDraining) {
addNodeTerminationHandlerSQSPermissions(p, resource)
}
return p, nil
}
@ -1143,6 +1148,23 @@ func addAmazonVPCCNIPermissions(p *Policy, resource stringorslice.StringOrSlice,
)
}
func addNodeTerminationHandlerSQSPermissions(p *Policy, resource stringorslice.StringOrSlice) {
p.Statement = append(p.Statement,
&Statement{
Effect: StatementEffectAllow,
Action: stringorslice.Slice([]string{
"autoscaling:CompleteLifecycleAction",
"autoscaling:DescribeAutoScalingInstances",
"autoscaling:DescribeTags",
"ec2:DescribeInstances",
"sqs:DeleteMessage",
"sqs:ReceiveMessage",
}),
Resource: resource,
},
)
}
func createResource(b *PolicyBuilder) stringorslice.StringOrSlice {
var resource stringorslice.StringOrSlice
if b.ResourceARN != nil {

View File

@ -265,3 +265,9 @@ func (b *KopsModelContext) LinkToPrivateRouteTableInZone(zoneName string) *awsta
func (b *KopsModelContext) InstanceName(ig *kops.InstanceGroup, suffix string) string {
return b.AutoscalingGroupName(ig) + suffix
}
func QueueNamePrefix(clusterName string) string {
// periods aren't allowed in queue name
queueName := strings.Replace(clusterName, ".", "-", -1)
return queueName + "-sqs-queue"
}

View File

@ -83,6 +83,11 @@ func ListResourcesAWS(cloud awsup.AWSCloud, clusterName string) (map[string]*res
ListIAMInstanceProfiles,
ListIAMRoles,
ListIAMOIDCProviders,
// SQS
ListSQSQueues,
// EventBridge
ListEventBridgeRules,
}
if featureflag.Spotinst.Enabled() {

View File

@ -0,0 +1,112 @@
/*
Copyright 2019 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package aws
import (
"fmt"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/eventbridge"
"k8s.io/klog/v2"
"k8s.io/kops/pkg/resources"
"k8s.io/kops/upup/pkg/fi"
"k8s.io/kops/upup/pkg/fi/cloudup/awsup"
)
func DumpEventBridgeRule(op *resources.DumpOperation, r *resources.Resource) error {
data := make(map[string]interface{})
data["id"] = r.ID
data["name"] = r.Name
data["type"] = r.Type
data["raw"] = r.Obj
op.Dump.Resources = append(op.Dump.Resources, data)
return nil
}
func DeleteEventBridgeRule(cloud fi.Cloud, r *resources.Resource) error {
c := cloud.(awsup.AWSCloud)
targets, err := c.EventBridge().ListTargetsByRule(&eventbridge.ListTargetsByRuleInput{
Rule: aws.String(r.Name),
})
if err != nil {
return fmt.Errorf("error listing targets for EventBridge Rule %q: %v", r.Name, err)
}
var ids []*string
for _, target := range targets.Targets {
ids = append(ids, target.Id)
}
klog.V(2).Infof("Removing EventBridge Targets for Rule %q", r.Name)
_, err = c.EventBridge().RemoveTargets(&eventbridge.RemoveTargetsInput{
Ids: ids,
Rule: aws.String(r.Name),
})
if err != nil {
return fmt.Errorf("error removing targets for EventBridge Rule %q: %v", r.Name, err)
}
klog.V(2).Infof("Deleting EventBridge Rule %q", r.Name)
request := &eventbridge.DeleteRuleInput{
Name: aws.String(r.Name),
}
_, err = c.EventBridge().DeleteRule(request)
if err != nil {
return fmt.Errorf("error deleting EventBridge Rule %q: %v", r.Name, err)
}
return nil
}
func ListEventBridgeRules(cloud fi.Cloud, clusterName string) ([]*resources.Resource, error) {
c := cloud.(awsup.AWSCloud)
klog.V(2).Infof("Listing EventBridge Rules")
// Rule names start with the cluster name so that we can search for them
request := &eventbridge.ListRulesInput{
EventBusName: nil,
Limit: nil,
NamePrefix: aws.String(clusterName),
}
response, err := c.EventBridge().ListRules(request)
if err != nil {
return nil, fmt.Errorf("error listing SQS queues: %v", err)
}
if response == nil || len(response.Rules) == 0 {
return nil, nil
}
var resourceTrackers []*resources.Resource
for _, rule := range response.Rules {
resourceTracker := &resources.Resource{
Name: *rule.Name,
ID: *rule.Name,
Type: "eventbridge",
Deleter: DeleteEventBridgeRule,
Dumper: DumpEventBridgeRule,
Obj: rule,
}
resourceTrackers = append(resourceTrackers, resourceTracker)
}
return resourceTrackers, nil
}

91
pkg/resources/aws/sqs.go Normal file
View File

@ -0,0 +1,91 @@
/*
Copyright 2019 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package aws
import (
"fmt"
"github.com/aws/aws-sdk-go/service/sqs"
"k8s.io/klog/v2"
"k8s.io/kops/pkg/model"
"k8s.io/kops/pkg/resources"
"k8s.io/kops/upup/pkg/fi"
"k8s.io/kops/upup/pkg/fi/cloudup/awsup"
)
func DumpSQSQueue(op *resources.DumpOperation, r *resources.Resource) error {
data := make(map[string]interface{})
data["id"] = r.ID
data["name"] = r.Name
data["type"] = r.Type
data["raw"] = r.Obj
op.Dump.Resources = append(op.Dump.Resources, data)
return nil
}
func DeleteSQSQueue(cloud fi.Cloud, r *resources.Resource) error {
c := cloud.(awsup.AWSCloud)
url := r.ID
klog.V(2).Infof("Deleting SQS queue %q", url)
request := &sqs.DeleteQueueInput{
QueueUrl: &url,
}
_, err := c.SQS().DeleteQueue(request)
if err != nil {
return fmt.Errorf("error deleting SQS queue %q: %v", url, err)
}
return nil
}
func ListSQSQueues(cloud fi.Cloud, clusterName string) ([]*resources.Resource, error) {
c := cloud.(awsup.AWSCloud)
klog.V(2).Infof("Listing SQS queues")
queueName := model.QueueNamePrefix(clusterName)
request := &sqs.ListQueuesInput{
QueueNamePrefix: &queueName,
}
response, err := c.SQS().ListQueues(request)
if err != nil {
return nil, fmt.Errorf("error listing SQS queues: %v", err)
}
if response == nil || len(response.QueueUrls) == 0 {
return nil, nil
}
var resourceTrackers []*resources.Resource
for _, queue := range response.QueueUrls {
resourceTracker := &resources.Resource{
Name: queueName,
ID: *queue,
Type: "sqs",
Deleter: DeleteSQSQueue,
Dumper: DumpSQSQueue,
Obj: queue,
}
resourceTrackers = append(resourceTrackers, resourceTracker)
}
return resourceTrackers, nil
}

View File

@ -0,0 +1,278 @@
{{ with .NodeTerminationHandler }}
# Sourced from https://github.com/aws/aws-node-termination-handler/releases/download/v1.12.1/all-resources-queue-processor.yaml
---
# Source: aws-node-termination-handler/templates/psp.yaml
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
name: aws-node-termination-handler
labels:
app.kubernetes.io/name: aws-node-termination-handler
app.kubernetes.io/instance: aws-node-termination-handler
k8s-app: aws-node-termination-handler
app.kubernetes.io/version: "1.12.1"
annotations:
seccomp.security.alpha.kubernetes.io/allowedProfileNames: '*'
spec:
privileged: false
hostIPC: false
hostNetwork: true
hostPID: false
readOnlyRootFilesystem: false
allowPrivilegeEscalation: false
allowedCapabilities:
- '*'
fsGroup:
rule: RunAsAny
runAsUser:
rule: RunAsAny
seLinux:
rule: RunAsAny
supplementalGroups:
rule: RunAsAny
volumes:
- '*'
---
# Source: aws-node-termination-handler/templates/serviceaccount.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: aws-node-termination-handler
namespace: kube-system
labels:
app.kubernetes.io/name: aws-node-termination-handler
app.kubernetes.io/instance: aws-node-termination-handler
k8s-app: aws-node-termination-handler
app.kubernetes.io/version: "1.12.1"
---
# Source: aws-node-termination-handler/templates/clusterrole.yaml
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: aws-node-termination-handler
rules:
- apiGroups:
- ""
resources:
- nodes
verbs:
- get
- list
- patch
- update
- apiGroups:
- ""
resources:
- pods
verbs:
- list
- apiGroups:
- ""
resources:
- pods/eviction
verbs:
- create
- apiGroups:
- extensions
resources:
- daemonsets
verbs:
- get
- apiGroups:
- apps
resources:
- daemonsets
verbs:
- get
---
# Source: aws-node-termination-handler/templates/psp.yaml
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: aws-node-termination-handler-psp
labels:
app.kubernetes.io/name: aws-node-termination-handler
app.kubernetes.io/instance: aws-node-termination-handler
k8s-app: aws-node-termination-handler
app.kubernetes.io/version: "1.12.1"
rules:
- apiGroups: ['policy']
resources: ['podsecuritypolicies']
verbs: ['use']
resourceNames:
- aws-node-termination-handler
---
# Source: aws-node-termination-handler/templates/clusterrolebinding.yaml
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: aws-node-termination-handler
subjects:
- kind: ServiceAccount
name: aws-node-termination-handler
namespace: kube-system
roleRef:
kind: ClusterRole
name: aws-node-termination-handler
apiGroup: rbac.authorization.k8s.io
---
# Source: aws-node-termination-handler/templates/psp.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: aws-node-termination-handler-psp
labels:
app.kubernetes.io/name: aws-node-termination-handler
app.kubernetes.io/instance: aws-node-termination-handler
k8s-app: aws-node-termination-handler
app.kubernetes.io/version: "1.12.1"
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: aws-node-termination-handler-psp
subjects:
- kind: ServiceAccount
name: aws-node-termination-handler
namespace: kube-system
---
# Source: aws-node-termination-handler/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: aws-node-termination-handler
namespace: kube-system
labels:
app.kubernetes.io/name: aws-node-termination-handler
app.kubernetes.io/instance: aws-node-termination-handler
k8s-app: aws-node-termination-handler
app.kubernetes.io/version: "1.12.1"
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: aws-node-termination-handler
app.kubernetes.io/instance: aws-node-termination-handler
kubernetes.io/os: linux
template:
metadata:
annotations:
labels:
app.kubernetes.io/name: aws-node-termination-handler
app.kubernetes.io/instance: aws-node-termination-handler
k8s-app: aws-node-termination-handler
kubernetes.io/os: linux
spec:
priorityClassName: "system-node-critical"
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: "kubernetes.io/os"
operator: In
values:
- linux
- key: "kubernetes.io/arch"
operator: In
values:
- amd64
- arm64
- arm
serviceAccountName: aws-node-termination-handler
hostNetwork: false
dnsPolicy: ""
securityContext:
fsGroup: 1000
containers:
- name: aws-node-termination-handler
image: public.ecr.aws/aws-ec2/aws-node-termination-handler:v1.12.1
imagePullPolicy: IfNotPresent
securityContext:
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
allowPrivilegeEscalation: false
env:
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: SPOT_POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: DELETE_LOCAL_DATA
value: ""
- name: IGNORE_DAEMON_SETS
value: ""
- name: POD_TERMINATION_GRACE_PERIOD
value: ""
- name: INSTANCE_METADATA_URL
value: ""
- name: NODE_TERMINATION_GRACE_PERIOD
value: ""
- name: WEBHOOK_URL
value: ""
- name: WEBHOOK_HEADERS
value: ""
- name: WEBHOOK_TEMPLATE
value: ""
- name: DRY_RUN
value: "false"
- name: METADATA_TRIES
value: "3"
- name: CORDON_ONLY
value: "false"
- name: TAINT_NODE
value: "false"
- name: JSON_LOGGING
value: "false"
- name: LOG_LEVEL
value: "info"
- name: WEBHOOK_PROXY
value: ""
- name: ENABLE_PROMETHEUS_SERVER
value: "false"
- name: ENABLE_SPOT_INTERRUPTION_DRAINING
value: "false"
- name: ENABLE_SCHEDULED_EVENT_DRAINING
value: "false"
- name: ENABLE_REBALANCE_MONITORING
value: "false"
- name: ENABLE_SQS_TERMINATION_DRAINING
value: "true"
- name: QUEUE_URL
value: ""
- name: PROMETHEUS_SERVER_PORT
value: "9092"
- name: AWS_REGION
value: ""
- name: AWS_ENDPOINT
value: ""
- name: CHECK_ASG_TAG_BEFORE_DRAINING
value: "true"
- name: MANAGED_ASG_TAG
value: "aws-node-termination-handler/managed"
- name: WORKERS
value: "10"
resources:
limits:
cpu: 100m
memory: 128Mi
requests:
cpu: 50m
memory: 64Mi
nodeSelector:
kubernetes.io/os: linux
tolerations:
- operator: Exists
{{ end }}

View File

@ -580,6 +580,14 @@ func (c *ApplyClusterCmd) Run(ctx context.Context) error {
l.Builders = append(l.Builders, awsModelBuilder)
}
nth := c.Cluster.Spec.NodeTerminationHandler
if nth != nil && fi.BoolValue(nth.Enabled) && fi.BoolValue(nth.EnableSqsTerminationDraining) {
l.Builders = append(l.Builders, &awsmodel.NodeTerminationHandlerBuilder{
AWSModelContext: awsModelContext,
Lifecycle: &clusterLifecycle,
})
}
case kops.CloudProviderDO:
doModelContext := &domodel.DOModelContext{
KopsModelContext: modelContext,
@ -649,6 +657,7 @@ func (c *ApplyClusterCmd) Run(ctx context.Context) error {
return fmt.Errorf("unknown cloudprovider %q", cluster.Spec.CloudProvider)
}
}
taskMap, err := l.BuildTasks(assetBuilder, &stageAssetsLifecycle, c.LifecycleOverrides)
if err != nil {
return fmt.Errorf("error building tasks: %v", err)

View File

@ -5,6 +5,8 @@ go_library(
srcs = [
"autoscalinggroup.go",
"autoscalinggroup_fitask.go",
"autoscalinggroup_lifecyclehook.go",
"autoscalinggroup_lifecyclehook_fitask.go",
"block_device_mappings.go",
"classic_load_balancer.go",
"classic_loadbalancer_attributes.go",
@ -22,6 +24,10 @@ go_library(
"ebsvolume_fitask.go",
"elastic_ip.go",
"elasticip_fitask.go",
"eventbridgerule.go",
"eventbridgerule_fitask.go",
"eventbridgetarget.go",
"eventbridgetarget_fitask.go",
"helper.go",
"iaminstanceprofile.go",
"iaminstanceprofile_fitask.go",
@ -59,6 +65,8 @@ go_library(
"securitygroup_fitask.go",
"securitygrouprule.go",
"securitygrouprule_fitask.go",
"sqs.go",
"sqs_fitask.go",
"sshkey.go",
"sshkey_fitask.go",
"subnet.go",

View File

@ -0,0 +1,153 @@
/*
Copyright 2019 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package awstasks
import (
"fmt"
"github.com/aws/aws-sdk-go/service/autoscaling"
"k8s.io/apimachinery/pkg/util/validation/field"
"k8s.io/kops/upup/pkg/fi"
"k8s.io/kops/upup/pkg/fi/cloudup/awsup"
"k8s.io/kops/upup/pkg/fi/cloudup/cloudformation"
"k8s.io/kops/upup/pkg/fi/cloudup/terraform"
)
// +kops:fitask
type AutoscalingLifecycleHook struct {
ID *string
Name *string
Lifecycle *fi.Lifecycle
AutoscalingGroup *AutoscalingGroup
DefaultResult *string
HeartbeatTimeout *int64
LifecycleTransition *string
Tags map[string]string
}
var _ fi.CompareWithID = &AutoscalingLifecycleHook{}
func (h *AutoscalingLifecycleHook) CompareWithID() *string {
return h.Name
}
func (h *AutoscalingLifecycleHook) Find(c *fi.Context) (*AutoscalingLifecycleHook, error) {
cloud := c.Cloud.(awsup.AWSCloud)
request := &autoscaling.DescribeLifecycleHooksInput{
AutoScalingGroupName: h.AutoscalingGroup.Name,
LifecycleHookNames: []*string{h.Name},
}
response, err := cloud.Autoscaling().DescribeLifecycleHooks(request)
if err != nil {
return nil, fmt.Errorf("error listing ASG Lifecycle Hooks: %v", err)
}
if response == nil || len(response.LifecycleHooks) == 0 {
return nil, nil
}
if len(response.LifecycleHooks) > 1 {
return nil, fmt.Errorf("found multiple ASG Lifecycle Hooks with the same name")
}
hook := response.LifecycleHooks[0]
actual := &AutoscalingLifecycleHook{
ID: hook.AutoScalingGroupName,
Name: h.Name,
Lifecycle: h.Lifecycle,
AutoscalingGroup: h.AutoscalingGroup,
}
return actual, nil
}
func (h *AutoscalingLifecycleHook) Run(c *fi.Context) error {
return fi.DefaultDeltaRunMethod(h, c)
}
func (_ *AutoscalingLifecycleHook) CheckChanges(a, e, changes *AutoscalingLifecycleHook) error {
if a == nil {
if e.Name == nil {
return field.Required(field.NewPath("Name"), "")
}
if e.AutoscalingGroup == nil {
return field.Required(field.NewPath("AutoScalingGroupName"), "")
}
}
return nil
}
func (h *AutoscalingLifecycleHook) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *AutoscalingLifecycleHook) error {
if a == nil {
request := &autoscaling.PutLifecycleHookInput{
AutoScalingGroupName: e.AutoscalingGroup.Name,
DefaultResult: h.DefaultResult,
HeartbeatTimeout: h.HeartbeatTimeout,
LifecycleHookName: e.Name,
LifecycleTransition: h.LifecycleTransition,
}
_, err := t.Cloud.Autoscaling().PutLifecycleHook(request)
if err != nil {
return err
}
}
return nil
}
type terraformASGLifecycleHook struct {
Name *string `json:"name" cty:"name"`
AutoScalingGroupName *terraform.Literal `json:"autoscaling_group_name" cty:"autoscaling_group_name"`
DefaultResult *string `json:"default_result" cty:"default_result"`
HeartbeatTimeout *int64 `json:"heartbeat_timeout" cty:"heartbeat_timeout"`
LifecycleTransition *string `json:"lifecycle_transition" cty:"lifecycle_transition"`
}
func (_ *AutoscalingLifecycleHook) RenderTerraform(t *terraform.TerraformTarget, a, e, changes *AutoscalingLifecycleHook) error {
tf := &terraformASGLifecycleHook{
Name: e.Name,
AutoScalingGroupName: e.AutoscalingGroup.TerraformLink(),
DefaultResult: e.DefaultResult,
HeartbeatTimeout: e.HeartbeatTimeout,
LifecycleTransition: e.LifecycleTransition,
}
return t.RenderResource("aws_autoscaling_lifecycle_hook", *e.Name, tf)
}
type cloudformationASGLifecycleHook struct {
LifecycleHookName *string
AutoScalingGroupName *cloudformation.Literal
DefaultResult *string
HeartbeatTimeout *int64
LifecycleTransition *string
}
func (_ *AutoscalingLifecycleHook) RenderCloudformation(t *cloudformation.CloudformationTarget, a, e, changes *AutoscalingLifecycleHook) error {
tf := &cloudformationASGLifecycleHook{
LifecycleHookName: e.Name,
AutoScalingGroupName: e.AutoscalingGroup.CloudformationLink(),
DefaultResult: e.DefaultResult,
HeartbeatTimeout: e.HeartbeatTimeout,
LifecycleTransition: e.LifecycleTransition,
}
return t.RenderResource("AWS::AutoScaling::LifecycleHook", *e.Name, tf)
}

View File

@ -0,0 +1,51 @@
// +build !ignore_autogenerated
/*
Copyright The Kubernetes 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 fitask. DO NOT EDIT.
package awstasks
import (
"k8s.io/kops/upup/pkg/fi"
)
// AutoscalingLifecycleHook
var _ fi.HasLifecycle = &AutoscalingLifecycleHook{}
// GetLifecycle returns the Lifecycle of the object, implementing fi.HasLifecycle
func (o *AutoscalingLifecycleHook) GetLifecycle() *fi.Lifecycle {
return o.Lifecycle
}
// SetLifecycle sets the Lifecycle of the object, implementing fi.SetLifecycle
func (o *AutoscalingLifecycleHook) SetLifecycle(lifecycle fi.Lifecycle) {
o.Lifecycle = &lifecycle
}
var _ fi.HasName = &AutoscalingLifecycleHook{}
// GetName returns the Name of the object, implementing fi.HasName
func (o *AutoscalingLifecycleHook) GetName() *string {
return o.Name
}
// String is the stringer function for the task, producing readable output using fi.TaskAsString
func (o *AutoscalingLifecycleHook) String() string {
return fi.TaskAsString(o)
}

View File

@ -0,0 +1,169 @@
/*
Copyright 2019 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package awstasks
import (
"fmt"
"k8s.io/apimachinery/pkg/util/validation/field"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/eventbridge"
"k8s.io/kops/upup/pkg/fi"
"k8s.io/kops/upup/pkg/fi/cloudup/awsup"
"k8s.io/kops/upup/pkg/fi/cloudup/cloudformation"
"k8s.io/kops/upup/pkg/fi/cloudup/terraform"
)
// +kops:fitask
type EventBridgeRule struct {
ID *string
Name *string
Lifecycle *fi.Lifecycle
EventPattern *string
TargetArn *string
Tags map[string]string
}
var _ fi.CompareWithID = &EventBridgeRule{}
func (eb *EventBridgeRule) CompareWithID() *string {
return eb.Name
}
func (eb *EventBridgeRule) Find(c *fi.Context) (*EventBridgeRule, error) {
cloud := c.Cloud.(awsup.AWSCloud)
if eb.Name == nil {
return nil, nil
}
request := &eventbridge.ListRulesInput{
NamePrefix: eb.Name,
}
response, err := cloud.EventBridge().ListRules(request)
if err != nil {
return nil, fmt.Errorf("error listing EventBridge rules: %v", err)
}
if response == nil || len(response.Rules) == 0 {
return nil, nil
}
if len(response.Rules) > 1 {
return nil, fmt.Errorf("found multiple EventBridge rules with the same name")
}
rule := response.Rules[0]
actual := &EventBridgeRule{
ID: eb.ID,
Name: eb.Name,
Lifecycle: eb.Lifecycle,
EventPattern: rule.EventPattern,
}
return actual, nil
}
func (eb *EventBridgeRule) Run(c *fi.Context) error {
return fi.DefaultDeltaRunMethod(eb, c)
}
func (_ *EventBridgeRule) CheckChanges(a, e, changes *EventBridgeRule) error {
if a == nil {
if e.Name == nil {
return field.Required(field.NewPath("Name"), "")
}
}
return nil
}
func (eb *EventBridgeRule) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *EventBridgeRule) error {
if a == nil {
var tags []*eventbridge.Tag
for k, v := range eb.Tags {
tags = append(tags, &eventbridge.Tag{
Key: aws.String(k),
Value: aws.String(v),
})
}
request := &eventbridge.PutRuleInput{
Name: eb.Name,
EventPattern: e.EventPattern,
Tags: tags,
}
_, err := t.Cloud.EventBridge().PutRule(request)
if err != nil {
return fmt.Errorf("error creating EventBridge rule: %v", err)
}
}
return nil
}
type terraformEventBridgeRule struct {
Name *string `json:"name" cty:"name"`
EventPattern *terraform.Literal `json:"event_pattern" cty:"event_pattern"`
Tags map[string]string `json:"tags,omitempty" cty:"tags"`
}
func (_ *EventBridgeRule) RenderTerraform(t *terraform.TerraformTarget, a, e, changes *EventBridgeRule) error {
m, err := t.AddFile("aws_cloudwatch_event_rule", *e.Name, "event_pattern", fi.NewStringResource(*e.EventPattern), false)
if err != nil {
return err
}
tf := &terraformEventBridgeRule{
Name: e.Name,
EventPattern: m,
Tags: e.Tags,
}
return t.RenderResource("aws_cloudwatch_event_rule", *e.Name, tf)
}
func (eb *EventBridgeRule) TerraformLink() *terraform.Literal {
return terraform.LiteralProperty("aws_cloudwatch_event_rule", fi.StringValue(eb.Name), "id")
}
type cloudformationTarget struct {
Id *string
Arn *string
}
type cloudformationEventBridgeRule struct {
Name *string `json:"Name"`
EventPattern *string `json:"EventPattern"`
Targets []cloudformationTarget `json:"Targets"`
}
func (_ *EventBridgeRule) RenderCloudformation(t *cloudformation.CloudformationTarget, a, e, changes *EventBridgeRule) error {
target := &cloudformationTarget{
Id: s("1"),
Arn: e.TargetArn,
}
cf := &cloudformationEventBridgeRule{
Name: e.Name,
EventPattern: e.EventPattern,
Targets: []cloudformationTarget{*target},
}
return t.RenderResource("AWS::Events::Rule", *e.Name, cf)
}

View File

@ -0,0 +1,51 @@
// +build !ignore_autogenerated
/*
Copyright The Kubernetes 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 fitask. DO NOT EDIT.
package awstasks
import (
"k8s.io/kops/upup/pkg/fi"
)
// EventBridgeRule
var _ fi.HasLifecycle = &EventBridgeRule{}
// GetLifecycle returns the Lifecycle of the object, implementing fi.HasLifecycle
func (o *EventBridgeRule) GetLifecycle() *fi.Lifecycle {
return o.Lifecycle
}
// SetLifecycle sets the Lifecycle of the object, implementing fi.SetLifecycle
func (o *EventBridgeRule) SetLifecycle(lifecycle fi.Lifecycle) {
o.Lifecycle = &lifecycle
}
var _ fi.HasName = &EventBridgeRule{}
// GetName returns the Name of the object, implementing fi.HasName
func (o *EventBridgeRule) GetName() *string {
return o.Name
}
// String is the stringer function for the task, producing readable output using fi.TaskAsString
func (o *EventBridgeRule) String() string {
return fi.TaskAsString(o)
}

View File

@ -0,0 +1,146 @@
/*
Copyright 2019 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package awstasks
import (
"fmt"
"k8s.io/apimachinery/pkg/util/validation/field"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/eventbridge"
"k8s.io/kops/upup/pkg/fi"
"k8s.io/kops/upup/pkg/fi/cloudup/awsup"
"k8s.io/kops/upup/pkg/fi/cloudup/cloudformation"
"k8s.io/kops/upup/pkg/fi/cloudup/terraform"
)
// +kops:fitask
type EventBridgeTarget struct {
ID *string
Name *string
Lifecycle *fi.Lifecycle
Rule *EventBridgeRule
TargetArn *string
}
var _ fi.CompareWithID = &EventBridgeTarget{}
func (eb *EventBridgeTarget) CompareWithID() *string {
return eb.Name
}
func (eb *EventBridgeTarget) Find(c *fi.Context) (*EventBridgeTarget, error) {
cloud := c.Cloud.(awsup.AWSCloud)
if eb.Rule == nil || eb.TargetArn == nil {
return nil, nil
}
// find the rule the target is attached to
rule, err := eb.Rule.Find(c)
if err != nil {
return nil, err
}
if rule == nil {
return nil, nil
}
request := &eventbridge.ListTargetsByRuleInput{
Rule: eb.Rule.Name,
}
response, err := cloud.EventBridge().ListTargetsByRule(request)
if err != nil {
return nil, fmt.Errorf("error listing EventBridge targets: %v", err)
}
if response == nil || len(response.Targets) == 0 {
return nil, nil
}
for _, target := range response.Targets {
if *target.Arn == *eb.TargetArn {
actual := &EventBridgeTarget{
ID: target.Id,
Name: eb.Name,
Lifecycle: eb.Lifecycle,
Rule: eb.Rule,
TargetArn: eb.TargetArn,
}
return actual, nil
}
}
return nil, nil
}
func (eb *EventBridgeTarget) Run(c *fi.Context) error {
return fi.DefaultDeltaRunMethod(eb, c)
}
func (_ *EventBridgeTarget) CheckChanges(a, e, changes *EventBridgeTarget) error {
if a == nil {
if e.Rule == nil {
return field.Required(field.NewPath("Rule"), "")
}
if e.TargetArn == nil {
return field.Required(field.NewPath("TargetArn"), "")
}
}
return nil
}
func (eb *EventBridgeTarget) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *EventBridgeTarget) error {
if a == nil {
target := &eventbridge.Target{
Arn: eb.TargetArn,
Id: aws.String("1"),
}
request := &eventbridge.PutTargetsInput{
Rule: eb.Rule.Name,
Targets: []*eventbridge.Target{target},
}
_, err := t.Cloud.EventBridge().PutTargets(request)
if err != nil {
return fmt.Errorf("error creating EventBridge target: %v", err)
}
}
return nil
}
type terraformEventBridgeTarget struct {
RuleName *terraform.Literal `json:"rule" cty:"rule"`
TargetArn *string `json:"arn" cty:"arn"`
}
func (_ *EventBridgeTarget) RenderTerraform(t *terraform.TerraformTarget, a, e, changes *EventBridgeTarget) error {
tf := &terraformEventBridgeTarget{
RuleName: e.Rule.TerraformLink(),
TargetArn: e.TargetArn,
}
return t.RenderResource("aws_cloudwatch_event_target", *e.Name, tf)
}
func (_ *EventBridgeTarget) RenderCloudformation(t *cloudformation.CloudformationTarget, a, e, changes *EventBridgeTarget) error {
// There is no Cloudformation EventBridge Target resource. Instead it's included in Cloudformation's EventBridge Rule resource
return nil
}

View File

@ -0,0 +1,51 @@
// +build !ignore_autogenerated
/*
Copyright The Kubernetes 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 fitask. DO NOT EDIT.
package awstasks
import (
"k8s.io/kops/upup/pkg/fi"
)
// EventBridgeTarget
var _ fi.HasLifecycle = &EventBridgeTarget{}
// GetLifecycle returns the Lifecycle of the object, implementing fi.HasLifecycle
func (o *EventBridgeTarget) GetLifecycle() *fi.Lifecycle {
return o.Lifecycle
}
// SetLifecycle sets the Lifecycle of the object, implementing fi.SetLifecycle
func (o *EventBridgeTarget) SetLifecycle(lifecycle fi.Lifecycle) {
o.Lifecycle = &lifecycle
}
var _ fi.HasName = &EventBridgeTarget{}
// GetName returns the Name of the object, implementing fi.HasName
func (o *EventBridgeTarget) GetName() *string {
return o.Name
}
// String is the stringer function for the task, producing readable output using fi.TaskAsString
func (o *EventBridgeTarget) String() string {
return fi.TaskAsString(o)
}

View File

@ -0,0 +1,230 @@
/*
Copyright 2019 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package awstasks
import (
"encoding/json"
"fmt"
"strconv"
"k8s.io/apimachinery/pkg/util/validation/field"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/sqs"
"k8s.io/kops/upup/pkg/fi"
"k8s.io/kops/upup/pkg/fi/cloudup/awsup"
"k8s.io/kops/upup/pkg/fi/cloudup/cloudformation"
"k8s.io/kops/upup/pkg/fi/cloudup/terraform"
)
// +kops:fitask
type SQS struct {
Name *string
Lifecycle *fi.Lifecycle
URL *string
MessageRetentionPeriod int
Policy fi.Resource // "inline" IAM policy
Tags map[string]string
}
var _ fi.CompareWithID = &SQS{}
func (q *SQS) CompareWithID() *string {
return q.URL
}
func (q *SQS) Find(c *fi.Context) (*SQS, error) {
cloud := c.Cloud.(awsup.AWSCloud)
if q.Name == nil {
return nil, nil
}
request := &sqs.ListQueuesInput{
MaxResults: aws.Int64(2),
QueueNamePrefix: q.Name,
}
response, err := cloud.SQS().ListQueues(request)
if err != nil {
return nil, fmt.Errorf("error listing SQS queues: %v", err)
}
if response == nil || len(response.QueueUrls) == 0 {
return nil, nil
}
if len(response.QueueUrls) != 1 {
return nil, fmt.Errorf("found multiple SQS queues matching queue name")
}
tags, err := cloud.SQS().ListQueueTags(&sqs.ListQueueTagsInput{
QueueUrl: q.URL,
})
actual := &SQS{
Name: q.Name,
URL: response.QueueUrls[0],
Tags: intersectSQSTags(tags.Tags, q.Tags),
Lifecycle: q.Lifecycle,
Policy: q.Policy,
}
return actual, nil
}
func (q *SQS) Run(c *fi.Context) error {
return fi.DefaultDeltaRunMethod(q, c)
}
func (q *SQS) CheckChanges(a, e, changes *SQS) error {
if a == nil {
if e.Name == nil {
return field.Required(field.NewPath("Name"), "")
}
}
if a != nil {
if changes.URL != nil {
return fi.CannotChangeField("URL")
}
}
return nil
}
func (q *SQS) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *SQS) error {
policy, err := fi.ResourceAsString(e.Policy)
if err != nil {
return fmt.Errorf("error rendering RolePolicyDocument: %v", err)
}
if a == nil {
request := &sqs.CreateQueueInput{
Attributes: map[string]*string{
"MessageRetentionPeriod": s(strconv.Itoa(q.MessageRetentionPeriod)),
"Policy": s(policy),
},
QueueName: q.Name,
Tags: convertTagsToPointers(q.Tags),
}
response, err := t.Cloud.SQS().CreateQueue(request)
if err != nil {
return fmt.Errorf("error creating SQS queue: %v", err)
}
q.URL = response.QueueUrl
}
return nil
}
type terraformSqsQueue struct {
Name *string `json:"name" cty:"name"`
MessageRetentionSeconds int `json:"message_retention_seconds" cty:"message_retention_seconds"`
Policy *terraform.Literal `json:"policy" cty:"policy"`
Tags map[string]string `json:"tags" cty:"tags"`
}
func (_ *SQS) RenderTerraform(t *terraform.TerraformTarget, a, e, changes *SQS) error {
p, err := t.AddFile("aws_sqs_queue", *e.Name, "policy", e.Policy, false)
if err != nil {
return err
}
tf := &terraformSqsQueue{
Name: e.Name,
MessageRetentionSeconds: e.MessageRetentionPeriod,
Policy: p,
Tags: e.Tags,
}
return t.RenderResource("aws_sqs_queue", *e.Name, tf)
}
type cloudformationSQSQueue struct {
QueueName *string `json:"QueueName"`
MessageRetentionPeriod int `json:"MessageRetentionPeriod"`
Tags []cloudformationTag `json:"Tags,omitempty"`
}
type cloudformationSQSQueuePolicy struct {
Queues []*cloudformation.Literal `json:"Queues"`
PolicyDocument map[string]interface{} `json:"PolicyDocument"`
Tags []cloudformationTag `json:"Tags,omitempty"`
}
func (_ *SQS) RenderCloudformation(t *cloudformation.CloudformationTarget, a, e, changes *SQS) error {
cfQueue := &cloudformationSQSQueue{
QueueName: e.Name,
MessageRetentionPeriod: e.MessageRetentionPeriod,
Tags: buildCloudformationTags(e.Tags),
}
err := t.RenderResource("AWS::SQS::Queue", *e.Name, cfQueue)
if err != nil {
return err
}
// convert Policy string into json
jsonString, err := fi.ResourceAsBytes(e.Policy)
if err != nil {
return err
}
data := make(map[string]interface{})
err = json.Unmarshal(jsonString, &data)
if err != nil {
return fmt.Errorf("error parsing SQS PolicyDocument: %v", err)
}
cfQueueRef := cloudformation.Ref("AWS::SQS::Queue", fi.StringValue(e.Name))
cfQueuePolicy := &cloudformationSQSQueuePolicy{
Queues: []*cloudformation.Literal{cfQueueRef},
PolicyDocument: data,
}
return t.RenderResource("AWS::SQS::QueuePolicy", *e.Name+"Policy", cfQueuePolicy)
}
// change tags to format required by CreateQueue
func convertTagsToPointers(tags map[string]string) map[string]*string {
newTags := map[string]*string{}
for k, v := range tags {
vv := v
newTags[k] = &vv
}
return newTags
}
// intersectSQSTags does the same thing as intersectTags, but takes different input because SQS tags are listed differently
func intersectSQSTags(tags map[string]*string, desired map[string]string) map[string]string {
if tags == nil {
return nil
}
actual := make(map[string]string)
for k, v := range tags {
vv := aws.StringValue(v)
if _, found := desired[k]; found {
actual[k] = vv
}
}
if len(actual) == 0 && desired == nil {
// Avoid problems with comparison between nil & {}
return nil
}
return actual
}

View File

@ -0,0 +1,51 @@
// +build !ignore_autogenerated
/*
Copyright The Kubernetes 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 fitask. DO NOT EDIT.
package awstasks
import (
"k8s.io/kops/upup/pkg/fi"
)
// SQS
var _ fi.HasLifecycle = &SQS{}
// GetLifecycle returns the Lifecycle of the object, implementing fi.HasLifecycle
func (o *SQS) GetLifecycle() *fi.Lifecycle {
return o.Lifecycle
}
// SetLifecycle sets the Lifecycle of the object, implementing fi.SetLifecycle
func (o *SQS) SetLifecycle(lifecycle fi.Lifecycle) {
o.Lifecycle = &lifecycle
}
var _ fi.HasName = &SQS{}
// GetName returns the Name of the object, implementing fi.HasName
func (o *SQS) GetName() *string {
return o.Name
}
// String is the stringer function for the task, producing readable output using fi.TaskAsString
func (o *SQS) String() string {
return fi.TaskAsString(o)
}

View File

@ -23,6 +23,11 @@ import (
"sync"
"time"
"github.com/aws/aws-sdk-go/service/eventbridge"
"github.com/aws/aws-sdk-go/service/eventbridge/eventbridgeiface"
"github.com/aws/aws-sdk-go/service/sqs"
"github.com/aws/aws-sdk-go/service/sqs/sqsiface"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/arn"
"github.com/aws/aws-sdk-go/aws/awserr"
@ -114,6 +119,9 @@ type AWSCloud interface {
Route53() route53iface.Route53API
Spotinst() spotinst.Cloud
SQS() sqsiface.SQSAPI
EventBridge() eventbridgeiface.EventBridgeAPI
// TODO: Document and rationalize these tags/filters methods
AddTags(name *string, tags map[string]string)
BuildFilters(name *string) []*ec2.Filter
@ -181,6 +189,8 @@ type awsCloudImplementation struct {
route53 *route53.Route53
spotinst spotinst.Cloud
sts *sts.STS
sqs *sqs.SQS
eventbridge *eventbridge.EventBridge
region string
@ -314,6 +324,22 @@ func NewAWSCloud(region string, tags map[string]string) (AWSCloud, error) {
}
}
sess, err = session.NewSession(config)
if err != nil {
return c, err
}
c.sqs = sqs.New(sess, config)
c.sqs.Handlers.Send.PushFront(requestLogger)
c.addHandlers(region, &c.sqs.Handlers)
sess, err = session.NewSession(config)
if err != nil {
return c, err
}
c.eventbridge = eventbridge.New(sess, config)
c.eventbridge.Handlers.Send.PushFront(requestLogger)
c.addHandlers(region, &c.eventbridge.Handlers)
awsCloudInstances[region] = c
raw = c
}
@ -1608,6 +1634,14 @@ func (c *awsCloudImplementation) Spotinst() spotinst.Cloud {
return c.spotinst
}
func (c *awsCloudImplementation) SQS() sqsiface.SQSAPI {
return c.sqs
}
func (c *awsCloudImplementation) EventBridge() eventbridgeiface.EventBridgeAPI {
return c.eventbridge
}
func (c *awsCloudImplementation) FindVPCInfo(vpcID string) (*fi.VPCInfo, error) {
return findVPCInfo(c, vpcID)
}

View File

@ -19,6 +19,9 @@ package awsup
import (
"fmt"
"github.com/aws/aws-sdk-go/service/eventbridge/eventbridgeiface"
"github.com/aws/aws-sdk-go/service/sqs/sqsiface"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/autoscaling/autoscalingiface"
"github.com/aws/aws-sdk-go/service/cloudformation"
@ -80,6 +83,8 @@ type MockCloud struct {
MockELB elbiface.ELBAPI
MockELBV2 elbv2iface.ELBV2API
MockSpotinst spotinst.Cloud
MockSQS sqsiface.SQSAPI
MockEventBridge eventbridgeiface.EventBridgeAPI
}
func (c *MockAWSCloud) DeleteGroup(g *cloudinstances.CloudInstanceGroup) error {
@ -261,6 +266,20 @@ func (c *MockAWSCloud) Spotinst() spotinst.Cloud {
return c.MockSpotinst
}
func (c *MockAWSCloud) SQS() sqsiface.SQSAPI {
if c.MockSQS == nil {
klog.Fatalf("MockSQS not set")
}
return c.MockSQS
}
func (c *MockAWSCloud) EventBridge() eventbridgeiface.EventBridgeAPI {
if c.MockEventBridge == nil {
klog.Fatalf("MockSQS not set")
}
return c.MockEventBridge
}
func (c *MockAWSCloud) FindVPCInfo(id string) (*fi.VPCInfo, error) {
return findVPCInfo(c, id)
}

View File

@ -546,6 +546,9 @@ func (b *BootstrapChannelBuilder) buildAddons(c *fi.ModelBuilderContext) (*chann
{
location := key + "/k8s-1.11.yaml"
if fi.BoolValue(nth.EnableSqsTerminationDraining) {
location = key + "/queue-processor-k8s-1.11.yaml"
}
id := "k8s-1.11"
addons.Spec.Addons = append(addons.Spec.Addons, &channelsapi.AddonSpec{

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,46 @@
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
// Package eventbridge provides the client and types for making API
// requests to Amazon EventBridge.
//
// Amazon EventBridge helps you to respond to state changes in your AWS resources.
// When your resources change state, they automatically send events into an
// event stream. You can create rules that match selected events in the stream
// and route them to targets to take action. You can also use rules to take
// action on a predetermined schedule. For example, you can configure rules
// to:
//
// * Automatically invoke an AWS Lambda function to update DNS entries when
// an event notifies you that Amazon EC2 instance enters the running state.
//
// * Direct specific API records from AWS CloudTrail to an Amazon Kinesis
// data stream for detailed analysis of potential security or availability
// risks.
//
// * Periodically invoke a built-in target to create a snapshot of an Amazon
// EBS volume.
//
// For more information about the features of Amazon EventBridge, see the Amazon
// EventBridge User Guide (https://docs.aws.amazon.com/eventbridge/latest/userguide).
//
// See https://docs.aws.amazon.com/goto/WebAPI/eventbridge-2015-10-07 for more information on this service.
//
// See eventbridge package documentation for more information.
// https://docs.aws.amazon.com/sdk-for-go/api/service/eventbridge/
//
// Using the Client
//
// To contact Amazon EventBridge with the SDK use the New function to create
// a new service client. With that client you can make API requests to the service.
// These clients are safe to use concurrently.
//
// See the SDK's documentation for more information on how to use the SDK.
// https://docs.aws.amazon.com/sdk-for-go/api/
//
// See aws.Config documentation for more information on configuring SDK clients.
// https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config
//
// See the Amazon EventBridge client EventBridge for more
// information on creating client for this service.
// https://docs.aws.amazon.com/sdk-for-go/api/service/eventbridge/#New
package eventbridge

View File

@ -0,0 +1,97 @@
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
package eventbridge
import (
"github.com/aws/aws-sdk-go/private/protocol"
)
const (
// ErrCodeConcurrentModificationException for service response error code
// "ConcurrentModificationException".
//
// There is concurrent modification on a rule, target, archive, or replay.
ErrCodeConcurrentModificationException = "ConcurrentModificationException"
// ErrCodeIllegalStatusException for service response error code
// "IllegalStatusException".
//
// An error occurred because a replay can be canceled only when the state is
// Running or Starting.
ErrCodeIllegalStatusException = "IllegalStatusException"
// ErrCodeInternalException for service response error code
// "InternalException".
//
// This exception occurs due to unexpected causes.
ErrCodeInternalException = "InternalException"
// ErrCodeInvalidEventPatternException for service response error code
// "InvalidEventPatternException".
//
// The event pattern is not valid.
ErrCodeInvalidEventPatternException = "InvalidEventPatternException"
// ErrCodeInvalidStateException for service response error code
// "InvalidStateException".
//
// The specified state is not a valid state for an event source.
ErrCodeInvalidStateException = "InvalidStateException"
// ErrCodeLimitExceededException for service response error code
// "LimitExceededException".
//
// The request failed because it attempted to create resource beyond the allowed
// service quota.
ErrCodeLimitExceededException = "LimitExceededException"
// ErrCodeManagedRuleException for service response error code
// "ManagedRuleException".
//
// This rule was created by an AWS service on behalf of your account. It is
// managed by that service. If you see this error in response to DeleteRule
// or RemoveTargets, you can use the Force parameter in those calls to delete
// the rule or remove targets from the rule. You cannot modify these managed
// rules by using DisableRule, EnableRule, PutTargets, PutRule, TagResource,
// or UntagResource.
ErrCodeManagedRuleException = "ManagedRuleException"
// ErrCodeOperationDisabledException for service response error code
// "OperationDisabledException".
//
// The operation you are attempting is not available in this region.
ErrCodeOperationDisabledException = "OperationDisabledException"
// ErrCodePolicyLengthExceededException for service response error code
// "PolicyLengthExceededException".
//
// The event bus policy is too long. For more information, see the limits.
ErrCodePolicyLengthExceededException = "PolicyLengthExceededException"
// ErrCodeResourceAlreadyExistsException for service response error code
// "ResourceAlreadyExistsException".
//
// The resource you are trying to create already exists.
ErrCodeResourceAlreadyExistsException = "ResourceAlreadyExistsException"
// ErrCodeResourceNotFoundException for service response error code
// "ResourceNotFoundException".
//
// An entity that you specified does not exist.
ErrCodeResourceNotFoundException = "ResourceNotFoundException"
)
var exceptionFromCode = map[string]func(protocol.ResponseMetadata) error{
"ConcurrentModificationException": newErrorConcurrentModificationException,
"IllegalStatusException": newErrorIllegalStatusException,
"InternalException": newErrorInternalException,
"InvalidEventPatternException": newErrorInvalidEventPatternException,
"InvalidStateException": newErrorInvalidStateException,
"LimitExceededException": newErrorLimitExceededException,
"ManagedRuleException": newErrorManagedRuleException,
"OperationDisabledException": newErrorOperationDisabledException,
"PolicyLengthExceededException": newErrorPolicyLengthExceededException,
"ResourceAlreadyExistsException": newErrorResourceAlreadyExistsException,
"ResourceNotFoundException": newErrorResourceNotFoundException,
}

View File

@ -0,0 +1,224 @@
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
// Package eventbridgeiface provides an interface to enable mocking the Amazon EventBridge service client
// for testing your code.
//
// It is important to note that this interface will have breaking changes
// when the service model is updated and adds new API operations, paginators,
// and waiters.
package eventbridgeiface
import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/service/eventbridge"
)
// EventBridgeAPI provides an interface to enable mocking the
// eventbridge.EventBridge service client's API operation,
// paginators, and waiters. This make unit testing your code that calls out
// to the SDK's service client's calls easier.
//
// The best way to use this interface is so the SDK's service client's calls
// can be stubbed out for unit testing your code with the SDK without needing
// to inject custom request handlers into the SDK's request pipeline.
//
// // myFunc uses an SDK service client to make a request to
// // Amazon EventBridge.
// func myFunc(svc eventbridgeiface.EventBridgeAPI) bool {
// // Make svc.ActivateEventSource request
// }
//
// func main() {
// sess := session.New()
// svc := eventbridge.New(sess)
//
// myFunc(svc)
// }
//
// In your _test.go file:
//
// // Define a mock struct to be used in your unit tests of myFunc.
// type mockEventBridgeClient struct {
// eventbridgeiface.EventBridgeAPI
// }
// func (m *mockEventBridgeClient) ActivateEventSource(input *eventbridge.ActivateEventSourceInput) (*eventbridge.ActivateEventSourceOutput, error) {
// // mock response/functionality
// }
//
// func TestMyFunc(t *testing.T) {
// // Setup Test
// mockSvc := &mockEventBridgeClient{}
//
// myfunc(mockSvc)
//
// // Verify myFunc's functionality
// }
//
// It is important to note that this interface will have breaking changes
// when the service model is updated and adds new API operations, paginators,
// and waiters. Its suggested to use the pattern above for testing, or using
// tooling to generate mocks to satisfy the interfaces.
type EventBridgeAPI interface {
ActivateEventSource(*eventbridge.ActivateEventSourceInput) (*eventbridge.ActivateEventSourceOutput, error)
ActivateEventSourceWithContext(aws.Context, *eventbridge.ActivateEventSourceInput, ...request.Option) (*eventbridge.ActivateEventSourceOutput, error)
ActivateEventSourceRequest(*eventbridge.ActivateEventSourceInput) (*request.Request, *eventbridge.ActivateEventSourceOutput)
CancelReplay(*eventbridge.CancelReplayInput) (*eventbridge.CancelReplayOutput, error)
CancelReplayWithContext(aws.Context, *eventbridge.CancelReplayInput, ...request.Option) (*eventbridge.CancelReplayOutput, error)
CancelReplayRequest(*eventbridge.CancelReplayInput) (*request.Request, *eventbridge.CancelReplayOutput)
CreateArchive(*eventbridge.CreateArchiveInput) (*eventbridge.CreateArchiveOutput, error)
CreateArchiveWithContext(aws.Context, *eventbridge.CreateArchiveInput, ...request.Option) (*eventbridge.CreateArchiveOutput, error)
CreateArchiveRequest(*eventbridge.CreateArchiveInput) (*request.Request, *eventbridge.CreateArchiveOutput)
CreateEventBus(*eventbridge.CreateEventBusInput) (*eventbridge.CreateEventBusOutput, error)
CreateEventBusWithContext(aws.Context, *eventbridge.CreateEventBusInput, ...request.Option) (*eventbridge.CreateEventBusOutput, error)
CreateEventBusRequest(*eventbridge.CreateEventBusInput) (*request.Request, *eventbridge.CreateEventBusOutput)
CreatePartnerEventSource(*eventbridge.CreatePartnerEventSourceInput) (*eventbridge.CreatePartnerEventSourceOutput, error)
CreatePartnerEventSourceWithContext(aws.Context, *eventbridge.CreatePartnerEventSourceInput, ...request.Option) (*eventbridge.CreatePartnerEventSourceOutput, error)
CreatePartnerEventSourceRequest(*eventbridge.CreatePartnerEventSourceInput) (*request.Request, *eventbridge.CreatePartnerEventSourceOutput)
DeactivateEventSource(*eventbridge.DeactivateEventSourceInput) (*eventbridge.DeactivateEventSourceOutput, error)
DeactivateEventSourceWithContext(aws.Context, *eventbridge.DeactivateEventSourceInput, ...request.Option) (*eventbridge.DeactivateEventSourceOutput, error)
DeactivateEventSourceRequest(*eventbridge.DeactivateEventSourceInput) (*request.Request, *eventbridge.DeactivateEventSourceOutput)
DeleteArchive(*eventbridge.DeleteArchiveInput) (*eventbridge.DeleteArchiveOutput, error)
DeleteArchiveWithContext(aws.Context, *eventbridge.DeleteArchiveInput, ...request.Option) (*eventbridge.DeleteArchiveOutput, error)
DeleteArchiveRequest(*eventbridge.DeleteArchiveInput) (*request.Request, *eventbridge.DeleteArchiveOutput)
DeleteEventBus(*eventbridge.DeleteEventBusInput) (*eventbridge.DeleteEventBusOutput, error)
DeleteEventBusWithContext(aws.Context, *eventbridge.DeleteEventBusInput, ...request.Option) (*eventbridge.DeleteEventBusOutput, error)
DeleteEventBusRequest(*eventbridge.DeleteEventBusInput) (*request.Request, *eventbridge.DeleteEventBusOutput)
DeletePartnerEventSource(*eventbridge.DeletePartnerEventSourceInput) (*eventbridge.DeletePartnerEventSourceOutput, error)
DeletePartnerEventSourceWithContext(aws.Context, *eventbridge.DeletePartnerEventSourceInput, ...request.Option) (*eventbridge.DeletePartnerEventSourceOutput, error)
DeletePartnerEventSourceRequest(*eventbridge.DeletePartnerEventSourceInput) (*request.Request, *eventbridge.DeletePartnerEventSourceOutput)
DeleteRule(*eventbridge.DeleteRuleInput) (*eventbridge.DeleteRuleOutput, error)
DeleteRuleWithContext(aws.Context, *eventbridge.DeleteRuleInput, ...request.Option) (*eventbridge.DeleteRuleOutput, error)
DeleteRuleRequest(*eventbridge.DeleteRuleInput) (*request.Request, *eventbridge.DeleteRuleOutput)
DescribeArchive(*eventbridge.DescribeArchiveInput) (*eventbridge.DescribeArchiveOutput, error)
DescribeArchiveWithContext(aws.Context, *eventbridge.DescribeArchiveInput, ...request.Option) (*eventbridge.DescribeArchiveOutput, error)
DescribeArchiveRequest(*eventbridge.DescribeArchiveInput) (*request.Request, *eventbridge.DescribeArchiveOutput)
DescribeEventBus(*eventbridge.DescribeEventBusInput) (*eventbridge.DescribeEventBusOutput, error)
DescribeEventBusWithContext(aws.Context, *eventbridge.DescribeEventBusInput, ...request.Option) (*eventbridge.DescribeEventBusOutput, error)
DescribeEventBusRequest(*eventbridge.DescribeEventBusInput) (*request.Request, *eventbridge.DescribeEventBusOutput)
DescribeEventSource(*eventbridge.DescribeEventSourceInput) (*eventbridge.DescribeEventSourceOutput, error)
DescribeEventSourceWithContext(aws.Context, *eventbridge.DescribeEventSourceInput, ...request.Option) (*eventbridge.DescribeEventSourceOutput, error)
DescribeEventSourceRequest(*eventbridge.DescribeEventSourceInput) (*request.Request, *eventbridge.DescribeEventSourceOutput)
DescribePartnerEventSource(*eventbridge.DescribePartnerEventSourceInput) (*eventbridge.DescribePartnerEventSourceOutput, error)
DescribePartnerEventSourceWithContext(aws.Context, *eventbridge.DescribePartnerEventSourceInput, ...request.Option) (*eventbridge.DescribePartnerEventSourceOutput, error)
DescribePartnerEventSourceRequest(*eventbridge.DescribePartnerEventSourceInput) (*request.Request, *eventbridge.DescribePartnerEventSourceOutput)
DescribeReplay(*eventbridge.DescribeReplayInput) (*eventbridge.DescribeReplayOutput, error)
DescribeReplayWithContext(aws.Context, *eventbridge.DescribeReplayInput, ...request.Option) (*eventbridge.DescribeReplayOutput, error)
DescribeReplayRequest(*eventbridge.DescribeReplayInput) (*request.Request, *eventbridge.DescribeReplayOutput)
DescribeRule(*eventbridge.DescribeRuleInput) (*eventbridge.DescribeRuleOutput, error)
DescribeRuleWithContext(aws.Context, *eventbridge.DescribeRuleInput, ...request.Option) (*eventbridge.DescribeRuleOutput, error)
DescribeRuleRequest(*eventbridge.DescribeRuleInput) (*request.Request, *eventbridge.DescribeRuleOutput)
DisableRule(*eventbridge.DisableRuleInput) (*eventbridge.DisableRuleOutput, error)
DisableRuleWithContext(aws.Context, *eventbridge.DisableRuleInput, ...request.Option) (*eventbridge.DisableRuleOutput, error)
DisableRuleRequest(*eventbridge.DisableRuleInput) (*request.Request, *eventbridge.DisableRuleOutput)
EnableRule(*eventbridge.EnableRuleInput) (*eventbridge.EnableRuleOutput, error)
EnableRuleWithContext(aws.Context, *eventbridge.EnableRuleInput, ...request.Option) (*eventbridge.EnableRuleOutput, error)
EnableRuleRequest(*eventbridge.EnableRuleInput) (*request.Request, *eventbridge.EnableRuleOutput)
ListArchives(*eventbridge.ListArchivesInput) (*eventbridge.ListArchivesOutput, error)
ListArchivesWithContext(aws.Context, *eventbridge.ListArchivesInput, ...request.Option) (*eventbridge.ListArchivesOutput, error)
ListArchivesRequest(*eventbridge.ListArchivesInput) (*request.Request, *eventbridge.ListArchivesOutput)
ListEventBuses(*eventbridge.ListEventBusesInput) (*eventbridge.ListEventBusesOutput, error)
ListEventBusesWithContext(aws.Context, *eventbridge.ListEventBusesInput, ...request.Option) (*eventbridge.ListEventBusesOutput, error)
ListEventBusesRequest(*eventbridge.ListEventBusesInput) (*request.Request, *eventbridge.ListEventBusesOutput)
ListEventSources(*eventbridge.ListEventSourcesInput) (*eventbridge.ListEventSourcesOutput, error)
ListEventSourcesWithContext(aws.Context, *eventbridge.ListEventSourcesInput, ...request.Option) (*eventbridge.ListEventSourcesOutput, error)
ListEventSourcesRequest(*eventbridge.ListEventSourcesInput) (*request.Request, *eventbridge.ListEventSourcesOutput)
ListPartnerEventSourceAccounts(*eventbridge.ListPartnerEventSourceAccountsInput) (*eventbridge.ListPartnerEventSourceAccountsOutput, error)
ListPartnerEventSourceAccountsWithContext(aws.Context, *eventbridge.ListPartnerEventSourceAccountsInput, ...request.Option) (*eventbridge.ListPartnerEventSourceAccountsOutput, error)
ListPartnerEventSourceAccountsRequest(*eventbridge.ListPartnerEventSourceAccountsInput) (*request.Request, *eventbridge.ListPartnerEventSourceAccountsOutput)
ListPartnerEventSources(*eventbridge.ListPartnerEventSourcesInput) (*eventbridge.ListPartnerEventSourcesOutput, error)
ListPartnerEventSourcesWithContext(aws.Context, *eventbridge.ListPartnerEventSourcesInput, ...request.Option) (*eventbridge.ListPartnerEventSourcesOutput, error)
ListPartnerEventSourcesRequest(*eventbridge.ListPartnerEventSourcesInput) (*request.Request, *eventbridge.ListPartnerEventSourcesOutput)
ListReplays(*eventbridge.ListReplaysInput) (*eventbridge.ListReplaysOutput, error)
ListReplaysWithContext(aws.Context, *eventbridge.ListReplaysInput, ...request.Option) (*eventbridge.ListReplaysOutput, error)
ListReplaysRequest(*eventbridge.ListReplaysInput) (*request.Request, *eventbridge.ListReplaysOutput)
ListRuleNamesByTarget(*eventbridge.ListRuleNamesByTargetInput) (*eventbridge.ListRuleNamesByTargetOutput, error)
ListRuleNamesByTargetWithContext(aws.Context, *eventbridge.ListRuleNamesByTargetInput, ...request.Option) (*eventbridge.ListRuleNamesByTargetOutput, error)
ListRuleNamesByTargetRequest(*eventbridge.ListRuleNamesByTargetInput) (*request.Request, *eventbridge.ListRuleNamesByTargetOutput)
ListRules(*eventbridge.ListRulesInput) (*eventbridge.ListRulesOutput, error)
ListRulesWithContext(aws.Context, *eventbridge.ListRulesInput, ...request.Option) (*eventbridge.ListRulesOutput, error)
ListRulesRequest(*eventbridge.ListRulesInput) (*request.Request, *eventbridge.ListRulesOutput)
ListTagsForResource(*eventbridge.ListTagsForResourceInput) (*eventbridge.ListTagsForResourceOutput, error)
ListTagsForResourceWithContext(aws.Context, *eventbridge.ListTagsForResourceInput, ...request.Option) (*eventbridge.ListTagsForResourceOutput, error)
ListTagsForResourceRequest(*eventbridge.ListTagsForResourceInput) (*request.Request, *eventbridge.ListTagsForResourceOutput)
ListTargetsByRule(*eventbridge.ListTargetsByRuleInput) (*eventbridge.ListTargetsByRuleOutput, error)
ListTargetsByRuleWithContext(aws.Context, *eventbridge.ListTargetsByRuleInput, ...request.Option) (*eventbridge.ListTargetsByRuleOutput, error)
ListTargetsByRuleRequest(*eventbridge.ListTargetsByRuleInput) (*request.Request, *eventbridge.ListTargetsByRuleOutput)
PutEvents(*eventbridge.PutEventsInput) (*eventbridge.PutEventsOutput, error)
PutEventsWithContext(aws.Context, *eventbridge.PutEventsInput, ...request.Option) (*eventbridge.PutEventsOutput, error)
PutEventsRequest(*eventbridge.PutEventsInput) (*request.Request, *eventbridge.PutEventsOutput)
PutPartnerEvents(*eventbridge.PutPartnerEventsInput) (*eventbridge.PutPartnerEventsOutput, error)
PutPartnerEventsWithContext(aws.Context, *eventbridge.PutPartnerEventsInput, ...request.Option) (*eventbridge.PutPartnerEventsOutput, error)
PutPartnerEventsRequest(*eventbridge.PutPartnerEventsInput) (*request.Request, *eventbridge.PutPartnerEventsOutput)
PutPermission(*eventbridge.PutPermissionInput) (*eventbridge.PutPermissionOutput, error)
PutPermissionWithContext(aws.Context, *eventbridge.PutPermissionInput, ...request.Option) (*eventbridge.PutPermissionOutput, error)
PutPermissionRequest(*eventbridge.PutPermissionInput) (*request.Request, *eventbridge.PutPermissionOutput)
PutRule(*eventbridge.PutRuleInput) (*eventbridge.PutRuleOutput, error)
PutRuleWithContext(aws.Context, *eventbridge.PutRuleInput, ...request.Option) (*eventbridge.PutRuleOutput, error)
PutRuleRequest(*eventbridge.PutRuleInput) (*request.Request, *eventbridge.PutRuleOutput)
PutTargets(*eventbridge.PutTargetsInput) (*eventbridge.PutTargetsOutput, error)
PutTargetsWithContext(aws.Context, *eventbridge.PutTargetsInput, ...request.Option) (*eventbridge.PutTargetsOutput, error)
PutTargetsRequest(*eventbridge.PutTargetsInput) (*request.Request, *eventbridge.PutTargetsOutput)
RemovePermission(*eventbridge.RemovePermissionInput) (*eventbridge.RemovePermissionOutput, error)
RemovePermissionWithContext(aws.Context, *eventbridge.RemovePermissionInput, ...request.Option) (*eventbridge.RemovePermissionOutput, error)
RemovePermissionRequest(*eventbridge.RemovePermissionInput) (*request.Request, *eventbridge.RemovePermissionOutput)
RemoveTargets(*eventbridge.RemoveTargetsInput) (*eventbridge.RemoveTargetsOutput, error)
RemoveTargetsWithContext(aws.Context, *eventbridge.RemoveTargetsInput, ...request.Option) (*eventbridge.RemoveTargetsOutput, error)
RemoveTargetsRequest(*eventbridge.RemoveTargetsInput) (*request.Request, *eventbridge.RemoveTargetsOutput)
StartReplay(*eventbridge.StartReplayInput) (*eventbridge.StartReplayOutput, error)
StartReplayWithContext(aws.Context, *eventbridge.StartReplayInput, ...request.Option) (*eventbridge.StartReplayOutput, error)
StartReplayRequest(*eventbridge.StartReplayInput) (*request.Request, *eventbridge.StartReplayOutput)
TagResource(*eventbridge.TagResourceInput) (*eventbridge.TagResourceOutput, error)
TagResourceWithContext(aws.Context, *eventbridge.TagResourceInput, ...request.Option) (*eventbridge.TagResourceOutput, error)
TagResourceRequest(*eventbridge.TagResourceInput) (*request.Request, *eventbridge.TagResourceOutput)
TestEventPattern(*eventbridge.TestEventPatternInput) (*eventbridge.TestEventPatternOutput, error)
TestEventPatternWithContext(aws.Context, *eventbridge.TestEventPatternInput, ...request.Option) (*eventbridge.TestEventPatternOutput, error)
TestEventPatternRequest(*eventbridge.TestEventPatternInput) (*request.Request, *eventbridge.TestEventPatternOutput)
UntagResource(*eventbridge.UntagResourceInput) (*eventbridge.UntagResourceOutput, error)
UntagResourceWithContext(aws.Context, *eventbridge.UntagResourceInput, ...request.Option) (*eventbridge.UntagResourceOutput, error)
UntagResourceRequest(*eventbridge.UntagResourceInput) (*request.Request, *eventbridge.UntagResourceOutput)
UpdateArchive(*eventbridge.UpdateArchiveInput) (*eventbridge.UpdateArchiveOutput, error)
UpdateArchiveWithContext(aws.Context, *eventbridge.UpdateArchiveInput, ...request.Option) (*eventbridge.UpdateArchiveOutput, error)
UpdateArchiveRequest(*eventbridge.UpdateArchiveInput) (*request.Request, *eventbridge.UpdateArchiveOutput)
}
var _ EventBridgeAPI = (*eventbridge.EventBridge)(nil)

View File

@ -0,0 +1,103 @@
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
package eventbridge
import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/client"
"github.com/aws/aws-sdk-go/aws/client/metadata"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/aws/signer/v4"
"github.com/aws/aws-sdk-go/private/protocol"
"github.com/aws/aws-sdk-go/private/protocol/jsonrpc"
)
// EventBridge provides the API operation methods for making requests to
// Amazon EventBridge. See this package's package overview docs
// for details on the service.
//
// EventBridge methods are safe to use concurrently. It is not safe to
// modify mutate any of the struct's properties though.
type EventBridge struct {
*client.Client
}
// Used for custom client initialization logic
var initClient func(*client.Client)
// Used for custom request initialization logic
var initRequest func(*request.Request)
// Service information constants
const (
ServiceName = "EventBridge" // Name of service.
EndpointsID = "events" // ID to lookup a service endpoint with.
ServiceID = "EventBridge" // ServiceID is a unique identifier of a specific service.
)
// New creates a new instance of the EventBridge client with a session.
// If additional configuration is needed for the client instance use the optional
// aws.Config parameter to add your extra config.
//
// Example:
// mySession := session.Must(session.NewSession())
//
// // Create a EventBridge client from just a session.
// svc := eventbridge.New(mySession)
//
// // Create a EventBridge client with additional configuration
// svc := eventbridge.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
func New(p client.ConfigProvider, cfgs ...*aws.Config) *EventBridge {
c := p.ClientConfig(EndpointsID, cfgs...)
return newClient(*c.Config, c.Handlers, c.PartitionID, c.Endpoint, c.SigningRegion, c.SigningName)
}
// newClient creates, initializes and returns a new service client instance.
func newClient(cfg aws.Config, handlers request.Handlers, partitionID, endpoint, signingRegion, signingName string) *EventBridge {
svc := &EventBridge{
Client: client.New(
cfg,
metadata.ClientInfo{
ServiceName: ServiceName,
ServiceID: ServiceID,
SigningName: signingName,
SigningRegion: signingRegion,
PartitionID: partitionID,
Endpoint: endpoint,
APIVersion: "2015-10-07",
JSONVersion: "1.1",
TargetPrefix: "AWSEvents",
},
handlers,
),
}
// Handlers
svc.Handlers.Sign.PushBackNamed(v4.SignRequestHandler)
svc.Handlers.Build.PushBackNamed(jsonrpc.BuildHandler)
svc.Handlers.Unmarshal.PushBackNamed(jsonrpc.UnmarshalHandler)
svc.Handlers.UnmarshalMeta.PushBackNamed(jsonrpc.UnmarshalMetaHandler)
svc.Handlers.UnmarshalError.PushBackNamed(
protocol.NewUnmarshalErrorHandler(jsonrpc.NewUnmarshalTypedError(exceptionFromCode)).NamedHandler(),
)
// Run custom client initialization if present
if initClient != nil {
initClient(svc.Client)
}
return svc
}
// newRequest creates a new request for a EventBridge operation and runs any
// custom request initialization.
func (c *EventBridge) newRequest(op *request.Operation, params, data interface{}) *request.Request {
req := c.NewRequest(op, params, data)
// Run custom request initialization if present
if initRequest != nil {
initRequest(req)
}
return req
}

5306
vendor/github.com/aws/aws-sdk-go/service/sqs/api.go generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,114 @@
package sqs
import (
"crypto/md5"
"encoding/hex"
"fmt"
"strings"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/awserr"
"github.com/aws/aws-sdk-go/aws/request"
)
var (
errChecksumMissingBody = fmt.Errorf("cannot compute checksum. missing body")
errChecksumMissingMD5 = fmt.Errorf("cannot verify checksum. missing response MD5")
)
func setupChecksumValidation(r *request.Request) {
if aws.BoolValue(r.Config.DisableComputeChecksums) {
return
}
switch r.Operation.Name {
case opSendMessage:
r.Handlers.Unmarshal.PushBack(verifySendMessage)
case opSendMessageBatch:
r.Handlers.Unmarshal.PushBack(verifySendMessageBatch)
case opReceiveMessage:
r.Handlers.Unmarshal.PushBack(verifyReceiveMessage)
}
}
func verifySendMessage(r *request.Request) {
if r.DataFilled() && r.ParamsFilled() {
in := r.Params.(*SendMessageInput)
out := r.Data.(*SendMessageOutput)
err := checksumsMatch(in.MessageBody, out.MD5OfMessageBody)
if err != nil {
setChecksumError(r, err.Error())
}
}
}
func verifySendMessageBatch(r *request.Request) {
if r.DataFilled() && r.ParamsFilled() {
entries := map[string]*SendMessageBatchResultEntry{}
ids := []string{}
out := r.Data.(*SendMessageBatchOutput)
for _, entry := range out.Successful {
entries[*entry.Id] = entry
}
in := r.Params.(*SendMessageBatchInput)
for _, entry := range in.Entries {
if e, ok := entries[*entry.Id]; ok {
if err := checksumsMatch(entry.MessageBody, e.MD5OfMessageBody); err != nil {
ids = append(ids, *e.MessageId)
}
}
}
if len(ids) > 0 {
setChecksumError(r, "invalid messages: %s", strings.Join(ids, ", "))
}
}
}
func verifyReceiveMessage(r *request.Request) {
if r.DataFilled() && r.ParamsFilled() {
ids := []string{}
out := r.Data.(*ReceiveMessageOutput)
for i, msg := range out.Messages {
err := checksumsMatch(msg.Body, msg.MD5OfBody)
if err != nil {
if msg.MessageId == nil {
if r.Config.Logger != nil {
r.Config.Logger.Log(fmt.Sprintf(
"WARN: SQS.ReceiveMessage failed checksum request id: %s, message %d has no message ID.",
r.RequestID, i,
))
}
continue
}
ids = append(ids, *msg.MessageId)
}
}
if len(ids) > 0 {
setChecksumError(r, "invalid messages: %s", strings.Join(ids, ", "))
}
}
}
func checksumsMatch(body, expectedMD5 *string) error {
if body == nil {
return errChecksumMissingBody
} else if expectedMD5 == nil {
return errChecksumMissingMD5
}
msum := md5.Sum([]byte(*body))
sum := hex.EncodeToString(msum[:])
if sum != *expectedMD5 {
return fmt.Errorf("expected MD5 checksum '%s', got '%s'", *expectedMD5, sum)
}
return nil
}
func setChecksumError(r *request.Request, format string, args ...interface{}) {
r.Retryable = aws.Bool(true)
r.Error = awserr.New("InvalidChecksum", fmt.Sprintf(format, args...), nil)
}

View File

@ -0,0 +1,9 @@
package sqs
import "github.com/aws/aws-sdk-go/aws/request"
func init() {
initRequest = func(r *request.Request) {
setupChecksumValidation(r)
}
}

59
vendor/github.com/aws/aws-sdk-go/service/sqs/doc.go generated vendored Normal file
View File

@ -0,0 +1,59 @@
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
// Package sqs provides the client and types for making API
// requests to Amazon Simple Queue Service.
//
// Welcome to the Amazon Simple Queue Service API Reference.
//
// Amazon Simple Queue Service (Amazon SQS) is a reliable, highly-scalable hosted
// queue for storing messages as they travel between applications or microservices.
// Amazon SQS moves data between distributed application components and helps
// you decouple these components.
//
// For information on the permissions you need to use this API, see Identity
// and access management (https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-authentication-and-access-control.html)
// in the Amazon Simple Queue Service Developer Guide.
//
// You can use AWS SDKs (http://aws.amazon.com/tools/#sdk) to access Amazon
// SQS using your favorite programming language. The SDKs perform tasks such
// as the following automatically:
//
// * Cryptographically sign your service requests
//
// * Retry requests
//
// * Handle error responses
//
// Additional Information
//
// * Amazon SQS Product Page (http://aws.amazon.com/sqs/)
//
// * Amazon Simple Queue Service Developer Guide Making API Requests (https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-making-api-requests.html)
// Amazon SQS Message Attributes (https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-message-metadata.html#sqs-message-attributes)
// Amazon SQS Dead-Letter Queues (https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-dead-letter-queues.html)
//
// * Amazon SQS in the AWS CLI Command Reference (http://docs.aws.amazon.com/cli/latest/reference/sqs/index.html)
//
// * Amazon Web Services General Reference Regions and Endpoints (https://docs.aws.amazon.com/general/latest/gr/rande.html#sqs_region)
//
// See https://docs.aws.amazon.com/goto/WebAPI/sqs-2012-11-05 for more information on this service.
//
// See sqs package documentation for more information.
// https://docs.aws.amazon.com/sdk-for-go/api/service/sqs/
//
// Using the Client
//
// To contact Amazon Simple Queue Service with the SDK use the New function to create
// a new service client. With that client you can make API requests to the service.
// These clients are safe to use concurrently.
//
// See the SDK's documentation for more information on how to use the SDK.
// https://docs.aws.amazon.com/sdk-for-go/api/
//
// See aws.Config documentation for more information on configuring SDK clients.
// https://docs.aws.amazon.com/sdk-for-go/api/aws/#Config
//
// See the Amazon Simple Queue Service client SQS for more
// information on creating client for this service.
// https://docs.aws.amazon.com/sdk-for-go/api/service/sqs/#New
package sqs

110
vendor/github.com/aws/aws-sdk-go/service/sqs/errors.go generated vendored Normal file
View File

@ -0,0 +1,110 @@
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
package sqs
const (
// ErrCodeBatchEntryIdsNotDistinct for service response error code
// "AWS.SimpleQueueService.BatchEntryIdsNotDistinct".
//
// Two or more batch entries in the request have the same Id.
ErrCodeBatchEntryIdsNotDistinct = "AWS.SimpleQueueService.BatchEntryIdsNotDistinct"
// ErrCodeBatchRequestTooLong for service response error code
// "AWS.SimpleQueueService.BatchRequestTooLong".
//
// The length of all the messages put together is more than the limit.
ErrCodeBatchRequestTooLong = "AWS.SimpleQueueService.BatchRequestTooLong"
// ErrCodeEmptyBatchRequest for service response error code
// "AWS.SimpleQueueService.EmptyBatchRequest".
//
// The batch request doesn't contain any entries.
ErrCodeEmptyBatchRequest = "AWS.SimpleQueueService.EmptyBatchRequest"
// ErrCodeInvalidAttributeName for service response error code
// "InvalidAttributeName".
//
// The specified attribute doesn't exist.
ErrCodeInvalidAttributeName = "InvalidAttributeName"
// ErrCodeInvalidBatchEntryId for service response error code
// "AWS.SimpleQueueService.InvalidBatchEntryId".
//
// The Id of a batch entry in a batch request doesn't abide by the specification.
ErrCodeInvalidBatchEntryId = "AWS.SimpleQueueService.InvalidBatchEntryId"
// ErrCodeInvalidIdFormat for service response error code
// "InvalidIdFormat".
//
// The specified receipt handle isn't valid for the current version.
ErrCodeInvalidIdFormat = "InvalidIdFormat"
// ErrCodeInvalidMessageContents for service response error code
// "InvalidMessageContents".
//
// The message contains characters outside the allowed set.
ErrCodeInvalidMessageContents = "InvalidMessageContents"
// ErrCodeMessageNotInflight for service response error code
// "AWS.SimpleQueueService.MessageNotInflight".
//
// The specified message isn't in flight.
ErrCodeMessageNotInflight = "AWS.SimpleQueueService.MessageNotInflight"
// ErrCodeOverLimit for service response error code
// "OverLimit".
//
// The specified action violates a limit. For example, ReceiveMessage returns
// this error if the maximum number of inflight messages is reached and AddPermission
// returns this error if the maximum number of permissions for the queue is
// reached.
ErrCodeOverLimit = "OverLimit"
// ErrCodePurgeQueueInProgress for service response error code
// "AWS.SimpleQueueService.PurgeQueueInProgress".
//
// Indicates that the specified queue previously received a PurgeQueue request
// within the last 60 seconds (the time it can take to delete the messages in
// the queue).
ErrCodePurgeQueueInProgress = "AWS.SimpleQueueService.PurgeQueueInProgress"
// ErrCodeQueueDeletedRecently for service response error code
// "AWS.SimpleQueueService.QueueDeletedRecently".
//
// You must wait 60 seconds after deleting a queue before you can create another
// queue with the same name.
ErrCodeQueueDeletedRecently = "AWS.SimpleQueueService.QueueDeletedRecently"
// ErrCodeQueueDoesNotExist for service response error code
// "AWS.SimpleQueueService.NonExistentQueue".
//
// The specified queue doesn't exist.
ErrCodeQueueDoesNotExist = "AWS.SimpleQueueService.NonExistentQueue"
// ErrCodeQueueNameExists for service response error code
// "QueueAlreadyExists".
//
// A queue with this name already exists. Amazon SQS returns this error only
// if the request includes attributes whose values differ from those of the
// existing queue.
ErrCodeQueueNameExists = "QueueAlreadyExists"
// ErrCodeReceiptHandleIsInvalid for service response error code
// "ReceiptHandleIsInvalid".
//
// The specified receipt handle isn't valid.
ErrCodeReceiptHandleIsInvalid = "ReceiptHandleIsInvalid"
// ErrCodeTooManyEntriesInBatchRequest for service response error code
// "AWS.SimpleQueueService.TooManyEntriesInBatchRequest".
//
// The batch request contains more entries than permissible.
ErrCodeTooManyEntriesInBatchRequest = "AWS.SimpleQueueService.TooManyEntriesInBatchRequest"
// ErrCodeUnsupportedOperation for service response error code
// "AWS.SimpleQueueService.UnsupportedOperation".
//
// Error code 400. Unsupported operation.
ErrCodeUnsupportedOperation = "AWS.SimpleQueueService.UnsupportedOperation"
)

View File

@ -0,0 +1,98 @@
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
package sqs
import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/client"
"github.com/aws/aws-sdk-go/aws/client/metadata"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/aws/signer/v4"
"github.com/aws/aws-sdk-go/private/protocol/query"
)
// SQS provides the API operation methods for making requests to
// Amazon Simple Queue Service. See this package's package overview docs
// for details on the service.
//
// SQS methods are safe to use concurrently. It is not safe to
// modify mutate any of the struct's properties though.
type SQS struct {
*client.Client
}
// Used for custom client initialization logic
var initClient func(*client.Client)
// Used for custom request initialization logic
var initRequest func(*request.Request)
// Service information constants
const (
ServiceName = "sqs" // Name of service.
EndpointsID = ServiceName // ID to lookup a service endpoint with.
ServiceID = "SQS" // ServiceID is a unique identifier of a specific service.
)
// New creates a new instance of the SQS client with a session.
// If additional configuration is needed for the client instance use the optional
// aws.Config parameter to add your extra config.
//
// Example:
// mySession := session.Must(session.NewSession())
//
// // Create a SQS client from just a session.
// svc := sqs.New(mySession)
//
// // Create a SQS client with additional configuration
// svc := sqs.New(mySession, aws.NewConfig().WithRegion("us-west-2"))
func New(p client.ConfigProvider, cfgs ...*aws.Config) *SQS {
c := p.ClientConfig(EndpointsID, cfgs...)
return newClient(*c.Config, c.Handlers, c.PartitionID, c.Endpoint, c.SigningRegion, c.SigningName)
}
// newClient creates, initializes and returns a new service client instance.
func newClient(cfg aws.Config, handlers request.Handlers, partitionID, endpoint, signingRegion, signingName string) *SQS {
svc := &SQS{
Client: client.New(
cfg,
metadata.ClientInfo{
ServiceName: ServiceName,
ServiceID: ServiceID,
SigningName: signingName,
SigningRegion: signingRegion,
PartitionID: partitionID,
Endpoint: endpoint,
APIVersion: "2012-11-05",
},
handlers,
),
}
// Handlers
svc.Handlers.Sign.PushBackNamed(v4.SignRequestHandler)
svc.Handlers.Build.PushBackNamed(query.BuildHandler)
svc.Handlers.Unmarshal.PushBackNamed(query.UnmarshalHandler)
svc.Handlers.UnmarshalMeta.PushBackNamed(query.UnmarshalMetaHandler)
svc.Handlers.UnmarshalError.PushBackNamed(query.UnmarshalErrorHandler)
// Run custom client initialization if present
if initClient != nil {
initClient(svc.Client)
}
return svc
}
// newRequest creates a new request for a SQS operation and runs any
// custom request initialization.
func (c *SQS) newRequest(op *request.Operation, params, data interface{}) *request.Request {
req := c.NewRequest(op, params, data)
// Run custom request initialization if present
if initRequest != nil {
initRequest(req)
}
return req
}

View File

@ -0,0 +1,150 @@
// Code generated by private/model/cli/gen-api/main.go. DO NOT EDIT.
// Package sqsiface provides an interface to enable mocking the Amazon Simple Queue Service service client
// for testing your code.
//
// It is important to note that this interface will have breaking changes
// when the service model is updated and adds new API operations, paginators,
// and waiters.
package sqsiface
import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/service/sqs"
)
// SQSAPI provides an interface to enable mocking the
// sqs.SQS service client's API operation,
// paginators, and waiters. This make unit testing your code that calls out
// to the SDK's service client's calls easier.
//
// The best way to use this interface is so the SDK's service client's calls
// can be stubbed out for unit testing your code with the SDK without needing
// to inject custom request handlers into the SDK's request pipeline.
//
// // myFunc uses an SDK service client to make a request to
// // Amazon Simple Queue Service.
// func myFunc(svc sqsiface.SQSAPI) bool {
// // Make svc.AddPermission request
// }
//
// func main() {
// sess := session.New()
// svc := sqs.New(sess)
//
// myFunc(svc)
// }
//
// In your _test.go file:
//
// // Define a mock struct to be used in your unit tests of myFunc.
// type mockSQSClient struct {
// sqsiface.SQSAPI
// }
// func (m *mockSQSClient) AddPermission(input *sqs.AddPermissionInput) (*sqs.AddPermissionOutput, error) {
// // mock response/functionality
// }
//
// func TestMyFunc(t *testing.T) {
// // Setup Test
// mockSvc := &mockSQSClient{}
//
// myfunc(mockSvc)
//
// // Verify myFunc's functionality
// }
//
// It is important to note that this interface will have breaking changes
// when the service model is updated and adds new API operations, paginators,
// and waiters. Its suggested to use the pattern above for testing, or using
// tooling to generate mocks to satisfy the interfaces.
type SQSAPI interface {
AddPermission(*sqs.AddPermissionInput) (*sqs.AddPermissionOutput, error)
AddPermissionWithContext(aws.Context, *sqs.AddPermissionInput, ...request.Option) (*sqs.AddPermissionOutput, error)
AddPermissionRequest(*sqs.AddPermissionInput) (*request.Request, *sqs.AddPermissionOutput)
ChangeMessageVisibility(*sqs.ChangeMessageVisibilityInput) (*sqs.ChangeMessageVisibilityOutput, error)
ChangeMessageVisibilityWithContext(aws.Context, *sqs.ChangeMessageVisibilityInput, ...request.Option) (*sqs.ChangeMessageVisibilityOutput, error)
ChangeMessageVisibilityRequest(*sqs.ChangeMessageVisibilityInput) (*request.Request, *sqs.ChangeMessageVisibilityOutput)
ChangeMessageVisibilityBatch(*sqs.ChangeMessageVisibilityBatchInput) (*sqs.ChangeMessageVisibilityBatchOutput, error)
ChangeMessageVisibilityBatchWithContext(aws.Context, *sqs.ChangeMessageVisibilityBatchInput, ...request.Option) (*sqs.ChangeMessageVisibilityBatchOutput, error)
ChangeMessageVisibilityBatchRequest(*sqs.ChangeMessageVisibilityBatchInput) (*request.Request, *sqs.ChangeMessageVisibilityBatchOutput)
CreateQueue(*sqs.CreateQueueInput) (*sqs.CreateQueueOutput, error)
CreateQueueWithContext(aws.Context, *sqs.CreateQueueInput, ...request.Option) (*sqs.CreateQueueOutput, error)
CreateQueueRequest(*sqs.CreateQueueInput) (*request.Request, *sqs.CreateQueueOutput)
DeleteMessage(*sqs.DeleteMessageInput) (*sqs.DeleteMessageOutput, error)
DeleteMessageWithContext(aws.Context, *sqs.DeleteMessageInput, ...request.Option) (*sqs.DeleteMessageOutput, error)
DeleteMessageRequest(*sqs.DeleteMessageInput) (*request.Request, *sqs.DeleteMessageOutput)
DeleteMessageBatch(*sqs.DeleteMessageBatchInput) (*sqs.DeleteMessageBatchOutput, error)
DeleteMessageBatchWithContext(aws.Context, *sqs.DeleteMessageBatchInput, ...request.Option) (*sqs.DeleteMessageBatchOutput, error)
DeleteMessageBatchRequest(*sqs.DeleteMessageBatchInput) (*request.Request, *sqs.DeleteMessageBatchOutput)
DeleteQueue(*sqs.DeleteQueueInput) (*sqs.DeleteQueueOutput, error)
DeleteQueueWithContext(aws.Context, *sqs.DeleteQueueInput, ...request.Option) (*sqs.DeleteQueueOutput, error)
DeleteQueueRequest(*sqs.DeleteQueueInput) (*request.Request, *sqs.DeleteQueueOutput)
GetQueueAttributes(*sqs.GetQueueAttributesInput) (*sqs.GetQueueAttributesOutput, error)
GetQueueAttributesWithContext(aws.Context, *sqs.GetQueueAttributesInput, ...request.Option) (*sqs.GetQueueAttributesOutput, error)
GetQueueAttributesRequest(*sqs.GetQueueAttributesInput) (*request.Request, *sqs.GetQueueAttributesOutput)
GetQueueUrl(*sqs.GetQueueUrlInput) (*sqs.GetQueueUrlOutput, error)
GetQueueUrlWithContext(aws.Context, *sqs.GetQueueUrlInput, ...request.Option) (*sqs.GetQueueUrlOutput, error)
GetQueueUrlRequest(*sqs.GetQueueUrlInput) (*request.Request, *sqs.GetQueueUrlOutput)
ListDeadLetterSourceQueues(*sqs.ListDeadLetterSourceQueuesInput) (*sqs.ListDeadLetterSourceQueuesOutput, error)
ListDeadLetterSourceQueuesWithContext(aws.Context, *sqs.ListDeadLetterSourceQueuesInput, ...request.Option) (*sqs.ListDeadLetterSourceQueuesOutput, error)
ListDeadLetterSourceQueuesRequest(*sqs.ListDeadLetterSourceQueuesInput) (*request.Request, *sqs.ListDeadLetterSourceQueuesOutput)
ListDeadLetterSourceQueuesPages(*sqs.ListDeadLetterSourceQueuesInput, func(*sqs.ListDeadLetterSourceQueuesOutput, bool) bool) error
ListDeadLetterSourceQueuesPagesWithContext(aws.Context, *sqs.ListDeadLetterSourceQueuesInput, func(*sqs.ListDeadLetterSourceQueuesOutput, bool) bool, ...request.Option) error
ListQueueTags(*sqs.ListQueueTagsInput) (*sqs.ListQueueTagsOutput, error)
ListQueueTagsWithContext(aws.Context, *sqs.ListQueueTagsInput, ...request.Option) (*sqs.ListQueueTagsOutput, error)
ListQueueTagsRequest(*sqs.ListQueueTagsInput) (*request.Request, *sqs.ListQueueTagsOutput)
ListQueues(*sqs.ListQueuesInput) (*sqs.ListQueuesOutput, error)
ListQueuesWithContext(aws.Context, *sqs.ListQueuesInput, ...request.Option) (*sqs.ListQueuesOutput, error)
ListQueuesRequest(*sqs.ListQueuesInput) (*request.Request, *sqs.ListQueuesOutput)
ListQueuesPages(*sqs.ListQueuesInput, func(*sqs.ListQueuesOutput, bool) bool) error
ListQueuesPagesWithContext(aws.Context, *sqs.ListQueuesInput, func(*sqs.ListQueuesOutput, bool) bool, ...request.Option) error
PurgeQueue(*sqs.PurgeQueueInput) (*sqs.PurgeQueueOutput, error)
PurgeQueueWithContext(aws.Context, *sqs.PurgeQueueInput, ...request.Option) (*sqs.PurgeQueueOutput, error)
PurgeQueueRequest(*sqs.PurgeQueueInput) (*request.Request, *sqs.PurgeQueueOutput)
ReceiveMessage(*sqs.ReceiveMessageInput) (*sqs.ReceiveMessageOutput, error)
ReceiveMessageWithContext(aws.Context, *sqs.ReceiveMessageInput, ...request.Option) (*sqs.ReceiveMessageOutput, error)
ReceiveMessageRequest(*sqs.ReceiveMessageInput) (*request.Request, *sqs.ReceiveMessageOutput)
RemovePermission(*sqs.RemovePermissionInput) (*sqs.RemovePermissionOutput, error)
RemovePermissionWithContext(aws.Context, *sqs.RemovePermissionInput, ...request.Option) (*sqs.RemovePermissionOutput, error)
RemovePermissionRequest(*sqs.RemovePermissionInput) (*request.Request, *sqs.RemovePermissionOutput)
SendMessage(*sqs.SendMessageInput) (*sqs.SendMessageOutput, error)
SendMessageWithContext(aws.Context, *sqs.SendMessageInput, ...request.Option) (*sqs.SendMessageOutput, error)
SendMessageRequest(*sqs.SendMessageInput) (*request.Request, *sqs.SendMessageOutput)
SendMessageBatch(*sqs.SendMessageBatchInput) (*sqs.SendMessageBatchOutput, error)
SendMessageBatchWithContext(aws.Context, *sqs.SendMessageBatchInput, ...request.Option) (*sqs.SendMessageBatchOutput, error)
SendMessageBatchRequest(*sqs.SendMessageBatchInput) (*request.Request, *sqs.SendMessageBatchOutput)
SetQueueAttributes(*sqs.SetQueueAttributesInput) (*sqs.SetQueueAttributesOutput, error)
SetQueueAttributesWithContext(aws.Context, *sqs.SetQueueAttributesInput, ...request.Option) (*sqs.SetQueueAttributesOutput, error)
SetQueueAttributesRequest(*sqs.SetQueueAttributesInput) (*request.Request, *sqs.SetQueueAttributesOutput)
TagQueue(*sqs.TagQueueInput) (*sqs.TagQueueOutput, error)
TagQueueWithContext(aws.Context, *sqs.TagQueueInput, ...request.Option) (*sqs.TagQueueOutput, error)
TagQueueRequest(*sqs.TagQueueInput) (*request.Request, *sqs.TagQueueOutput)
UntagQueue(*sqs.UntagQueueInput) (*sqs.UntagQueueOutput, error)
UntagQueueWithContext(aws.Context, *sqs.UntagQueueInput, ...request.Option) (*sqs.UntagQueueOutput, error)
UntagQueueRequest(*sqs.UntagQueueInput) (*request.Request, *sqs.UntagQueueOutput)
}
var _ SQSAPI = (*sqs.SQS)(nil)