func resourceComputeKeypairV2Create(d *schema.ResourceData, meta interface{}) error { config := meta.(*Config) computeClient, err := config.computeV2Client(d.Get("region").(string)) if err != nil { return fmt.Errorf("Error creating OpenStack compute client: %s", err) } createOpts := KeyPairCreateOpts{ keypairs.CreateOpts{ Name: d.Get("name").(string), PublicKey: d.Get("public_key").(string), }, MapValueSpecs(d), } log.Printf("[DEBUG] Create Options: %#v", createOpts) kp, err := keypairs.Create(computeClient, createOpts).Extract() if err != nil { return fmt.Errorf("Error creating OpenStack keypair: %s", err) } d.SetId(kp.Name) return resourceComputeKeypairV2Read(d, meta) }
func TestCreate(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() HandleCreateSuccessfully(t) actual, err := keypairs.Create(client.ServiceClient(), keypairs.CreateOpts{ Name: "createdkey", }).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &CreatedKeyPair, actual) }
func TestImport(t *testing.T) { th.SetupHTTP() defer th.TeardownHTTP() HandleImportSuccessfully(t) actual, err := keypairs.Create(client.ServiceClient(), keypairs.CreateOpts{ Name: "importedkey", PublicKey: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQDx8nkQv/zgGgB4rMYmIf+6A4l6Rr+o/6lHBQdW5aYd44bd8JttDCE/F/pNRr0lRE+PiqSPO8nDPHw0010JeMH9gYgnnFlyY3/OcJ02RhIPyyxYpv9FhY+2YiUkpwFOcLImyrxEsYXpD/0d3ac30bNH6Sw9JD9UZHYcpSxsIbECHw== Generated by Nova", }).Extract() th.AssertNoErr(t, err) th.CheckDeepEquals(t, &ImportedKeyPair, actual) }
// CreateKeyPair will create a KeyPair with a random name. An error will occur // if the keypair failed to be created. An error will be returned if the // keypair was unable to be created. func CreateKeyPair(t *testing.T, client *gophercloud.ServiceClient) (*keypairs.KeyPair, error) { keyPairName := tools.RandomString("keypair_", 5) t.Logf("Attempting to create keypair: %s", keyPairName) createOpts := keypairs.CreateOpts{ Name: keyPairName, } keyPair, err := keypairs.Create(client, createOpts).Extract() if err != nil { return keyPair, err } t.Logf("Created keypair: %s", keyPairName) return keyPair, nil }
// deploy achieves the aims of Deploy(). func (p *openstackp) deploy(resources *Resources, requiredPorts []int) (err error) { // the resource name can only contain letters, numbers, underscores, // spaces and hyphens if !openstackValidResourceNameRegexp.MatchString(resources.ResourceName) { err = Error{"openstack", "deploy", ErrBadResourceName} return } // get/create key pair kp, err := keypairs.Get(p.computeClient, resources.ResourceName).Extract() if err != nil { if _, notfound := err.(gophercloud.ErrDefault404); notfound { // create a new keypair; we can't just let Openstack create one for // us because in latest versions it does not return a DER encoded // key, which is what GO built-in library supports. privateKey, errk := rsa.GenerateKey(rand.Reader, 1024) if errk != nil { err = errk return } privateKeyPEM := &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(privateKey)} privateKeyPEMBytes := pem.EncodeToMemory(privateKeyPEM) pub, errk := ssh.NewPublicKey(&privateKey.PublicKey) if errk != nil { err = errk return err } publicKeyStr := ssh.MarshalAuthorizedKey(pub) kp, err = keypairs.Create(p.computeClient, keypairs.CreateOpts{Name: resources.ResourceName, PublicKey: string(publicKeyStr)}).Extract() if err != nil { return } resources.PrivateKey = string(privateKeyPEMBytes) } else { return } } resources.Details["keypair"] = kp.Name // based on hostname, see if we're currently running on an openstack server, // in which case we'll use this server's security group and network. hostname, err := os.Hostname() inCloud := false if err == nil { pager := servers.List(p.computeClient, servers.ListOpts{}) err = pager.EachPage(func(page pagination.Page) (bool, error) { serverList, err := servers.ExtractServers(page) if err != nil { return false, err } for _, server := range serverList { if server.Name == hostname { p.ownName = hostname // get the first networkUUID we come across *** not sure // what the other possibilities are and what else we can do // instead for networkName := range server.Addresses { networkUUID, _ := networks.IDFromName(p.networkClient, networkName) if networkUUID != "" { p.networkName = networkName p.networkUUID = networkUUID break } } // get the first security group *** again, not sure how to // pick the "best" if more than one for _, smap := range server.SecurityGroups { if value, found := smap["name"]; found && value.(string) != "" { p.securityGroup = value.(string) break } } if p.networkUUID != "" && p.securityGroup != "" { inCloud = true return false, nil } } } return true, nil }) } //*** actually, if in cloud, we should create a security group that allows // the given ports, only accessible by things in the current security group // don't create any more resources if we're already running in OpenStack if inCloud { return } // get/create security group pager := secgroups.List(p.computeClient) var group *secgroups.SecurityGroup foundGroup := false err = pager.EachPage(func(page pagination.Page) (bool, error) { groupList, err := secgroups.ExtractSecurityGroups(page) if err != nil { return false, err } for _, g := range groupList { if g.Name == resources.ResourceName { group = &g foundGroup = true return false, nil } } return true, nil }) if err != nil { return } if !foundGroup { // create a new security group with rules allowing the desired ports group, err = secgroups.Create(p.computeClient, secgroups.CreateOpts{Name: resources.ResourceName, Description: "access amongst wr-spawned nodes"}).Extract() if err != nil { return } //*** check if the rules are already there, in case we previously died // between previous line and this one for _, port := range requiredPorts { _, err = secgroups.CreateRule(p.computeClient, secgroups.CreateRuleOpts{ ParentGroupID: group.ID, FromPort: port, ToPort: port, IPProtocol: "TCP", CIDR: "0.0.0.0/0", // FromGroupID: group.ID if we were creating a head node and then wanted a rule for all worker nodes... }).Extract() if err != nil { return } } // ICMP may help networking work as expected _, err = secgroups.CreateRule(p.computeClient, secgroups.CreateRuleOpts{ ParentGroupID: group.ID, FromPort: 0, ToPort: 0, // *** results in a port of '0', which is not the same as "ALL ICMP" which then says "Any" in the web interface IPProtocol: "ICMP", CIDR: "0.0.0.0/0", }).Extract() if err != nil { return } } resources.Details["secgroup"] = group.ID p.securityGroup = resources.ResourceName // get/create network var network *networks.Network networkID, err := networks.IDFromName(p.networkClient, resources.ResourceName) if err != nil { if _, notfound := err.(gophercloud.ErrResourceNotFound); notfound { // create a network for ourselves network, err = networks.Create(p.networkClient, networks.CreateOpts{Name: resources.ResourceName, AdminStateUp: gophercloud.Enabled}).Extract() if err != nil { return } networkID = network.ID } else { return } } else { network, err = networks.Get(p.networkClient, networkID).Extract() if err != nil { return } } resources.Details["network"] = networkID p.networkName = resources.ResourceName p.networkUUID = networkID // get/create subnet var subnetID string if len(network.Subnets) == 1 { subnetID = network.Subnets[0] // *** check it's valid? could we end up with more than 1 subnet? } else { // add a big enough subnet var gip = new(string) *gip = "192.168.0.1" var subnet *subnets.Subnet subnet, err = subnets.Create(p.networkClient, subnets.CreateOpts{ NetworkID: networkID, CIDR: "192.168.0.0/16", GatewayIP: gip, DNSNameservers: dnsNameServers[:], // this is critical, or servers on new networks can't be ssh'd to for many minutes IPVersion: 4, Name: resources.ResourceName, }).Extract() if err != nil { return } subnetID = subnet.ID } resources.Details["subnet"] = subnetID // get/create router var routerID string pager = routers.List(p.networkClient, routers.ListOpts{Name: resources.ResourceName}) err = pager.EachPage(func(page pagination.Page) (bool, error) { routerList, err := routers.ExtractRouters(page) if err != nil { return false, err } routerID = routerList[0].ID // *** check it's valid? could we end up with more than 1 router? return false, nil }) if err != nil { return } if routerID == "" { var router *routers.Router router, err = routers.Create(p.networkClient, routers.CreateOpts{ Name: resources.ResourceName, GatewayInfo: &routers.GatewayInfo{NetworkID: p.externalNetworkID}, AdminStateUp: gophercloud.Enabled, }).Extract() if err != nil { return } routerID = router.ID // add our subnet _, err = routers.AddInterface(p.networkClient, routerID, routers.AddInterfaceOpts{SubnetID: subnetID}).Extract() if err != nil { // if this fails, we'd be stuck with a useless router, so we try and // delete it routers.Delete(p.networkClient, router.ID) return } } resources.Details["router"] = routerID return }
func (s *StepKeyPair) Run(state multistep.StateBag) multistep.StepAction { if s.PrivateKeyFile != "" { privateKeyBytes, err := ioutil.ReadFile(s.PrivateKeyFile) if err != nil { state.Put("error", fmt.Errorf( "Error loading configured private key file: %s", err)) return multistep.ActionHalt } state.Put("keyPair", s.KeyPairName) state.Put("privateKey", string(privateKeyBytes)) return multistep.ActionContinue } config := state.Get("config").(Config) ui := state.Get("ui").(packer.Ui) if config.Comm.Type == "ssh" && config.Comm.SSHPassword != "" { ui.Say("Not creating temporary keypair when using password.") return multistep.ActionContinue } // We need the v2 compute client computeClient, err := config.computeV2Client() if err != nil { err = fmt.Errorf("Error initializing compute client: %s", err) state.Put("error", err) return multistep.ActionHalt } keyName := fmt.Sprintf("packer %s", uuid.TimeOrderedUUID()) ui.Say(fmt.Sprintf("Creating temporary keypair: %s ...", keyName)) keypair, err := keypairs.Create(computeClient, keypairs.CreateOpts{ Name: keyName, }).Extract() if err != nil { state.Put("error", fmt.Errorf("Error creating temporary keypair: %s", err)) return multistep.ActionHalt } if keypair.PrivateKey == "" { state.Put("error", fmt.Errorf("The temporary keypair returned was blank")) return multistep.ActionHalt } ui.Say(fmt.Sprintf("Created temporary keypair: %s", keyName)) keypair.PrivateKey = berToDer(keypair.PrivateKey, ui) // If we're in debug mode, output the private key to the working // directory. if s.Debug { ui.Message(fmt.Sprintf("Saving key for debug purposes: %s", s.DebugKeyPath)) f, err := os.Create(s.DebugKeyPath) if err != nil { state.Put("error", fmt.Errorf("Error saving debug key: %s", err)) return multistep.ActionHalt } defer f.Close() // Write the key out if _, err := f.Write([]byte(keypair.PrivateKey)); err != nil { state.Put("error", fmt.Errorf("Error saving debug key: %s", err)) return multistep.ActionHalt } // Chmod it so that it is SSH ready if runtime.GOOS != "windows" { if err := f.Chmod(0600); err != nil { state.Put("error", fmt.Errorf("Error setting permissions of debug key: %s", err)) return multistep.ActionHalt } } } // Set the keyname so we know to delete it later s.keyName = keyName // Set some state data for use in future steps state.Put("keyPair", keyName) state.Put("privateKey", keypair.PrivateKey) return multistep.ActionContinue }