// Instances returns an implementation of Instances for OpenStack.
func (os *OpenStack) Instances() (cloudprovider.Instances, bool) {
	servers, err := gophercloud.ServersApi(os.access, gophercloud.ApiCriteria{
		Type:      "compute",
		UrlChoice: gophercloud.PublicURL,
		Region:    os.region,
	})

	if err != nil {
		return nil, false
	}

	flavors, err := servers.ListFlavors()
	if err != nil {
		return nil, false
	}
	flavor_to_resource := make(map[string]*api.NodeResources, len(flavors))
	for _, flavor := range flavors {
		rsrc := api.NodeResources{
			Capacity: api.ResourceList{
				"cpu":                      util.NewIntOrStringFromInt(flavor.VCpus),
				"memory":                   util.NewIntOrStringFromString(fmt.Sprintf("%dMiB", flavor.Ram)),
				"openstack.org/disk":       util.NewIntOrStringFromString(fmt.Sprintf("%dGB", flavor.Disk)),
				"openstack.org/rxTxFactor": util.NewIntOrStringFromInt(int(flavor.RxTxFactor * 1000)),
				"openstack.org/swap":       util.NewIntOrStringFromString(fmt.Sprintf("%dMiB", flavor.Swap)),
			},
		}
		flavor_to_resource[flavor.Id] = &rsrc
	}

	return &Instances{servers, flavor_to_resource}, true
}
func (r *Rackspace) UpdateCache() error {
	api, err := gophercloud.ServersApi(r.accessProvider,
		gophercloud.ApiCriteria{
			Name:      "cloudServersOpenStack",
			VersionId: "2",
			UrlChoice: gophercloud.PublicURL,
			Region:    r.region,
		})

	if err != nil {
		return err
	}

	servers, err := api.ListServers()

	if err != nil {
		return err
	}
	h := md5.New()
	for _, s := range servers {
		h.Write([]byte(s.Id))
		h.Write([]byte(s.Status))
		h.Write([]byte(fmt.Sprint("%s", s.Metadata)))
	}

	serverHash := hex.EncodeToString(h.Sum(nil))

	r.mu.Lock()
	defer r.mu.Unlock()

	r.servers = servers
	r.serversHash = serverHash
	return nil
}
func resource_openstack_compute_refresh(
	s *terraform.ResourceState,
	meta interface{}) (*terraform.ResourceState, error) {

	p := meta.(*ResourceProvider)
	client := p.client

	serversApi, err := gophercloud.ServersApi(client.AccessProvider, gophercloud.ApiCriteria{
		Name:      "nova",
		UrlChoice: gophercloud.PublicURL,
	})
	if err != nil {
		return nil, err
	}

	server, err := serversApi.ServerById(s.ID)
	if err != nil {
		httpError, ok := err.(*perigee.UnexpectedResponseCodeError)
		if !ok {
			return nil, err
		}

		if httpError.Actual == 404 {
			return nil, nil
		}

		return nil, err
	}

	s.Attributes["name"] = server.Name
	s.Attributes["flavor_ref"] = server.Flavor.Id

	return s, nil
}
func resource_openstack_compute_update(
	s *terraform.ResourceState,
	d *terraform.ResourceDiff,
	meta interface{}) (*terraform.ResourceState, error) {

	p := meta.(*ResourceProvider)
	client := p.client

	// Merge the diff into the state so that we have all the attributes
	// properly.
	rs := s.MergeDiff(d)

	serversApi, err := gophercloud.ServersApi(client.AccessProvider, gophercloud.ApiCriteria{
		Name:      "nova",
		UrlChoice: gophercloud.PublicURL,
	})
	if err != nil {
		return nil, err
	}

	if attr, ok := d.Attributes["name"]; ok {
		_, err := serversApi.UpdateServer(rs.ID, gophercloud.NewServerSettings{
			Name: attr.New,
		})

		if err != nil {
			return nil, err
		}

		rs.Attributes["name"] = attr.New
	}

	if attr, ok := d.Attributes["flavor_ref"]; ok {
		err := serversApi.ResizeServer(rs.Attributes["id"], rs.Attributes["name"], attr.New, "")

		if err != nil {
			return nil, err
		}

		stateConf := &resource.StateChangeConf{
			Pending:    []string{"ACTIVE"},
			Target:     "VERIFY_RESIZE",
			Refresh:    WaitForServerState(serversApi, rs.Attributes["id"]),
			Timeout:    10 * time.Minute,
			Delay:      10 * time.Second,
			MinTimeout: 3 * time.Second,
		}

		_, err = stateConf.WaitForState()

		if err != nil {
			return nil, err
		}

		err = serversApi.ConfirmResize(rs.Attributes["id"])
	}

	return rs, nil
}
Exemple #5
0
func GetClient(project string, region string, cache_path string) (Client, error) {
	c := Client{}
	cache, err := config.LoadCredCache(cache_path)
	if err != nil {
		fmt.Println("unable to get cache")
		return c, err
	}
	c.cache = cache
	if region == "" {
		region = defaultRegion
	}
	c.region = region
	if c.cache.Rackspace.User == "" || c.cache.Rackspace.APIKey == "" {
		var rack_user string
		var rack_pass string
		fmt.Printf("rackspace user: "******"%s", &rack_user)
		if err != nil {
			return c, err
		}
		fmt.Printf("rackspace api key: ")
		_, err = fmt.Scanf("%s", &rack_pass)
		if err != nil {
			return c, err
		}
		c.cache.Rackspace.User = rack_user
		c.cache.Rackspace.APIKey = rack_pass
		c.cache.Save()
		if err != nil {
			return c, err
		}
	}
	ao := gophercloud.AuthOptions{
		Username:    c.cache.Rackspace.User,
		ApiKey:      c.cache.Rackspace.APIKey,
		AllowReauth: true,
	}
	access, err := gophercloud.Authenticate("rackspace-us", ao)
	if err != nil {
		c.cache.Rackspace.User = ""
		c.cache.Rackspace.APIKey = ""
		c.cache.Save()
		return c, err
	}
	ac, err := gophercloud.PopulateApi("rackspace")
	if err != nil {
		return c, err
	}
	client, err := gophercloud.ServersApi(access, ac)
	if err != nil {
		return c, err
	}
	c.client = client
	return c, nil
}
// withServerApi acquires the cloud servers API.
func withServerApi(acc gophercloud.AccessProvider, f func(gophercloud.CloudServersProvider)) {
	api, err := gophercloud.ServersApi(acc, gophercloud.ApiCriteria{
		Name:      "cloudServersOpenStack",
		VersionId: "2",
		UrlChoice: gophercloud.PublicURL,
	})
	if err != nil {
		panic(err)
	}

	f(api)
}
Exemple #7
0
// withServerApi acquires the cloud servers API.
func withServerApi(acc gophercloud.AccessProvider, f func(gophercloud.CloudServersProvider)) {
	api, err := gophercloud.ServersApi(acc, gophercloud.ApiCriteria{
		Name:      "nova",
		Type:      "compute",
		UrlChoice: gophercloud.PublicURL,
	})
	if err != nil {
		panic(err)
	}

	f(api)
}
Exemple #8
0
func (rax *RaxCloud) createGopherCtx() (err error) {
	var (
		provider    string
		authOptions gophercloud.AuthOptions
		apiCriteria gophercloud.ApiCriteria
		access      *gophercloud.Access
		csp         gophercloud.CloudServersProvider
	)

	// Create our auth options set by the user's environment
	provider, authOptions, err = getAuthOptions()
	if err != nil {
		return err
	}

	// Set our API criteria
	apiCriteria, err = gophercloud.PopulateApi("rackspace-us")
	if err != nil {
		return err
	}

	// Set the region
	apiCriteria.Type = "compute"
	apiCriteria.Region = os.Getenv("OS_REGION_NAME")

	if rax.regionOverride != "" {
		log.Printf("Overriding region set in env with %s", rax.regionOverride)
		apiCriteria.Region = rax.regionOverride
	}

	if apiCriteria.Region == "" {
		return fmt.Errorf("No region set. Please set the OS_REGION_NAME environment variable or use the --region flag.")
	}

	// Attempt to authenticate
	access, err = gophercloud.Authenticate(provider, authOptions)
	if err != nil {
		fmt.Printf("ERROR: %v\n\n\n", err)
		return err
	}

	// Get a CSP ref!
	csp, err = gophercloud.ServersApi(access, apiCriteria)
	if err != nil {
		return err
	}

	rax.gopher = csp
	return nil
}
func resource_openstack_compute_destroy(
	s *terraform.ResourceState,
	meta interface{}) error {

	p := meta.(*ResourceProvider)
	client := p.client

	serversApi, err := gophercloud.ServersApi(client.AccessProvider, gophercloud.ApiCriteria{
		Name:      "nova",
		UrlChoice: gophercloud.PublicURL,
	})
	if err != nil {
		return err
	}

	err = serversApi.DeleteServerById(s.ID)

	return err
}
Exemple #10
0
func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) {
	auth, err := b.config.AccessConfig.Auth()
	if err != nil {
		return nil, err
	}
	api := &gophercloud.ApiCriteria{
		Name:      "cloudServersOpenStack",
		Region:    b.config.AccessConfig.Region(),
		VersionId: "2",
		UrlChoice: gophercloud.PublicURL,
	}
	csp, err := gophercloud.ServersApi(auth, *api)
	if err != nil {
		log.Printf("Region: %s", b.config.AccessConfig.Region())
		return nil, err
	}

	// Setup the state bag and initial state for the steps
	state := new(multistep.BasicStateBag)
	state.Put("config", b.config)
	state.Put("csp", csp)
	state.Put("hook", hook)
	state.Put("ui", ui)

	// Build the steps
	steps := []multistep.Step{
		&StepKeyPair{},
		&StepRunSourceServer{
			Name:        b.config.ImageName,
			Flavor:      b.config.Flavor,
			SourceImage: b.config.SourceImage,
		},
		&common.StepConnectSSH{
			SSHAddress:     SSHAddress(csp, b.config.SSHPort),
			SSHConfig:      SSHConfig(b.config.SSHUsername),
			SSHWaitTimeout: b.config.SSHTimeout(),
		},
		&common.StepProvision{},
		&stepCreateImage{},
	}

	// Run!
	if b.config.PackerDebug {
		b.runner = &multistep.DebugRunner{
			Steps:   steps,
			PauseFn: common.MultistepDebugFn(ui),
		}
	} else {
		b.runner = &multistep.BasicRunner{Steps: steps}
	}

	b.runner.Run(state)

	// If there was an error, return that
	if rawErr, ok := state.GetOk("error"); ok {
		return nil, rawErr.(error)
	}

	// If there are no images, then just return
	if _, ok := state.GetOk("image"); !ok {
		return nil, nil
	}

	// Build the artifact and return it
	artifact := &Artifact{
		ImageId:        state.Get("image").(string),
		BuilderIdValue: BuilderId,
		Conn:           csp,
	}

	return artifact, nil
}
Exemple #11
0
func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) {
	auth, err := b.config.AccessConfig.Auth()
	if err != nil {
		return nil, err
	}
	//fetches the api requisites from gophercloud for the appropriate
	//openstack variant
	api, err := gophercloud.PopulateApi(b.config.RunConfig.OpenstackProvider)
	if err != nil {
		return nil, err
	}
	api.Region = b.config.AccessConfig.Region()

	csp, err := gophercloud.ServersApi(auth, api)
	if err != nil {
		log.Printf("Region: %s", b.config.AccessConfig.Region())
		return nil, err
	}

	// Setup the state bag and initial state for the steps
	state := new(multistep.BasicStateBag)
	state.Put("config", b.config)
	state.Put("csp", csp)
	state.Put("hook", hook)
	state.Put("ui", ui)

	// Build the steps
	steps := []multistep.Step{
		&StepKeyPair{
			Debug:        b.config.PackerDebug,
			DebugKeyPath: fmt.Sprintf("os_%s.pem", b.config.PackerBuildName),
		},
		&StepRunSourceServer{
			Name:        b.config.ImageName,
			Flavor:      b.config.Flavor,
			SourceImage: b.config.SourceImage,
		},
		&common.StepConnectSSH{
			SSHAddress:     SSHAddress(csp, b.config.SSHPort),
			SSHConfig:      SSHConfig(b.config.SSHUsername),
			SSHWaitTimeout: b.config.SSHTimeout(),
		},
		&common.StepProvision{},
		&stepCreateImage{},
	}

	// Run!
	if b.config.PackerDebug {
		b.runner = &multistep.DebugRunner{
			Steps:   steps,
			PauseFn: common.MultistepDebugFn(ui),
		}
	} else {
		b.runner = &multistep.BasicRunner{Steps: steps}
	}

	b.runner.Run(state)

	// If there was an error, return that
	if rawErr, ok := state.GetOk("error"); ok {
		return nil, rawErr.(error)
	}

	// If there are no images, then just return
	if _, ok := state.GetOk("image"); !ok {
		return nil, nil
	}

	// Build the artifact and return it
	artifact := &Artifact{
		ImageId:        state.Get("image").(string),
		BuilderIdValue: BuilderId,
		Conn:           csp,
	}

	return artifact, nil
}
func resource_openstack_compute_create(
	s *terraform.ResourceState,
	d *terraform.ResourceDiff,
	meta interface{}) (*terraform.ResourceState, error) {

	p := meta.(*ResourceProvider)
	client := p.client

	// Merge the diff into the state so that we have all the attributes
	// properly.
	rs := s.MergeDiff(d)

	serversApi, err := gophercloud.ServersApi(client.AccessProvider, gophercloud.ApiCriteria{
		Name:      "nova",
		UrlChoice: gophercloud.PublicURL,
	})
	if err != nil {
		return nil, err
	}

	name := rs.Attributes["name"]
	if len(name) == 0 {
		name = randomString(16)
	}

	var osNetworks []gophercloud.NetworkConfig

	if raw := flatmap.Expand(rs.Attributes, "networks"); raw != nil {
		if entries, ok := raw.([]interface{}); ok {
			for _, entry := range entries {
				value, ok := entry.(string)
				if !ok {
					continue
				}

				osNetwork := gophercloud.NetworkConfig{value}
				osNetworks = append(osNetworks, osNetwork)
			}
		}
	}

	var securityGroup []map[string]interface{}

	if raw := flatmap.Expand(rs.Attributes, "security_groups"); raw != nil {
		if entries, ok := raw.([]interface{}); ok {
			for _, entry := range entries {
				value, ok := entry.(string)
				if !ok {
					continue
				}

				securityGroup = append(securityGroup, map[string]interface{}{"name": value})
			}
		}
	}

	newServer, err := serversApi.CreateServer(gophercloud.NewServer{
		Name:          name,
		ImageRef:      rs.Attributes["image_ref"],
		FlavorRef:     rs.Attributes["flavor_ref"],
		Networks:      osNetworks,
		SecurityGroup: securityGroup,
	})

	if err != nil {
		return nil, err
	}

	rs.ID = newServer.Id
	rs.Attributes["id"] = newServer.Id
	rs.Attributes["name"] = name

	return rs, nil
}
Exemple #13
0
func New(authURL, providerName string, credential, builder map[string]interface{}) (*Openstack, error) {
	// OpenStack's auto-generated openrc.sh files do not append the suffix
	// /tokens to the authentication URL. This ensures it is present when
	// specifying the URL.
	if strings.Contains(authURL, "://") && !strings.HasSuffix(authURL, "/tokens") {
		authURL += "/tokens"
	}

	o := &Openstack{
		AuthURL:  authURL,
		Provider: providerName,
	}

	// Credentials
	if err := mapstructure.Decode(credential, &o.Creds); err != nil {
		return nil, err
	}

	// Builder data
	if err := mapstructure.Decode(builder, &o.Builder); err != nil {
		return nil, err
	}

	if o.Creds.Username == "" {
		return nil, errors.New("Username is not set")
	}

	if o.Creds.Password == "" && o.Creds.ApiKey == "" {
		return nil, errors.New("Password/ApiKey is not set")
	}

	authoptions := gophercloud.AuthOptions{
		AllowReauth: true,
		ApiKey:      o.Creds.ApiKey,
		TenantId:    o.Creds.TenantId,
		TenantName:  o.Creds.TenantName,
		Username:    o.Creds.Username,
		Password:    o.Creds.Password,
	}

	access, err := gophercloud.Authenticate(authURL, authoptions)
	if err != nil {
		return nil, err
	}

	//fetches the api requisites from gophercloud for the appropriate
	//openstack variant
	api, err := gophercloud.PopulateApi(providerName)
	if err != nil {
		return nil, err
	}

	// if not given the default is used which is returned for that account.
	if o.Builder.RawRegion != "" {
		api.Region = o.Builder.RawRegion
	}

	csp, err := gophercloud.ServersApi(access, api)
	if err != nil {
		log.Printf("Region: %s", o.Builder.RawRegion)
		return nil, err
	}
	o.Client = csp

	return o, nil
}
Exemple #14
0
func (b *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) {
	auth, err := b.config.AccessConfig.Auth()
	if err != nil {
		return nil, err
	}
	api := &gophercloud.ApiCriteria{
		Name:      "cloudServersOpenStack",
		Region:    "DFW",
		VersionId: "2",
		UrlChoice: gophercloud.PublicURL,
	}
	csp, err := gophercloud.ServersApi(auth, *api)
	if err != nil {
		return nil, err
	}

	// Setup the state bag and initial state for the steps
	state := make(map[string]interface{})
	state["config"] = b.config
	state["csp"] = csp
	state["hook"] = hook
	state["ui"] = ui

	// Build the steps
	steps := []multistep.Step{
		&StepKeyPair{},
		&StepRunSourceServer{
			Name:        b.config.ImageName,
			Flavor:      b.config.Flavor,
			SourceImage: b.config.SourceImage,
		},
		&common.StepConnectSSH{
			SSHAddress:     SSHAddress(csp, b.config.SSHPort),
			SSHConfig:      SSHConfig(b.config.SSHUsername),
			SSHWaitTimeout: b.config.SSHTimeout(),
		},
		&common.StepProvision{},
		&stepCreateImage{},
	}

	// Run!
	if b.config.PackerDebug {
		b.runner = &multistep.DebugRunner{
			Steps:   steps,
			PauseFn: common.MultistepDebugFn(ui),
		}
	} else {
		b.runner = &multistep.BasicRunner{Steps: steps}
	}

	b.runner.Run(state)

	// If there was an error, return that
	if rawErr, ok := state["error"]; ok {
		return nil, rawErr.(error)
	}

	// Build the artifact and return it
	artifact := &Artifact{
		ImageId:        state["image"].(string),
		BuilderIdValue: BuilderId,
		Conn:           csp,
	}

	return artifact, nil
}