From 753c52bf33180f5ded2f0f4cec7ebd238b593ccc Mon Sep 17 00:00:00 2001 From: Dean Troyer Date: Thu, 5 May 2016 12:19:12 -0500 Subject: [PATCH] Separate service catalog to prepare for v3 * Move service catalog bits to openstack/service-catalog.go * Add AuthRef.GetProject() * Add sanity check to 00-authntication Change-Id: I45b24a222527cd0117401146fe788ca6ba414980 --- examples/00-authentication.go | 7 ++++ openstack/auth-token.go | 29 ++++--------- openstack/auth.go | 1 + openstack/service-catalog.go | 77 +++++++++++++++++++++++++++++++++++ 4 files changed, 92 insertions(+), 22 deletions(-) create mode 100644 openstack/service-catalog.go diff --git a/examples/00-authentication.go b/examples/00-authentication.go index 60b295c..1e1370d 100644 --- a/examples/00-authentication.go +++ b/examples/00-authentication.go @@ -76,4 +76,11 @@ func main() { fmt.Println("There was an error. The auth token has an invalid expiration.") return } + + // Get the first endpoint + ep, err := auth.GetEndpoint("compute", "") + if err != nil { + fmt.Println("No compute endpoint found:", err) + return + } } diff --git a/openstack/auth-token.go b/openstack/auth-token.go index 48beb65..d7bffbf 100644 --- a/openstack/auth-token.go +++ b/openstack/auth-token.go @@ -41,22 +41,6 @@ type Token struct { } `json:"tenant"` } -type ServiceCatalogEntry struct { - Name string `json:"name"` - Type string `json:"type"` - Endpoints []ServiceEndpoint `json:"endpoints"` - // Endpoints []map[string]string `json:"endpoints"` -} - -type ServiceEndpoint struct { - Type string `json:"type"` - Region string `json:"region"` - PublicURL string `json:"publicurl"` - AdminURL string `json:"adminurl"` - InternalURL string `json:"internalurl"` - VersionID string `json:"versionid"` -} - func (s AuthToken) GetToken() string { return s.Access.Token.ID } @@ -69,13 +53,14 @@ func (s AuthToken) GetEndpoint(serviceType string, regionName string) (string, e // Parse service catalog for _, v := range s.Access.ServiceCatalog { - if v.Type == serviceType { - for _, r := range v.Endpoints { - if regionName == "" || r.Region == regionName { - return r.PublicURL, nil - } - } + ep, err := v.GetEndpoint(serviceType, "public", regionName) + if err == nil { + return ep, nil } } return "", errors.New("err: endpoint not found") } + +func (s AuthToken) GetProject() string { + return s.Access.Token.Project.Name +} diff --git a/openstack/auth.go b/openstack/auth.go index d73cae3..ec2bc80 100644 --- a/openstack/auth.go +++ b/openstack/auth.go @@ -30,6 +30,7 @@ type AuthRef interface { GetToken() string GetExpiration() time.Time GetEndpoint(string, string) (string, error) + GetProject() string } // AuthOpts is the set of credentials used to authenticate to OpenStack diff --git a/openstack/service-catalog.go b/openstack/service-catalog.go new file mode 100644 index 0000000..023f0a0 --- /dev/null +++ b/openstack/service-catalog.go @@ -0,0 +1,77 @@ +// service-catalog - Service Catalog structs +// Copyright 2015 Dean Troyer +// +// 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 openstack + +import ( + "errors" + "fmt" + "strings" +) + +type ServiceCatalogEntry struct { + Name string `json:"name"` + Type string `json:"type"` + Endpoints []ServiceEndpoint `json:"endpoints"` + // Endpoints []map[string]string `json:"endpoints"` +} + +type ServiceEndpoint struct { + Type string `json:"type"` + Region string `json:"region"` + PublicURL string `json:"publicurl"` + AdminURL string `json:"adminurl"` + InternalURL string `json:"internalurl"` + VersionID string `json:"versionid"` +} + +// Valid interfaceType values: 'public', 'publicURL', 'admin', 'admin URL', 'internal', 'internalURL' +func (sce ServiceCatalogEntry) GetEndpoint( + serviceType string, + interfaceType string, + regionName string, +) (string, error) { + if interfaceType == "" { + // Set the default value + interfaceType = "public" + } + if sce.Type == serviceType { + for _, r := range sce.Endpoints { + if regionName == "" || r.Region == regionName { + // Translate passed interface types + sc_int := strings.ToLower(interfaceType) + if sc_int == "public" || sc_int == "publicurl" { + return r.PublicURL, nil + } + if sc_int == "admin" || sc_int == "adminurl" { + return r.AdminURL, nil + } + if sc_int == "internal" || sc_int == "internalURL" { + return r.InternalURL, nil + } + } + } + } + + var msg string + if regionName != "" { + msg = fmt.Sprintf("%s endpoint for %s service in %s region not found", + interfaceType, serviceType, regionName) + } else { + msg = fmt.Sprintf("%s endpoint for %s service not found", + interfaceType, serviceType) + } + return "", errors.New(msg) +}