본문 바로가기
개발/Terraform on NaverCloud

MSSQL 개발하기 (2) & pr 올리기

by 컴쏘 2023. 9. 21.
728x90

이번에는 cloud_mssql_data_source 코드를 작성해보자.

 

cloud_mssql_data_source.go는 cloud_mssql.go를 한 번 작성해보아서 인지, 쉽게 작성할 수 있었다.

resource와 data sourec가 연관되어 있어서 인지, cloud_mssql_data_source에 대한 test를 해보면서, cloud_mssql 코드 및 go-sdk 코드도 수정을 하게 되었다.  

 

작업 내용... 하루만에 끝난 작업이 아니기에, 생각날만한 부분 위주로 기록했다.. 

 

2023-08-29T22:13:10.595+0900 [WARN]  sdk.helper_resource: Error running Terraform CLI command:
  error=
  | exit status 1
  |
  | Error: json: cannot unmarshal array into Go struct field CreateCloudMssqlInstanceResponse.cloudMssqlInstanceList of type vmssql.CloudMssqlInstanceList
  |
  |   with ncloud_mssql.mssql,
  |   on terraform_plugin_test.tf line 14, in resource "ncloud_mssql" "mssql":
  |   14: \t\tresource "ncloud_mssql" "mssql" {
  |
   test_name=TestAccDataSourceNcloudMssql_vpc_basic test_terraform_path=C:\terraform_1.5.3\terraform.exe test_working_directory=C:\Users\jpark\AppData\Local\Temp\plugintest3313195977 test_step_number=1

 

  • CreateCloudMssqlInstance 요청의 응답을 처리할 때 발생
  • 응답에 대한 구문 분석이 실패했으며, Go에서 응답을 vmssql.CloudMssqlInstanceList 형식으로 구문 분석하려고 시도했지만 배열로 구문 분석되어 예상대로 동작하지 않았음

sdk 문제인 것으로 보여, 멘토님께 문의했다. 

멘토님 답변

 

위의 sdk 수정한 것을 반영하고 테스트하면서, 다른 sdk 문제가 발생했다. 

2023-08-30T09:55:05.456+0900 [WARN]  sdk.helper_resource: Error running Terraform CLI command: test_step_number=1
  error=
  | exit status 1
  |
  | Error: Error waiting for CloudMssqlInstanceStatus state to be "USED": json: cannot unmarshal array into Go struct field GetCloudMssqlInstanceListResponse.cloudMssqlInstanceList of type vmssql.CloudMssqlInstanceList
  |
  |   with ncloud_mssql.mssql,
  |   on terraform_plugin_test.tf line 14, in resource "ncloud_mssql" "mssql":
  |   14: \t\tresource "ncloud_mssql" "mssql" {
  |
   test_working_directory=C:\Users\jpark\AppData\Local\Temp\plugintest943736052 test_name=TestAccDataSourceNcloudMssql_vpc_basic test_terraform_path=C:\terraform_1.5.3\terraform.exe

 

2023/08/30 09:55:05 [ERROR] DeleteCloudMssqlInstance error params="19286575", err=Status: 400 Bad Request, Body: {
  "responseError": {
    "returnCode": "5001005",
    "returnMessage": "The cluster is working on something else. Please try again after the existing work is completed."   
  }
}
2023-08-30T09:55:05.962+0900 [ERROR] sdk.proto: Response contains error diagnostic:
  diagnostic_summary=
  | Status: 400 Bad Request, Body: {
  |   "responseError": {
  |     "returnCode": "5001005",
  |     "returnMessage": "The cluster is working on something else. Please try again after the existing work is completed."
  |   }
  | }
   tf_provider_addr=registry.terraform.io/hashicorp/ncloud tf_proto_version=5.3 tf_resource_type=ncloud_mssql tf_rpc=ApplyResourceChange tf_req_id=b0fb22a8-2e28-460e-0379-212f7d2ae4f0 diagnostic_detail="" diagnostic_severity=ERROR
2023-08-30T09:55:05.982+0900 [WARN]  sdk.helper_resource: Error running Terraform CLI command: test_working_directory=C:\Users\jpark\AppData\Local\Temp\plugintest943736052 test_name=TestAccDataSourceNcloudMssql_vpc_basic test_terraform_path=C:\terraform_1.5.3\terraform.exe test_step_number=1
  error=
  | exit status 1
  |
  | Error: Status: 400 Bad Request, Body: {
  |   "responseError": {
  |     "returnCode": "5001005",
  |     "returnMessage": "The cluster is working on something else. Please try again after the existing work is completed."
  |   }
  | }
  |

 

  • mssql 리소스를 가져오는 과정에서 문제가 발생했다.
  • 위에서처럼 동일하게 go sdk api 응답 과정에서 문제가 발생했다.

 

문제가 발생했다고 예상되는 지점 (cloud_mssql.go)

func GetCloudMssqlInstance(client *conn.NcloudAPIClient, cloudMssqlInstanceNo string) (*vmssql.CloudMssqlInstance, error) {
	reqParams := &vmssql.GetCloudMssqlInstanceListRequest{
		CloudMssqlInstanceNoList: []*string{ncloud.String(cloudMssqlInstanceNo)},
	}
	LogCommonRequest("GetCloudMssqlInstanceList", reqParams)
	resp, err := client.Vmssql.V2Api.GetCloudMssqlInstanceList(reqParams)
	if err != nil {
		LogErrorResponse("GetCloudMssqlInstanceList", err, reqParams)
		return nil, err
	}
	LogCommonResponse("GetCloudMssqlInstanceList", GetCommonResponse(resp))

	for _, inst := range resp.CloudMssqlInstanceList.CloudMssqlInstanceList {
		if cloudMssqlInstanceNo == ncloud.StringValue(inst.CloudMssqlInstanceNo) {
			return inst, nil
		}
	}
	return nil, nil
}

 

멘토님께 go sdk api 수정을 한번 더 부탁드리고 수정된 sdk를 반영 및 cloud_mssql.go, cloud_mssql_data_source.go 코드를 수정했다.

멘토님 문의

 

기존 코드 (GetCloudMssqlInstance)

for _, inst := range resp.CloudMssqlInstanceList.CloudMssqlInstanceList {

 

수정 코드 (GetCloudMssqlInstance)

for _, inst := range resp.CloudMssqlInstanceList

 

기존 코드 (getCloudMssqlList)

for _, ms := range resp.CloudMssqlInstanceList.CloudMssqlInstanceList {

 

수정 코드 (getCloudMssqlList)

for _, ms := range resp.CloudMssqlInstanceList {

 

 

cloud_mssql.go의 read 함수에서 값을 잘 읽어오지 못하는 것 같아, 코드를 수정하였다. 

func resourceNcloudMssqlRead(d *schema.ResourceData, meta interface{}) error {
	client := meta.(*conn.ProviderConfig).Client

	ms, err := GetCloudMssqlInstance(client, d.Id())
	if err != nil {
		return err
	}

	if ms == nil {
		log.Printf("unable to find resource: %s", d.Id())
		d.SetId("") // resource not found

		return nil
	}

	d.SetId(ncloud.StringValue(ms.CloudMssqlInstanceNo))
	d.Set("instance_no", ncloud.StringValue(ms.CloudMssqlInstanceNo))

	convertedInstance := ConvertToMap(ms)
	SetSingularResourceDataFromMapSchema(ResourceNcloudMssql(), d, convertedInstance)

	return nil
}

 

 

이렇게 수정하고 data source 테스트하기 

 

결과

panic: Invalid address to set: []string{"instance_no"}

 

내용

api의 response를 보고 instance_no를 설정해주어야 하는 줄 알았는데, 필요가 없었다. 

 

create와 read 함수 부분에 d.SetId() 부분만 남겼다. 

d.SetId(ncloud.StringValue(ms.CloudMssqlInstanceNo))

 

 

다시 테스트 하기 .... 

 

결과

2023/08/31 15:29:31 [INFO] GetCloudMssqlInstanceList success response=RequestID: bad68f71-20e6-4868-b593-135ebf612fce, ReturnCode: 0, ReturnMessage: success 
panic: interface conversion: interface {} is nil, not string

 

내용

생성한 리소스를 가져오는 과정 중에 타입이 안 맞아서 생긴 오류이다.

 

수정하기

 

1) 생성한 types.go에서 struct를 수정해주었다.

 

type CloudMssqlInstance struct에서 AccessControlGroupNoList를 수정하고, CloudMssqlServerInstanceList는 지웠다.

AccessControlGroupNoList     []*string `json:"accessControlGroupNoList,omitempty"`

 

2) cloud_mssql.go를 수정해주었다.

 

 

convertCloudMssql에서 return에 AccessControlGroupNoList: instance.AccessControlGroupNoList를 추가했다.

 

다시 테스트 .... !!

 

결과 

2023/08/31 16:57:36 [INFO] GetCloudMssqlInstanceList success response=RequestID: 5eeeb354-9b3c-4eea-a4fc-09b811ffc4cf, ReturnCode: 0, ReturnMessage: success 
panic: interface conversion: interface {} is nil, not string

 

내용 

인터페이스 형(type)을 다른 형으로 변환하려고 시도할 때, nil 값을 포함하는 인터페이스를 문자열(string)로 변환하려고 할 때 발생

  • cloud_mssql_data_source.go 파일의 172번째 줄 주변에 해당하는 코드를 검토

 

생성된 mssql 리소스의 id를 의미하는 cloud_mssql_no를 작성했는데, 없기 때문에 사용할 수 없음 (load_balancer를 참고하여 개발했기 때문인 것 같다.)

 

따라서 그냥 id를 의미하는 id로 수정하였다. 

 

dataSourceNcloudMssqlRead에서 SetId 부분을 다음과 같이 변경했다. 

d.SetId(msListMap[0]["id"].(string))

 

.... 다시 테스트 하였는데... 같은 오류를 마주하였다...!!! 

 

멘토님 문의하기 

멘토님 문의
멘토님 답변

 

cloud_mssql.go에서 schema 정의를 할 때, id 값을 넣어주었다.

id 값 넣기

 

dataSourceNcloudMssqlRead에서 SetId 부분을 다음과 같이 변경했다. 

d.SetId(msListMap[0]["cloudMssqlInstanceNo"].(string))

 

다시 테스트 !!

 

결과

2023-09-01T23:12:08.585+0900 [ERROR] sdk.proto: Response contains error diagnostic: tf_rpc=ApplyResourceChange tf_resource_type=ncloud_subnet
  diagnostic_detail=
  | Status: 400 Bad Request, Body: {
  |   "responseError": {
  |     "returnCode": "1001019",
  |     "returnMessage": "There is a product in operation on Subnet. 관련된 Server, Network Interface, Cloud functions, Load balancer, Auto Scaling, NAT Gateway (New) 을 모두 삭제해주세요."
  |   }
  | }
   diagnostic_severity=ERROR diagnostic_summary="DeleteSubnet Subnet Instance params={0xc0005d29d8 0xc0004b9850}" tf_provider_addr=registry.terraform.io/hashicorp/ncloud tf_req_id=74f15e99-e424-69ae-29ae-268e97e3b5ce tf_proto_version=5.3

 

resource test 할 때와 동일한 에러가 발생했다.. 

 

여기서 이제, cloud_mssql.go에서의 문제를 해결했었다. 

 

data source 문제는 해결하지 못하여, 우선 pr을 올려서 멘토님의 피드백을 받아보기로 하였다. 

pr 올리기

 

pr을 올리고 멘토님께도 질문을 남겼다. 

질문 남기기
질문 남기기
멘토님 답변

 

멘토님이 주신 답변을 반영해보자. 

 

destory 함수는 nil을 반환할 때만 성공한다고 한다.

  • 멘토님이 주신 코드를 참고해서 수정해보자.

 

cloud_mssql_test.go의 destroy 함수에 다음의 로직을 반영해보자.

resp, err := config.Client.Vmssql.V2Api.GetCloudMssqlInstanceDetail(reqParams)
	if err != nil {
		commonErr, parseErr := GetCommonErrorBody(err)
		if parseErr == nil && commonErr.ReturnCode == "5001269" {
			return  nil
		}

		return err
	}

 

waitForCloudMssqlBackupListDeletion에서 instanceNo 잘 넘어오는지 확인 

instanceNo 확인

 

cloud_mssql.go에서 waitForCloudMssqlBackupListDeletion를 추가했지만, 계속해서 5001269 발생해서 test 코드의 destory 부분에서 처리하기로 결정하였다. 

 

func testAccCheckCloudMssqlDestroy(s *terraform.State, provider *schema.Provider) error {
	config := provider.Meta().(*conn.ProviderConfig)

	for _, rs := range s.RootModule().Resources {
		if rs.Type != "ncloud_mssql" {
			continue
		}

		cloudMssql, err := mssqlservice.GetCloudMssqlInstance(config, rs.Primary.ID)
		if err != nil {
			commonErr, parseErr := GetCommonErrorBody(err)
			if parseErr == nil && commonErr.ReturnCode == "1001019" {
				time.Sleep(3 * time.Minute)
				return nil
			}
			return err
		}

		if cloudMssql != nil {
			return fmt.Errorf("CloudMssql(%s) still exists", ncloud.StringValue(cloudMssql.CloudMssqlInstanceNo))
		}
	}

	return nil
}

 

waitForCloudMssqlBackupListDeletion 함수도 추가하여 적용해보았지만, 이 함수를 적용해도 이미 지워진 db라는 메시지가 떴다. 

추측 → 이미 지워진 db라 조회가 안되는 것 같다. 

 

따라서, 이 함수는 적용하지 않고 Destory를 수정하고 다시 pr을 올렸다. 

pr 올리기

 

테스트, 수정, 테스트, 수정..... 과정의 연속이었지만, 테스트를 하고 수정하는 과정이 더 좋은 코드를 만드는 방향으로 나아가게 하는 것 같다 ! 

 

728x90