Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable logical port tags config for discovered VM #171

Merged
merged 1 commit into from
Jun 25, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 102 additions & 2 deletions nsxt/resource_nsxt_vm_tags.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ func resourceNsxtVMTags() *schema.Resource {
Description: "Instance id",
Required: true,
},
"tag": getTagsSchema(),
"tag": getTagsSchema(),
"logical_port_tag": getTagsSchema(),
},
}
}
Expand All @@ -51,6 +52,36 @@ func getVMList(nsxClient *api.APIClient) (*manager.VirtualMachineListResult, err

}

func getVIFList(nsxClient *api.APIClient) (*manager.VirtualNetworkInterfaceListResult, error) {

localVarOptionals := make(map[string]interface{})
vifList, resp, err := nsxClient.FabricApi.ListVifs(nsxClient.Context, localVarOptionals)
if err != nil {
return nil, err
}

if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("Unexpected status returned during operation on Logical Port Tags: %v", resp.StatusCode)
}

return &vifList, nil

}

func getPortList(nsxClient *api.APIClient) (*manager.LogicalPortListResult, error) {
localVarOptionals := make(map[string]interface{})
portList, resp, err := nsxClient.LogicalSwitchingApi.ListLogicalPorts(nsxClient.Context, localVarOptionals)
if err != nil {
return nil, err
}

if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("Unexpected status returned during operation on Logical Port Tags: %v", resp.StatusCode)
}

return &portList, nil
}

func findVMIDByLocalID(nsxClient *api.APIClient, localID string) (*manager.VirtualMachine, error) {
// VM provider (for example, vsphere provider) can supply host id(BIOS id) for the VM
// NSX API needs NSX id for the update tags API call
Expand Down Expand Up @@ -87,6 +118,42 @@ func findVMByExternalID(nsxClient *api.APIClient, instanceID string) (*manager.V
return nil, fmt.Errorf("Failed to find Virtual Machine with id %s in inventory", instanceID)
}

func findVIFByExternalID(nsxClient *api.APIClient, instanceID string) (*manager.VirtualNetworkInterface, error) {

vifList, err := getVIFList(nsxClient)
if err != nil {
return nil, err
}

for _, vif := range vifList.Results {
if vif.OwnerVmId == instanceID {
return &vif, nil
}
}

return nil, fmt.Errorf("Failed to find VIF for VM id %s in inventory", instanceID)
}

func findPortByExternalID(nsxClient *api.APIClient, instanceID string) (*manager.LogicalPort, error) {

vif, err := findVIFByExternalID(nsxClient, instanceID)
if err != nil {
return nil, err
}

portList, err := getPortList(nsxClient)
if err != nil {
return nil, err
}
for _, elem := range portList.Results {
if elem.Attachment != nil && elem.Attachment.Id == vif.LportAttachmentId {
return &elem, nil
}
}

return nil, fmt.Errorf("Failed to find logical port with attachment id %s", vif.LportAttachmentId)
}

func updateTags(nsxClient *api.APIClient, id string, tags []common.Tag) error {
log.Printf("[DEBUG] Updating tags for %s", id)

Expand All @@ -108,6 +175,24 @@ func updateTags(nsxClient *api.APIClient, id string, tags []common.Tag) error {
return nil
}

func updatePortTags(nsxClient *api.APIClient, id string, tags []common.Tag) error {
log.Printf("[DEBUG] Updating logical port tags for %s", id)

port, err := findPortByExternalID(nsxClient, id)
if err != nil {
return err
}

port.Tags = tags
_, resp, err := nsxClient.LogicalSwitchingApi.UpdateLogicalPort(nsxClient.Context, port.Id, *port)

if err != nil || resp.StatusCode == http.StatusNotFound {
return fmt.Errorf("Error while updating logical port %s: %v", id, err)
}

return nil
}

func resourceNsxtVMTagsCreate(d *schema.ResourceData, m interface{}) error {
instanceID := d.Get("instance_id").(string)

Expand All @@ -118,9 +203,13 @@ func resourceNsxtVMTagsCreate(d *schema.ResourceData, m interface{}) error {
}

tags := getTagsFromSchema(d)

err = updateTags(nsxClient, vm.ExternalId, tags)
if err != nil {
return err
}

portTags := getCustomizedTagsFromSchema(d, "logical_port_tag")
err = updatePortTags(nsxClient, vm.ExternalId, portTags)
if err != nil {
return err
}
Expand All @@ -142,7 +231,13 @@ func resourceNsxtVMTagsRead(d *schema.ResourceData, m interface{}) error {
return fmt.Errorf("Error during VM retrieval: %v", err)
}

port, err := findPortByExternalID(nsxClient, id)
if err != nil {
return fmt.Errorf("Error during logical port retrieval: %v", err)
}

setTagsInSchema(d, vm.Tags)
setCustomizedTagsInSchema(d, port.Tags, "logical_port_tag")

return nil
}
Expand All @@ -162,10 +257,15 @@ func resourceNsxtVMTagsDelete(d *schema.ResourceData, m interface{}) error {

tags := make([]common.Tag, 0)
err = updateTags(nsxClient, vm.ExternalId, tags)
err2 := updatePortTags(nsxClient, vm.ExternalId, tags)

if err != nil {
return err
}

if err2 != nil {
return err2
}

return nil
}
16 changes: 16 additions & 0 deletions nsxt/resource_nsxt_vm_tags_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,19 @@ func TestAccResourceNsxtVMTags_basic(t *testing.T) {
Check: resource.ComposeTestCheckFunc(
testAccNSXVMTagsCheckExists(),
resource.TestCheckResourceAttr(vmTagsFullResourceName, "tag.#", "1"),
resource.TestCheckResourceAttr(vmTagsFullResourceName, "logical_port_tag.#", "1"),
resource.TestCheckResourceAttr(vmTagsFullResourceName, "logical_port_tag.934310497.scope", "a"),
resource.TestCheckResourceAttr(vmTagsFullResourceName, "logical_port_tag.934310497.tag", "b"),
),
},
{
Config: testAccNSXVMTagsUpdateTemplate(vmID),
Check: resource.ComposeTestCheckFunc(
testAccNSXVMTagsCheckExists(),
resource.TestCheckResourceAttr(vmTagsFullResourceName, "tag.#", "2"),
resource.TestCheckResourceAttr(vmTagsFullResourceName, "logical_port_tag.#", "1"),
resource.TestCheckResourceAttr(vmTagsFullResourceName, "logical_port_tag.600822426.scope", "c"),
resource.TestCheckResourceAttr(vmTagsFullResourceName, "logical_port_tag.600822426.tag", "d"),
),
},
},
Expand Down Expand Up @@ -119,6 +125,11 @@ resource "nsxt_vm_tags" "%s" {
scope = "scope1"
tag = "tag1"
}

logical_port_tag {
scope = "a"
tag = "b"
}
}`, vmTagsResourceName, instanceID)
}

Expand All @@ -136,5 +147,10 @@ resource "nsxt_vm_tags" "%s" {
scope = "scope2"
tag = "tag2"
}

logical_port_tag {
scope = "c"
tag = "d"
}
}`, vmTagsResourceName, instanceID)
}
15 changes: 11 additions & 4 deletions nsxt/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,8 +115,8 @@ func getTagsSchemaForceNew() *schema.Schema {
return getTagsSchemaInternal(true)
}

