Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
716052077b | ||
|
|
5b7b669b41 | ||
|
|
7b4ee7f403 | ||
|
|
916324ee64 | ||
|
|
11d3d6d523 | ||
|
|
4758d5d9cd |
No files matched your search
@@ -1,4 +1,4 @@
|
||||
Copyright IBM Corp. 2021, 2025
|
||||
Copyright IBM Corp. 2021, 2026
|
||||
|
||||
Mozilla Public License Version 2.0
|
||||
==================================
|
||||
|
||||
@@ -3,13 +3,13 @@ module github.com/hashicorp/boundary-plugin-aws
|
||||
go 1.24.0
|
||||
|
||||
require (
|
||||
github.com/aws/aws-sdk-go-v2 v1.40.0
|
||||
github.com/aws/aws-sdk-go-v2 v1.41.5
|
||||
github.com/aws/aws-sdk-go-v2/service/ec2 v1.193.0
|
||||
github.com/aws/aws-sdk-go-v2/service/iam v1.52.2
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.69.0
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.97.3
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.41.2
|
||||
github.com/aws/smithy-go v1.24.0
|
||||
github.com/google/go-cmp v0.6.0
|
||||
github.com/aws/smithy-go v1.24.2
|
||||
github.com/google/go-cmp v0.7.0
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/hashicorp/boundary/sdk v0.0.51
|
||||
github.com/hashicorp/go-multierror v1.1.1
|
||||
@@ -18,24 +18,24 @@ require (
|
||||
github.com/hashicorp/terraform-json v0.23.0
|
||||
github.com/mitchellh/mapstructure v1.5.0
|
||||
github.com/stretchr/testify v1.10.0
|
||||
google.golang.org/grpc v1.68.0
|
||||
google.golang.org/protobuf v1.36.1
|
||||
google.golang.org/grpc v1.79.3
|
||||
google.golang.org/protobuf v1.36.10
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.8 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/config v1.32.2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.19.2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.14 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.14 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.14 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.21 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.21 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.24 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.3 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.5 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.14 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.5 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.22 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.13 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.21 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.21 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/signin v1.0.2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.30.5 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.10 // indirect
|
||||
@@ -59,11 +59,11 @@ require (
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/ryanuber/go-glob v1.0.0 // indirect
|
||||
github.com/zclconf/go-cty v1.15.0 // indirect
|
||||
golang.org/x/crypto v0.36.0 // indirect
|
||||
golang.org/x/net v0.38.0 // indirect
|
||||
golang.org/x/sys v0.38.0 // indirect
|
||||
golang.org/x/text v0.23.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 // indirect
|
||||
golang.org/x/crypto v0.46.0 // indirect
|
||||
golang.org/x/net v0.48.0 // indirect
|
||||
golang.org/x/sys v0.39.0 // indirect
|
||||
golang.org/x/text v0.32.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
@@ -8,38 +8,38 @@ github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4=
|
||||
github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI=
|
||||
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/aws/aws-sdk-go-v2 v1.40.0 h1:/WMUA0kjhZExjOQN2z3oLALDREea1A7TobfuiBrKlwc=
|
||||
github.com/aws/aws-sdk-go-v2 v1.40.0/go.mod h1:c9pm7VwuW0UPxAEYGyTmyurVcNrbF6Rt/wixFqDhcjE=
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7 h1:lL7IfaFzngfx0ZwUGOZdsFFnQ5uLvR0hWqqhyE7Q9M8=
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7/go.mod h1:QraP0UcVlQJsmHfioCrveWOC1nbiWUl3ej08h4mXWoc=
|
||||
github.com/aws/aws-sdk-go-v2 v1.41.5 h1:dj5kopbwUsVUVFgO4Fi5BIT3t4WyqIDjGKCangnV/yY=
|
||||
github.com/aws/aws-sdk-go-v2 v1.41.5/go.mod h1:mwsPRE8ceUUpiTgF7QmQIJ7lgsKUPQOUl3o72QBrE1o=
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.8 h1:eBMB84YGghSocM7PsjmmPffTa+1FBUeNvGvFou6V/4o=
|
||||
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.8/go.mod h1:lyw7GFp3qENLh7kwzf7iMzAxDn+NzjXEAGjKS2UOKqI=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.32.2 h1:4liUsdEpUUPZs5WVapsJLx5NPmQhQdez7nYFcovrytk=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.32.2/go.mod h1:l0hs06IFz1eCT+jTacU/qZtC33nvcnLADAPL/XyrkZI=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.19.2 h1:qZry8VUyTK4VIo5aEdUcBjPZHL2v4FyQ3QEOaWcFLu4=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.19.2/go.mod h1:YUqm5a1/kBnoK+/NY5WEiMocZihKSo15/tJdmdXnM5g=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.14 h1:WZVR5DbDgxzA0BJeudId89Kmgy6DIU4ORpxwsVHz0qA=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.14/go.mod h1:Dadl9QO0kHgbrH1GRqGiZdYtW5w+IXXaBNCHTIaheM4=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.14 h1:PZHqQACxYb8mYgms4RZbhZG0a7dPW06xOjmaH0EJC/I=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.14/go.mod h1:VymhrMJUWs69D8u0/lZ7jSB6WgaG/NqHi3gX0aYf6U0=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.14 h1:bOS19y6zlJwagBfHxs0ESzr1XCOU2KXJCWcq3E2vfjY=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.14/go.mod h1:1ipeGBMAxZ0xcTm6y6paC2C/J6f6OO7LBODV9afuAyM=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.21 h1:Rgg6wvjjtX8bNHcvi9OnXWwcE0a2vGpbwmtICOsvcf4=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.21/go.mod h1:A/kJFst/nm//cyqonihbdpQZwiUhhzpqTsdbhDdRF9c=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.21 h1:PEgGVtPoB6NTpPrBgqSE5hE/o47Ij9qk/SEZFbUOe9A=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.21/go.mod h1:p+hz+PRAYlY3zcpJhPwXlLC4C+kqn70WIHwnzAfs6ps=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4 h1:WKuaxf++XKWlHWu9ECbMlha8WOEGm0OUEZqm4K/Gcfk=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.4/go.mod h1:ZWy7j6v1vWGmPReu0iSGvRiise4YI5SkR3OHKTZ6Wuc=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.24 h1:JX70yGKLj25+lMC5Yyh8wBtvB01GDilyRuJvXJ4piD0=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.3.24/go.mod h1:+Ln60j9SUTD0LEwnhEB0Xhg61DHqplBrbZpLgyjoEHg=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.22 h1:rWyie/PxDRIdhNf4DzRk0lvjVOqFJuNnO8WwaIRVxzQ=
|
||||
github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.22/go.mod h1:zd/JsJ4P7oGfUhXn1VyLqaRZwPmZwg44Jf2dS84Dm3Y=
|
||||
github.com/aws/aws-sdk-go-v2/service/ec2 v1.193.0 h1:RhSoBFT5/8tTmIseJUXM6INTXTQDF8+0oyxWBnozIms=
|
||||
github.com/aws/aws-sdk-go-v2/service/ec2 v1.193.0/go.mod h1:mzj8EEjIHSN2oZRXiw1Dd+uB4HZTl7hC8nBzX9IZMWw=
|
||||
github.com/aws/aws-sdk-go-v2/service/iam v1.52.2 h1:li0ooCUfHIivHn8nB3LstP6HgdNefwu5gnXE4MLVz/U=
|
||||
github.com/aws/aws-sdk-go-v2/service/iam v1.52.2/go.mod h1:PuHz5kGh1jtsNpjezdYhRp7xgn6DzCNJJfQt7O7U9Aw=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.3 h1:x2Ibm/Af8Fi+BH+Hsn9TXGdT+hKbDd5XOTZxTMxDk7o=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.3/go.mod h1:IW1jwyrQgMdhisceG8fQLmQIydcT/jWY21rFhzgaKwo=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.5 h1:gvZOjQKPxFXy1ft3QnEyXmT+IqneM9QAUWlM3r0mfqw=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.4.5/go.mod h1:DLWnfvIcm9IET/mmjdxeXbBKmTCm0ZB8p1za9BVteM8=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.14 h1:FIouAnCE46kyYqyhs0XEBDFFSREtdnr8HQuLPQPLCrY=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.14/go.mod h1:UTwDc5COa5+guonQU8qBikJo1ZJ4ln2r1MkF7Dqag1E=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.5 h1:P1doBzv5VEg1ONxnJss1Kh5ZG/ewoIE4MQtKKc6Crgg=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.18.5/go.mod h1:NOP+euMW7W3Ukt28tAxPuoWao4rhhqJD3QEBk7oCg7w=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.69.0 h1:Q2ax8S21clKOnHhhr933xm3JxdJebql+R7aNo7p7GBQ=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.69.0/go.mod h1:ralv4XawHjEMaHOWnTFushl0WRqim/gQWesAMF6hTow=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7 h1:5EniKhLZe4xzL7a+fU3C2tfUN4nWIqlLesfrjkuPFTY=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.13.7/go.mod h1:x0nZssQ3qZSnIcePWLvcoFisRXJzcTVvYpAAdYX8+GI=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.13 h1:JRaIgADQS/U6uXDqlPiefP32yXTda7Kqfx+LgspooZM=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.9.13/go.mod h1:CEuVn5WqOMilYl+tbccq8+N2ieCy0gVn3OtRb0vBNNM=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.21 h1:c31//R3xgIJMSC8S6hEVq+38DcvUlgFY0FM6mSI5oto=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.13.21/go.mod h1:r6+pf23ouCB718FUxaqzZdbpYFyDtehyZcmP5KL9FkA=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.21 h1:ZlvrNcHSFFWURB8avufQq9gFsheUgjVD9536obIknfM=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.19.21/go.mod h1:cv3TNhVrssKR0O/xxLJVRfd2oazSnZnkUeTf6ctUwfQ=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.97.3 h1:HwxWTbTrIHm5qY+CAEur0s/figc3qwvLWsNkF4RPToo=
|
||||
github.com/aws/aws-sdk-go-v2/service/s3 v1.97.3/go.mod h1:uoA43SdFwacedBfSgfFSjjCvYe8aYBS7EnU5GZ/YKMM=
|
||||
github.com/aws/aws-sdk-go-v2/service/signin v1.0.2 h1:MxMBdKTYBjPQChlJhi4qlEueqB1p1KcbTEa7tD5aqPs=
|
||||
github.com/aws/aws-sdk-go-v2/service/signin v1.0.2/go.mod h1:iS6EPmNeqCsGo+xQmXv0jIMjyYtQfnwg36zl2FwEouk=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.30.5 h1:ksUT5KtgpZd3SAiFJNJ0AFEJVva3gjBmN7eXUZjzUwQ=
|
||||
@@ -48,10 +48,12 @@ github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.10 h1:GtsxyiF3Nd3JahRBJbxLCCd
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.10/go.mod h1:/j67Z5XBVDx8nZVp9EuFM9/BS5dvBznbqILGuu73hug=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.41.2 h1:a5UTtD4mHBU3t0o6aHQZFJTNKVfxFWfPX7J0Lr7G+uY=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.41.2/go.mod h1:6TxbXoDSgBQ225Qd8Q+MbxUxUh6TtNKwbRt/EPS9xso=
|
||||
github.com/aws/smithy-go v1.24.0 h1:LpilSUItNPFr1eY85RYgTIg5eIEPtvFbskaFcmmIUnk=
|
||||
github.com/aws/smithy-go v1.24.0/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0=
|
||||
github.com/aws/smithy-go v1.24.2 h1:FzA3bu/nt/vDvmnkg+R8Xl46gmzEDam6mZ1hzmwXFng=
|
||||
github.com/aws/smithy-go v1.24.2/go.mod h1:YE2RhdIuDbA5E5bTdciG9KrW3+TiEONeUWCqxX9i1Fc=
|
||||
github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY=
|
||||
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
@@ -59,14 +61,18 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
||||
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
|
||||
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
|
||||
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
||||
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-test/deep v1.0.4 h1:u2CU3YKy9I2pmu9pX0eq50wCgjfGIt539SqR7FbHiho=
|
||||
github.com/go-test/deep v1.0.4/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/hashicorp/boundary/sdk v0.0.51 h1:a7XpHNTYaeBXRhJkc8MC0siPtfJELYH/ibjw/0UbJEg=
|
||||
@@ -180,14 +186,26 @@ github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/zclconf/go-cty v1.15.0 h1:tTCRWxsexYUmtt/wVxgDClUe+uQusuI443uL6e+5sXQ=
|
||||
github.com/zclconf/go-cty v1.15.0/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE=
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
|
||||
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
|
||||
go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48=
|
||||
go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8=
|
||||
go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0=
|
||||
go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs=
|
||||
go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18=
|
||||
go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew=
|
||||
go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI=
|
||||
go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA=
|
||||
go.uber.org/goleak v1.0.0/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
|
||||
go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA=
|
||||
go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
|
||||
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
|
||||
golang.org/x/crypto v0.46.0 h1:cKRW/pmt1pKAfetfu+RCEvjvZkA9RimPbh7bhFjGVBU=
|
||||
golang.org/x/crypto v0.46.0/go.mod h1:Evb/oLKmMraqjZ2iQTwDwvCtJkczlDuTmdJXoZVzqU0=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
@@ -197,8 +215,8 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
|
||||
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
||||
golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU=
|
||||
golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -210,12 +228,12 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
|
||||
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
|
||||
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
|
||||
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
|
||||
golang.org/x/text v0.32.0 h1:ZD01bjUt1FQ9WJ0ClOL5vxgxOI/sVCNgX1YtKwcY0mU=
|
||||
golang.org/x/text v0.32.0/go.mod h1:o/rUWzghvpD5TXrTIBuJU77MTaN0ljMWE47kxGJQ7jY=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
@@ -226,14 +244,16 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1 h1:hjSy6tcFQZ171igDaN5QHOw2n6vx40juYbC/x67CEhc=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:qpvKtACPCQhAdu3PyQgV4l3LMXZEtft7y8QcarRsp9I=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1 h1:pPJltXNxVzT4pK9yD8vR9X75DaWYYmLGMsEvBfFQZzQ=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:UqMtugtsSgubUsoxbuAoiCXvqvErP7Gf0so0mK9tHxU=
|
||||
google.golang.org/grpc v1.68.0 h1:aHQeeJbo8zAkAa3pRzrVjZlbz6uSfeOXlJNQM0RAbz0=
|
||||
google.golang.org/grpc v1.68.0/go.mod h1:fmSPC5AsjSBCK54MyHRx48kpOti1/jRfOlwEWywNjWA=
|
||||
google.golang.org/protobuf v1.36.1 h1:yBPeRvTftaleIgM3PZ/WBIZ7XM/eEYAaEyCwvyjq/gk=
|
||||
google.golang.org/protobuf v1.36.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
|
||||
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
||||
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217 h1:fCvbg86sFXwdrl5LgVcTEvNC+2txB5mgROGmRL5mrls=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:+rXWjjaukWZun3mLfjmVnQi18E1AsFbDN9QdJ5YXLto=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217 h1:gRkg/vSppuSQoDjxyiGfN4Upv/h/DQmIR10ZU8dh4Ww=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251202230838-ff82c1b0f217/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk=
|
||||
google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE=
|
||||
google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=
|
||||
google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
|
||||
google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright IBM Corp. 2021, 2025
|
||||
// Copyright IBM Corp. 2021, 2026
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package credential
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright IBM Corp. 2021, 2025
|
||||
// Copyright IBM Corp. 2021, 2026
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package credential
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright IBM Corp. 2021, 2025
|
||||
// Copyright IBM Corp. 2021, 2026
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package credential
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright IBM Corp. 2021, 2025
|
||||
// Copyright IBM Corp. 2021, 2026
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package credential
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright IBM Corp. 2021, 2025
|
||||
// Copyright IBM Corp. 2021, 2026
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package credential
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright IBM Corp. 2021, 2025
|
||||
// Copyright IBM Corp. 2021, 2026
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package credential
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright IBM Corp. 2021, 2025
|
||||
// Copyright IBM Corp. 2021, 2026
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package errors
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright IBM Corp. 2021, 2025
|
||||
// Copyright IBM Corp. 2021, 2026
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package errors
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright IBM Corp. 2021, 2025
|
||||
// Copyright IBM Corp. 2021, 2026
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package errors
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright IBM Corp. 2021, 2025
|
||||
// Copyright IBM Corp. 2021, 2026
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package values
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright IBM Corp. 2021, 2025
|
||||
// Copyright IBM Corp. 2021, 2026
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package values
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// Copyright IBM Corp. 2021, 2025
|
||||
// Copyright IBM Corp. 2021, 2026
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package plugin
|
||||
|
||||
@@ -16,6 +16,36 @@ boundary host-catalogs create plugin \
|
||||
-secret secret_access_key='SECRET'
|
||||
```
|
||||
|
||||
To create a host catalog that returns addresses only from the primary network
|
||||
interface:
|
||||
|
||||
```
|
||||
boundary host-catalogs create plugin \
|
||||
-scope-id p_1234567890 \
|
||||
-name "Example Plugin-Based Host Catalog" \
|
||||
-description "Description for plugin-based host catalog" \
|
||||
-plugin-name aws \
|
||||
-attr region=REGION \
|
||||
-attr primary_interface_only=true \
|
||||
-secret access_key_id='KEY' \
|
||||
-secret secret_access_key='SECRET'
|
||||
```
|
||||
|
||||
To create a host catalog that excludes public IPv4 addresses while keeping
|
||||
private IPv4 addresses:
|
||||
|
||||
```
|
||||
boundary host-catalogs create plugin \
|
||||
-scope-id p_1234567890 \
|
||||
-name "Example Plugin-Based Host Catalog" \
|
||||
-description "Description for plugin-based host catalog" \
|
||||
-plugin-name aws \
|
||||
-attr region=REGION \
|
||||
-attr exclude_public_ips=true \
|
||||
-secret access_key_id='KEY' \
|
||||
-secret secret_access_key='SECRET'
|
||||
```
|
||||
|
||||
To create a host set, filtering the host set based on tag keys `foo` or `bar`
|
||||
(either tag can be present), ensuring that any targets set to this host set only
|
||||
connect to external addresses in the `54.0.0.0/8` class A subnet:
|
||||
@@ -75,7 +105,6 @@ a configured IAM user for this provider:
|
||||
"Resource": "*"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
* `iam:GetUser`, `iam:CreateAccessKey`, and `iam:DeleteAccessKey`, configured to
|
||||
@@ -116,6 +145,16 @@ The following `attributes` are valid on an AWS host catalog resource:
|
||||
provider.
|
||||
- `role_tags` (object): The key-value pair tags configured for the `AssumeRole`
|
||||
provider.
|
||||
- `primary_interface_only` (bool): If `true`, only addresses from the primary
|
||||
ENI are returned. When `false` or omitted, addresses from all attached ENIs
|
||||
are considered.
|
||||
- `exclude_private_ips` (bool): If `true`, private IPv4 addresses are omitted.
|
||||
- `exclude_public_ips` (bool): If `true`, public IPv4 addresses are omitted.
|
||||
|
||||
If none of the exclusion flags are set, the plugin preserves the historical
|
||||
behavior and returns all discovered address classes. The exclusion flags apply
|
||||
to both IPv4 and IPv6 addresses based on whether the IP is classified as public
|
||||
or private.
|
||||
|
||||
The following `secrets` are required on an AWS host catalog resource:
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright IBM Corp. 2021, 2025
|
||||
// Copyright IBM Corp. 2021, 2026
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package host
|
||||
@@ -22,6 +22,18 @@ type CatalogAttributes struct {
|
||||
|
||||
// DualStack is used for configuring how the aws client will resolve requests.
|
||||
DualStack bool
|
||||
|
||||
// PrimaryInterfaceOnly restricts discovery to the instance's primary ENI.
|
||||
PrimaryInterfaceOnly bool
|
||||
|
||||
// ExcludePrivateIps controls whether private IPv4 addresses are omitted.
|
||||
ExcludePrivateIps bool
|
||||
|
||||
// ExcludePublicIps controls whether public IPv4 addresses are omitted.
|
||||
ExcludePublicIps bool
|
||||
|
||||
// ExcludeIpv6 controls whether IPv6 addresses are omitted.
|
||||
ExcludeIpv6 bool
|
||||
}
|
||||
|
||||
func getCatalogAttributes(in *structpb.Struct) (*CatalogAttributes, error) {
|
||||
@@ -40,6 +52,36 @@ func getCatalogAttributes(in *structpb.Struct) (*CatalogAttributes, error) {
|
||||
}
|
||||
delete(unknownFields, ConstAwsDualStack)
|
||||
|
||||
primaryInterfaceOnly, err := values.GetBoolValue(in, ConstPrimaryInterfaceOnly, false)
|
||||
if err != nil {
|
||||
badFields[fmt.Sprintf("attributes.%s", ConstPrimaryInterfaceOnly)] = err.Error()
|
||||
}
|
||||
delete(unknownFields, ConstPrimaryInterfaceOnly)
|
||||
|
||||
excludePrivateIPs, err := values.GetBoolValue(in, ConstExcludePrivateIps, false)
|
||||
if err != nil {
|
||||
badFields[fmt.Sprintf("attributes.%s", ConstExcludePrivateIps)] = err.Error()
|
||||
}
|
||||
delete(unknownFields, ConstExcludePrivateIps)
|
||||
|
||||
excludePublicIPs, err := values.GetBoolValue(in, ConstExcludePublicIps, false)
|
||||
if err != nil {
|
||||
badFields[fmt.Sprintf("attributes.%s", ConstExcludePublicIps)] = err.Error()
|
||||
}
|
||||
delete(unknownFields, ConstExcludePublicIps)
|
||||
|
||||
excludeIpv6, err := values.GetBoolValue(in, ConstExcludeIpv6, false)
|
||||
if err != nil {
|
||||
badFields[fmt.Sprintf("attributes.%s", ConstExcludeIpv6)] = err.Error()
|
||||
}
|
||||
delete(unknownFields, ConstExcludeIpv6)
|
||||
|
||||
if excludePrivateIPs && excludePublicIPs && excludeIpv6 {
|
||||
badFields[fmt.Sprintf("attributes.%s", ConstExcludePrivateIps)] = "cannot be combined with exclude_public_ips and exclude_ipv6"
|
||||
badFields[fmt.Sprintf("attributes.%s", ConstExcludePublicIps)] = "cannot be combined with exclude_private_ips and exclude_ipv6"
|
||||
badFields[fmt.Sprintf("attributes.%s", ConstExcludeIpv6)] = "cannot be combined with exclude_private_ips and exclude_public_ips"
|
||||
}
|
||||
|
||||
for s := range unknownFields {
|
||||
switch s {
|
||||
// Ignore knownFields from CredentialAttributes
|
||||
@@ -67,6 +109,10 @@ func getCatalogAttributes(in *structpb.Struct) (*CatalogAttributes, error) {
|
||||
return &CatalogAttributes{
|
||||
CredentialAttributes: credAttributes,
|
||||
DualStack: dualStack,
|
||||
PrimaryInterfaceOnly: primaryInterfaceOnly,
|
||||
ExcludePrivateIps: excludePrivateIPs,
|
||||
ExcludePublicIps: excludePublicIPs,
|
||||
ExcludeIpv6: excludeIpv6,
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright IBM Corp. 2021, 2025
|
||||
// Copyright IBM Corp. 2021, 2026
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package host
|
||||
@@ -59,6 +59,106 @@ func TestGetCatalogAttributes(t *testing.T) {
|
||||
DualStack: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with primary interface only",
|
||||
in: &structpb.Struct{
|
||||
Fields: map[string]*structpb.Value{
|
||||
"region": structpb.NewStringValue("us-west-2"),
|
||||
"primary_interface_only": structpb.NewBoolValue(true),
|
||||
},
|
||||
},
|
||||
expected: &CatalogAttributes{
|
||||
CredentialAttributes: &credential.CredentialAttributes{
|
||||
Region: "us-west-2",
|
||||
DisableCredentialRotation: false,
|
||||
},
|
||||
PrimaryInterfaceOnly: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with exclude public ip",
|
||||
in: &structpb.Struct{
|
||||
Fields: map[string]*structpb.Value{
|
||||
"region": structpb.NewStringValue("us-west-2"),
|
||||
"exclude_public_ips": structpb.NewBoolValue(true),
|
||||
},
|
||||
},
|
||||
expected: &CatalogAttributes{
|
||||
CredentialAttributes: &credential.CredentialAttributes{
|
||||
Region: "us-west-2",
|
||||
DisableCredentialRotation: false,
|
||||
},
|
||||
ExcludePublicIps: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with exclude private ip",
|
||||
in: &structpb.Struct{
|
||||
Fields: map[string]*structpb.Value{
|
||||
"region": structpb.NewStringValue("us-west-2"),
|
||||
"exclude_private_ips": structpb.NewBoolValue(true),
|
||||
},
|
||||
},
|
||||
expected: &CatalogAttributes{
|
||||
CredentialAttributes: &credential.CredentialAttributes{
|
||||
Region: "us-west-2",
|
||||
DisableCredentialRotation: false,
|
||||
},
|
||||
ExcludePrivateIps: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with mixed attributes",
|
||||
in: &structpb.Struct{
|
||||
Fields: map[string]*structpb.Value{
|
||||
"region": structpb.NewStringValue("us-west-2"),
|
||||
"dual_stack": structpb.NewBoolValue(true),
|
||||
"exclude_private_ips": structpb.NewBoolValue(true),
|
||||
"exclude_ipv6": structpb.NewBoolValue(true),
|
||||
"primary_interface_only": structpb.NewBoolValue(true),
|
||||
},
|
||||
},
|
||||
expected: &CatalogAttributes{
|
||||
CredentialAttributes: &credential.CredentialAttributes{
|
||||
Region: "us-west-2",
|
||||
DisableCredentialRotation: false,
|
||||
},
|
||||
DualStack: true,
|
||||
ExcludePrivateIps: true,
|
||||
ExcludeIpv6: true,
|
||||
PrimaryInterfaceOnly: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "can exclude public and private IPs when IPv6 remains enabled",
|
||||
in: &structpb.Struct{
|
||||
Fields: map[string]*structpb.Value{
|
||||
"region": structpb.NewStringValue("us-west-2"),
|
||||
"exclude_private_ips": structpb.NewBoolValue(true),
|
||||
"exclude_public_ips": structpb.NewBoolValue(true),
|
||||
},
|
||||
},
|
||||
expected: &CatalogAttributes{
|
||||
CredentialAttributes: &credential.CredentialAttributes{
|
||||
Region: "us-west-2",
|
||||
DisableCredentialRotation: false,
|
||||
},
|
||||
ExcludePrivateIps: true,
|
||||
ExcludePublicIps: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "cannot exclude public private and IPv6 together",
|
||||
in: &structpb.Struct{
|
||||
Fields: map[string]*structpb.Value{
|
||||
"region": structpb.NewStringValue("us-west-2"),
|
||||
"exclude_private_ips": structpb.NewBoolValue(true),
|
||||
"exclude_public_ips": structpb.NewBoolValue(true),
|
||||
"exclude_ipv6": structpb.NewBoolValue(true),
|
||||
},
|
||||
},
|
||||
expectedErrContains: "attributes.exclude_ipv6: cannot be combined with exclude_private_ips and exclude_public_ips, attributes.exclude_private_ips: cannot be combined with exclude_public_ips and exclude_ipv6, attributes.exclude_public_ips: cannot be combined with exclude_private_ips and exclude_ipv6",
|
||||
},
|
||||
{
|
||||
name: "default",
|
||||
in: &structpb.Struct{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright IBM Corp. 2021, 2025
|
||||
// Copyright IBM Corp. 2021, 2026
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package host
|
||||
@@ -13,4 +13,16 @@ const (
|
||||
|
||||
// ConstAwsDualStack is the key for the dualstack flag in the aws s3 client.
|
||||
ConstAwsDualStack = "dual_stack"
|
||||
|
||||
// ConstPrimaryInterfaceOnly limits host discovery to the primary ENI.
|
||||
ConstPrimaryInterfaceOnly = "primary_interface_only"
|
||||
|
||||
// ConstExcludePrivateIps excludes private IPv4 addresses.
|
||||
ConstExcludePrivateIps = "exclude_private_ips"
|
||||
|
||||
// ConstExcludePublicIps excludes public IPv4 addresses associated to ENI IPs.
|
||||
ConstExcludePublicIps = "exclude_public_ips"
|
||||
|
||||
// ConstExcludeIpv6 excludes IPv6 addresses.
|
||||
ConstExcludeIpv6 = "exclude_ipv6"
|
||||
)
|
||||
@@ -1,8 +1,8 @@
|
||||
package host
|
||||
|
||||
// Copyright IBM Corp. 2021, 2025
|
||||
// Copyright IBM Corp. 2021, 2026
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package host
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
@@ -550,7 +550,7 @@ func (p *HostPlugin) ListHosts(ctx context.Context, req *pb.ListHostsRequest) (*
|
||||
// set of hosts afterwards (possibly removing duplicates).
|
||||
for _, reservation := range output.Reservations {
|
||||
for _, instance := range reservation.Instances {
|
||||
host, err := awsInstanceToHost(instance)
|
||||
host, err := awsInstanceToHost(instance, catalogAttributes)
|
||||
if err != nil {
|
||||
return nil, errors.BadRequestStatus("error processing host results for host set id %q: %s", query.Id, err)
|
||||
}
|
||||
@@ -648,10 +648,13 @@ func buildDescribeInstancesInput(attrs *SetAttributes, dryRun bool) (*ec2.Descri
|
||||
// awsInstanceToHost processes data from an ec2.Instance and returns
|
||||
// a ListHostsResponseHost with the ID and network addresses
|
||||
// populated.
|
||||
func awsInstanceToHost(instance types.Instance) (*pb.ListHostsResponseHost, error) {
|
||||
func awsInstanceToHost(instance types.Instance, catalogAttributes *CatalogAttributes) (*pb.ListHostsResponseHost, error) {
|
||||
if aws.ToString(instance.InstanceId) == "" {
|
||||
return nil, fmt.Errorf("response integrity error: missing instance id")
|
||||
}
|
||||
if catalogAttributes == nil {
|
||||
return nil, fmt.Errorf("catalog attributes are required")
|
||||
}
|
||||
|
||||
result := new(pb.ListHostsResponseHost)
|
||||
|
||||
@@ -666,22 +669,46 @@ func awsInstanceToHost(instance types.Instance) (*pb.ListHostsResponseHost, erro
|
||||
}
|
||||
}
|
||||
|
||||
result.IpAddresses = appendDistinct(result.IpAddresses, instance.PrivateIpAddress, instance.PublicIpAddress)
|
||||
result.DnsNames = appendDistinct(result.DnsNames, instance.PrivateDnsName, instance.PublicDnsName)
|
||||
if !catalogAttributes.ExcludePrivateIps {
|
||||
result.IpAddresses = appendDistinct(result.IpAddresses, instance.PrivateIpAddress)
|
||||
result.DnsNames = appendDistinct(result.DnsNames, instance.PrivateDnsName)
|
||||
}
|
||||
if !catalogAttributes.ExcludePublicIps {
|
||||
result.IpAddresses = appendDistinct(result.IpAddresses, instance.PublicIpAddress)
|
||||
result.DnsNames = appendDistinct(result.DnsNames, instance.PublicDnsName)
|
||||
}
|
||||
|
||||
// Now go through all of the interfaces and log the IP address of
|
||||
// every interface.
|
||||
for _, iface := range instance.NetworkInterfaces {
|
||||
if catalogAttributes.PrimaryInterfaceOnly {
|
||||
if iface.Attachment == nil || aws.ToInt32(iface.Attachment.DeviceIndex) != 0 {
|
||||
// We only want to sync the primary interface so skip any others
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
// Populate default IP addresses/DNS name similar to how we do
|
||||
// for the entire instance.
|
||||
result.IpAddresses = appendDistinct(result.IpAddresses, iface.PrivateIpAddress)
|
||||
result.DnsNames = appendDistinct(result.DnsNames, iface.PrivateDnsName)
|
||||
if !catalogAttributes.ExcludePrivateIps {
|
||||
result.IpAddresses = appendDistinct(result.IpAddresses, iface.PrivateIpAddress)
|
||||
result.DnsNames = appendDistinct(result.DnsNames, iface.PrivateDnsName)
|
||||
}
|
||||
|
||||
// Iterate through the private IP addresses and log the
|
||||
// information.
|
||||
for _, addr := range iface.PrivateIpAddresses {
|
||||
result.IpAddresses = appendDistinct(result.IpAddresses, addr.PrivateIpAddress)
|
||||
result.DnsNames = appendDistinct(result.DnsNames, addr.PrivateDnsName)
|
||||
if !catalogAttributes.ExcludePrivateIps {
|
||||
result.IpAddresses = appendDistinct(result.IpAddresses, addr.PrivateIpAddress)
|
||||
result.DnsNames = appendDistinct(result.DnsNames, addr.PrivateDnsName)
|
||||
}
|
||||
|
||||
if catalogAttributes.ExcludePublicIps {
|
||||
// skip adding public addresses if we are excluding them
|
||||
continue
|
||||
}
|
||||
|
||||
// PublicIP for iface is only available via an association to the private IP
|
||||
if addr.Association != nil {
|
||||
result.IpAddresses = appendDistinct(result.IpAddresses, addr.Association.PublicIp)
|
||||
result.DnsNames = appendDistinct(result.DnsNames, addr.Association.PublicDnsName)
|
||||
@@ -689,8 +716,10 @@ func awsInstanceToHost(instance types.Instance) (*pb.ListHostsResponseHost, erro
|
||||
}
|
||||
|
||||
// Add the IPv6 addresses.
|
||||
for _, addr := range iface.Ipv6Addresses {
|
||||
result.IpAddresses = appendDistinct(result.IpAddresses, addr.Ipv6Address)
|
||||
if !catalogAttributes.ExcludeIpv6 {
|
||||
for _, addr := range iface.Ipv6Addresses {
|
||||
result.IpAddresses = appendDistinct(result.IpAddresses, addr.Ipv6Address)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright IBM Corp. 2021, 2025
|
||||
// Copyright IBM Corp. 2021, 2026
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package host
|
||||
@@ -638,7 +638,8 @@ func TestPluginOnCreateCatalogErr(t *testing.T) {
|
||||
Fields: map[string]*structpb.Value{
|
||||
credential.ConstAccessKeyId: structpb.NewStringValue("AKIA_foobar"),
|
||||
credential.ConstSecretAccessKey: structpb.NewStringValue("bazqux"),
|
||||
}},
|
||||
},
|
||||
},
|
||||
Attrs: &hostcatalogs.HostCatalog_Attributes{
|
||||
Attributes: &structpb.Struct{
|
||||
Fields: map[string]*structpb.Value{
|
||||
@@ -664,7 +665,8 @@ func TestPluginOnCreateCatalogErr(t *testing.T) {
|
||||
Fields: map[string]*structpb.Value{
|
||||
credential.ConstAccessKeyId: structpb.NewStringValue("AKIA_foobar"),
|
||||
credential.ConstSecretAccessKey: structpb.NewStringValue("bazqux"),
|
||||
}},
|
||||
},
|
||||
},
|
||||
Attrs: &hostcatalogs.HostCatalog_Attributes{
|
||||
Attributes: &structpb.Struct{
|
||||
Fields: map[string]*structpb.Value{
|
||||
@@ -694,7 +696,8 @@ func TestPluginOnCreateCatalogErr(t *testing.T) {
|
||||
Fields: map[string]*structpb.Value{
|
||||
credential.ConstAccessKeyId: structpb.NewStringValue("AKIA_foobar"),
|
||||
credential.ConstSecretAccessKey: structpb.NewStringValue("bazqux"),
|
||||
}},
|
||||
},
|
||||
},
|
||||
Attrs: &hostcatalogs.HostCatalog_Attributes{
|
||||
Attributes: &structpb.Struct{
|
||||
Fields: map[string]*structpb.Value{
|
||||
@@ -721,7 +724,8 @@ func TestPluginOnCreateCatalogErr(t *testing.T) {
|
||||
Fields: map[string]*structpb.Value{
|
||||
credential.ConstAccessKeyId: structpb.NewStringValue("AKIA_foobar"),
|
||||
credential.ConstSecretAccessKey: structpb.NewStringValue("bazqux"),
|
||||
}},
|
||||
},
|
||||
},
|
||||
Attrs: &hostcatalogs.HostCatalog_Attributes{
|
||||
Attributes: &structpb.Struct{
|
||||
Fields: map[string]*structpb.Value{
|
||||
@@ -2383,10 +2387,11 @@ func TestBuildDescribeInstancesInput(t *testing.T) {
|
||||
|
||||
func TestAwsInstanceToHost(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
instance types.Instance
|
||||
expected *pb.ListHostsResponseHost
|
||||
expectedErr string
|
||||
name string
|
||||
instance types.Instance
|
||||
catalogAttributes *CatalogAttributes
|
||||
expected *pb.ListHostsResponseHost
|
||||
expectedErr string
|
||||
}{
|
||||
{
|
||||
name: "missing instance id",
|
||||
@@ -2591,14 +2596,45 @@ func TestAwsInstanceToHost(t *testing.T) {
|
||||
},
|
||||
Ipv6Addresses: []types.InstanceIpv6Address{
|
||||
{Ipv6Address: nil}, // Just coverage for nil assertion which is skipped
|
||||
{Ipv6Address: aws.String("some::fake::address")},
|
||||
{Ipv6Address: aws.String("2001:db8::1")},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: &pb.ListHostsResponseHost{
|
||||
ExternalId: "foobar",
|
||||
IpAddresses: []string{"10.0.0.1", "1.1.1.1", "some::fake::address"},
|
||||
IpAddresses: []string{"10.0.0.1", "1.1.1.1", "2001:db8::1"},
|
||||
DnsNames: []string{"test.example.internal", "test.example.com"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "good, single IP w/public addr",
|
||||
instance: types.Instance{
|
||||
InstanceId: aws.String("foobar"),
|
||||
PrivateIpAddress: aws.String("10.0.0.1"),
|
||||
PrivateDnsName: aws.String("test.example.internal"),
|
||||
PublicIpAddress: aws.String("1.1.1.1"),
|
||||
PublicDnsName: aws.String("test.example.com"),
|
||||
NetworkInterfaces: []types.InstanceNetworkInterface{
|
||||
{
|
||||
PrivateIpAddress: aws.String("10.0.0.1"),
|
||||
PrivateDnsName: aws.String("test.example.internal"),
|
||||
PrivateIpAddresses: []types.InstancePrivateIpAddress{
|
||||
{
|
||||
Association: &types.InstanceNetworkInterfaceAssociation{
|
||||
PublicIp: aws.String("1.1.1.1"),
|
||||
PublicDnsName: aws.String("test.example.com"),
|
||||
},
|
||||
PrivateIpAddress: aws.String("10.0.0.1"),
|
||||
PrivateDnsName: aws.String("test.example.internal"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: &pb.ListHostsResponseHost{
|
||||
ExternalId: "foobar",
|
||||
IpAddresses: []string{"10.0.0.1", "1.1.1.1"},
|
||||
DnsNames: []string{"test.example.internal", "test.example.com"},
|
||||
},
|
||||
},
|
||||
@@ -2676,18 +2712,663 @@ func TestAwsInstanceToHost(t *testing.T) {
|
||||
DnsNames: []string{"test.example.internal", "test.example.com"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "primary_interface_only keeps all addresses on primary ENI",
|
||||
catalogAttributes: &CatalogAttributes{
|
||||
PrimaryInterfaceOnly: true,
|
||||
},
|
||||
instance: types.Instance{
|
||||
InstanceId: aws.String("foobar"),
|
||||
PrivateIpAddress: aws.String("10.0.0.1"),
|
||||
PrivateDnsName: aws.String("test.example.internal"),
|
||||
PublicIpAddress: aws.String("1.1.1.1"),
|
||||
PublicDnsName: aws.String("test.example.com"),
|
||||
NetworkInterfaces: []types.InstanceNetworkInterface{
|
||||
{
|
||||
Attachment: &types.InstanceNetworkInterfaceAttachment{
|
||||
DeviceIndex: aws.Int32(0),
|
||||
},
|
||||
PrivateIpAddress: aws.String("10.0.0.1"),
|
||||
PrivateDnsName: aws.String("test.example.internal"),
|
||||
PrivateIpAddresses: []types.InstancePrivateIpAddress{
|
||||
{
|
||||
Primary: aws.Bool(true),
|
||||
PrivateIpAddress: aws.String("10.0.0.1"),
|
||||
PrivateDnsName: aws.String("test.example.internal"),
|
||||
},
|
||||
// Secondary IPs on primary ENI (e.g. VPC CNI pod IPs).
|
||||
{
|
||||
Primary: aws.Bool(false),
|
||||
PrivateIpAddress: aws.String("10.0.0.42"),
|
||||
PrivateDnsName: aws.String("pod-a.example.internal"),
|
||||
},
|
||||
{
|
||||
Primary: aws.Bool(false),
|
||||
PrivateIpAddress: aws.String("10.0.0.43"),
|
||||
PrivateDnsName: aws.String("pod-b.example.internal"),
|
||||
},
|
||||
},
|
||||
},
|
||||
// Secondary ENI attached by VPC CNI for additional pod IPs.
|
||||
{
|
||||
Attachment: &types.InstanceNetworkInterfaceAttachment{
|
||||
DeviceIndex: aws.Int32(1),
|
||||
},
|
||||
PrivateIpAddress: aws.String("10.0.0.99"),
|
||||
PrivateDnsName: aws.String("eni1.example.internal"),
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: &pb.ListHostsResponseHost{
|
||||
ExternalId: "foobar",
|
||||
IpAddresses: []string{"10.0.0.1", "1.1.1.1", "10.0.0.42", "10.0.0.43"},
|
||||
DnsNames: []string{"test.example.internal", "test.example.com", "pod-a.example.internal", "pod-b.example.internal"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "primary_interface_only keeps IPv6 on primary ENI",
|
||||
catalogAttributes: &CatalogAttributes{
|
||||
PrimaryInterfaceOnly: true,
|
||||
},
|
||||
instance: types.Instance{
|
||||
InstanceId: aws.String("foobar"),
|
||||
PrivateIpAddress: aws.String("10.0.0.1"),
|
||||
PrivateDnsName: aws.String("test.example.internal"),
|
||||
NetworkInterfaces: []types.InstanceNetworkInterface{
|
||||
// Secondary ENI listed first to verify ordering does not matter.
|
||||
{
|
||||
Attachment: &types.InstanceNetworkInterfaceAttachment{
|
||||
DeviceIndex: aws.Int32(1),
|
||||
},
|
||||
PrivateIpAddress: aws.String("10.0.0.99"),
|
||||
Ipv6Addresses: []types.InstanceIpv6Address{
|
||||
{Ipv6Address: aws.String("2001:db8::2")},
|
||||
},
|
||||
},
|
||||
{
|
||||
Attachment: &types.InstanceNetworkInterfaceAttachment{
|
||||
DeviceIndex: aws.Int32(0),
|
||||
},
|
||||
PrivateIpAddress: aws.String("10.0.0.1"),
|
||||
Ipv6Addresses: []types.InstanceIpv6Address{
|
||||
{Ipv6Address: aws.String("2001:db8::3")},
|
||||
{Ipv6Address: aws.String("2001:db8::4")},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: &pb.ListHostsResponseHost{
|
||||
ExternalId: "foobar",
|
||||
IpAddresses: []string{"10.0.0.1", "2001:db8::3", "2001:db8::4"},
|
||||
DnsNames: []string{"test.example.internal"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "primary_interface_only without interfaces still returns top-level IPs",
|
||||
catalogAttributes: &CatalogAttributes{
|
||||
PrimaryInterfaceOnly: true,
|
||||
},
|
||||
instance: types.Instance{
|
||||
InstanceId: aws.String("foobar"),
|
||||
PrivateIpAddress: aws.String("10.0.0.1"),
|
||||
PrivateDnsName: aws.String("test.example.internal"),
|
||||
PublicIpAddress: aws.String("1.1.1.1"),
|
||||
PublicDnsName: aws.String("test.example.com"),
|
||||
},
|
||||
expected: &pb.ListHostsResponseHost{
|
||||
ExternalId: "foobar",
|
||||
IpAddresses: []string{"10.0.0.1", "1.1.1.1"},
|
||||
DnsNames: []string{"test.example.internal", "test.example.com"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "exclude_public_ips excludes public IPv4 sources but keeps IPv6",
|
||||
catalogAttributes: &CatalogAttributes{
|
||||
ExcludePublicIps: true,
|
||||
},
|
||||
instance: types.Instance{
|
||||
InstanceId: aws.String("i-1234"),
|
||||
PrivateIpAddress: aws.String("10.0.0.1"),
|
||||
PrivateDnsName: aws.String("host.internal"),
|
||||
PublicIpAddress: aws.String("1.2.3.4"),
|
||||
PublicDnsName: aws.String("host.public"),
|
||||
NetworkInterfaces: []types.InstanceNetworkInterface{
|
||||
{
|
||||
PrivateIpAddress: aws.String("10.0.0.1"),
|
||||
PrivateDnsName: aws.String("host.internal"),
|
||||
PrivateIpAddresses: []types.InstancePrivateIpAddress{
|
||||
{
|
||||
PrivateIpAddress: aws.String("10.0.0.1"),
|
||||
PrivateDnsName: aws.String("host.internal"),
|
||||
Association: &types.InstanceNetworkInterfaceAssociation{
|
||||
PublicIp: aws.String("1.2.3.4"),
|
||||
PublicDnsName: aws.String("host.public"),
|
||||
},
|
||||
},
|
||||
},
|
||||
Ipv6Addresses: []types.InstanceIpv6Address{{Ipv6Address: aws.String("2001:db8::1")}},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: &pb.ListHostsResponseHost{
|
||||
ExternalId: "i-1234",
|
||||
IpAddresses: []string{"10.0.0.1", "2001:db8::1"},
|
||||
DnsNames: []string{"host.internal"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "exclude_private_ips excludes private IPv4 sources but keeps IPv6",
|
||||
catalogAttributes: &CatalogAttributes{
|
||||
ExcludePrivateIps: true,
|
||||
},
|
||||
instance: types.Instance{
|
||||
InstanceId: aws.String("i-1234"),
|
||||
PublicIpAddress: aws.String("1.2.3.4"),
|
||||
PublicDnsName: aws.String("host.public"),
|
||||
NetworkInterfaces: []types.InstanceNetworkInterface{
|
||||
{
|
||||
PrivateIpAddresses: []types.InstancePrivateIpAddress{
|
||||
{Association: &types.InstanceNetworkInterfaceAssociation{PublicIp: aws.String("1.2.3.4"), PublicDnsName: aws.String("host.public")}},
|
||||
},
|
||||
Ipv6Addresses: []types.InstanceIpv6Address{{Ipv6Address: aws.String("2001:db8::1")}},
|
||||
},
|
||||
{
|
||||
PrivateIpAddresses: []types.InstancePrivateIpAddress{
|
||||
{Association: &types.InstanceNetworkInterfaceAssociation{PublicIp: aws.String("1.2.3.5"), PublicDnsName: aws.String("svc.public")}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: &pb.ListHostsResponseHost{
|
||||
ExternalId: "i-1234",
|
||||
IpAddresses: []string{"1.2.3.4", "2001:db8::1", "1.2.3.5"},
|
||||
DnsNames: []string{"host.public", "svc.public"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "exclude_public_ips keeps IPv6 addresses",
|
||||
catalogAttributes: &CatalogAttributes{
|
||||
ExcludePublicIps: true,
|
||||
},
|
||||
instance: types.Instance{
|
||||
InstanceId: aws.String("i-1234"),
|
||||
PrivateIpAddress: aws.String("10.0.0.1"),
|
||||
PrivateDnsName: aws.String("host.internal"),
|
||||
NetworkInterfaces: []types.InstanceNetworkInterface{
|
||||
{
|
||||
PrivateIpAddress: aws.String("10.0.0.1"),
|
||||
PrivateDnsName: aws.String("host.internal"),
|
||||
Ipv6Addresses: []types.InstanceIpv6Address{{Ipv6Address: aws.String("fd00::1")}},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: &pb.ListHostsResponseHost{
|
||||
ExternalId: "i-1234",
|
||||
IpAddresses: []string{"10.0.0.1", "fd00::1"},
|
||||
DnsNames: []string{"host.internal"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "exclude_ipv6 omits IPv6 while preserving IPv4 and DNS",
|
||||
catalogAttributes: &CatalogAttributes{
|
||||
ExcludeIpv6: true,
|
||||
},
|
||||
instance: types.Instance{
|
||||
InstanceId: aws.String("i-1234"),
|
||||
PrivateIpAddress: aws.String("10.0.0.1"),
|
||||
PrivateDnsName: aws.String("host.internal"),
|
||||
PublicIpAddress: aws.String("1.2.3.4"),
|
||||
PublicDnsName: aws.String("host.public"),
|
||||
NetworkInterfaces: []types.InstanceNetworkInterface{
|
||||
{
|
||||
PrivateIpAddress: aws.String("10.0.0.1"),
|
||||
PrivateDnsName: aws.String("host.internal"),
|
||||
PrivateIpAddresses: []types.InstancePrivateIpAddress{
|
||||
{
|
||||
PrivateIpAddress: aws.String("10.0.0.1"),
|
||||
PrivateDnsName: aws.String("host.internal"),
|
||||
Association: &types.InstanceNetworkInterfaceAssociation{
|
||||
PublicIp: aws.String("1.2.3.4"),
|
||||
PublicDnsName: aws.String("host.public"),
|
||||
},
|
||||
},
|
||||
},
|
||||
Ipv6Addresses: []types.InstanceIpv6Address{{Ipv6Address: aws.String("2001:db8::1")}},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: &pb.ListHostsResponseHost{
|
||||
ExternalId: "i-1234",
|
||||
IpAddresses: []string{"10.0.0.1", "1.2.3.4"},
|
||||
DnsNames: []string{"host.internal", "host.public"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "exclude_public_ips with exclude_ipv6 keeps only private IPv4 sources",
|
||||
catalogAttributes: &CatalogAttributes{
|
||||
ExcludePublicIps: true,
|
||||
ExcludeIpv6: true,
|
||||
},
|
||||
instance: types.Instance{
|
||||
InstanceId: aws.String("i-1234"),
|
||||
PrivateIpAddress: aws.String("10.0.0.1"),
|
||||
PrivateDnsName: aws.String("host.internal"),
|
||||
PublicIpAddress: aws.String("1.2.3.4"),
|
||||
PublicDnsName: aws.String("host.public"),
|
||||
NetworkInterfaces: []types.InstanceNetworkInterface{
|
||||
{
|
||||
PrivateIpAddress: aws.String("10.0.0.1"),
|
||||
PrivateDnsName: aws.String("host.internal"),
|
||||
PrivateIpAddresses: []types.InstancePrivateIpAddress{
|
||||
{
|
||||
PrivateIpAddress: aws.String("10.0.0.1"),
|
||||
PrivateDnsName: aws.String("host.internal"),
|
||||
Association: &types.InstanceNetworkInterfaceAssociation{
|
||||
PublicIp: aws.String("1.2.3.4"),
|
||||
PublicDnsName: aws.String("host.public"),
|
||||
},
|
||||
},
|
||||
{
|
||||
PrivateIpAddress: aws.String("10.0.0.2"),
|
||||
PrivateDnsName: aws.String("svc.internal"),
|
||||
},
|
||||
},
|
||||
Ipv6Addresses: []types.InstanceIpv6Address{{Ipv6Address: aws.String("2001:db8::1")}},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: &pb.ListHostsResponseHost{
|
||||
ExternalId: "i-1234",
|
||||
IpAddresses: []string{"10.0.0.1", "10.0.0.2"},
|
||||
DnsNames: []string{"host.internal", "svc.internal"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "exclude_private_ips with exclude_ipv6 keeps only public IPv4 sources",
|
||||
catalogAttributes: &CatalogAttributes{
|
||||
ExcludePrivateIps: true,
|
||||
ExcludeIpv6: true,
|
||||
},
|
||||
instance: types.Instance{
|
||||
InstanceId: aws.String("i-1234"),
|
||||
PublicIpAddress: aws.String("1.2.3.4"),
|
||||
PublicDnsName: aws.String("host.public"),
|
||||
NetworkInterfaces: []types.InstanceNetworkInterface{
|
||||
{
|
||||
PrivateIpAddresses: []types.InstancePrivateIpAddress{
|
||||
{
|
||||
Association: &types.InstanceNetworkInterfaceAssociation{
|
||||
PublicIp: aws.String("1.2.3.4"),
|
||||
PublicDnsName: aws.String("host.public"),
|
||||
},
|
||||
},
|
||||
{
|
||||
Association: &types.InstanceNetworkInterfaceAssociation{
|
||||
PublicIp: aws.String("1.2.3.5"),
|
||||
PublicDnsName: aws.String("svc.public"),
|
||||
},
|
||||
},
|
||||
},
|
||||
Ipv6Addresses: []types.InstanceIpv6Address{{Ipv6Address: aws.String("fd00::1")}},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: &pb.ListHostsResponseHost{
|
||||
ExternalId: "i-1234",
|
||||
IpAddresses: []string{"1.2.3.4", "1.2.3.5"},
|
||||
DnsNames: []string{"host.public", "svc.public"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "primary_interface_only with exclude_ipv6 drops IPv6 from primary ENI",
|
||||
catalogAttributes: &CatalogAttributes{
|
||||
PrimaryInterfaceOnly: true,
|
||||
ExcludeIpv6: true,
|
||||
},
|
||||
instance: types.Instance{
|
||||
InstanceId: aws.String("foobar"),
|
||||
PrivateIpAddress: aws.String("10.0.0.1"),
|
||||
PrivateDnsName: aws.String("test.example.internal"),
|
||||
PublicIpAddress: aws.String("1.1.1.1"),
|
||||
PublicDnsName: aws.String("test.example.com"),
|
||||
NetworkInterfaces: []types.InstanceNetworkInterface{
|
||||
{
|
||||
Attachment: &types.InstanceNetworkInterfaceAttachment{
|
||||
DeviceIndex: aws.Int32(0),
|
||||
},
|
||||
PrivateIpAddress: aws.String("10.0.0.1"),
|
||||
PrivateDnsName: aws.String("test.example.internal"),
|
||||
PrivateIpAddresses: []types.InstancePrivateIpAddress{
|
||||
{
|
||||
PrivateIpAddress: aws.String("10.0.0.42"),
|
||||
PrivateDnsName: aws.String("pod-a.example.internal"),
|
||||
},
|
||||
},
|
||||
Ipv6Addresses: []types.InstanceIpv6Address{{Ipv6Address: aws.String("2001:db8::3")}},
|
||||
},
|
||||
{
|
||||
Attachment: &types.InstanceNetworkInterfaceAttachment{
|
||||
DeviceIndex: aws.Int32(1),
|
||||
},
|
||||
PrivateIpAddress: aws.String("10.0.0.99"),
|
||||
PrivateDnsName: aws.String("eni1.example.internal"),
|
||||
Ipv6Addresses: []types.InstanceIpv6Address{{Ipv6Address: aws.String("2001:db8::4")}},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: &pb.ListHostsResponseHost{
|
||||
ExternalId: "foobar",
|
||||
IpAddresses: []string{"10.0.0.1", "1.1.1.1", "10.0.0.42"},
|
||||
DnsNames: []string{"test.example.internal", "test.example.com", "pod-a.example.internal"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "exclude_ipv6 on IPv6-only interface leaves no addresses",
|
||||
catalogAttributes: &CatalogAttributes{
|
||||
ExcludeIpv6: true,
|
||||
},
|
||||
instance: types.Instance{
|
||||
InstanceId: aws.String("i-1234"),
|
||||
NetworkInterfaces: []types.InstanceNetworkInterface{
|
||||
{
|
||||
Ipv6Addresses: []types.InstanceIpv6Address{
|
||||
{Ipv6Address: aws.String("2001:db8::1")},
|
||||
{Ipv6Address: aws.String("fd00::1")},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: &pb.ListHostsResponseHost{
|
||||
ExternalId: "i-1234",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "deduplicates repeated addresses and DNS names across instance and interfaces",
|
||||
instance: types.Instance{
|
||||
InstanceId: aws.String("i-1234"),
|
||||
PrivateIpAddress: aws.String("10.0.0.1"),
|
||||
PrivateDnsName: aws.String("host.internal"),
|
||||
PublicIpAddress: aws.String("1.2.3.4"),
|
||||
PublicDnsName: aws.String("host.public"),
|
||||
NetworkInterfaces: []types.InstanceNetworkInterface{
|
||||
{
|
||||
PrivateIpAddress: aws.String("10.0.0.1"),
|
||||
PrivateDnsName: aws.String("host.internal"),
|
||||
PrivateIpAddresses: []types.InstancePrivateIpAddress{
|
||||
{
|
||||
PrivateIpAddress: aws.String("10.0.0.1"),
|
||||
PrivateDnsName: aws.String("host.internal"),
|
||||
Association: &types.InstanceNetworkInterfaceAssociation{
|
||||
PublicIp: aws.String("1.2.3.4"),
|
||||
PublicDnsName: aws.String("host.public"),
|
||||
},
|
||||
},
|
||||
},
|
||||
Ipv6Addresses: []types.InstanceIpv6Address{
|
||||
{Ipv6Address: aws.String("2001:db8::1")},
|
||||
{Ipv6Address: aws.String("2001:db8::1")},
|
||||
},
|
||||
},
|
||||
{
|
||||
PrivateIpAddress: aws.String("10.0.0.1"),
|
||||
PrivateDnsName: aws.String("host.internal"),
|
||||
PrivateIpAddresses: []types.InstancePrivateIpAddress{
|
||||
{
|
||||
Association: &types.InstanceNetworkInterfaceAssociation{
|
||||
PublicIp: aws.String("1.2.3.4"),
|
||||
PublicDnsName: aws.String("host.public"),
|
||||
},
|
||||
},
|
||||
},
|
||||
Ipv6Addresses: []types.InstanceIpv6Address{
|
||||
{Ipv6Address: aws.String("2001:db8::1")},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: &pb.ListHostsResponseHost{
|
||||
ExternalId: "i-1234",
|
||||
IpAddresses: []string{"10.0.0.1", "1.2.3.4", "2001:db8::1"},
|
||||
DnsNames: []string{"host.internal", "host.public"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "primary_interface_only skips interfaces without attachment metadata",
|
||||
catalogAttributes: &CatalogAttributes{
|
||||
PrimaryInterfaceOnly: true,
|
||||
},
|
||||
instance: types.Instance{
|
||||
InstanceId: aws.String("i-1234"),
|
||||
PrivateIpAddress: aws.String("10.0.0.1"),
|
||||
PrivateDnsName: aws.String("host.internal"),
|
||||
PublicIpAddress: aws.String("1.2.3.4"),
|
||||
PublicDnsName: aws.String("host.public"),
|
||||
NetworkInterfaces: []types.InstanceNetworkInterface{
|
||||
{
|
||||
PrivateIpAddress: aws.String("10.0.0.99"),
|
||||
PrivateDnsName: aws.String("missing-attachment.internal"),
|
||||
PrivateIpAddresses: []types.InstancePrivateIpAddress{
|
||||
{
|
||||
PrivateIpAddress: aws.String("10.0.0.99"),
|
||||
PrivateDnsName: aws.String("missing-attachment.internal"),
|
||||
},
|
||||
},
|
||||
Ipv6Addresses: []types.InstanceIpv6Address{{Ipv6Address: aws.String("2001:db8::99")}},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: &pb.ListHostsResponseHost{
|
||||
ExternalId: "i-1234",
|
||||
IpAddresses: []string{"10.0.0.1", "1.2.3.4"},
|
||||
DnsNames: []string{"host.internal", "host.public"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "exclude_private_ips removes private DNS names even when public addresses remain",
|
||||
catalogAttributes: &CatalogAttributes{
|
||||
ExcludePrivateIps: true,
|
||||
},
|
||||
instance: types.Instance{
|
||||
InstanceId: aws.String("i-1234"),
|
||||
PublicIpAddress: aws.String("1.2.3.4"),
|
||||
PublicDnsName: aws.String("host.public"),
|
||||
NetworkInterfaces: []types.InstanceNetworkInterface{
|
||||
{
|
||||
PrivateIpAddress: aws.String("10.0.0.1"),
|
||||
PrivateDnsName: aws.String("host.internal"),
|
||||
PrivateIpAddresses: []types.InstancePrivateIpAddress{
|
||||
{
|
||||
PrivateIpAddress: aws.String("10.0.0.1"),
|
||||
PrivateDnsName: aws.String("host.internal"),
|
||||
Association: &types.InstanceNetworkInterfaceAssociation{
|
||||
PublicIp: aws.String("1.2.3.4"),
|
||||
PublicDnsName: aws.String("host.public"),
|
||||
},
|
||||
},
|
||||
{
|
||||
PrivateIpAddress: aws.String("10.0.0.2"),
|
||||
PrivateDnsName: aws.String("svc.internal"),
|
||||
Association: &types.InstanceNetworkInterfaceAssociation{
|
||||
PublicIp: aws.String("1.2.3.5"),
|
||||
PublicDnsName: aws.String("svc.public"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: &pb.ListHostsResponseHost{
|
||||
ExternalId: "i-1234",
|
||||
IpAddresses: []string{"1.2.3.4", "1.2.3.5"},
|
||||
DnsNames: []string{"host.public", "svc.public"},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
tc := tc
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
require := require.New(t)
|
||||
actual, err := awsInstanceToHost(tc.instance)
|
||||
attrs := tc.catalogAttributes
|
||||
if attrs == nil {
|
||||
attrs = &CatalogAttributes{}
|
||||
}
|
||||
actual, err := awsInstanceToHost(tc.instance, attrs)
|
||||
if tc.expectedErr != "" {
|
||||
require.EqualError(err, tc.expectedErr)
|
||||
return
|
||||
}
|
||||
require.NoError(err)
|
||||
require.Equal(tc.expected, actual)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetCatalogAttributesAddressSelection(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
in *structpb.Struct
|
||||
expectedErr string
|
||||
expected *CatalogAttributes
|
||||
}{
|
||||
{
|
||||
name: "valid selectors",
|
||||
in: &structpb.Struct{
|
||||
Fields: map[string]*structpb.Value{
|
||||
"region": structpb.NewStringValue("us-west-2"),
|
||||
"primary_interface_only": structpb.NewBoolValue(true),
|
||||
"exclude_public_ips": structpb.NewBoolValue(true),
|
||||
"exclude_ipv6": structpb.NewBoolValue(true),
|
||||
},
|
||||
},
|
||||
expected: &CatalogAttributes{
|
||||
CredentialAttributes: &credential.CredentialAttributes{
|
||||
Region: "us-west-2",
|
||||
DisableCredentialRotation: false,
|
||||
},
|
||||
PrimaryInterfaceOnly: true,
|
||||
ExcludePublicIps: true,
|
||||
ExcludeIpv6: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "exclude_private_ips can be combined with exclude_ipv6",
|
||||
in: &structpb.Struct{
|
||||
Fields: map[string]*structpb.Value{
|
||||
"region": structpb.NewStringValue("us-west-2"),
|
||||
"exclude_private_ips": structpb.NewBoolValue(true),
|
||||
"exclude_ipv6": structpb.NewBoolValue(true),
|
||||
},
|
||||
},
|
||||
expected: &CatalogAttributes{
|
||||
CredentialAttributes: &credential.CredentialAttributes{
|
||||
Region: "us-west-2",
|
||||
DisableCredentialRotation: false,
|
||||
},
|
||||
ExcludePrivateIps: true,
|
||||
ExcludeIpv6: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "exclude_public_ips can be combined with exclude_ipv6",
|
||||
in: &structpb.Struct{
|
||||
Fields: map[string]*structpb.Value{
|
||||
"region": structpb.NewStringValue("us-west-2"),
|
||||
"exclude_public_ips": structpb.NewBoolValue(true),
|
||||
"exclude_ipv6": structpb.NewBoolValue(true),
|
||||
},
|
||||
},
|
||||
expected: &CatalogAttributes{
|
||||
CredentialAttributes: &credential.CredentialAttributes{
|
||||
Region: "us-west-2",
|
||||
DisableCredentialRotation: false,
|
||||
},
|
||||
ExcludePublicIps: true,
|
||||
ExcludeIpv6: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "exclude_private_ips and exclude_public_ips can be combined when IPv6 remains enabled",
|
||||
in: &structpb.Struct{
|
||||
Fields: map[string]*structpb.Value{
|
||||
"region": structpb.NewStringValue("us-west-2"),
|
||||
"exclude_private_ips": structpb.NewBoolValue(true),
|
||||
"exclude_public_ips": structpb.NewBoolValue(true),
|
||||
},
|
||||
},
|
||||
expected: &CatalogAttributes{
|
||||
CredentialAttributes: &credential.CredentialAttributes{
|
||||
Region: "us-west-2",
|
||||
DisableCredentialRotation: false,
|
||||
},
|
||||
ExcludePrivateIps: true,
|
||||
ExcludePublicIps: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "exclude_private_ips and exclude_public_ips cannot also exclude_ipv6",
|
||||
in: &structpb.Struct{
|
||||
Fields: map[string]*structpb.Value{
|
||||
"region": structpb.NewStringValue("us-west-2"),
|
||||
"exclude_private_ips": structpb.NewBoolValue(true),
|
||||
"exclude_public_ips": structpb.NewBoolValue(true),
|
||||
"exclude_ipv6": structpb.NewBoolValue(true),
|
||||
},
|
||||
},
|
||||
expectedErr: "attributes.exclude_ipv6: cannot be combined with exclude_private_ips and exclude_public_ips, attributes.exclude_private_ips: cannot be combined with exclude_public_ips and exclude_ipv6, attributes.exclude_public_ips: cannot be combined with exclude_private_ips and exclude_ipv6",
|
||||
},
|
||||
{
|
||||
name: "exclude_ipv6 alone is accepted",
|
||||
in: &structpb.Struct{
|
||||
Fields: map[string]*structpb.Value{
|
||||
"region": structpb.NewStringValue("us-west-2"),
|
||||
"exclude_ipv6": structpb.NewBoolValue(true),
|
||||
},
|
||||
},
|
||||
expected: &CatalogAttributes{
|
||||
CredentialAttributes: &credential.CredentialAttributes{
|
||||
Region: "us-west-2",
|
||||
DisableCredentialRotation: false,
|
||||
},
|
||||
ExcludeIpv6: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "exclude_ipv6 requires a boolean",
|
||||
in: &structpb.Struct{
|
||||
Fields: map[string]*structpb.Value{
|
||||
"region": structpb.NewStringValue("us-west-2"),
|
||||
"exclude_ipv6": structpb.NewStringValue("true"),
|
||||
},
|
||||
},
|
||||
expectedErr: "attributes.exclude_ipv6",
|
||||
},
|
||||
{
|
||||
name: "no selectors configured preserves historical behavior",
|
||||
in: &structpb.Struct{
|
||||
Fields: map[string]*structpb.Value{
|
||||
"region": structpb.NewStringValue("us-west-2"),
|
||||
},
|
||||
},
|
||||
expected: &CatalogAttributes{
|
||||
CredentialAttributes: &credential.CredentialAttributes{
|
||||
Region: "us-west-2",
|
||||
DisableCredentialRotation: false,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
tc := tc
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
require := require.New(t)
|
||||
actual, err := getCatalogAttributes(tc.in)
|
||||
if tc.expectedErr != "" {
|
||||
require.Error(err)
|
||||
require.Contains(err.Error(), tc.expectedErr)
|
||||
return
|
||||
}
|
||||
require.NoError(err)
|
||||
require.Equal(tc.expected, actual)
|
||||
})
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright IBM Corp. 2021, 2025
|
||||
// Copyright IBM Corp. 2021, 2026
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package host
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright IBM Corp. 2021, 2025
|
||||
// Copyright IBM Corp. 2021, 2026
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package host
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright IBM Corp. 2021, 2025
|
||||
// Copyright IBM Corp. 2021, 2026
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package host
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright IBM Corp. 2021, 2025
|
||||
// Copyright IBM Corp. 2021, 2026
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package storage
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright IBM Corp. 2021, 2025
|
||||
// Copyright IBM Corp. 2021, 2026
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package storage
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright IBM Corp. 2021, 2025
|
||||
// Copyright IBM Corp. 2021, 2026
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package storage
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright IBM Corp. 2021, 2025
|
||||
// Copyright IBM Corp. 2021, 2026
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package storage
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright IBM Corp. 2021, 2025
|
||||
// Copyright IBM Corp. 2021, 2026
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package storage
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright IBM Corp. 2021, 2025
|
||||
// Copyright IBM Corp. 2021, 2026
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package storage
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright IBM Corp. 2021, 2025
|
||||
// Copyright IBM Corp. 2021, 2026
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package storage
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright IBM Corp. 2021, 2025
|
||||
// Copyright IBM Corp. 2021, 2026
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package storage
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright IBM Corp. 2021, 2025
|
||||
// Copyright IBM Corp. 2021, 2026
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package storage
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright IBM Corp. 2021, 2025
|
||||
// Copyright IBM Corp. 2021, 2026
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package storage
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright IBM Corp. 2021, 2025
|
||||
// Copyright IBM Corp. 2021, 2026
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package testing
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright IBM Corp. 2021, 2025
|
||||
// Copyright IBM Corp. 2021, 2026
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package testing
|
||||
|
||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
||||
# Copyright IBM Corp. 2021, 2025
|
||||
# Copyright IBM Corp. 2021, 2026
|
||||
# SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
variable "iam_user_prefix" {
|
||||
|
||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
||||
# Copyright IBM Corp. 2021, 2025
|
||||
# Copyright IBM Corp. 2021, 2026
|
||||
# SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
terraform {
|
||||
|
||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
||||
# Copyright IBM Corp. 2021, 2025
|
||||
# Copyright IBM Corp. 2021, 2026
|
||||
# SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
variable "instance_tags" {
|
||||
|
||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
||||
# Copyright IBM Corp. 2021, 2025
|
||||
# Copyright IBM Corp. 2021, 2026
|
||||
# SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
resource "random_id" "foo" {
|
||||
|
||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
||||
# Copyright IBM Corp. 2021, 2025
|
||||
# Copyright IBM Corp. 2021, 2026
|
||||
# SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
resource "aws_iam_role" "valid" {
|
||||
|
||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
||||
# Copyright IBM Corp. 2021, 2025
|
||||
# Copyright IBM Corp. 2021, 2026
|
||||
# SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
terraform {
|
||||
|
||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
||||
# Copyright IBM Corp. 2021, 2025
|
||||
# Copyright IBM Corp. 2021, 2026
|
||||
# SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
output "bucket_name" {
|
||||
|
||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
||||
# Copyright IBM Corp. 2021, 2025
|
||||
# Copyright IBM Corp. 2021, 2026
|
||||
# SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
resource "aws_s3_bucket" "test" {
|
||||
|
||||
Vendored
+1
-1
@@ -1,4 +1,4 @@
|
||||
# Copyright IBM Corp. 2021, 2025
|
||||
# Copyright IBM Corp. 2021, 2026
|
||||
# SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
data "aws_caller_identity" "current" {}
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// Copyright IBM Corp. 2021, 2025
|
||||
// Copyright IBM Corp. 2021, 2026
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package testing
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright IBM Corp. 2021, 2025
|
||||
// Copyright IBM Corp. 2021, 2026
|
||||
// SPDX-License-Identifier: MPL-2.0
|
||||
|
||||
package testing
|
||||
|
||||
Reference in new issue
Block a user