Пример #1
0
// Create a single server
func (vp *vultrProvider) createServer(options providers.CreateInstanceOptions) (string, error) {
	// Find SSH key ID
	var sshid string
	if len(options.SSHKeyNames) > 0 {
		var err error
		sshid, err = vp.findSSHKeyID(options.SSHKeyNames[0])
		if err != nil {
			return "", maskAny(err)
		}
	}
	// Fetch SSH keys
	sshKeys, err := providers.FetchSSHKeys(options.SSHKeyGithubAccount)
	if err != nil {
		return "", maskAny(err)
	}

	// Create cloud-config
	// user-data
	ccOpts := options.NewCloudConfigOptions()
	ccOpts.PrivateIPv4 = "$private_ipv4"
	ccOpts.SshKeys = sshKeys
	userData, err := templates.Render(cloudConfigTemplate, ccOpts)
	if err != nil {
		return "", maskAny(err)
	}

	name := options.InstanceName
	opts := &lib.ServerOptions{
		IPV6:              true,
		PrivateNetworking: true,
		SSHKey:            sshid,
		UserData:          userData,
	}
	regionID, err := strconv.Atoi(options.RegionID)
	if err != nil {
		return "", maskAny(err)
	}
	planID, err := strconv.Atoi(options.TypeID)
	if err != nil {
		return "", maskAny(err)
	}
	osID, err := strconv.Atoi(options.ImageID)
	if err != nil {
		return "", maskAny(err)
	}
	server, err := vp.client.CreateServer(name, regionID, planID, osID, opts)
	if err != nil {
		vp.Logger.Debugf("CreateServer failed: %#v", err)
		return "", maskAny(err)
	}
	vp.Logger.Infof("Created server %s %s\n", server.ID, server.Name)

	return server.ID, nil
}
Пример #2
0
// Apply defaults for the given options
func (vp *scalewayProvider) CreateInstanceDefaults(options providers.CreateInstanceOptions) providers.CreateInstanceOptions {
	options.ClusterInfo = vp.ClusterDefaults(options.ClusterInfo)
	options.InstanceConfig = vp.instanceConfigDefaults(options.InstanceConfig)
	if options.TincIpv4 == "" && options.TincCIDR != "" {
		instances, err := vp.GetInstances(options.ClusterInfo)
		if err != nil {
			vp.Logger.Warningf("Failed to load instances: %#v", err)
		} else {
			ip, err := instances.CreateClusterIP(options.TincCIDR)
			if err != nil {
				vp.Logger.Warningf("Failed to create new cluster IP: %#v", err)
			} else {
				options.TincIpv4 = ip.String()
				if options.InstanceIndex == 0 {
					options.InstanceIndex = int(ip.To4()[3])
				}
			}
		}
	}
	return options
}
Пример #3
0
// createAndStartServer creates a new server and starts it.
// It then waits until the instance is active.
func (vp *scalewayProvider) createAndStartServer(options providers.CreateInstanceOptions) (providers.ClusterInstance, error) {
	zeroInstance := providers.ClusterInstance{}

	// Validate input
	if options.TincIpv4 == "" {
		return zeroInstance, maskAny(fmt.Errorf("TincIpv4 is empty"))
	}

	// Fetch SSH keys
	sshKeys, err := providers.FetchSSHKeys(options.SSHKeyGithubAccount)
	if err != nil {
		return zeroInstance, maskAny(err)
	}

	// Create cloud-config
	// user-data
	ccOpts := options.NewCloudConfigOptions()
	ccOpts.PrivateIPv4 = "$private_ipv4"
	ccOpts.SshKeys = sshKeys
	_ /*userData*/, err = templates.Render(cloudConfigTemplate, ccOpts)
	if err != nil {
		return zeroInstance, maskAny(err)
	}

	var arch string
	switch options.TypeID[:2] {
	case "C1":
		arch = "arm"
	case "C2", "VC":
		arch = "x86_64"
	}

	// Find image
	imageID, err := vp.getImageID(options.ImageID, arch)
	if err != nil {
		vp.Logger.Errorf("getImageID failed: %#v", err)
		return zeroInstance, maskAny(err)
	}

	name := options.InstanceName
	image := &imageID
	dynamicIPRequired := !vp.NoIPv4
	//bootscript := ""

	volID := ""
	/*if options.TypeID != commercialTypeVC1 {
		volDef := api.ScalewayVolumeDefinition{
			Name:         vp.volumeName(name),
			Size:         volumeSize,
			Type:         volumeType,
			Organization: vp.organization,
		}
		volID, err = vp.client.PostVolume(volDef)
		if err != nil {
			vp.Logger.Errorf("PostVolume failed: %#v", err)
			return zeroInstance, maskAny(err)
		}
	}*/

	publicIPIdentifier := ""
	if options.RoleLoadBalancer && vp.ReserveLoadBalancerIP {
		ip, err := vp.getFreeIP()
		if err != nil {
			return zeroInstance, maskAny(err)
		}
		publicIPIdentifier = ip.ID
	}

	opts := api.ScalewayServerDefinition{
		Name:              name,
		Image:             image,
		Volumes:           map[string]string{},
		DynamicIPRequired: &dynamicIPRequired,
		//Bootscript:        &bootscript,
		Tags: []string{
			options.ClusterInfo.ID,
			options.TincIpv4,
		},
		Organization:   vp.Organization,
		CommercialType: options.TypeID,
		PublicIP:       publicIPIdentifier,
		EnableIPV6:     vp.EnableIPV6,
	}
	if volID != "" {
		opts.Volumes["0"] = volID
	}
	vp.Logger.Debugf("Creating server %s: %#v\n", name, opts)
	id, err := vp.client.PostServer(opts)
	if err != nil {
		vp.Logger.Errorf("PostServer failed: %#v", err)
		// Delete volume
		if volID != "" {
			if err := vp.client.DeleteVolume(volID); err != nil {
				vp.Logger.Errorf("DeleteVolume failed: %#v", err)
			}
		}
		return zeroInstance, maskAny(err)
	}

	// Start server
	if err := vp.client.PostServerAction(id, "poweron"); err != nil {
		vp.Logger.Errorf("poweron failed: %#v", err)
		return zeroInstance, maskAny(err)
	}

	// Wait until server starts
	server, err := vp.waitUntilServerActive(id, true)
	if err != nil {
		return zeroInstance, maskAny(err)
	}

	// Download & copy fleet,etcd
	instance := vp.clusterInstance(server, true)
	return instance, nil
}
Пример #4
0
// Apply defaults for the given options
func (vp *vultrProvider) CreateInstanceDefaults(options providers.CreateInstanceOptions) providers.CreateInstanceOptions {
	options.ClusterInfo = vp.ClusterDefaults(options.ClusterInfo)
	options.InstanceConfig = instanceConfigDefaults(options.InstanceConfig)
	return options
}
Пример #5
0
func (dp *doProvider) CreateInstance(log *logging.Logger, options providers.CreateInstanceOptions, dnsProvider providers.DnsProvider) (providers.ClusterInstance, error) {
	client := NewDOClient(dp.token)

	keys := []godo.DropletCreateSSHKey{}
	listedKeys, err := KeyList(client)
	if err != nil {
		return providers.ClusterInstance{}, maskAny(err)
	}
	for _, key := range options.SSHKeyNames {
		k := findKeyID(key, listedKeys)
		if k == nil {
			return providers.ClusterInstance{}, maskAny(errors.New("Key not found"))
		}
		keys = append(keys, godo.DropletCreateSSHKey{ID: k.ID})
	}

	opts := options.NewCloudConfigOptions()
	opts.PrivateIPv4 = "$private_ipv4"

	cloudConfig, err := templates.Render(cloudConfigTemplate, opts)
	if err != nil {
		return providers.ClusterInstance{}, maskAny(err)
	}

	request := &godo.DropletCreateRequest{
		Name:              options.InstanceName,
		Region:            options.RegionID,
		Size:              options.TypeID,
		Image:             godo.DropletCreateImage{Slug: options.ImageID},
		SSHKeys:           keys,
		Backups:           false,
		IPv6:              true,
		PrivateNetworking: true,
		UserData:          cloudConfig,
	}

	// Create droplet
	dp.Logger.Infof("Creating droplet: %s, %s, %s", request.Region, request.Size, options.ImageID)
	dp.Logger.Debugf(cloudConfig)
	createDroplet, _, err := client.Droplets.Create(request)
	if err != nil {
		return providers.ClusterInstance{}, maskAny(err)
	}

	// Wait for active
	dp.Logger.Infof("Waiting for droplet '%s'", createDroplet.Name)
	droplet, err := dp.waitUntilDropletActive(createDroplet.ID)
	if err != nil {
		return providers.ClusterInstance{}, maskAny(err)
	}

	privateIpv4 := getIpv4(*droplet, "private")
	publicIpv4 := getIpv4(*droplet, "public")
	publicIpv6 := getIpv6(*droplet, "public")
	if err := providers.RegisterInstance(dp.Logger, dnsProvider, options, createDroplet.Name, options.RegisterInstance, options.RoleLoadBalancer, options.RoleLoadBalancer, publicIpv4, publicIpv6, privateIpv4); err != nil {
		return providers.ClusterInstance{}, maskAny(err)
	}

	dp.Logger.Infof("Droplet '%s' is ready", createDroplet.Name)

	return dp.clusterInstance(*droplet), nil
}