Skip to content

Commit

Permalink
Merge pull request #6 from fpt-corp/feature/improve_model_terraform
Browse files Browse the repository at this point in the history
feat: improve api path and create instance model
  • Loading branch information
ducdm49 authored Aug 22, 2024
2 parents 0a1557b + 09c97f3 commit 385bbe0
Show file tree
Hide file tree
Showing 15 changed files with 116 additions and 83 deletions.
66 changes: 35 additions & 31 deletions commons/api_path.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ var ApiPath = struct {
StorageUpdateAttached func(vpcId string, storageId string) string
StoragePolicy func(vpcId string) string
Flavor func(vpcId string) string
GetFlavorByName func(vpcId string) string
Image func(vpcId string) string
SecurityGroup func(vpcId string) string
RenameSecurityGroup func(vpcId string, securityGroupId string) string
Expand Down Expand Up @@ -40,99 +41,102 @@ var ApiPath = struct {
}{
SSH: "/v1/user/sshs",
Storage: func(vpcId string) string {
return fmt.Sprintf("/v1/terraform/vpc/%s/storage", vpcId)
return fmt.Sprintf("/v2/vpc/%s/storage", vpcId)
},
StorageUpdateAttached: func(vpcId string, storageId string) string {
return fmt.Sprintf("/v1/terraform/vpc/%s/storage/%s/update-attached", vpcId, storageId)
return fmt.Sprintf("/v2/vpc/%s/storage/%s/update-attached", vpcId, storageId)
},
StoragePolicy: func(vpcId string) string {
return fmt.Sprintf("/v1/terraform/vpc/%s/storage-policies", vpcId)
return fmt.Sprintf("/v2/vpc/%s/storage-policies", vpcId)
},
Flavor: func(vpcId string) string {
return fmt.Sprintf("/v1/terraform/vpc/%s/flavors", vpcId)
return fmt.Sprintf("/v2/vpc/%s/flavors", vpcId)
},
Image: func(vpcId string) string {
return fmt.Sprintf("/v1/terraform/vpc/%s/images", vpcId)
return fmt.Sprintf("/v2/vpc/%s/images", vpcId)
},
SecurityGroup: func(vpcId string) string {
return fmt.Sprintf("/v1/terraform/vpc/%s/security-group", vpcId)
return fmt.Sprintf("/v2/vpc/%s/security-group", vpcId)
},
RenameSecurityGroup: func(vpcId string, securityGroupId string) string {
return fmt.Sprintf("/v1/terraform/vpc/%s/security-group/%s/rename", vpcId, securityGroupId)
return fmt.Sprintf("/v2/vpc/%s/security-group/%s/rename", vpcId, securityGroupId)
},
UpdateApplyToSecurityGroup: func(vpcId string, securityGroupId string) string {
return fmt.Sprintf("/v1/terraform/vpc/%s/security-group/%s/apply-to", vpcId, securityGroupId)
return fmt.Sprintf("/v2/vpc/%s/security-group/%s/apply-to", vpcId, securityGroupId)
},
SecurityGroupRule: func(vpcId string, securityGroupRuleId string) string {
return fmt.Sprintf("/v1/terraform/vpc/%s/security-group-rule/%s", vpcId, securityGroupRuleId)
return fmt.Sprintf("/v2/vpc/%s/security-group-rule/%s", vpcId, securityGroupRuleId)
},
CreateSecurityGroupRule: func(vpcId string) string {
return fmt.Sprintf("/v1/terraform/vpc/%s/security-group-rule", vpcId)
return fmt.Sprintf("/v2/vpc/%s/security-group-rule", vpcId)
},
Instance: func(vpcId string) string {
return fmt.Sprintf("/v1/terraform/vpc/%s/instance", vpcId)
return fmt.Sprintf("/v2/vpc/%s/instance", vpcId)
},
RenameInstance: func(vpcId string, instanceId string) string {
return fmt.Sprintf("/v1/terraform/vpc/%s/instance/%s/rename", vpcId, instanceId)
return fmt.Sprintf("/v2/vpc/%s/instance/%s/rename", vpcId, instanceId)
},
ChangeStatusInstance: func(vpcId string, instanceId string) string {
return fmt.Sprintf("/v1/terraform/vpc/%s/instance/%s/change-status", vpcId, instanceId)
return fmt.Sprintf("/v2/vpc/%s/instance/%s/change-status", vpcId, instanceId)
},
ResizeInstance: func(vpcId string, instanceId string) string {
return fmt.Sprintf("/v1/vmware/vpc/%s/compute/instance/%s/reconfigure-vm", vpcId, instanceId)
},
GetFlavorByName: func(vpcId string) string {
return fmt.Sprintf("/v2/vpc/%s/flavor/find-by-name", vpcId)
},
Tenant: func(tenantName string) string {
return fmt.Sprintf("/v1/terraform/tenant/%s", tenantName)
return fmt.Sprintf("/v2/tenant/%s", tenantName)
},
Vpc: func(tenantId string) string {
return fmt.Sprintf("/v1/terraform/org/%s/vpc", tenantId)
return fmt.Sprintf("/v2/org/%s/vpc", tenantId)
},
VMGroupPolicies: func(vpcId string) string {
return fmt.Sprintf("/v1/terraform/vpc/%s/vm-group-policies", vpcId)
return fmt.Sprintf("/v2/vpc/%s/vm-group-policies", vpcId)
},
CreateInstanceGroup: func(vpcId string) string {
return fmt.Sprintf("/v1/terraform/vpc/%s/vm-group", vpcId)
return fmt.Sprintf("/v2/vpc/%s/vm-group", vpcId)
},
FindInstanceGroup: func(vpcId string) string {
return fmt.Sprintf("/v1/terraform/vpc/%s/vm-groups", vpcId)
return fmt.Sprintf("/v2/vpc/%s/vm-groups", vpcId)
},
DeleteInstanceGroup: func(vpcId string, instanceGroupId string) string {
return fmt.Sprintf("/v1/terraform/vpc/%s/vm-group/%s", vpcId, instanceGroupId)
return fmt.Sprintf("/v2/vpc/%s/vm-group/%s", vpcId, instanceGroupId)
},
CreateFloatingIp: func(vpcId string) string {
return fmt.Sprintf("/v1/terraform/vpc/%s/floating-ip", vpcId)
return fmt.Sprintf("/v2/vpc/%s/floating-ip", vpcId)
},
FindFloatingIp: func(vpcId string, floatingIpId string) string {
return fmt.Sprintf("/v1/terraform/vpc/%s/floating-ip/%s", vpcId, floatingIpId)
return fmt.Sprintf("/v2/vpc/%s/floating-ip/%s", vpcId, floatingIpId)
},
FindFloatingIpByAddress: func(vpcId string) string {
return fmt.Sprintf("/v1/terraform/vpc/%s/floating-ip-address", vpcId)
return fmt.Sprintf("/v2/vpc/%s/floating-ip-address", vpcId)
},
ListFloatingIp: func(vpcId string) string {
return fmt.Sprintf("/v1/terraform/vpc/%s/floating-ips", vpcId)
return fmt.Sprintf("/v2/vpc/%s/floating-ips", vpcId)
},
DeleteFloatingIp: func(vpcId string, floatingIpId string) string {
return fmt.Sprintf("/v1/terraform/vpc/%s/floating-ip/%s/release", vpcId, floatingIpId)
return fmt.Sprintf("/v2/vpc/%s/floating-ip/%s/release", vpcId, floatingIpId)
},
AssociateFloatingIp: func(vpcId string) string {
return fmt.Sprintf("/v1/terraform/vpc/%s/floating-ip/associate", vpcId)
return fmt.Sprintf("/v2/vpc/%s/floating-ip/associate", vpcId)
},
DisassociateFloatingIp: func(vpcId string, floatingIpId string) string {
return fmt.Sprintf("/v1/terraform/vpc/%s/floating-ip/%s/disassociate", vpcId, floatingIpId)
return fmt.Sprintf("/v2/vpc/%s/floating-ip/%s/disassociate", vpcId, floatingIpId)
},
CreateSubnet: func(vpcId string) string {
return fmt.Sprintf("/v1/terraform/vpc/%s/networks", vpcId)
return fmt.Sprintf("/v2/vpc/%s/networks", vpcId)
},
DeleteSubnet: func(vpcId string, subnetId string) string {
return fmt.Sprintf("/v1/terraform/vpc/%s/network/%s", vpcId, subnetId)
return fmt.Sprintf("/v2/vpc/%s/network/%s", vpcId, subnetId)
},
FindSubnetByName: func(vpcId string) string {
return fmt.Sprintf("/v1/terraform/vpc/%s/network-by-name", vpcId)
return fmt.Sprintf("/v2/vpc/%s/network-by-name", vpcId)
},
FindSubnet: func(vpcId string, subnetId string) string {
return fmt.Sprintf("/v1/terraform/vpc/%s/network/%s", vpcId, subnetId)
return fmt.Sprintf("/v2/vpc/%s/network/%s", vpcId, subnetId)
},
ListSubnets: func(vpcId string) string {
return fmt.Sprintf("/v1/terraform/vpc/%s/networks", vpcId)
return fmt.Sprintf("/v2/vpc/%s/networks", vpcId)
},
}
6 changes: 3 additions & 3 deletions examples/resources/fptcloud_instance/resource.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ resource "fptcloud_instance" "example" {
name = "example"
vpc_id = "your_vpc_id"
ssh_key = "your_public_key"
image_id = "your_image_id"
flavor_id = "your_flavor_id"
image_name = "CentOS-7"
flavor_name = "1C1G"
public_ip = "your_ip_public"
subnet_id = "f25b15f5-9098-429e-887d-1c9562b648ae"
subnet_id = "your_subnet_id"
storage_size_gb = 50
storage_policy_id = "your_storage_policy_id"
security_group_ids = []
Expand Down
4 changes: 2 additions & 2 deletions fptcloud/flavor/flavor_service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
func TestListFlavor_ReturnsFlavors(t *testing.T) {
mockResponse := `{"data": [{"id": "1", "name": "flavor1", "info": {"vcpu": 2, "memory_mb": 2048, "gpu_memory_gb": 1}, "type": "VM_TYPE"}]}`
mockClient, server, _ := common.NewClientForTesting(map[string]string{
"/v1/terraform/vpc/vpc_id/flavors": mockResponse,
"/v2/vpc/vpc_id/flavors": mockResponse,
})
defer server.Close()
service := fptcloud_flavor.NewFlavorService(mockClient)
Expand All @@ -30,7 +30,7 @@ func TestListFlavor_ReturnsFlavors(t *testing.T) {
func TestListFlavor_ReturnsEmptyListOnEmptyResponse(t *testing.T) {
mockResponse := `{"data": []}`
mockClient, server, _ := common.NewClientForTesting(map[string]string{
"/v1/terraform/vpc/vpc_id/flavors": mockResponse,
"/v2/vpc/vpc_id/flavors": mockResponse,
})
defer server.Close()
service := fptcloud_flavor.NewFlavorService(mockClient)
Expand Down
6 changes: 3 additions & 3 deletions fptcloud/image/image_service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
func TestListImage_ReturnsImages(t *testing.T) {
mockResponse := `{"data": [{"id": "1", "name": "image-name", "catalog": "windows", "is_gpu": true}]}`
mockClient, server, _ := common.NewClientForTesting(map[string]string{
"/v1/terraform/vpc/vpc_id/images": mockResponse,
"/v2/vpc/vpc_id/images": mockResponse,
})
defer server.Close()
service := fptcloud_image.NewImageService(mockClient)
Expand All @@ -28,7 +28,7 @@ func TestListImage_ReturnsImages(t *testing.T) {
func TestListImage_ReturnsErrorOnInvalidJSON(t *testing.T) {
mockResponse := `invalid json`
mockClient, server, _ := common.NewClientForTesting(map[string]string{
"/v1/terraform/vpc/vpc_id/images": mockResponse,
"/v2/vpc/vpc_id/images": mockResponse,
})
defer server.Close()
service := fptcloud_image.NewImageService(mockClient)
Expand All @@ -40,7 +40,7 @@ func TestListImage_ReturnsErrorOnInvalidJSON(t *testing.T) {
func TestListImage_ReturnsEmptyListOnEmptyResponse(t *testing.T) {
mockResponse := `{"data": []}`
mockClient, server, _ := common.NewClientForTesting(map[string]string{
"/v1/terraform/vpc/vpc_id/images": mockResponse,
"/v2/vpc/vpc_id/images": mockResponse,
})
defer server.Close()
service := fptcloud_image.NewImageService(mockClient)
Expand Down
2 changes: 1 addition & 1 deletion fptcloud/instance/datasource_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func dataSourceInstanceRead(_ context.Context, d *schema.ResourceData, m interfa
setError = d.Set("public_ip", foundInstance.PublicIp)
setError = d.Set("memory_mb", foundInstance.MemoryMb)
setError = d.Set("cpu_number", foundInstance.CpuNumber)
setError = d.Set("flavor_id", foundInstance.FlavorId)
setError = d.Set("flavor_name", foundInstance.FlavorName)
setError = d.Set("subnet_id", foundInstance.SubnetId)
setError = d.Set("storage_size_gb", foundInstance.StorageSizeGb)
setError = d.Set("storage_policy", foundInstance.StoragePolicy)
Expand Down
19 changes: 19 additions & 0 deletions fptcloud/instance/instance_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ type InstanceService interface {
Rename(vpcId string, instanceId string, newName string) (*common.SimpleResponse, error)
ChangeStatus(vpcId string, instanceId string, status string) (*common.SimpleResponse, error)
Resize(vpcId string, instanceId string, flavorId string) (*common.SimpleResponse, error)
GetFlavorByName(vpcId string, flavorName string) (*FlavorDTO, error)
}

// InstanceServiceImpl is the implementation of InstanceService
Expand Down Expand Up @@ -126,3 +127,21 @@ func (s *InstanceServiceImpl) Resize(vpcId string, instanceId string, flavorId s

return result, nil
}

// GetFlavorByName get flavor by name
func (s *InstanceServiceImpl) GetFlavorByName(vpcId string, flavorName string) (*FlavorDTO, error) {
var apiPath = common.ApiPath.GetFlavorByName(vpcId)
resp, err := s.client.SendPostRequest(apiPath, map[string]string{"flavor_name": flavorName})
if err != nil {
return nil, common.DecodeError(err)
}

flavor := FlavorDTO{}
err = json.Unmarshal(resp, &flavor)

if err != nil {
return nil, common.DecodeError(err)
}

return &flavor, nil
}
14 changes: 7 additions & 7 deletions fptcloud/instance/instance_service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ func TestFindInstance_ReturnsInstance(t *testing.T) {
}
}`
mockClient, server, _ := common.NewClientForTesting(map[string]string{
"/v1/terraform/vpc/vpc_id/instance": mockResponse,
"/v2/vpc/vpc_id/instance": mockResponse,
})
defer server.Close()
service := fptcloud_instance.NewInstanceService(mockClient)
Expand All @@ -47,7 +47,7 @@ func TestFindInstance_ReturnsInstance(t *testing.T) {
func TestFindInstance_ReturnsErrorOnRequestFailure(t *testing.T) {
mockResponse := `invalid`
mockClient, server, _ := common.NewClientForTesting(map[string]string{
"/v1/terraform/vpc/vpc_id/instance": mockResponse,
"/v2/vpc/vpc_id/instance": mockResponse,
})
defer server.Close()
service := fptcloud_instance.NewInstanceService(mockClient)
Expand All @@ -60,7 +60,7 @@ func TestFindInstance_ReturnsErrorOnRequestFailure(t *testing.T) {
func TestCreateInstance_ReturnsInstanceIdWhenSuccess(t *testing.T) {
mockResponse := `{"instance_id": "instance_id"}`
mockClient, server, _ := common.NewClientForTesting(map[string]string{
"/v1/terraform/vpc/vpc_id/instance": mockResponse,
"/v2/vpc/vpc_id/instance": mockResponse,
})
defer server.Close()
service := fptcloud_instance.NewInstanceService(mockClient)
Expand All @@ -72,7 +72,7 @@ func TestCreateInstance_ReturnsInstanceIdWhenSuccess(t *testing.T) {

func TestDeleteInstance_ReturnsSuccess(t *testing.T) {
mockClient, server, _ := common.NewClientForTesting(map[string]string{
"/v1/terraform/vpc/vpc_id/instance": "",
"/v2/vpc/vpc_id/instance": "",
})
defer server.Close()
service := fptcloud_instance.NewInstanceService(mockClient)
Expand All @@ -84,7 +84,7 @@ func TestDeleteInstance_ReturnsSuccess(t *testing.T) {

func TestRenameInstance_ReturnsSuccess(t *testing.T) {
mockClient, server, _ := common.NewClientForTesting(map[string]string{
"/v1/terraform/vpc/vpc_id/instance": "",
"/v2/vpc/vpc_id/instance": "",
})
defer server.Close()
service := fptcloud_instance.NewInstanceService(mockClient)
Expand All @@ -96,7 +96,7 @@ func TestRenameInstance_ReturnsSuccess(t *testing.T) {

func TestChangeStatusInstance_ReturnsSuccess(t *testing.T) {
mockClient, server, _ := common.NewClientForTesting(map[string]string{
"/v1/terraform/vpc/vpc_id/instance": "",
"/v2/vpc/vpc_id/instance": "",
})
defer server.Close()
service := fptcloud_instance.NewInstanceService(mockClient)
Expand All @@ -108,7 +108,7 @@ func TestChangeStatusInstance_ReturnsSuccess(t *testing.T) {

func TestResizeInstance_ReturnsSuccess(t *testing.T) {
mockClient, server, _ := common.NewClientForTesting(map[string]string{
"/v1/terraform/vpc/vpc_id/instance": "",
"/v2/vpc/vpc_id/instance": "",
})
defer server.Close()
service := fptcloud_instance.NewInstanceService(mockClient)
Expand Down
10 changes: 8 additions & 2 deletions fptcloud/instance/model_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type InstanceModel struct {
MemoryMb int `json:"memory_mb"`
CpuNumber int `json:"cpu_number"`
FlavorId *string `json:"flavor_id,omitempty"`
FlavorName *string `json:"flavor_name,omitempty"`
SubnetId string `json:"subnet_id"`
StorageSizeGb int `json:"storage_size_gb"`
StoragePolicy string `json:"storage_policy"`
Expand All @@ -31,8 +32,8 @@ type CreateInstanceDTO struct {
Name string `json:"name"`
PrivateIp *string `json:"private_ip,omitempty"`
PublicIp *string `json:"public_ip,omitempty"`
FlavorId string `json:"flavor_id"`
ImageId string `json:"image_id"`
FlavorName string `json:"flavor_name"`
ImageName string `json:"image_name"`
SubnetId string `json:"subnet_id"`
StorageSizeGb int `json:"storage_size_gb"`
StoragePolicyId string `json:"storage_policy_id"`
Expand All @@ -41,3 +42,8 @@ type CreateInstanceDTO struct {
SshKey *string `json:"ssh_key,omitempty"`
Password *string `json:"password,omitempty"`
}

type FlavorDTO struct {
ID string `json:"id"`
Name string `json:"name"`
}
20 changes: 12 additions & 8 deletions fptcloud/instance/resource_instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,12 @@ func resourceInstanceCreate(ctx context.Context, d *schema.ResourceData, m inter
createdModel.PublicIp = &publicIpValue
}

if flavorId, ok := d.GetOk("flavor_id"); ok {
createdModel.FlavorId = flavorId.(string)
if flavorName, ok := d.GetOk("flavor_name"); ok {
createdModel.FlavorName = flavorName.(string)
}

if imageId, ok := d.GetOk("image_id"); ok {
createdModel.ImageId = imageId.(string)
if imageName, ok := d.GetOk("image_name"); ok {
createdModel.ImageName = imageName.(string)
}

if subnetId, ok := d.GetOk("subnet_id"); ok {
Expand Down Expand Up @@ -169,7 +169,7 @@ func resourceInstanceRead(_ context.Context, d *schema.ResourceData, m interface
setError = d.Set("name", foundInstance.Name)
setError = d.Set("status", foundInstance.Status)
setError = d.Set("public_ip", foundInstance.PublicIp)
setError = d.Set("flavor_id", foundInstance.FlavorId)
setError = d.Set("flavor_name", foundInstance.FlavorName)
setError = d.Set("subnet_id", foundInstance.SubnetId)
setError = d.Set("security_group_ids", foundInstance.SecurityGroupIds)
setError = d.Set("instance_group_id", foundInstance.InstanceGroupId)
Expand Down Expand Up @@ -236,7 +236,7 @@ func resourceInstanceUpdate(ctx context.Context, d *schema.ResourceData, m inter

vpcId := d.Get("vpc_id").(string)
hasChangedName := d.HasChange("name")
hasChangeFlavor := d.HasChange("flavor_id")
hasChangeFlavor := d.HasChange("flavor_name")
hasChangeStatus := d.HasChange("status")

if hasChangedName {
Expand All @@ -256,8 +256,12 @@ func resourceInstanceUpdate(ctx context.Context, d *schema.ResourceData, m inter
}

if hasChangeFlavor {
newFlavorId := d.Get("flavor_id").(string)
_, err := instanceService.Resize(vpcId, d.Id(), newFlavorId)
newFlavorName := d.Get("flavor_name").(string)
flavor, flavorErr := instanceService.GetFlavorByName(vpcId, newFlavorName)
if flavorErr != nil {
return diag.Errorf("[ERR] Flavor not found %s", flavorErr)
}
_, err := instanceService.Resize(vpcId, d.Id(), flavor.ID)
if err != nil {
return diag.Errorf("[ERR] An error occurred while resize instance %s", err)
}
Expand Down
Loading

0 comments on commit 385bbe0

Please sign in to comment.