Skip to content

Commit f3184c1

Browse files
committed
add service quota validator; refactor
1 parent 2e2a52c commit f3184c1

16 files changed

Lines changed: 703 additions & 326 deletions

File tree

README.md

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,28 @@ The AWS [valid8or](https://github.com/spectrocloud-labs/valid8or) plugin ensures
55
The AWS valid8or plugin reconciles `AwsValidator` custom resources to perform the following validations against your AWS environment:
66

77
1. Compare the IAM permissions associated with an IAM role against an expected permission set
8-
2. Compare the tags associated with a subnet against an expected tag set
8+
2. Compare the usage for a particular service quota against the active quota
9+
3. Compare the tags associated with a subnet against an expected tag set
910

1011
Each `AwsValidator` CR is (re)-processed every two minutes to continuously ensure that your AWS environment matches the expected state.
1112

1213
See the [samples](https://github.com/spectrocloud-labs/valid8or-plugin-aws/tree/main/config/samples) directory for example `AwsValidator` configurations.
1314

15+
## Supported Service Quotas by AWS Service
16+
EC2:
17+
- EC2-VPC Elastic IPs
18+
19+
ELB:
20+
- Application Load Balancers per Region
21+
- Classic Load Balancers per Region
22+
23+
VPC:
24+
- VPCs per Region
25+
- Subnets per VPC
26+
- NAT gateways per Availability Zone
27+
- Network interfaces per Region
28+
- Internet gateways per Region
29+
1430
## Getting Started
1531
You’ll need a Kubernetes cluster to run against. You can use [kind](https://sigs.k8s.io/kind) to get a local cluster for testing, or run against a remote cluster.
1632
**Note:** Your controller will automatically use the current context in your kubeconfig file (i.e. whatever cluster `kubectl cluster-info` shows).

api/v1alpha1/awsvalidator_types.go

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,10 @@ import (
2525

2626
// AwsValidatorSpec defines the desired state of AwsValidator
2727
type AwsValidatorSpec struct {
28-
Auth AwsAuth `json:"auth"`
29-
IamRules []IamRule `json:"iamRules,omitempty"`
30-
TagRules []TagRule `json:"tagRules,omitempty"`
28+
Auth AwsAuth `json:"auth"`
29+
IamRules []IamRule `json:"iamRules,omitempty"`
30+
ServiceQuotaRules []ServiceQuotaRule `json:"serviceQuotaRules,omitempty"`
31+
TagRules []TagRule `json:"tagRules,omitempty"`
3132
}
3233

3334
type AwsAuth struct {
@@ -65,6 +66,17 @@ func (c *Condition) String() string {
6566
return fmt.Sprintf("%s: %s=%s", c.Type, c.Key, c.Values)
6667
}
6768

69+
type ServiceQuotaRule struct {
70+
Region string `json:"region"`
71+
ServiceCode string `json:"serviceCode"`
72+
ServiceQuotas []ServiceQuota `json:"serviceQuotas"`
73+
}
74+
75+
type ServiceQuota struct {
76+
Name string `json:"name"`
77+
Buffer int `json:"buffer"`
78+
}
79+
6880
type TagRule struct {
6981
Key string `json:"key"`
7082
ExpectedValue string `json:"expectedValue"`

api/v1alpha1/zz_generated.deepcopy.go

Lines changed: 42 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cmd/main.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,8 +68,6 @@ func main() {
6868

6969
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
7070
Scheme: scheme,
71-
MetricsBindAddress: metricsAddr,
72-
Port: 9443,
7371
HealthProbeBindAddress: probeAddr,
7472
LeaderElection: enableLeaderElection,
7573
LeaderElectionID: "1f172fb1.spectrocloud.labs",

config/crd/bases/validation.spectrocloud.labs_awsvalidators.yaml

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,31 @@ spec:
100100
- iamRole
101101
type: object
102102
type: array
103+
serviceQuotaRules:
104+
items:
105+
properties:
106+
region:
107+
type: string
108+
serviceCode:
109+
type: string
110+
serviceQuotas:
111+
items:
112+
properties:
113+
buffer:
114+
type: integer
115+
name:
116+
type: string
117+
required:
118+
- buffer
119+
- name
120+
type: object
121+
type: array
122+
required:
123+
- region
124+
- serviceCode
125+
- serviceQuotas
126+
type: object
127+
type: array
103128
tagRules:
104129
items:
105130
properties:
@@ -132,22 +157,34 @@ spec:
132157
conditions:
133158
items:
134159
properties:
160+
details:
161+
description: Human-readable messages indicating additional details
162+
for the last transition.
163+
items:
164+
type: string
165+
type: array
135166
failures:
167+
description: Human-readable messages indicating additional failure
168+
details for the last transition.
136169
items:
137170
type: string
138171
type: array
139-
lastTransitionTime:
172+
lastValidationTime:
173+
description: Timestamp of most recent execution of the validation
174+
rule associated with the condition.
140175
format: date-time
141176
type: string
142177
message:
143178
description: Human-readable message indicating details about
144-
last transition.
145-
type: string
146-
reason:
147-
description: Unique, one-word, CamelCase reason for the condition's
148-
last transition.
179+
the last transition.
149180
type: string
150181
status:
182+
description: True if the validation rule succeeded, otherwise
183+
False
184+
type: string
185+
validationRule:
186+
description: Unique, one-word description of the validation
187+
rule associated with the condition.
151188
type: string
152189
required:
153190
- status
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
apiVersion: validation.spectrocloud.labs/v1alpha1
2+
kind: AwsValidator
3+
metadata:
4+
name: awsvalidator-sample-service-quota
5+
spec:
6+
auth:
7+
secretName: aws-creds
8+
serviceQuotaRules:
9+
- region: us-east-2
10+
serviceCode: ec2
11+
serviceQuotas:
12+
- name: "EC2-VPC Elastic IPs"
13+
buffer: 5
14+
# - region: us-east-2
15+
# serviceCode: elb
16+
# serviceQuotas:
17+
# - name: "Application Load Balancers per Region"
18+
# buffer: 5
19+
# - region: us-east-2
20+
# serviceCode: elb
21+
# serviceQuotas:
22+
# - name: "Classic Load Balancers per Region"
23+
# buffer: 5
24+
- region: us-east-2
25+
serviceCode: vpc
26+
serviceQuotas:
27+
- name: "VPCs per Region"
28+
buffer: 2
29+
# - region: us-east-2
30+
# serviceCode: vpc
31+
# serviceQuotas:
32+
# - name: "Subnets per VPC"
33+
# buffer: 5
34+
# - region: us-east-2
35+
# serviceCode: vpc
36+
# serviceQuotas:
37+
# - name: "NAT gateways per Availability Zone"
38+
# buffer: 5
39+
# - region: us-east-2
40+
# serviceCode: vpc
41+
# serviceQuotas:
42+
# - name: "Network interfaces per Region"
43+
# buffer: 5
44+
# - region: us-east-2
45+
# serviceCode: vpc
46+
# serviceQuotas:
47+
# - name: "Internet gateways per Region"
48+
# buffer: 5

go.mod

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ require (
88
github.com/go-logr/logr v1.2.4
99
github.com/onsi/ginkgo/v2 v2.9.5
1010
github.com/onsi/gomega v1.27.7
11-
github.com/spectrocloud-labs/valid8or v0.0.0-20230822220544-57329831a947
11+
github.com/spectrocloud-labs/valid8or v0.0.0-20230824230819-6ac1c98bffb8
12+
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63
1213
k8s.io/api v0.27.2
1314
k8s.io/apimachinery v0.27.2
1415
k8s.io/client-go v0.27.2
@@ -57,13 +58,13 @@ require (
5758
go.uber.org/atomic v1.7.0 // indirect
5859
go.uber.org/multierr v1.6.0 // indirect
5960
go.uber.org/zap v1.24.0 // indirect
60-
golang.org/x/net v0.10.0 // indirect
61+
golang.org/x/net v0.14.0 // indirect
6162
golang.org/x/oauth2 v0.5.0 // indirect
62-
golang.org/x/sys v0.8.0 // indirect
63-
golang.org/x/term v0.8.0 // indirect
64-
golang.org/x/text v0.9.0 // indirect
63+
golang.org/x/sys v0.11.0 // indirect
64+
golang.org/x/term v0.11.0 // indirect
65+
golang.org/x/text v0.12.0 // indirect
6566
golang.org/x/time v0.3.0 // indirect
66-
golang.org/x/tools v0.9.1 // indirect
67+
golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 // indirect
6768
gomodules.xyz/jsonpatch/v2 v2.3.0 // indirect
6869
google.golang.org/appengine v1.6.7 // indirect
6970
google.golang.org/protobuf v1.30.0 // indirect

go.sum

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,8 @@ github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjR
143143
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
144144
github.com/rs/zerolog v1.28.0 h1:MirSo27VyNi7RJYP3078AA1+Cyzd2GB66qy3aUHvsWY=
145145
github.com/rs/zerolog v1.28.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0=
146-
github.com/spectrocloud-labs/valid8or v0.0.0-20230822220544-57329831a947 h1:vg8aqrY/HK1JDNJUekf+XIDPgB0iA9jHUwUIGGiZ2rc=
147-
github.com/spectrocloud-labs/valid8or v0.0.0-20230822220544-57329831a947/go.mod h1:COf3zhXbhc8Qhmp/lSISXYX1nP5ueHgpGYEG9evZc2I=
146+
github.com/spectrocloud-labs/valid8or v0.0.0-20230824230819-6ac1c98bffb8 h1:BawkBTwqPCRvQZ707WrM5ujt53UwxjviICVh2j0oe4A=
147+
github.com/spectrocloud-labs/valid8or v0.0.0-20230824230819-6ac1c98bffb8/go.mod h1:d2uYGVs/uB0FnyTBup6EL94SQ27bLE0gejLkr3akqvQ=
148148
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
149149
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
150150
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
@@ -176,6 +176,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
176176
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
177177
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
178178
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
179+
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63 h1:m64FZMko/V45gv0bNmrNYoDEq8U5YUhetc9cBWKS1TQ=
180+
golang.org/x/exp v0.0.0-20230817173708-d852ddb80c63/go.mod h1:0v4NqG35kSWCMzLaMeX+IQrlSnVE/bqGSyC2cz/9Le8=
179181
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
180182
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
181183
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
@@ -184,7 +186,7 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
184186
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
185187
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
186188
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
187-
golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
189+
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
188190
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
189191
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
190192
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -198,8 +200,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
198200
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
199201
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
200202
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
201-
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
202-
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
203+
golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
204+
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
203205
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
204206
golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s=
205207
golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I=
@@ -227,20 +229,20 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
227229
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
228230
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
229231
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
230-
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
231-
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
232+
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
233+
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
232234
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
233235
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
234236
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
235-
golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols=
236-
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
237+
golang.org/x/term v0.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0=
238+
golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
237239
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
238240
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
239241
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
240242
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
241243
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
242-
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
243-
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
244+
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
245+
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
244246
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
245247
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
246248
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -253,8 +255,8 @@ golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roY
253255
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
254256
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
255257
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
256-
golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo=
257-
golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
258+
golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846 h1:Vve/L0v7CXXuxUmaMGIEK/dEeq7uiqb5qBgQrZzIE7E=
259+
golang.org/x/tools v0.12.1-0.20230815132531-74c255bcf846/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM=
258260
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
259261
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
260262
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

internal/aws/aws.go

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package aws
2+
3+
import (
4+
"github.com/aws/aws-sdk-go/aws"
5+
"github.com/aws/aws-sdk-go/aws/session"
6+
"github.com/aws/aws-sdk-go/service/ec2"
7+
"github.com/aws/aws-sdk-go/service/iam"
8+
"github.com/aws/aws-sdk-go/service/servicequotas"
9+
)
10+
11+
// IAMService creates an AWS IAM service object for a specific session
12+
func IAMService(session *session.Session) *iam.IAM {
13+
return iam.New(session, &aws.Config{})
14+
}
15+
16+
// EC2Service creates an AWS EC2 service object for a specific session and region
17+
func EC2Service(session *session.Session, region string) *ec2.EC2 {
18+
config := &aws.Config{}
19+
if region != "" {
20+
config.Region = aws.String(region)
21+
}
22+
return ec2.New(session, config)
23+
}
24+
25+
// ServiceQuotasService creates an AWS service quotas service object for a specific session and region
26+
func ServiceQuotasService(session *session.Session, region string) *servicequotas.ServiceQuotas {
27+
config := &aws.Config{}
28+
if region != "" {
29+
config.Region = aws.String(region)
30+
}
31+
return servicequotas.New(session, config)
32+
}
33+
34+
// String wraps aws.String
35+
func String(s string) *string {
36+
return aws.String(s)
37+
}

internal/constants/constants.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package constants
2+
3+
const ValidationRulePrefix string = "validation"

0 commit comments

Comments
 (0)