From e14b73bd308fd92871be305ec5c83eaf5fcb7484 Mon Sep 17 00:00:00 2001 From: Angus Lees Date: Tue, 30 Dec 2014 15:47:04 +1100 Subject: [PATCH] Reauthenticate to OpenStack periodically It appears that gophercloud's "AllowReauth" AuthOption doesn't actually do anything, and the keystone/auth token is never refreshed. Eventually it expires and all OpenStack calls receive HTTP 401 responses. This change reauthenticates every time the Instances() or TCPLoadBalancer() API object is requested. This is more frequently than required, but exposing token expiry information will require gophercloud surgery. --- pkg/cloudprovider/openstack/openstack.go | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/pkg/cloudprovider/openstack/openstack.go b/pkg/cloudprovider/openstack/openstack.go index ef3f4c60edf..1df479f48ef 100644 --- a/pkg/cloudprovider/openstack/openstack.go +++ b/pkg/cloudprovider/openstack/openstack.go @@ -71,6 +71,7 @@ type LoadBalancerOpts struct { // OpenStack is an implementation of cloud provider Interface for OpenStack. type OpenStack struct { provider *gophercloud.ProviderClient + authOpts gophercloud.AuthOptions region string lbOpts LoadBalancerOpts } @@ -111,7 +112,11 @@ func (cfg Config) toAuthOptions() gophercloud.AuthOptions { TenantID: cfg.Global.TenantId, TenantName: cfg.Global.TenantName, - // Persistent service, so we need to be able to renew tokens + // Persistent service, so we need to be able to renew + // tokens. + // (gophercloud doesn't appear to actually reauth yet, + // hence the explicit openstack.Authenticate() calls + // below) AllowReauth: true, } } @@ -128,13 +133,15 @@ func readConfig(config io.Reader) (Config, error) { } func newOpenStack(cfg Config) (*OpenStack, error) { - provider, err := openstack.AuthenticatedClient(cfg.toAuthOptions()) + authOpts := cfg.toAuthOptions() + provider, err := openstack.AuthenticatedClient(authOpts) if err != nil { return nil, err } os := OpenStack{ provider: provider, + authOpts: authOpts, region: cfg.Global.Region, lbOpts: cfg.LoadBalancer, } @@ -150,6 +157,11 @@ type Instances struct { func (os *OpenStack) Instances() (cloudprovider.Instances, bool) { glog.V(4).Info("openstack.Instances() called") + if err := openstack.Authenticate(os.provider, os.authOpts); err != nil { + glog.Warningf("Failed to reauthenticate: %v", err) + return nil, false + } + compute, err := openstack.NewComputeV2(os.provider, gophercloud.EndpointOpts{ Region: os.region, }) @@ -360,6 +372,13 @@ type LoadBalancer struct { } func (os *OpenStack) TCPLoadBalancer() (cloudprovider.TCPLoadBalancer, bool) { + glog.V(4).Info("openstack.TCPLoadBalancer() called") + + if err := openstack.Authenticate(os.provider, os.authOpts); err != nil { + glog.Warningf("Failed to reauthenticate: %v", err) + return nil, false + } + // TODO: Search for and support Rackspace loadbalancer API, and others. network, err := openstack.NewNetworkV2(os.provider, gophercloud.EndpointOpts{ Region: os.region,