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

API key via kubernetes secret #402

Merged
merged 1 commit into from
Oct 29, 2021
Merged
Show file tree
Hide file tree
Changes from all 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
9 changes: 3 additions & 6 deletions cloud/scope/clients.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,11 @@ type IBMVPCClients struct {
//ServiceEndPoint string
}

func (c *IBMVPCClients) setIBMVPCService(iamEndpoint string, svcEndpoint string, apiKey string) error {
func (c *IBMVPCClients) setIBMVPCService(authenticator core.Authenticator, svcEndpoint string) error {
var err error
c.VPCService, err = vpcv1.NewVpcV1(&vpcv1.VpcV1Options{
Authenticator: &core.IamAuthenticator{
ApiKey: apiKey,
URL: iamEndpoint,
},
URL: svcEndpoint,
Authenticator: authenticator,
URL: svcEndpoint,
})

return err
Expand Down
4 changes: 2 additions & 2 deletions cloud/scope/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ type ClusterScope struct {
IBMVPCCluster *infrav1.IBMVPCCluster
}

func NewClusterScope(params ClusterScopeParams, iamEndpoint string, apiKey string, svcEndpoint string) (*ClusterScope, error) {
func NewClusterScope(params ClusterScopeParams, authenticator core.Authenticator, svcEndpoint string) (*ClusterScope, error) {
if params.Cluster == nil {
return nil, errors.New("failed to generate new scope from nil Cluster")
}
Expand All @@ -69,7 +69,7 @@ func NewClusterScope(params ClusterScopeParams, iamEndpoint string, apiKey strin
return nil, errors.Wrap(err, "failed to init patch helper")
}

vpcErr := params.IBMVPCClients.setIBMVPCService(iamEndpoint, svcEndpoint, apiKey)
vpcErr := params.IBMVPCClients.setIBMVPCService(authenticator, svcEndpoint)
if vpcErr != nil {
return nil, errors.Wrap(vpcErr, "failed to create IBM VPC session")
}
Expand Down
5 changes: 3 additions & 2 deletions cloud/scope/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/go-logr/logr"
"github.com/pkg/errors"

"github.com/IBM/go-sdk-core/v5/core"
"github.com/IBM/vpc-go-sdk/vpcv1"

corev1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -58,7 +59,7 @@ type MachineScope struct {
IBMVPCMachine *infrav1.IBMVPCMachine
}

func NewMachineScope(params MachineScopeParams, iamEndpoint string, apiKey string, svcEndpoint string) (*MachineScope, error) {
func NewMachineScope(params MachineScopeParams, authenticator core.Authenticator, svcEndpoint string) (*MachineScope, error) {
if params.Machine == nil {
return nil, errors.New("failed to generate new scope from nil Machine")
}
Expand All @@ -75,7 +76,7 @@ func NewMachineScope(params MachineScopeParams, iamEndpoint string, apiKey strin
return nil, errors.Wrap(err, "failed to init patch helper")
}

vpcErr := params.IBMVPCClients.setIBMVPCService(iamEndpoint, svcEndpoint, apiKey)
vpcErr := params.IBMVPCClients.setIBMVPCService(authenticator, svcEndpoint)
if vpcErr != nil {
return nil, errors.Wrap(vpcErr, "failed to create IBM VPC session")
}
Expand Down
11 changes: 11 additions & 0 deletions config/default/credentials.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
apiVersion: v1
kind: Secret
metadata:
name: manager-bootstrap-credentials
namespace: system
type: Opaque
stringData:
ibm-credentials.env: |-
IBMCLOUD_AUTH_TYPE=iam
IBMCLOUD_APIKEY=${IBMCLOUD_API_KEY}
IBMCLOUD_AUTH_URL=https://iam.cloud.ibm.com
4 changes: 4 additions & 0 deletions config/default/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,14 @@ bases:
# [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'.
#- ../prometheus

resources:
- credentials.yaml

patchesStrategicMerge:
# Protect the /metrics endpoint by putting it behind auth.
# If you want your controller-manager to expose the /metrics
# endpoint w/o any authn/z, please comment the following line.
- manager_credentials_patch.yaml
- manager_auth_proxy_patch.yaml
- manager_image_patch.yaml

Expand Down
20 changes: 20 additions & 0 deletions config/default/manager_credentials_patch.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: controller-manager
namespace: system
spec:
template:
spec:
containers:
- name: manager
env:
- name: IBM_CREDENTIALS_FILE
value: /home/.ibmcloud/ibm-credentials.env
volumeMounts:
- name: credentials
mountPath: /home/.ibmcloud
volumes:
- name: credentials
secret:
secretName: manager-bootstrap-credentials
11 changes: 8 additions & 3 deletions controllers/ibmvpccluster_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import (

infrastructurev1alpha3 "sigs.k8s.io/cluster-api-provider-ibmcloud/api/v1alpha3"
"sigs.k8s.io/cluster-api-provider-ibmcloud/cloud/scope"
"sigs.k8s.io/cluster-api-provider-ibmcloud/pkg"
)

// IBMVPCClusterReconciler reconciles a IBMVPCCluster object
Expand Down Expand Up @@ -75,16 +76,20 @@ func (r *IBMVPCClusterReconciler) Reconcile(ctx context.Context, req ctrl.Reques
}

// Create the scope.
iamEndpoint := os.Getenv("IAM_ENDPOINT")
apiKey := os.Getenv("API_KEY")
// TODO: Will be removed once we find a better way of overriding the service endpoint, generate via spec
svcEndpoint := os.Getenv("SERVICE_ENDPOINT")

authenticator, err := pkg.GetAuthenticator()
if err != nil {
return ctrl.Result{}, errors.Wrapf(err, "failed to get authenticator")
}

clusterScope, err := scope.NewClusterScope(scope.ClusterScopeParams{
Client: r.Client,
Logger: log,
Cluster: cluster,
IBMVPCCluster: ibmCluster,
}, iamEndpoint, apiKey, svcEndpoint)
}, authenticator, svcEndpoint)

// Always close the scope when exiting this function so we can persist any GCPMachine changes.
defer func() {
Expand Down
10 changes: 7 additions & 3 deletions controllers/ibmvpcmachine_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import (

infrastructurev1alpha3 "sigs.k8s.io/cluster-api-provider-ibmcloud/api/v1alpha3"
"sigs.k8s.io/cluster-api-provider-ibmcloud/cloud/scope"
"sigs.k8s.io/cluster-api-provider-ibmcloud/pkg"
)

// IBMVPCMachineReconciler reconciles a IBMVPCMachine object
Expand Down Expand Up @@ -97,10 +98,13 @@ func (r *IBMVPCMachineReconciler) Reconcile(ctx context.Context, req ctrl.Reques
}

// Create the cluster scope
iamEndpoint := os.Getenv("IAM_ENDPOINT")
apiKey := os.Getenv("API_KEY")
svcEndpoint := os.Getenv("SERVICE_ENDPOINT")

authenticator, err := pkg.GetAuthenticator()
if err != nil {
return ctrl.Result{}, errors.Wrapf(err, "failed to get authenticator")
}

// Create the machine scope
machineScope, err := scope.NewMachineScope(scope.MachineScopeParams{
Client: r.Client,
Expand All @@ -109,7 +113,7 @@ func (r *IBMVPCMachineReconciler) Reconcile(ctx context.Context, req ctrl.Reques
IBMVPCCluster: ibmCluster,
Machine: machine,
IBMVPCMachine: ibmVpcMachine,
}, iamEndpoint, apiKey, svcEndpoint)
}, authenticator, svcEndpoint)
if err != nil {
return ctrl.Result{}, errors.Errorf("failed to create scope: %+v", err)
}
Expand Down
51 changes: 51 additions & 0 deletions pkg/authenticator.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
/*
Copyright 2021 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package pkg

import (
"fmt"
"github.com/IBM/go-sdk-core/v5/core"
)

// This expects the credential file in the following search order:
// 1) ${IBM_CREDENTIALS_FILE}
// 2) <user-home-dir>/ibm-credentials.env
// 3) <current-working-directory>/ibm-credentials.env
//
// and the format is:
// $ cat ibm-credentials.env
// IBMCLOUD_AUTH_TYPE=iam
// IBMCLOUD_APIKEY=xxxxxxxxxxxxx
// IBMCLOUD_AUTH_URL=https://iam.cloud.ibm.com

const (
serviceIBMCloud = "IBMCLOUD"
)

// GetAuthenticator instantiates an Authenticator from external config file
func GetAuthenticator() (core.Authenticator, error) {
auth, err := core.GetAuthenticatorFromEnvironment(serviceIBMCloud)
if err != nil {
return nil, err
}
switch auth.(type) {
case *core.IamAuthenticator:
return auth, nil
default:
return nil, fmt.Errorf("only IAM authenticator is supported")
}
}
13 changes: 12 additions & 1 deletion pkg/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ import (

"github.com/golang-jwt/jwt"

"github.com/IBM-Cloud/bluemix-go"
"github.com/IBM-Cloud/bluemix-go/api/resource/resourcev2/controllerv2"
"github.com/IBM-Cloud/bluemix-go/authentication"
"github.com/IBM-Cloud/bluemix-go/http"
"github.com/IBM-Cloud/bluemix-go/rest"
bxsession "github.com/IBM-Cloud/bluemix-go/session"
"github.com/IBM/go-sdk-core/v5/core"

"k8s.io/klog/v2"
)
Expand Down Expand Up @@ -98,7 +100,16 @@ func fetchUserDetails(sess *bxsession.Session, generation int) (*User, error) {
func NewClient() *Client {
c := &Client{}

bxSess, err := bxsession.New()
authenticator, err := GetAuthenticator()
if err != nil {
klog.Fatal(err)
}
//TODO: this will be removed once power-go-client migrated to go-sdk-core
auth, ok := authenticator.(*core.IamAuthenticator)
if !ok {
klog.Fatal("failed to assert the authenticator as IAM type, please check the ibm-credentials.env file")
}
bxSess, err := bxsession.New(&bluemix.Config{BluemixAPIKey: auth.ApiKey})
if err != nil {
klog.Fatal(err)
}
Expand Down