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 }
// NewNetworkV2Client returns a *ServiceClient for making calls to the // OpenStack Networking v2 API. An error will be returned if authentication // or client creation was not possible. func NewNetworkV2Client() (*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.NewNetworkV2(client, gophercloud.EndpointOpts{ Region: os.Getenv("OS_REGION_NAME"), }) }
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 (c *Config) networkingV2Client(region string) (*gophercloud.ServiceClient, error) { return openstack.NewNetworkV2(c.osClient, gophercloud.EndpointOpts{ Region: region, Availability: c.getEndpointType(), }) }
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()`)) } }