func getTagsFromSchema(d *schema.ResourceData) []common.Tag {
tags := d.Get("tag").(*schema.Set).List()
func getCustomizedTagsFromSchema(d *schema.ResourceData, schemaName string) []common.Tag {
tags := d.Get(schemaName).(*schema.Set).List()
var tagList []common.Tag
for _, tag := range tags {
data := tag.(map[string]interface{})
Expand All @@ -129,17 +129,24 @@ func getTagsFromSchema(d *schema.ResourceData) []common.Tag {
return tagList
}

func setTagsInSchema(d *schema.ResourceData, tags []common.Tag) error {
func setCustomizedTagsInSchema(d *schema.ResourceData, tags []common.Tag, schemaName string) error {
var tagList []map[string]string
for _, tag := range tags {
elem := make(map[string]string)
elem["scope"] = tag.Scope
elem["tag"] = tag.Tag
tagList = append(tagList, elem)
}
err := d.Set("tag", tagList)
err := d.Set(schemaName, tagList)
return err
}
func getTagsFromSchema(d *schema.ResourceData) []common.Tag {
return getCustomizedTagsFromSchema(d, "tag")
}

func setTagsInSchema(d *schema.ResourceData, tags []common.Tag) error {
return setCustomizedTagsInSchema(d, tags, "tag")
}

// utilities to define & handle switching profiles
func getSwitchingProfileIdsSchema() *schema.Schema {
Expand Down
8 changes: 7 additions & 1 deletion website/docs/r/vm_tags.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ resource "nsxt_vm_tags" "vm1_tags" {
scope = "color"
tag = "blue"
}

logical_port_tag {
scope = "color"
tag = "blue"
}
}
```

Expand All @@ -27,7 +32,8 @@ resource "nsxt_vm_tags" "vm1_tags" {
The following arguments are supported:

* `instance_id` - (Required) BIOS Id of the Virtual Machine.
* `tag` - (Required) A list of scope + tag pairs to associate with this VM.
* `tag` - (Optional) A list of scope + tag pairs to associate with this VM.
* `logical_port_tag` - (Optional) A list of scope + tag pairs to associate with logical port that is automatically created for this VM.

## Importing

Expand Down