// 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 }
// 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 }
// 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 }
// 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 }
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 }