Skip to content

Commit

Permalink
aws: support custom CA bundle for AWS API
Browse files Browse the repository at this point in the history
When a cluster is installed in a AWS C2S region, access to the AWS
API requires a custom CA bundle for trust. The custom CA bundle
is read from the "ca-bundle.pem" key of the kube-cloud-config
ConfigMap in the openshift-config-managed namespace.

https://issues.redhat.com/browse/CORS-1584
  • Loading branch information
staebler committed Nov 10, 2020
1 parent 43f2d57 commit 87684b6
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 6 deletions.
19 changes: 13 additions & 6 deletions pkg/aws/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,17 @@ limitations under the License.
package aws

import (
"strings"

"github.com/aws/aws-sdk-go/aws"
awssdk "github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/request"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/iam"
"github.com/aws/aws-sdk-go/service/iam/iamiface"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/aws/aws-sdk-go/service/s3/s3iface"

"github.com/openshift/cloud-credential-operator/pkg/version"
)

Expand Down Expand Up @@ -60,6 +62,7 @@ type ClientParams struct {
InfraName string
Region string
Endpoint string
CABundle string
}

type awsClient struct {
Expand Down Expand Up @@ -132,22 +135,26 @@ func (c *awsClient) PutObject(input *s3.PutObjectInput) (*s3.PutObjectOutput, er

// NewClient creates our client wrapper object for the actual AWS clients we use.
func NewClient(accessKeyID, secretAccessKey []byte, params *ClientParams) (Client, error) {
awsConfig := &awssdk.Config{}
var awsOpts session.Options

if params != nil {
if params.Region != "" {
awsConfig.Region = aws.String(params.Region)
awsOpts.Config.Region = aws.String(params.Region)
}

if params.Endpoint != "" {
awsConfig.Endpoint = aws.String(params.Endpoint)
awsOpts.Config.Endpoint = aws.String(params.Endpoint)
}
}

awsConfig.Credentials = credentials.NewStaticCredentials(
awsOpts.Config.Credentials = credentials.NewStaticCredentials(
string(accessKeyID), string(secretAccessKey), "")

s, err := session.NewSession(awsConfig)
if params.CABundle != "" {
awsOpts.CustomCABundle = strings.NewReader(params.CABundle)
}

s, err := session.NewSessionWithOptions(awsOpts)
if err != nil {
return nil, err
}
Expand Down
24 changes: 24 additions & 0 deletions pkg/operator/utils/aws/utils.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
package aws

import (
"context"
"encoding/base64"
"fmt"

"github.com/pkg/errors"
log "github.com/sirupsen/logrus"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"

"sigs.k8s.io/controller-runtime/pkg/client"

Expand All @@ -23,6 +30,12 @@ func ClientBuilder(accessKeyID, secretAccessKey []byte, c client.Client) (ccaws.

params := setupClientParams(infra)

caBundle, err := loadCABundle(c)
if err != nil {
return nil, errors.Wrap(err, "could not load CA bundle")
}
params.CABundle = caBundle

return ccaws.NewClient(accessKeyID, secretAccessKey, params)
}

Expand Down Expand Up @@ -69,3 +82,14 @@ func getIAMEndpoint(infra *configv1.Infrastructure) string {
}
return ""
}

func loadCABundle(c client.Client) (string, error) {
cm := &corev1.ConfigMap{}
switch err := c.Get(context.Background(), client.ObjectKey{Namespace: "openshift-config-managed", Name: "kube-cloud-config"}, cm); {
case apierrors.IsNotFound(err):
return "", nil
case err != nil:
return "", errors.Wrap(err, "failed to get kube-cloud-config ConfigMap")
}
return cm.Data["ca-bundle.pem"], nil
}

0 comments on commit 87684b6

Please sign in to comment.