Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clevos 94481 remove hardcoded endpoints #5484

Merged
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions ibm/conns/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
"log"
"net"
Expand Down Expand Up @@ -3567,6 +3568,27 @@ func EnvFallBack(envs []string, defaultValue string) string {
return defaultValue
}

func FileFallBack(endpointsFile, visibility, key, region, defaultValue string) string {
var fileMap map[string]interface{}
if f := EnvFallBack([]string{"IBMCLOUD_ENDPOINTS_FILE_PATH", "IC_ENDPOINTS_FILE_PATH"}, endpointsFile); f != "" {
jsonFile, err := os.Open(f)
if err != nil {
log.Fatalf("Unable to open Endpoints File %s", err)
}
defer jsonFile.Close()
bytes, err := io.ReadAll(jsonFile)
if err != nil {
log.Fatalf("Unable to read Endpoints File %s", err)
}
err = json.Unmarshal([]byte(bytes), &fileMap)
if err != nil {
log.Fatalf("Unable to unmarshal Endpoints File %s", err)
}
}

return fileFallBack(fileMap, visibility, key, region, defaultValue)
}

func fileFallBack(fileMap map[string]interface{}, visibility, key, region, defaultValue string) string {
if val, ok := fileMap[key]; ok {
if v, ok := val.(map[string]interface{})[visibility]; ok {
Expand Down
23 changes: 16 additions & 7 deletions ibm/service/cos/data_source_ibm_cos_bucket.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ import (

var bucketTypes = []string{"single_site_location", "region_location", "cross_region_location"}

var cosConfigUrls = map[string]string{
"private": "https://config.private.cloud-object-storage.cloud.ibm.com/v1",
"direct": "https://config.direct.cloud-object-storage.cloud.ibm.com/v1",
}

func DataSourceIBMCosBucket() *schema.Resource {
return &schema.Resource{
Read: dataSourceIBMCosBucketRead,
Expand Down Expand Up @@ -62,7 +67,7 @@ func DataSourceIBMCosBucket() *schema.Resource {
Optional: true,
// ValidateFunc: validate.ValidateAllowedStringValues([]string{"public", "private", "direct"}),
ValidateFunc: validate.InvokeDataSourceValidator("ibm_cos_bucket", "endpoint_type"),
Description: "public or private",
Description: "COS endpoint type: public, private, direct",
ConflictsWith: []string{"satellite_location_id"},
Default: "public",
},
Expand Down Expand Up @@ -602,7 +607,7 @@ func dataSourceIBMCosBucketRead(d *schema.ResourceData, meta interface{}) error
keyProtectFlag = true
}

var satlc_id, apiEndpoint, apiEndpointPrivate, directApiEndpoint string
var satlc_id, apiEndpoint, apiEndpointPrivate, directApiEndpoint, visibility string

if satlc, ok := d.GetOk("satellite_location_id"); ok {
satlc_id = satlc.(string)
Expand All @@ -617,15 +622,19 @@ func dataSourceIBMCosBucketRead(d *schema.ResourceData, meta interface{}) error

} else {
apiEndpoint, apiEndpointPrivate, directApiEndpoint = SelectCosApi(bucketLocationConvert(bucketType), bucketRegion)
visibility = endpointType
if endpointType == "private" {
apiEndpoint = apiEndpointPrivate
}
if endpointType == "direct" {
// visibility type "direct" is not supported in endpoints file.
visibility = "private"
apiEndpoint = directApiEndpoint
}

}

apiEndpoint = conns.FileFallBack(rsConClient.Config.EndpointsFile, visibility, "IBMCLOUD_COS_ENDPOINT", bucketRegion, apiEndpoint)
apiEndpoint = conns.EnvFallBack([]string{"IBMCLOUD_COS_ENDPOINT"}, apiEndpoint)
if apiEndpoint == "" {
return fmt.Errorf("[ERROR] The endpoint doesn't exists for given location %s and endpoint type %s", bucketRegion, endpointType)
Expand Down Expand Up @@ -716,11 +725,11 @@ func dataSourceIBMCosBucketRead(d *schema.ResourceData, meta interface{}) error
if err != nil {
return err
}
if endpointType == "private" {
sess.SetServiceURL("https://config.private.cloud-object-storage.cloud.ibm.com/v1")
}
if endpointType == "direct" {
sess.SetServiceURL("https://config.direct.cloud-object-storage.cloud.ibm.com/v1")
if endpointType != "public" {
// User is expected to define both private and direct url type under "private" in endpoints file since visibility type "direct" is not supported.
cosConfigURL := conns.FileFallBack(rsConClient.Config.EndpointsFile, "private", "IBMCLOUD_COS_CONFIG_ENDPOINT", bucketRegion, cosConfigUrls[endpointType])
cosConfigURL = conns.EnvFallBack([]string{"IBMCLOUD_COS_CONFIG_ENDPOINT"}, cosConfigURL)
sess.SetServiceURL(cosConfigURL)
}

if bucketType == "sl" {
Expand Down
48 changes: 31 additions & 17 deletions ibm/service/cos/resource_ibm_cos_bucket.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ func ResourceIBMCOSBucket() *schema.Resource {
"endpoint_type": {
Type: schema.TypeString,
Optional: true,
Description: "public or private",
Description: "COS endpoint type: public, private, direct",
ConflictsWith: []string{"satellite_location_id"},
DiffSuppressFunc: flex.ApplyOnce,
Default: "public",
Expand Down Expand Up @@ -751,21 +751,27 @@ func resourceIBMCOSBucketUpdate(d *schema.ResourceData, meta interface{}) error
serviceID = bucketsatcrn
}

var apiEndpoint, apiEndpointPrivate, directApiEndpoint string
var apiEndpoint, apiEndpointPrivate, directApiEndpoint, visibility string

if apiType == "sl" {
apiEndpoint = SelectSatlocCosApi(apiType, serviceID, bLocation)
} else {
apiEndpoint, apiEndpointPrivate, directApiEndpoint = SelectCosApi(apiType, bLocation)
visibility = endpointType
if endpointType == "private" {
apiEndpoint = apiEndpointPrivate
}
if endpointType == "direct" {
// visibility type "direct" is not supported in endpoints file.
visibility = "private"
apiEndpoint = directApiEndpoint
}

}

apiEndpoint = conns.FileFallBack(rsConClient.Config.EndpointsFile, visibility, "IBMCLOUD_COS_ENDPOINT", bLocation, apiEndpoint)
apiEndpoint = conns.EnvFallBack([]string{"IBMCLOUD_COS_ENDPOINT"}, apiEndpoint)

authEndpoint, err := rsConClient.Config.EndpointLocator.IAMEndpoint()

if err != nil {
Expand All @@ -774,7 +780,7 @@ func resourceIBMCOSBucketUpdate(d *schema.ResourceData, meta interface{}) error
authEndpointPath := fmt.Sprintf("%s%s", authEndpoint, "/identity/token")
apiKey := rsConClient.Config.BluemixAPIKey
if apiKey != "" {
s3Conf = aws.NewConfig().WithEndpoint(conns.EnvFallBack([]string{"IBMCLOUD_COS_ENDPOINT"}, apiEndpoint)).WithCredentials(ibmiam.NewStaticCredentials(aws.NewConfig(), authEndpointPath, apiKey, serviceID)).WithS3ForcePathStyle(true)
s3Conf = aws.NewConfig().WithEndpoint(apiEndpoint).WithCredentials(ibmiam.NewStaticCredentials(aws.NewConfig(), authEndpointPath, apiKey, serviceID)).WithS3ForcePathStyle(true)
}
iamAccessToken := rsConClient.Config.IAMAccessToken
if iamAccessToken != "" {
Expand All @@ -787,7 +793,7 @@ func resourceIBMCOSBucketUpdate(d *schema.ResourceData, meta interface{}) error
Expiration: time.Now().Add(-1 * time.Hour).Unix(),
}, nil
}
s3Conf = aws.NewConfig().WithEndpoint(conns.EnvFallBack([]string{"IBMCLOUD_COS_ENDPOINT"}, apiEndpoint)).WithCredentials(ibmiam.NewCustomInitFuncCredentials(aws.NewConfig(), initFunc, authEndpointPath, serviceID)).WithS3ForcePathStyle(true)
s3Conf = aws.NewConfig().WithEndpoint(apiEndpoint).WithCredentials(ibmiam.NewCustomInitFuncCredentials(aws.NewConfig(), initFunc, authEndpointPath, serviceID)).WithS3ForcePathStyle(true)
}
s3Sess := session.Must(session.NewSession())
s3Client := s3.New(s3Sess, s3Conf)
Expand Down Expand Up @@ -928,11 +934,12 @@ func resourceIBMCOSBucketUpdate(d *schema.ResourceData, meta interface{}) error
if err != nil {
return err
}
if endpointType == "private" {
sess.SetServiceURL("https://config.private.cloud-object-storage.cloud.ibm.com/v1")
}
if endpointType == "direct" {
sess.SetServiceURL("https://config.direct.cloud-object-storage.cloud.ibm.com/v1")

if endpointType != "public" {
// User is expected to define both private and direct url type under "private" in endpoints file since visibility type "direct" is not supported.
cosConfigURL := conns.FileFallBack(rsConClient.Config.EndpointsFile, "private", "IBMCLOUD_COS_CONFIG_ENDPOINT", bLocation, cosConfigUrls[endpointType])
cosConfigURL = conns.EnvFallBack([]string{"IBMCLOUD_COS_CONFIG_ENDPOINT"}, cosConfigURL)
sess.SetServiceURL(cosConfigURL)
}

if apiType == "sl" {
Expand Down Expand Up @@ -1194,11 +1201,11 @@ func resourceIBMCOSBucketRead(d *schema.ResourceData, meta interface{}) error {
if err != nil {
return err
}
if endpointType == "private" {
sess.SetServiceURL("https://config.private.cloud-object-storage.cloud.ibm.com/v1")
}
if endpointType == "direct" {
sess.SetServiceURL("https://config.direct.cloud-object-storage.cloud.ibm.com/v1")
if endpointType != "public" {
// User is expected to define both private and direct url type under "private" in endpoints file since visibility type "direct" is not supported.
cosConfigURL := conns.FileFallBack(rsConClient.Config.EndpointsFile, "private", "IBMCLOUD_COS_CONFIG_ENDPOINT", bLocation, cosConfigUrls[endpointType])
cosConfigURL = conns.EnvFallBack([]string{"IBMCLOUD_COS_CONFIG_ENDPOINT"}, cosConfigURL)
sess.SetServiceURL(cosConfigURL)
}

if apiType == "sl" {
Expand Down Expand Up @@ -1382,22 +1389,25 @@ func resourceIBMCOSBucketCreate(d *schema.ResourceData, meta interface{}) error

var endpointType = d.Get("endpoint_type").(string)

var apiEndpoint, privateApiEndpoint, directApiEndpoint string
var apiEndpoint, privateApiEndpoint, directApiEndpoint, visibility string
if apiType == "sl" {

apiEndpoint = SelectSatlocCosApi(apiType, serviceID, bLocation)

} else {
apiEndpoint, privateApiEndpoint, directApiEndpoint = SelectCosApi(apiType, bLocation)
visibility = endpointType
if endpointType == "private" {
apiEndpoint = privateApiEndpoint
}
if endpointType == "direct" {
// visibility type "direct" is not supported in endpoints file.
visibility = "private"
apiEndpoint = directApiEndpoint
}

}

apiEndpoint = conns.FileFallBack(rsConClient.Config.EndpointsFile, visibility, "IBMCLOUD_COS_ENDPOINT", bLocation, apiEndpoint)
apiEndpoint = conns.EnvFallBack([]string{"IBMCLOUD_COS_ENDPOINT"}, apiEndpoint)

if apiEndpoint == "" {
Expand Down Expand Up @@ -1501,23 +1511,27 @@ func resourceIBMCOSBucketDelete(d *schema.ResourceData, meta interface{}) error

endpointType := parseBucketId(d.Id(), "endpointType")

var apiEndpoint, apiEndpointPrivate, directApiEndpoint string
var apiEndpoint, apiEndpointPrivate, directApiEndpoint, visibility string

if apiType == "sl" {

apiEndpoint = SelectSatlocCosApi(apiType, serviceID, bLocation)

} else {
apiEndpoint, apiEndpointPrivate, directApiEndpoint = SelectCosApi(apiType, bLocation)
visibility = endpointType
if endpointType == "private" {
apiEndpoint = apiEndpointPrivate
}
if endpointType == "direct" {
// visibility type "direct" is not supported in endpoints file.
visibility = "private"
apiEndpoint = directApiEndpoint
}

}

apiEndpoint = conns.FileFallBack(rsConClient.Config.EndpointsFile, visibility, "IBMCLOUD_COS_ENDPOINT", bLocation, apiEndpoint)
apiEndpoint = conns.EnvFallBack([]string{"IBMCLOUD_COS_ENDPOINT"}, apiEndpoint)

if apiEndpoint == "" {
Expand Down
44 changes: 39 additions & 5 deletions website/docs/d/cos_bucket.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -231,8 +231,42 @@ In addition to all argument reference list, you can access the following attribu

- `website_endpoint` - (string) Website endpoint, if the bucket is configured with a website. If not, this will be an empty string.

- `single_site_location` - (string) The location to create a single site bucket.
- `storage_class` - (string) The storage class of the bucket.
- `s3_endpoint_public` - (string) Public endpoint for cos bucket.
- `s3_endpoint_private` - (string) Private endpoint for cos bucket.
- `s3_endpoint_direct` - (string) Direct endpoint for cos bucket.
- `single_site_location` - (String) The location to create a single site bucket.
- `storage_class` - (String) The storage class of the bucket.
- `s3_endpoint_public` - (String) Public endpoint for cos bucket.
- `s3_endpoint_private` - (String) Private endpoint for cos bucket.
- `s3_endpoint_direct` - (String) Direct endpoint for cos bucket.
**Note:**

Since the current endpoints file schema does not support "direct", the user must define direct url under "private" for "IBMCLOUD_COS_CONFIG_ENDPOINT" and "IBMCLOUD_COS_ENDPOINT".


**Example**:

```json
{
"IBMCLOUD_COS_CONFIG_ENDPOINT":{
"public":{
"us-south":"https://config.cloud-object-storage.cloud.ibm.com/v1"
},
"private":{
"us-south":"https://config.direct.cloud-object-storage.cloud.ibm.com/v1"
}
}
}
```

OR

```json
{
"IBMCLOUD_COS_CONFIG_ENDPOINT":{
"public":{
"us-south":"https://config.cloud-object-storage.cloud.ibm.com/v1"
},
"private":{
"us-south":"https://config.private.cloud-object-storage.cloud.ibm.com/v1"
}
}
}
```
36 changes: 36 additions & 0 deletions website/docs/guides/custom-service-endpoints.html.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,42 @@ To use public and private regional endpoints for a service, you must add these e
}
}
```
**Note:**

The endpoints file accepts "public", "private" and "public-and-private" as visibility while COS resources support "public", "private" and "direct as endpoint-types.
Since endpoints file schema does not supprt "direct", users must define the url for "direct" endpoint-type under exisiting visibility type "private" for "IBMCLOUD_COS_CONFIG_ENDPOINT" and "IBMCLOUD_COS_ENDPOINT".
The user cannot define urls for both private and direct endpoint-type simultaneously in the endpoints file under "private" field.

**Example**:

```json
{
"IBMCLOUD_COS_CONFIG_ENDPOINT":{
"public":{
"us-south":"https://config.cloud-object-storage.cloud.ibm.com/v1"
},
"private":{
"us-south":"https://config.direct.cloud-object-storage.cloud.ibm.com/v1"
}
}
}
```

OR

```json
{
"IBMCLOUD_COS_CONFIG_ENDPOINT":{
"public":{
"us-south":"https://config.cloud-object-storage.cloud.ibm.com/v1"
},
"private":{
"us-south":"https://config.private.cloud-object-storage.cloud.ibm.com/v1"
}
}
}
```


## Prioritisation of endpoints

Expand Down
34 changes: 34 additions & 0 deletions website/docs/r/cos_bucket.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -625,4 +625,38 @@ id = `$CRN:meta:$buckettype:$bucketlocation`

$ terraform import ibm_cos_bucket.cos_bucket crn:v1:staging:public:cloud-object-storage:satloc_dal_c8fctn320qtrspbisg80:a/81ee25188545f05150650a0a4ee015bb:a2deec95-0836-4720-bfc7-ca41c28a8c66:bucket:tf-listbuckettest:meta:sl:c8fctn320qtrspbisg80:public

```

**Note:**

Since the current endpoints file schema does not support "direct", the user must define direct url under "private" for "IBMCLOUD_COS_CONFIG_ENDPOINT" and "IBMCLOUD_COS_ENDPOINT".

**Example**:

```json
{
"IBMCLOUD_COS_CONFIG_ENDPOINT":{
"public":{
"us-south":"https://config.cloud-object-storage.cloud.ibm.com/v1"
},
"private":{
"us-south":"https://config.direct.cloud-object-storage.cloud.ibm.com/v1"
}
}
}
```

OR

```json
{
"IBMCLOUD_COS_CONFIG_ENDPOINT":{
"public":{
"us-south":"https://config.cloud-object-storage.cloud.ibm.com/v1"
},
"private":{
"us-south":"https://config.private.cloud-object-storage.cloud.ibm.com/v1"
}
}
}
```
Loading