diff --git a/cohesity/provider.go b/cohesity/provider.go index 84e29b3d..c77babe7 100644 --- a/cohesity/provider.go +++ b/cohesity/provider.go @@ -40,6 +40,7 @@ func Provider() terraform.ResourceProvider { "cohesity_physical_edition_cluster": resourceCohesityPhysicalEditionCluster(), "cohesity_source_vmware": resourceCohesitySourceVMware(), "cohesity_job_vmware": resourceCohesityJobVMware(), + "cohesity_source_physical_server": resourceCohesitySourcePhysicalServer(), }, ConfigureFunc: providerConfigure, } diff --git a/cohesity/resource_cohesity_source_physicalServer.go b/cohesity/resource_cohesity_source_physicalServer.go new file mode 100644 index 00000000..e5bdac94 --- /dev/null +++ b/cohesity/resource_cohesity_source_physicalServer.go @@ -0,0 +1,141 @@ +package cohesity + +import ( + "errors" + "log" + "strconv" + + CohesityManagementSdk "github.com/cohesity/management-sdk-go/managementsdk" + "github.com/cohesity/management-sdk-go/models" + "github.com/hashicorp/terraform/helper/schema" +) + +//ProtectionSourceID Id of protection source registered. +var ProtectionSourceID int64 + +func resourceCohesitySourcePhysicalServer() *schema.Resource { + return &schema.Resource{ + Create: resourceCohesitySourcePhysicalServerCreate, + Read: resourceCohesitySourcePhysicalServerRead, + Delete: resourceCohesitySourcePhysicalServerDelete, + Update: resourceCohesitySourcePhysicalServerUpdate, + Schema: map[string]*schema.Schema{ + "endpoint": { + Type: schema.TypeString, + Required: true, + Description: `Specifies the network endpoint of the Protection Source where it is reachable. It could be an URL or hostname or + an IP address of the Protection Source`, + }, + "force_register": { + Type: schema.TypeBool, + Optional: true, + Default: true, + Description: "Forcefully register physical server to target cluster", + }, + "host_type": { + Type: schema.TypeString, + Required: true, + Description: "OS type on the physical server.", + }, + "physical_type": { + Type: schema.TypeString, + Required: true, + Description: "Host Type for physical server.", + }, + }, + } +} + +func resourceCohesitySourcePhysicalServerCreate(resourceData *schema.ResourceData, configMetaData interface{}) error { + log.Printf("[INFO] Starting Physical Server Registration") + var cohesityConfig = configMetaData.(Config) + client, err := CohesityManagementSdk.NewCohesitySdkClient(cohesityConfig.clusterVip, + cohesityConfig.clusterUsername, cohesityConfig.clusterPassword, cohesityConfig.clusterDomain) + if err != nil { + log.Printf(err.Error()) + return errors.New("Failed to authenticate with Cohesity") + } + var endpoint = resourceData.Get("endpoint").(string) + var forceRegister = resourceData.Get("force_register").(bool) + + //Creating Request Body + var requestBody models.RegisterProtectionSourceParameters + requestBody.Endpoint = &endpoint + requestBody.ForceRegister = &forceRegister + requestBody.Environment = models.EnvironmentRegisterProtectionSourceParameters_KPHYSICAL + requestBody.HostType = models.HostTypeRegisterProtectionSourceParameters_KLINUX + requestBody.PhysicalType = models.PhysicalType_KHOST + + log.Printf("[INFO] Register Physical Server as protection source %s", endpoint) + result, err := client.ProtectionSources().CreateRegisterProtectionSource(&requestBody) + + if err != nil { + log.Printf(err.Error()) + return errors.New("Failed to register source Physical Server") + } + resourceData.SetId(strconv.FormatInt(*result.Id, 10)) + log.Printf("[INFO] Successfully registered physical server protection source %s", endpoint) + log.Printf("[INFO] ID %s", resourceData.Id()) + return resourceCohesitySourcePhysicalServerRead(resourceData, configMetaData) +} + +func resourceCohesitySourcePhysicalServerRead(resourceData *schema.ResourceData, configMetaData interface{}) error { + log.Printf("[INFO] Starting Read") + var cohesityConfig = configMetaData.(Config) + client, err := CohesityManagementSdk.NewCohesitySdkClient(cohesityConfig.clusterVip, + cohesityConfig.clusterUsername, cohesityConfig.clusterPassword, cohesityConfig.clusterDomain) + if err != nil { + log.Printf(err.Error()) + return errors.New("Failed to authenticate with Cohesity") + } + var trueValue = true + var environmentType = []models.EnvironmentListProtectionSourcesEnum{models.EnvironmentListProtectionSources_KPHYSICAL} + var endpoint = resourceData.Get("endpoint").(string) + + // Converting to int64 + ProtectionSourceID, _ = strconv.ParseInt(resourceData.Id(), 10, 64) + log.Printf("[INFO] Read Cohesity Physical Server protection source %v, %T", ProtectionSourceID, ProtectionSourceID) + + result, err := client.ProtectionSources().ListProtectionSources(&ProtectionSourceID, nil, nil, &trueValue, &trueValue, &trueValue, environmentType, nil, &trueValue, nil, nil, &trueValue) + + for _, protectionSource := range result { + log.Printf("[INFO] Protection Name: %s", *protectionSource.ProtectionSource.Name) + if *protectionSource.ProtectionSource.Name == endpoint { + log.Printf("[INFO] Found the Physical Server protection source %s on cohesity cluster", + *protectionSource.ProtectionSource.Name) + return nil + } + } + log.Printf("[INFO] Couldn't find the Physical Server protection source %s", err) + resourceData.SetId("") + return nil +} + +func resourceCohesitySourcePhysicalServerDelete(resourceData *schema.ResourceData, configMetaData interface{}) error { + log.Printf("[INFO] Starting Delete") + var cohesityConfig = configMetaData.(Config) + client, err := CohesityManagementSdk.NewCohesitySdkClient(cohesityConfig.clusterVip, + cohesityConfig.clusterUsername, cohesityConfig.clusterPassword, cohesityConfig.clusterDomain) + if err != nil { + log.Printf(err.Error()) + return errors.New("Failed to authenticate with Cohesity") + } + + // Converting type to int64 + protectionSourceID, _ := strconv.ParseInt(resourceData.Id(), 10, 64) + log.Printf("[INFO] Unregistering the Physical Server protection source %s", resourceData. + Get("endpoint").(string)) + + err = client.ProtectionSources().DeleteUnregisterProtectionSource(protectionSourceID) + if err != nil { + log.Printf(err.Error()) + return errors.New("Failed to unregister Physical Server protection source") + } + log.Printf("[INFO] Successfully unregistered the Physical Server protection source %s", + resourceData.Get("endpoint").(string)) + return nil +} + +func resourceCohesitySourcePhysicalServerUpdate(resourceData *schema.ResourceData, configMetaData interface{}) error { + return errors.New("Update Operation is unavailable for source Physical Server") +} diff --git a/cohesity/resource_cohesity_source_physicalServer_test.go b/cohesity/resource_cohesity_source_physicalServer_test.go new file mode 100644 index 00000000..f3c74537 --- /dev/null +++ b/cohesity/resource_cohesity_source_physicalServer_test.go @@ -0,0 +1,131 @@ +package cohesity + +import ( + "errors" + "fmt" + "log" + "testing" + + CohesityManagementSdk "github.com/cohesity/management-sdk-go/managementsdk" + "github.com/cohesity/management-sdk-go/models" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccSourcePhysicalServer(t *testing.T) { + resource.Test(t, resource.TestCase{ + Providers: testAccProviders, + CheckDestroy: testAccCheckSourcePhysicalServerDestroy, + Steps: []resource.TestStep{ + { + Config: testAccSourcePhysicalServerConfig, + Check: resource.ComposeTestCheckFunc( + testAccCheckSourcePhysicalServerCreated(), + ), + }, + }, + }) +} + +func testAccCheckSourcePhysicalServerCreated() resource.TestCheckFunc { + return func(s *terraform.State) error { + var cohesityConfig = testAccProvider.Meta().(Config) + client, err := CohesityManagementSdk.NewCohesitySdkClient(cohesityConfig.clusterVip, + cohesityConfig.clusterUsername, cohesityConfig.clusterPassword, cohesityConfig.clusterDomain) + if err != nil { + log.Printf(err.Error()) + return errors.New("Failed to authenticate with Cohesity") + } + + var endpoint = "10.2.150.118" + var environmentType = []models.EnvironmentListProtectionSourcesEnum{models.EnvironmentListProtectionSources_KPHYSICAL} + var trueValue = true + log.Printf("[INFO] Get list of Physical Server sources to verify %s creation", endpoint) + + log.Println("[INFO] Access to Global", ProtectionSourceID) + // result, err := client.ProtectionSources(). + // ListProtectionSources(nil, nil, nil, &trueValue, &trueValue, + // &trueValue, environmentType, nil, nil, nil, nil, nil) + + result, err := client.ProtectionSources().ListProtectionSources(&ProtectionSourceID, nil, nil, &trueValue, &trueValue, &trueValue, environmentType, nil, &trueValue, nil, nil, &trueValue) + + if err != nil { + log.Printf(err.Error()) + return fmt.Errorf("Failed to get Physical Server protection sources") + } + + for _, protectionSource := range result { + if *protectionSource.ProtectionSource.Name == endpoint { + log.Printf("[INFO] Found the Physical Server protection source %s on cohesity cluster", endpoint) + //validate the Physical Server Source Registration + if *protectionSource.LogicalSize == 0 { + return fmt.Errorf("Failed to valaidate created physical server source") + } + // Check if registered + // Check if deleted + + // *protectionSource.RegistrationInfo.AccessInfo.Endpoint != endpoint { + // return fmt.Errorf("Failed to valaidate created physical server source") + // } + + // if *protectionSource.RegistrationInfo.ThrottlingPolicy.IsEnabled != true || + // *protectionSource.RegistrationInfo.ThrottlingPolicy.EnforceMaxStreams != true || + // *protectionSource.RegistrationInfo.ThrottlingPolicy.MaxConcurrentStreams != 5 || + // *protectionSource.RegistrationInfo.ThrottlingPolicy.LatencyThresholds.NewTaskMsecs != 110 || + // *protectionSource.RegistrationInfo.ThrottlingPolicy.LatencyThresholds.ActiveTaskMsecs != 120 { + // return fmt.Errorf("Failed to valaidate throttling policy parameters of created Vmware source") + // } + return nil + } + } + return fmt.Errorf("Failed to create Physical Server protection source: %s", endpoint) + } +} + +func testAccCheckSourcePhysicalServerDestroy(s *terraform.State) error { + var cohesityConfig = testAccProvider.Meta().(Config) + client, err := CohesityManagementSdk.NewCohesitySdkClient(cohesityConfig.clusterVip, + cohesityConfig.clusterUsername, cohesityConfig.clusterPassword, cohesityConfig.clusterDomain) + if err != nil { + log.Printf(err.Error()) + return fmt.Errorf("Failed to authenticate with Cohesity") + } + + var endpoint = "10.2.150.118" + var environmentType = []models.EnvironmentListProtectionSourcesEnum{models.EnvironmentListProtectionSources_KPHYSICAL} + var trueValue = true + log.Printf("[INFO] Get list of Physical Server protection sources to verify %s deletion", endpoint) + + result, err := client.ProtectionSources(). + ListProtectionSources(nil, nil, nil, &trueValue, &trueValue, + &trueValue, environmentType, nil, nil, nil, nil, nil) + if err != nil { + log.Printf(err.Error()) + return fmt.Errorf("Failed to get Physical Server protection sources") + } + + for _, protectionSource := range result { + log.Printf("[INFO] Protection Name: %s", *protectionSource.ProtectionSource.Name) + if *protectionSource.ProtectionSource.Name == endpoint { + log.Printf("[INFO] Found the Physical Server protection source %s on cohesity cluster", + *protectionSource.ProtectionSource.Name) + return fmt.Errorf("Failed to unregister the Physical Server protection source %s", endpoint) + } + } + return nil +} + +const testAccSourcePhysicalServerConfig = ` +provider "cohesity" { + cluster_vip = "10.2.145.47" + cluster_username = "admin" + cluster_domain = "LOCAL" +} + +resource "cohesity_source_physical_server" "physical_server"{ + endpoint = "10.2.150.118" + force_register = true + host_type = "kWindows" + physical_type = "kHost" +} +`