// 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)
	}
}
Exemple #4
0
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
}
Exemple #5
0
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")
	}
}
Exemple #7
0
// 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"),
	})
}
Exemple #8
0
// 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)
}
Exemple #10
0
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
}
Exemple #11
0
// 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
}
Exemple #12
0
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)
}