// Get performs lazy initalization of client for given tenant using given auth options. // If optional parameter givent its used as authenticated client func (self CachedNovas) Get(auth gophercloud.AuthOptions, tenant string, providers ...*gophercloud.ProviderClient) (v2.NovaV2, error) { cached, ok := self[tenant] if ok { return cached, nil } var provider *gophercloud.ProviderClient if len(providers) > 0 { provider = providers[0] } else { newAuth := authNoTenant(auth) newAuth.TenantName = tenant provider2, err := openstack.AuthenticatedClient(newAuth) if err != nil { return v2.NovaV2{}, fmt.Errorf("authentication failed: (%v)", err) } provider = provider2 } client, err := openstack.NewComputeV2(provider, gophercloud.EndpointOpts{}) if err != nil { return v2.NovaV2{}, fmt.Errorf("retrieving endpoint failed: (%v)", err) } self[tenant] = v2.NovaV2{Client: client} return self[tenant], nil }
// newCollector creates and initializes instance of collector. Error is returned // when either authentication or endpoint retrieval failed. func newCollector(config Config) (collectorInterface, error) { auth := gophercloud.AuthOptions{ IdentityEndpoint: config.Url, Username: config.User, Password: config.Pass, TenantName: config.Tenant, AllowReauth: true, } self := &collector{ NovaCache: CachedNovas{}, Auth: auth, config: config, } provider, err := openstack.AuthenticatedClient(auth) if err != nil { return nil, fmt.Errorf("cannot authenticate: (%v)", err) } _, err = self.NovaCache.Get(auth, config.Tenant, provider) if err != nil { return nil, err } client, err := openstack.NewIdentityV2(provider, gophercloud.EndpointOpts{}) if err != nil { return nil, fmt.Errorf("retrieving identity service failed: (%v)", err) } self.Keystone = client return self, nil }
func TestAuthenticatedClient(t *testing.T) { // Obtain credentials from the environment. ao, err := openstack.AuthOptionsFromEnv() if err != nil { t.Fatalf("Unable to acquire credentials: %v", err) } client, err := openstack.AuthenticatedClient(ao) if err != nil { t.Fatalf("Unable to authenticate: %v", err) } if client.TokenID == "" { t.Errorf("No token ID assigned to the client") } t.Logf("Client successfully acquired a token: %v", client.TokenID) // Find the storage service in the service catalog. storage, err := openstack.NewObjectStorageV1(client, gophercloud.EndpointOpts{ Region: os.Getenv("OS_REGION_NAME"), }) if err != nil { t.Errorf("Unable to locate a storage service: %v", err) } else { t.Logf("Located a storage service at endpoint: [%s]", storage.Endpoint) } }
func NewOpenStack(config io.Reader) (*OpenStack, error) { var cfg Config err := gcfg.ReadInto(&cfg, config) if err != nil { glog.Warning("Failed to parse openstack configure file: %v", err) return nil, err } provider, err := openstack.AuthenticatedClient(cfg.toAuthOptions()) if err != nil { glog.Warning("Failed to auth openstack: %v", err) return nil, err } identity, err := openstack.NewIdentityV2(provider, gophercloud.EndpointOpts{ Availability: gophercloud.AvailabilityAdmin, }) if err != nil { glog.Warning("Failed to find identity endpoint") return nil, err } network, err := openstack.NewNetworkV2(provider, gophercloud.EndpointOpts{ Region: cfg.Global.Region, }) if err != nil { glog.Warning("Failed to find neutron endpoint: %v", err) return nil, err } os := OpenStack{ identity: identity, network: network, provider: provider, region: cfg.Global.Region, lbOpts: cfg.LoadBalancer, pluginOpts: cfg.Plugin, ExtNetID: cfg.Global.ExtNetID, } // init plugin if cfg.Plugin.PluginName != "" { integrationBriage := "br-int" if cfg.Plugin.IntegrationBridge != "" { integrationBriage = cfg.Plugin.IntegrationBridge } plugin, _ := plugins.GetNetworkPlugin(cfg.Plugin.PluginName) if plugin != nil { plugin.Init(integrationBriage) os.Plugin = plugin } } return &os, nil }
func newClient(t *testing.T) *gophercloud.ServiceClient { ao, err := openstack.AuthOptionsFromEnv() th.AssertNoErr(t, err) client, err := openstack.AuthenticatedClient(ao) th.AssertNoErr(t, err) c, err := openstack.NewObjectStorageV1(client, gophercloud.EndpointOpts{ Region: os.Getenv("OS_REGION_NAME"), }) th.AssertNoErr(t, err) return c }
func testAuthenticatedClientFails(t *testing.T, endpoint string) { options := gophercloud.AuthOptions{ Username: "******", Password: "******", DomainName: "default", TenantName: "project", IdentityEndpoint: endpoint, } _, err := openstack.AuthenticatedClient(options) if err == nil { t.Fatal("expected error but call succeeded") } }
// NewBlockStorageV1Client returns a *ServiceClient for making calls // to the OpenStack Block Storage v1 API. An error will be returned // if authentication or client creation was not possible. func NewBlockStorageV1Client() (*gophercloud.ServiceClient, error) { ao, err := openstack.AuthOptionsFromEnv() if err != nil { return nil, err } client, err := openstack.AuthenticatedClient(ao) if err != nil { return nil, err } return openstack.NewBlockStorageV1(client, gophercloud.EndpointOpts{ Region: os.Getenv("OS_REGION_NAME"), }) }
// NewIdentityV2AdminClient returns a *ServiceClient for making calls // to the Admin Endpoint of the OpenStack Identity v2 API. An error // will be returned if authentication or client creation was not possible. func NewIdentityV2AdminClient() (*gophercloud.ServiceClient, error) { ao, err := openstack.AuthOptionsFromEnv() if err != nil { return nil, err } client, err := openstack.AuthenticatedClient(ao) if err != nil { return nil, err } return openstack.NewIdentityV2(client, gophercloud.EndpointOpts{ Region: os.Getenv("OS_REGION_NAME"), Availability: gophercloud.AvailabilityAdmin, }) }
func TestAuthenticatedClientV3(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, ` { "versions": { "values": [ { "status": "stable", "id": "v3.0", "links": [ { "href": "%s", "rel": "self" } ] }, { "status": "stable", "id": "v2.0", "links": [ { "href": "%s", "rel": "self" } ] } ] } } `, th.Endpoint()+"v3/", th.Endpoint()+"v2.0/") }) th.Mux.HandleFunc("/v3/auth/tokens", func(w http.ResponseWriter, r *http.Request) { w.Header().Add("X-Subject-Token", ID) w.WriteHeader(http.StatusCreated) fmt.Fprintf(w, `{ "token": { "expires_at": "2013-02-02T18:30:59.000000Z" } }`) }) options := gophercloud.AuthOptions{ Username: "******", Password: "******", DomainName: "default", TenantName: "project", IdentityEndpoint: th.Endpoint(), } client, err := openstack.AuthenticatedClient(options) th.AssertNoErr(t, err) th.CheckEquals(t, ID, client.TokenID) }
func NewNeutronMapper(g *graph.Graph, wsClient *shttp.WSAsyncClient, authURL, username, password, tenantName, regionName, domainName string, availability gophercloud.Availability) (*NeutronMapper, error) { mapper := &NeutronMapper{graph: g, wsClient: wsClient} opts := gophercloud.AuthOptions{ IdentityEndpoint: authURL, Username: username, Password: password, TenantName: tenantName, DomainName: domainName, AllowReauth: true, } provider, err := openstack.AuthenticatedClient(opts) if err != nil { return nil, err } client, err := openstack.NewNetworkV2(provider, gophercloud.EndpointOpts{ Name: "neutron", Region: regionName, Availability: availability, }) if err != nil { return nil, err } mapper.client = client // Create a cache with a default expiration time of 5 minutes, and which // purges expired items every 30 seconds expire := config.GetConfig().GetInt("cache.expire") cleanup := config.GetConfig().GetInt("cache.cleanup") mapper.cache = cache.New(time.Duration(expire)*time.Second, time.Duration(cleanup)*time.Second) mapper.nodeUpdaterChan = make(chan graph.Identifier, 500) g.AddEventListener(mapper) return mapper, nil }
// initialize uses our required environment variables to authenticate with // OpenStack and create some clients we will use in the other methods func (p *openstackp) initialize() (err error) { // authenticate opts, err := openstack.AuthOptionsFromEnv() if err != nil { return } provider, err := openstack.AuthenticatedClient(opts) if err != nil { return } // make a compute client p.computeClient, err = openstack.NewComputeV2(provider, gophercloud.EndpointOpts{ Region: os.Getenv("OS_REGION_NAME"), }) if err != nil { return } // make a network client p.networkClient, err = openstack.NewNetworkV2(provider, gophercloud.EndpointOpts{ //Name: "neutron", //*** "services can have the same Type but a different Name, which is why [...] Name [is] sometimes needed... but how do I see the available names? Region: os.Getenv("OS_REGION_NAME"), }) if err != nil { return } // we need to know the network pool name *** does this have to be a user // input/config option? Or can it be discovered? p.poolName = os.Getenv("OS_POOL_NAME") // I made this one up, so we'll default to nova if p.poolName == "" { p.poolName = "nova" } p.externalNetworkID, err = networks.IDFromName(p.networkClient, p.poolName) if err != nil { return } // get the details of all the possible server flavors p.fmap = make(map[string]Flavor) pager := flavors.ListDetail(p.computeClient, flavors.ListOpts{}) err = pager.EachPage(func(page pagination.Page) (bool, error) { flavorList, err := flavors.ExtractFlavors(page) if err != nil { return false, err } for _, f := range flavorList { p.fmap[f.ID] = Flavor{ ID: f.ID, Name: f.Name, Cores: f.VCPUs, RAM: f.RAM, Disk: f.Disk, } } return true, nil }) return }
func TestNeutron(t *testing.T) { authUrl := os.Getenv("OS_AUTH_URL") username := os.Getenv("OS_USERNAME") password := os.Getenv("OS_PASSWORD") tenantName := os.Getenv("OS_TENANT_NAME") regionName := os.Getenv("OS_REGION_NAME") opts := gophercloud.AuthOptions{ IdentityEndpoint: authUrl, Username: username, Password: password, TenantName: tenantName, } provider, err := openstack.AuthenticatedClient(opts) if err != nil { t.Fatal(err.Error()) } client, err := openstack.NewNetworkV2(provider, gophercloud.EndpointOpts{ Name: "neutron", Region: regionName, Availability: gophercloud.AvailabilityPublic, }) if err != nil { t.Fatalf("Failed to create neutron client: %s", err.Error()) } netResult := networks.Create(client, networks.CreateOpts{Name: "skydive-test-network"}) if netResult.Err != nil { t.Fatalf("Failed to create neutron network: %s", netResult.Err.Error()) } network, err := netResult.Extract() if err != nil { t.Fatalf("Failed to create neutron network: %s", err.Error()) } subResult := subnets.Create(client, subnets.CreateOpts{Name: "skydive-test-subnet", NetworkID: network.ID, CIDR: "192.168.1.0/24", IPVersion: 4}) if subResult.Err != nil { t.Fatalf("Failed to create neutron subnet: %s", subResult.Err.Error()) } subnet, err := subResult.Extract() if err != nil { t.Fatalf("Failed to create neutron subnet: %s", err.Error()) } portResult := ports.Create(client, ports.CreateOpts{NetworkID: network.ID, DeviceID: "skydive-123", DeviceOwner: "skydive-test"}) if portResult.Err != nil { t.Fatalf("Failed to create neutron port: %s", subResult.Err.Error()) } port, err := portResult.Extract() if err != nil { t.Fatalf("Failed to create neutron port: %s", err.Error()) } defer ports.Delete(client, port.ID) defer subnets.Delete(client, subnet.ID) defer networks.Delete(client, network.ID) authOptions := &shttp.AuthenticationOpts{ Username: username, Password: password, } subID := port.ID[0:11] dev := fmt.Sprintf("tap%s", subID) ovsctl := `ovs-vsctl add-port br-int %s -- set Interface %s external-ids:iface-id=%s` ovsctl += ` external-ids:iface-status=active external-ids:attached-mac=%s external-ids:vm-uuid=skydive-vm type=internal` setupCmds := []helper.Cmd{ {fmt.Sprintf(ovsctl, dev, dev, port.ID, port.MACAddress), true}, {"sleep 1", true}, {fmt.Sprintf("ip link set %s up", dev), true}, } tearDownCmds := []helper.Cmd{ {fmt.Sprintf("ovs-vsctl del-port %s", dev), true}, } helper.ExecCmds(t, setupCmds...) defer helper.ExecCmds(t, tearDownCmds...) gh := helper.NewGremlinQueryHelper(authOptions) // let neutron update the port time.Sleep(5 * time.Second) nodes := gh.GetNodesFromGremlinReply(t, `g.V().Has("Manager", "neutron", "ExtID/vm-uuid", "skydive-vm", "Name", "`+dev+`", "Neutron/PortID", "`+port.ID+`")`) if len(nodes) != 1 { t.Errorf("Should find the neutron port in the topology: %v", gh.GetNodesFromGremlinReply(t, `g.V()`)) } }
func TestAuthenticatedClientV2(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, ` { "versions": { "values": [ { "status": "experimental", "id": "v3.0", "links": [ { "href": "%s", "rel": "self" } ] }, { "status": "stable", "id": "v2.0", "links": [ { "href": "%s", "rel": "self" } ] } ] } } `, th.Endpoint()+"v3/", th.Endpoint()+"v2.0/") }) th.Mux.HandleFunc("/v2.0/tokens", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, ` { "access": { "token": { "id": "01234567890", "expires": "2014-10-01T10:00:00.000000Z" }, "serviceCatalog": [ { "name": "Cloud Servers", "type": "compute", "endpoints": [ { "tenantId": "t1000", "publicURL": "https://compute.north.host.com/v1/t1000", "internalURL": "https://compute.north.internal/v1/t1000", "region": "North", "versionId": "1", "versionInfo": "https://compute.north.host.com/v1/", "versionList": "https://compute.north.host.com/" }, { "tenantId": "t1000", "publicURL": "https://compute.north.host.com/v1.1/t1000", "internalURL": "https://compute.north.internal/v1.1/t1000", "region": "North", "versionId": "1.1", "versionInfo": "https://compute.north.host.com/v1.1/", "versionList": "https://compute.north.host.com/" } ], "endpoints_links": [] }, { "name": "Cloud Files", "type": "object-store", "endpoints": [ { "tenantId": "t1000", "publicURL": "https://storage.north.host.com/v1/t1000", "internalURL": "https://storage.north.internal/v1/t1000", "region": "North", "versionId": "1", "versionInfo": "https://storage.north.host.com/v1/", "versionList": "https://storage.north.host.com/" }, { "tenantId": "t1000", "publicURL": "https://storage.south.host.com/v1/t1000", "internalURL": "https://storage.south.internal/v1/t1000", "region": "South", "versionId": "1", "versionInfo": "https://storage.south.host.com/v1/", "versionList": "https://storage.south.host.com/" } ] } ] } } `) }) options := gophercloud.AuthOptions{ Username: "******", Password: "******", IdentityEndpoint: th.Endpoint(), } client, err := openstack.AuthenticatedClient(options) th.AssertNoErr(t, err) th.CheckEquals(t, "01234567890", client.TokenID) }
func TestIdentityAdminV3Client(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() th.Mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, ` { "versions": { "values": [ { "status": "stable", "id": "v3.0", "links": [ { "href": "%s", "rel": "self" } ] }, { "status": "stable", "id": "v2.0", "links": [ { "href": "%s", "rel": "self" } ] } ] } } `, th.Endpoint()+"v3/", th.Endpoint()+"v2.0/") }) th.Mux.HandleFunc("/v3/auth/tokens", func(w http.ResponseWriter, r *http.Request) { w.Header().Add("X-Subject-Token", ID) w.WriteHeader(http.StatusCreated) fmt.Fprintf(w, ` { "token": { "audit_ids": ["VcxU2JYqT8OzfUVvrjEITQ", "qNUTIJntTzO1-XUk5STybw"], "catalog": [ { "endpoints": [ { "id": "39dc322ce86c4111b4f06c2eeae0841b", "interface": "public", "region": "RegionOne", "url": "http://localhost:5000" }, { "id": "ec642f27474842e78bf059f6c48f4e99", "interface": "internal", "region": "RegionOne", "url": "http://localhost:5000" }, { "id": "c609fc430175452290b62a4242e8a7e8", "interface": "admin", "region": "RegionOne", "url": "http://localhost:35357" } ], "id": "4363ae44bdf34a3981fde3b823cb9aa2", "type": "identity", "name": "keystone" } ], "expires_at": "2013-02-27T18:30:59.999999Z", "is_domain": false, "issued_at": "2013-02-27T16:30:59.999999Z", "methods": [ "password" ], "project": { "domain": { "id": "1789d1", "name": "example.com" }, "id": "263fd9", "name": "project-x" }, "roles": [ { "id": "76e72a", "name": "admin" }, { "id": "f4f392", "name": "member" } ], "service_providers": [ { "auth_url":"https://example.com:5000/v3/OS-FEDERATION/identity_providers/acme/protocols/saml2/auth", "id": "sp1", "sp_url": "https://example.com:5000/Shibboleth.sso/SAML2/ECP" }, { "auth_url":"https://other.example.com:5000/v3/OS-FEDERATION/identity_providers/acme/protocols/saml2/auth", "id": "sp2", "sp_url": "https://other.example.com:5000/Shibboleth.sso/SAML2/ECP" } ], "user": { "domain": { "id": "1789d1", "name": "example.com" }, "id": "0ca8f6", "name": "Joe", "password_expires_at": "2016-11-06T15:32:17.000000" } } } `) }) options := gophercloud.AuthOptions{ Username: "******", Password: "******", DomainID: "12345", IdentityEndpoint: th.Endpoint(), } pc, err := openstack.AuthenticatedClient(options) th.AssertNoErr(t, err) sc, err := openstack.NewIdentityV3(pc, gophercloud.EndpointOpts{ Availability: gophercloud.AvailabilityAdmin, }) th.AssertNoErr(t, err) th.CheckEquals(t, "http://localhost:35357/", sc.Endpoint) }