-
Notifications
You must be signed in to change notification settings - Fork 454
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #881 from terraform-providers/mnshtiwari:f-spbm-su…
…pport Pulling in additional acceptance tests and doc updates
- Loading branch information
Showing
12 changed files
with
477 additions
and
51 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package vsphere | ||
|
||
import ( | ||
"github.com/hashicorp/terraform/helper/schema" | ||
"github.com/terraform-providers/terraform-provider-vsphere/vsphere/internal/helper/spbm" | ||
) | ||
|
||
func dataSourceVSphereStoragePolicy() *schema.Resource { | ||
return &schema.Resource{ | ||
Read: dataSourceVSphereStoragePolicyRead, | ||
Schema: map[string]*schema.Schema{ | ||
"name": { | ||
Type: schema.TypeString, | ||
Description: "The display name of the storage policy.", | ||
Required: true, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func dataSourceVSphereStoragePolicyRead(d *schema.ResourceData, meta interface{}) error { | ||
client := meta.(*VSphereClient).vimClient | ||
|
||
id, err := spbm.PolicyIDByName(client, d.Get("name").(string)) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
d.SetId(id) | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package vsphere | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"regexp" | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform/helper/resource" | ||
) | ||
|
||
func TestAccDataSourceVSphereStoragePolicy_basic(t *testing.T) { | ||
resource.Test(t, resource.TestCase{ | ||
PreCheck: func() { | ||
testAccPreCheck(t) | ||
testAccDataSourceVSphereStoragePolicyPreCheck(t) | ||
testAccSkipIfEsxi(t) | ||
}, | ||
Providers: testAccProviders, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccDataSourceVSphereStoragePolicyConfig(), | ||
Check: resource.ComposeTestCheckFunc( | ||
resource.TestMatchResourceAttr("data.vsphere_storage_policy.storage_policy", "id", regexp.MustCompile("^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$")), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func testAccDataSourceVSphereStoragePolicyPreCheck(t *testing.T) { | ||
if os.Getenv("VSPHERE_STORAGE_POLICY") == "" { | ||
t.Skip("set VSPHERE_STORAGE_POLICY to run vsphere_storage_policy acceptance tests") | ||
} | ||
} | ||
|
||
func testAccDataSourceVSphereStoragePolicyConfig() string { | ||
return fmt.Sprintf(` | ||
variable "storage_policy" { | ||
default = "%s" | ||
} | ||
data "vsphere_storage_policy" "storage_policy" { | ||
name = "${var.storage_policy}" | ||
} | ||
`, | ||
os.Getenv("VSPHERE_STORAGE_POLICY"), | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
package spbm | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"log" | ||
|
||
"github.com/terraform-providers/terraform-provider-vsphere/vsphere/internal/helper/provider" | ||
"github.com/terraform-providers/terraform-provider-vsphere/vsphere/internal/helper/viapi" | ||
"github.com/vmware/govmomi" | ||
"github.com/vmware/govmomi/pbm" | ||
"github.com/vmware/govmomi/pbm/methods" | ||
pbmtypes "github.com/vmware/govmomi/pbm/types" | ||
"github.com/vmware/govmomi/vim25/types" | ||
) | ||
|
||
// pbmClientFromGovmomiClient creates a new pbm client from given govmomi client. | ||
// Can we have it in govmomi client as a field similar to tag client? | ||
// We should not create a new pbm client every time we need it. | ||
func pbmClientFromGovmomiClient(ctx context.Context, client *govmomi.Client) (*pbm.Client, error) { | ||
if err := viapi.ValidateVirtualCenter(client); err != nil { | ||
return nil, err | ||
} | ||
|
||
pc, err := pbm.NewClient(ctx, client.Client) | ||
return pc, err | ||
|
||
} | ||
|
||
// PolicyIDByName finds a SPBM storage policy by name and returns its ID. | ||
func PolicyIDByName(client *govmomi.Client, name string) (string, error) { | ||
ctx, cancel := context.WithTimeout(context.Background(), provider.DefaultAPITimeout) | ||
defer cancel() | ||
pc, err := pbmClientFromGovmomiClient(ctx, client) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
return pc.ProfileIDByName(ctx, name) | ||
} | ||
|
||
// policyNameByID returns storage policy name by its ID. | ||
func policyNameByID(client *govmomi.Client, id string) (string, error) { | ||
ctx, cancel := context.WithTimeout(context.Background(), provider.DefaultAPITimeout) | ||
defer cancel() | ||
pc, err := pbmClientFromGovmomiClient(ctx, client) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
log.Printf("[DEBUG] Retrieving contents of storage profiles by id: %s.", id) | ||
profileId := []pbmtypes.PbmProfileId{ | ||
pbmtypes.PbmProfileId{ | ||
UniqueId: id, | ||
}, | ||
} | ||
policies, err := pc.RetrieveContent(ctx, profileId) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
return policies[0].GetPbmProfile().Name, err | ||
} | ||
|
||
// PolicySpecByID creates and returns VirtualMachineDefinedProfileSpec by policy ID. | ||
func PolicySpecByID(id string) []types.BaseVirtualMachineProfileSpec { | ||
return []types.BaseVirtualMachineProfileSpec{ | ||
&types.VirtualMachineDefinedProfileSpec{ | ||
ProfileId: id, | ||
}, | ||
} | ||
} | ||
|
||
// PolicyIDByVirtualDisk fetches the storage policy associated with a virtual disk. | ||
func PolicyIDByVirtualDisk(client *govmomi.Client, vmMOID string, diskKey int) (string, error) { | ||
ctx, cancel := context.WithTimeout(context.Background(), provider.DefaultAPITimeout) | ||
defer cancel() | ||
pc, err := pbmClientFromGovmomiClient(ctx, client) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
pbmSOR := pbmtypes.PbmServerObjectRef{ | ||
ObjectType: "virtualDiskId", | ||
Key: fmt.Sprintf("%s:%d", vmMOID, diskKey), | ||
} | ||
|
||
policies, err := queryAssociatedProfile(ctx, pc, pbmSOR) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
// If no policy returned then virtual disk is not associated with a policy | ||
if policies == nil || len(policies) == 0 { | ||
return "", nil | ||
} | ||
|
||
return policies[0].UniqueId, nil | ||
} | ||
|
||
// PolicyIDByVirtualMachine fetches the storage policy associated with a virtual machine. | ||
func PolicyIDByVirtualMachine(client *govmomi.Client, vmMOID string) (string, error) { | ||
ctx, cancel := context.WithTimeout(context.Background(), provider.DefaultAPITimeout) | ||
defer cancel() | ||
pc, err := pbmClientFromGovmomiClient(ctx, client) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
pbmSOR := pbmtypes.PbmServerObjectRef{ | ||
ObjectType: "virtualMachine", | ||
Key: vmMOID, | ||
} | ||
|
||
policies, err := queryAssociatedProfile(ctx, pc, pbmSOR) | ||
if err != nil { | ||
return "", err | ||
} | ||
|
||
// If no policy returned then VM is not associated with a policy | ||
if policies == nil || len(policies) == 0 { | ||
return "", nil | ||
} | ||
|
||
return policies[0].UniqueId, nil | ||
} | ||
|
||
// queryAssociatedProfile returns the PbmProfileId of the storage policy associated with entity. | ||
func queryAssociatedProfile(ctx context.Context, pc *pbm.Client, ref pbmtypes.PbmServerObjectRef) ([]pbmtypes.PbmProfileId, error) { | ||
log.Printf("[DEBUG] queryAssociatedProfile: Retrieving storage policy of server object of type [%s] and key [%s].", ref.ObjectType, ref.Key) | ||
req := pbmtypes.PbmQueryAssociatedProfile{ | ||
This: pc.ServiceContent.ProfileManager, | ||
Entity: ref, | ||
} | ||
|
||
res, err := methods.PbmQueryAssociatedProfile(ctx, pc, &req) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return res.Returnval, nil | ||
} |
Oops, something went wrong.