fix: sqlserver beta fixes #51
9 changed files with 291 additions and 35 deletions
|
|
@ -269,7 +269,7 @@ func (r *databaseResource) Read(ctx context.Context, req resource.ReadRequest, r
|
||||||
|
|
||||||
ctx = core.InitProviderContext(ctx)
|
ctx = core.InitProviderContext(ctx)
|
||||||
|
|
||||||
projectId, instanceId, region, databaseName, errExt := r.extractIdentityData(model, identityData)
|
projectId, region, instanceId, databaseName, errExt := r.extractIdentityData(model, identityData)
|
||||||
if errExt != nil {
|
if errExt != nil {
|
||||||
core.LogAndAddError(
|
core.LogAndAddError(
|
||||||
ctx,
|
ctx,
|
||||||
|
|
@ -353,7 +353,7 @@ func (r *databaseResource) Delete(ctx context.Context, req resource.DeleteReques
|
||||||
|
|
||||||
ctx = core.InitProviderContext(ctx)
|
ctx = core.InitProviderContext(ctx)
|
||||||
|
|
||||||
projectId, instanceId, region, databaseName, errExt := r.extractIdentityData(model, identityData)
|
projectId, region, instanceId, databaseName, errExt := r.extractIdentityData(model, identityData)
|
||||||
if errExt != nil {
|
if errExt != nil {
|
||||||
core.LogAndAddError(
|
core.LogAndAddError(
|
||||||
ctx,
|
ctx,
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,9 @@ func mapResourceFields(source *sqlserverflexbeta.GetDatabaseResponse, model *res
|
||||||
model.ProjectId = types.StringValue(model.ProjectId.ValueString())
|
model.ProjectId = types.StringValue(model.ProjectId.ValueString())
|
||||||
model.InstanceId = types.StringValue(model.InstanceId.ValueString())
|
model.InstanceId = types.StringValue(model.InstanceId.ValueString())
|
||||||
|
|
||||||
|
model.CompatibilityLevel = types.Int64Value(source.GetCompatibilityLevel())
|
||||||
|
model.CollationName = types.StringValue(source.GetCollationName())
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-framework/path"
|
"github.com/hashicorp/terraform-plugin-framework/path"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/resource"
|
"github.com/hashicorp/terraform-plugin-framework/resource"
|
||||||
|
|
@ -17,6 +18,7 @@ import (
|
||||||
"github.com/stackitcloud/stackit-sdk-go/core/oapierror"
|
"github.com/stackitcloud/stackit-sdk-go/core/oapierror"
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/sqlserverflexbeta"
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/sqlserverflexbeta"
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/conversion"
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/conversion"
|
||||||
|
wait "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/wait/sqlserverflexbeta"
|
||||||
|
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/core"
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/core"
|
||||||
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils"
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils"
|
||||||
|
|
@ -59,7 +61,7 @@ type DatabaseResourceIdentityModel struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *databaseResource) Metadata(
|
func (r *databaseResource) Metadata(
|
||||||
ctx context.Context,
|
_ context.Context,
|
||||||
req resource.MetadataRequest,
|
req resource.MetadataRequest,
|
||||||
resp *resource.MetadataResponse,
|
resp *resource.MetadataResponse,
|
||||||
) {
|
) {
|
||||||
|
|
@ -179,6 +181,26 @@ func (r *databaseResource) Create(ctx context.Context, req resource.CreateReques
|
||||||
Owner: data.Owner.ValueStringPointer(),
|
Owner: data.Owner.ValueStringPointer(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_, err := wait.WaitForUserWaitHandler(
|
||||||
|
ctx,
|
||||||
|
r.client,
|
||||||
|
projectId,
|
||||||
|
instanceId,
|
||||||
|
region,
|
||||||
|
data.Owner.ValueString(),
|
||||||
|
).
|
||||||
|
SetSleepBeforeWait(10 * time.Second).
|
||||||
|
WaitWithContext(ctx)
|
||||||
|
if err != nil {
|
||||||
|
core.LogAndAddError(
|
||||||
|
ctx,
|
||||||
|
&resp.Diagnostics,
|
||||||
|
createErr,
|
||||||
|
fmt.Sprintf("Calling API: %v", err),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
createResp, err := r.client.CreateDatabaseRequest(ctx, projectId, region, instanceId).
|
createResp, err := r.client.CreateDatabaseRequest(ctx, projectId, region, instanceId).
|
||||||
CreateDatabaseRequestPayload(payLoad).
|
CreateDatabaseRequestPayload(payLoad).
|
||||||
Execute()
|
Execute()
|
||||||
|
|
@ -221,7 +243,7 @@ func (r *databaseResource) Create(ctx context.Context, req resource.CreateReques
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: is this neccessary to wait for the database-> API say 200 ?
|
// TODO: is this neccessary to wait for the database-> API say 200 ?
|
||||||
/*waitResp, err := wait.CreateDatabaseWaitHandler(
|
waitResp, err := wait.CreateDatabaseWaitHandler(
|
||||||
ctx,
|
ctx,
|
||||||
r.client,
|
r.client,
|
||||||
projectId,
|
projectId,
|
||||||
|
|
@ -253,7 +275,7 @@ func (r *databaseResource) Create(ctx context.Context, req resource.CreateReques
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if *waitResp.Id != createId {
|
if *waitResp.Id != databaseId {
|
||||||
core.LogAndAddError(
|
core.LogAndAddError(
|
||||||
ctx,
|
ctx,
|
||||||
&resp.Diagnostics,
|
&resp.Diagnostics,
|
||||||
|
|
@ -281,7 +303,7 @@ func (r *databaseResource) Create(ctx context.Context, req resource.CreateReques
|
||||||
"Database creation waiting: returned name is different",
|
"Database creation waiting: returned name is different",
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
}*/
|
}
|
||||||
|
|
||||||
database, err := r.client.GetDatabaseRequest(ctx, projectId, region, instanceId, databaseName).Execute()
|
database, err := r.client.GetDatabaseRequest(ctx, projectId, region, instanceId, databaseName).Execute()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -334,7 +356,7 @@ func (r *databaseResource) Read(ctx context.Context, req resource.ReadRequest, r
|
||||||
|
|
||||||
ctx = core.InitProviderContext(ctx)
|
ctx = core.InitProviderContext(ctx)
|
||||||
|
|
||||||
projectId, instanceId, region, databaseName, errExt := r.extractIdentityData(model, identityData)
|
projectId, region, instanceId, databaseName, errExt := r.extractIdentityData(model, identityData)
|
||||||
if errExt != nil {
|
if errExt != nil {
|
||||||
core.LogAndAddError(
|
core.LogAndAddError(
|
||||||
ctx,
|
ctx,
|
||||||
|
|
@ -418,7 +440,7 @@ func (r *databaseResource) Delete(ctx context.Context, req resource.DeleteReques
|
||||||
|
|
||||||
ctx = core.InitProviderContext(ctx)
|
ctx = core.InitProviderContext(ctx)
|
||||||
|
|
||||||
projectId, instanceId, region, databaseName, errExt := r.extractIdentityData(model, identityData)
|
projectId, region, instanceId, databaseName, errExt := r.extractIdentityData(model, identityData)
|
||||||
if errExt != nil {
|
if errExt != nil {
|
||||||
core.LogAndAddError(
|
core.LogAndAddError(
|
||||||
ctx,
|
ctx,
|
||||||
|
|
@ -436,7 +458,13 @@ func (r *databaseResource) Delete(ctx context.Context, req resource.DeleteReques
|
||||||
// Delete existing record set
|
// Delete existing record set
|
||||||
err := r.client.DeleteDatabaseRequestExecute(ctx, projectId, region, instanceId, databaseName)
|
err := r.client.DeleteDatabaseRequestExecute(ctx, projectId, region, instanceId, databaseName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
core.LogAndAddError(ctx, &resp.Diagnostics, "Error deleting database", fmt.Sprintf("Calling API: %v", err))
|
core.LogAndAddError(
|
||||||
|
ctx,
|
||||||
|
&resp.Diagnostics,
|
||||||
|
"Error deleting database",
|
||||||
|
fmt.Sprintf(
|
||||||
|
"Calling API: %v\nname: %s, region: %s, instanceId: %s", err, databaseName, region, instanceId))
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx = core.LogResponse(ctx)
|
ctx = core.LogResponse(ctx)
|
||||||
|
|
|
||||||
|
|
@ -241,7 +241,7 @@ func (r *instanceResource) Create(ctx context.Context, req resource.CreateReques
|
||||||
InstanceId,
|
InstanceId,
|
||||||
region,
|
region,
|
||||||
).SetSleepBeforeWait(
|
).SetSleepBeforeWait(
|
||||||
30 * time.Second,
|
10 * time.Second,
|
||||||
).SetTimeout(
|
).SetTimeout(
|
||||||
90 * time.Minute,
|
90 * time.Minute,
|
||||||
).WaitWithContext(ctx)
|
).WaitWithContext(ctx)
|
||||||
|
|
|
||||||
|
|
@ -215,6 +215,7 @@ func TestAccInstanceWithUsers(t *testing.T) {
|
||||||
|
|
||||||
func TestAccInstanceWithDatabases(t *testing.T) {
|
func TestAccInstanceWithDatabases(t *testing.T) {
|
||||||
data := getExample()
|
data := getExample()
|
||||||
|
t.Logf(" ... working on instance %s", data.TfName)
|
||||||
dbName := "testDb"
|
dbName := "testDb"
|
||||||
userName := "testUser"
|
userName := "testUser"
|
||||||
data.Users = []User{
|
data.Users = []User{
|
||||||
|
|
@ -258,13 +259,15 @@ func TestAccInstanceWithDatabases(t *testing.T) {
|
||||||
data,
|
data,
|
||||||
),
|
),
|
||||||
Check: resource.ComposeAggregateTestCheckFunc(
|
Check: resource.ComposeAggregateTestCheckFunc(
|
||||||
resource.TestCheckResourceAttr(resName, "name", data.Name),
|
|
||||||
resource.TestCheckResourceAttrSet(resName, "id"),
|
resource.TestCheckResourceAttrSet(resName, "id"),
|
||||||
resource.TestCheckResourceAttr(resUserName, "name", userName),
|
resource.TestCheckResourceAttr(resName, "name", data.Name),
|
||||||
|
|
||||||
resource.TestCheckResourceAttrSet(resUserName, "id"),
|
resource.TestCheckResourceAttrSet(resUserName, "id"),
|
||||||
|
resource.TestCheckResourceAttr(resUserName, "username", userName),
|
||||||
|
|
||||||
|
resource.TestCheckResourceAttrSet(resDbName, "id"),
|
||||||
resource.TestCheckResourceAttr(resDbName, "name", dbName),
|
resource.TestCheckResourceAttr(resDbName, "name", dbName),
|
||||||
resource.TestCheckResourceAttr(resDbName, "owner", userName),
|
resource.TestCheckResourceAttr(resDbName, "owner", userName),
|
||||||
resource.TestCheckResourceAttrSet(resDbName, "id"),
|
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -44,10 +44,13 @@ resource "stackitprivatepreview_sqlserverflexbeta_user" "{{ $user.Name }}" {
|
||||||
{{ $tfName := .TfName }}
|
{{ $tfName := .TfName }}
|
||||||
{{ range $db := .Databases }}
|
{{ range $db := .Databases }}
|
||||||
resource "stackitprivatepreview_sqlserverflexbeta_database" "{{ $db.Name }}" {
|
resource "stackitprivatepreview_sqlserverflexbeta_database" "{{ $db.Name }}" {
|
||||||
|
depends_on = [stackitprivatepreview_sqlserverflexbeta_user.{{ $db.Owner }}]
|
||||||
project_id = "{{ $db.ProjectId }}"
|
project_id = "{{ $db.ProjectId }}"
|
||||||
instance_id = stackitprivatepreview_sqlserverflexbeta_instance.{{ $tfName }}.instance_id
|
instance_id = stackitprivatepreview_sqlserverflexbeta_instance.{{ $tfName }}.instance_id
|
||||||
name = "{{ $db.Name }}"
|
name = "{{ $db.Name }}"
|
||||||
owner = "{{ $db.Owner }}"
|
owner = "{{ $db.Owner }}"
|
||||||
|
collation = "Albanian_BIN"
|
||||||
|
compatibility = "160"
|
||||||
}
|
}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
|
||||||
|
|
@ -153,6 +153,9 @@ func mapFieldsCreate(userResp *sqlserverflexbeta.CreateUserResponse, model *reso
|
||||||
model.Roles = types.List(types.SetNull(types.StringType))
|
model.Roles = types.List(types.SetNull(types.StringType))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
model.Password = types.StringPointerValue(user.Password)
|
||||||
|
model.Uri = types.StringPointerValue(user.Uri)
|
||||||
|
|
||||||
model.Host = types.StringPointerValue(user.Host)
|
model.Host = types.StringPointerValue(user.Host)
|
||||||
model.Port = types.Int64PointerValue(user.Port)
|
model.Port = types.Int64PointerValue(user.Port)
|
||||||
model.Region = types.StringValue(region)
|
model.Region = types.StringValue(region)
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-framework/path"
|
"github.com/hashicorp/terraform-plugin-framework/path"
|
||||||
"github.com/hashicorp/terraform-plugin-framework/resource"
|
"github.com/hashicorp/terraform-plugin-framework/resource"
|
||||||
|
|
@ -47,7 +48,7 @@ type UserResourceIdentityModel struct {
|
||||||
ProjectID types.String `tfsdk:"project_id"`
|
ProjectID types.String `tfsdk:"project_id"`
|
||||||
Region types.String `tfsdk:"region"`
|
Region types.String `tfsdk:"region"`
|
||||||
InstanceID types.String `tfsdk:"instance_id"`
|
InstanceID types.String `tfsdk:"instance_id"`
|
||||||
UserID types.Int64 `tfsdk:"database_id"`
|
UserID types.Int64 `tfsdk:"user_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type userResource struct {
|
type userResource struct {
|
||||||
|
|
@ -215,10 +216,22 @@ func (r *userResource) Create(
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
userId := *userResp.Id
|
userId := *userResp.Id
|
||||||
ctx = tflog.SetField(ctx, "user_id", userId)
|
ctx = tflog.SetField(ctx, "user_id", userId)
|
||||||
|
|
||||||
// Map response body to schema
|
// Set data returned by API in identity
|
||||||
|
identity := UserResourceIdentityModel{
|
||||||
|
ProjectID: types.StringValue(projectId),
|
||||||
|
Region: types.StringValue(region),
|
||||||
|
InstanceID: types.StringValue(instanceId),
|
||||||
|
UserID: types.Int64Value(userId),
|
||||||
|
}
|
||||||
|
resp.Diagnostics.Append(resp.Identity.Set(ctx, identity)...)
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
err = mapFieldsCreate(userResp, &model, region)
|
err = mapFieldsCreate(userResp, &model, region)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
core.LogAndAddError(
|
core.LogAndAddError(
|
||||||
|
|
@ -229,6 +242,51 @@ func (r *userResource) Create(
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
waitResp, err := sqlserverflexbetaWait.CreateUserWaitHandler(
|
||||||
|
ctx,
|
||||||
|
r.client,
|
||||||
|
projectId,
|
||||||
|
instanceId,
|
||||||
|
region,
|
||||||
|
userId,
|
||||||
|
).SetSleepBeforeWait(
|
||||||
|
90 * time.Second,
|
||||||
|
).SetTimeout(
|
||||||
|
90 * time.Minute,
|
||||||
|
).WaitWithContext(ctx)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
core.LogAndAddError(
|
||||||
|
ctx,
|
||||||
|
&resp.Diagnostics,
|
||||||
|
"create user",
|
||||||
|
fmt.Sprintf("Instance creation waiting: %v", err),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if waitResp.Id == nil {
|
||||||
|
core.LogAndAddError(
|
||||||
|
ctx,
|
||||||
|
&resp.Diagnostics,
|
||||||
|
"create user",
|
||||||
|
"Instance creation waiting: returned id is nil",
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map response body to schema
|
||||||
|
err = mapFields(waitResp, &model, region)
|
||||||
|
if err != nil {
|
||||||
|
core.LogAndAddError(
|
||||||
|
ctx,
|
||||||
|
&resp.Diagnostics,
|
||||||
|
"Error creating user",
|
||||||
|
fmt.Sprintf("Processing API payload: %v", err),
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
// Set state to fully populated data
|
// Set state to fully populated data
|
||||||
diags = resp.State.Set(ctx, model)
|
diags = resp.State.Set(ctx, model)
|
||||||
resp.Diagnostics.Append(diags...)
|
resp.Diagnostics.Append(diags...)
|
||||||
|
|
@ -350,9 +408,29 @@ func (r *userResource) Delete(
|
||||||
|
|
||||||
// Delete existing record set
|
// Delete existing record set
|
||||||
// err := r.client.DeleteUserRequest(ctx, projectId, region, instanceId, userId).Execute()
|
// err := r.client.DeleteUserRequest(ctx, projectId, region, instanceId, userId).Execute()
|
||||||
|
err := r.client.DeleteUserRequestExecute(ctx, projectId, region, instanceId, userId)
|
||||||
|
if err != nil {
|
||||||
|
var oapiErr *oapierror.GenericOpenAPIError
|
||||||
|
ok := errors.As(err, &oapiErr)
|
||||||
|
if !ok {
|
||||||
|
// TODO err handling
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch oapiErr.StatusCode {
|
||||||
|
case http.StatusNotFound:
|
||||||
|
resp.State.RemoveResource(ctx)
|
||||||
|
return
|
||||||
|
// case http.StatusInternalServerError:
|
||||||
|
// tflog.Warn(ctx, "[delete user] Wait handler got error 500")
|
||||||
|
// return false, nil, nil
|
||||||
|
default:
|
||||||
|
// TODO err handling
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
// Delete existing record set
|
// Delete existing record set
|
||||||
_, err := sqlserverflexbetaWait.DeleteUserWaitHandler(ctx, r.client, projectId, region, instanceId, userId).
|
_, err = sqlserverflexbetaWait.DeleteUserWaitHandler(ctx, r.client, projectId, region, instanceId, userId).
|
||||||
WaitWithContext(ctx)
|
WaitWithContext(ctx)
|
||||||
//err := r.client.DeleteUserRequest(ctx, arg.projectId, arg.region, arg.instanceId, userId).Execute()
|
//err := r.client.DeleteUserRequest(ctx, arg.projectId, arg.region, arg.instanceId, userId).Execute()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -45,6 +45,22 @@ type APIClientInterface interface {
|
||||||
instanceId string,
|
instanceId string,
|
||||||
userId int64,
|
userId int64,
|
||||||
) (*sqlserverflex.GetUserResponse, error)
|
) (*sqlserverflex.GetUserResponse, error)
|
||||||
|
|
||||||
|
ListRolesRequestExecute(
|
||||||
|
ctx context.Context,
|
||||||
|
projectId string,
|
||||||
|
region string,
|
||||||
|
instanceId string,
|
||||||
|
) (*sqlserverflex.ListRolesResponse, error)
|
||||||
|
|
||||||
|
ListUsersRequest(ctx context.Context, projectId string, region string, instanceId string) sqlserverflex.ApiListUsersRequestRequest
|
||||||
|
|
||||||
|
ListUsersRequestExecute(
|
||||||
|
ctx context.Context,
|
||||||
|
projectId string,
|
||||||
|
region string,
|
||||||
|
instanceId string,
|
||||||
|
) (*sqlserverflex.ListUserResponse, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// APIClientUserInterface Interface needed for tests
|
// APIClientUserInterface Interface needed for tests
|
||||||
|
|
@ -85,6 +101,54 @@ func CreateInstanceWaitHandler(
|
||||||
return false, nil, nil
|
return false, nil, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tflog.Info(ctx, "trying to get roles")
|
||||||
|
time.Sleep(10 * time.Second)
|
||||||
|
_, rolesErr := a.ListRolesRequestExecute(ctx, projectId, region, instanceId)
|
||||||
|
if rolesErr != nil {
|
||||||
|
var oapiErr *oapierror.GenericOpenAPIError
|
||||||
|
ok := errors.As(rolesErr, &oapiErr)
|
||||||
|
if !ok {
|
||||||
|
return false, nil, fmt.Errorf("could not convert error to oapierror.GenericOpenAPIError")
|
||||||
|
}
|
||||||
|
if oapiErr.StatusCode != http.StatusInternalServerError {
|
||||||
|
tflog.Info(
|
||||||
|
ctx, "got error from api", map[string]interface{}{
|
||||||
|
"error": rolesErr.Error(),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
return false, nil, rolesErr
|
||||||
|
}
|
||||||
|
tflog.Info(
|
||||||
|
ctx, "wait for get-roles to work hack", map[string]interface{}{},
|
||||||
|
)
|
||||||
|
time.Sleep(10 * time.Second)
|
||||||
|
return false, nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
tflog.Info(ctx, "trying to get users")
|
||||||
|
time.Sleep(10 * time.Second)
|
||||||
|
_, usersErr := a.ListUsersRequestExecute(ctx, projectId, region, instanceId)
|
||||||
|
if usersErr != nil {
|
||||||
|
var oapiErr *oapierror.GenericOpenAPIError
|
||||||
|
ok := errors.As(usersErr, &oapiErr)
|
||||||
|
if !ok {
|
||||||
|
return false, nil, fmt.Errorf("could not convert error to oapierror.GenericOpenAPIError")
|
||||||
|
}
|
||||||
|
if oapiErr.StatusCode != http.StatusInternalServerError {
|
||||||
|
tflog.Info(
|
||||||
|
ctx, "got error from api", map[string]interface{}{
|
||||||
|
"error": rolesErr.Error(),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
return false, nil, usersErr
|
||||||
|
}
|
||||||
|
tflog.Info(
|
||||||
|
ctx, "wait for get-users to work hack", map[string]interface{}{},
|
||||||
|
)
|
||||||
|
time.Sleep(10 * time.Second)
|
||||||
|
return false, nil, nil
|
||||||
|
}
|
||||||
return true, s, nil
|
return true, s, nil
|
||||||
case strings.ToLower(InstanceStateUnknown), strings.ToLower(InstanceStateFailed):
|
case strings.ToLower(InstanceStateUnknown), strings.ToLower(InstanceStateFailed):
|
||||||
return true, s, fmt.Errorf("create failed for instance with id %s", instanceId)
|
return true, s, fmt.Errorf("create failed for instance with id %s", instanceId)
|
||||||
|
|
@ -94,6 +158,7 @@ func CreateInstanceWaitHandler(
|
||||||
"status": *s.Status,
|
"status": *s.Status,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
time.Sleep(10 * time.Second)
|
||||||
return false, nil, nil
|
return false, nil, nil
|
||||||
default:
|
default:
|
||||||
tflog.Info(
|
tflog.Info(
|
||||||
|
|
@ -187,11 +252,36 @@ func CreateDatabaseWaitHandler(
|
||||||
func() (waitFinished bool, response *sqlserverflex.GetDatabaseResponse, err error) {
|
func() (waitFinished bool, response *sqlserverflex.GetDatabaseResponse, err error) {
|
||||||
s, err := a.GetDatabaseRequestExecute(ctx, projectId, region, instanceId, databaseName)
|
s, err := a.GetDatabaseRequestExecute(ctx, projectId, region, instanceId, databaseName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
var oapiErr *oapierror.GenericOpenAPIError
|
||||||
|
ok := errors.As(err, &oapiErr)
|
||||||
|
if !ok {
|
||||||
|
return false, nil, fmt.Errorf("get database - could not convert error to oapierror.GenericOpenAPIError: %s", err.Error())
|
||||||
|
}
|
||||||
|
if oapiErr.StatusCode != http.StatusNotFound {
|
||||||
return false, nil, err
|
return false, nil, err
|
||||||
}
|
}
|
||||||
if s == nil || s.Name == nil || *s.Name != databaseName {
|
|
||||||
return false, nil, nil
|
return false, nil, nil
|
||||||
}
|
}
|
||||||
|
if s == nil || s.Name == nil || *s.Name != databaseName {
|
||||||
|
return false, nil, errors.New("response did return different result")
|
||||||
|
}
|
||||||
|
return true, s, nil
|
||||||
|
},
|
||||||
|
)
|
||||||
|
return handler
|
||||||
|
}
|
||||||
|
|
||||||
|
// CreateUserWaitHandler will wait for instance creation
|
||||||
|
func CreateUserWaitHandler(
|
||||||
|
ctx context.Context,
|
||||||
|
a APIClientInterface,
|
||||||
|
projectId, instanceId, region string,
|
||||||
|
userId int64,
|
||||||
|
) *wait.AsyncActionHandler[sqlserverflex.GetUserResponse] {
|
||||||
|
handler := wait.New(
|
||||||
|
func() (waitFinished bool, response *sqlserverflex.GetUserResponse, err error) {
|
||||||
|
s, err := a.GetUserRequestExecute(ctx, projectId, region, instanceId, userId)
|
||||||
|
if err != nil {
|
||||||
var oapiErr *oapierror.GenericOpenAPIError
|
var oapiErr *oapierror.GenericOpenAPIError
|
||||||
ok := errors.As(err, &oapiErr)
|
ok := errors.As(err, &oapiErr)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
@ -200,7 +290,58 @@ func CreateDatabaseWaitHandler(
|
||||||
if oapiErr.StatusCode != http.StatusNotFound {
|
if oapiErr.StatusCode != http.StatusNotFound {
|
||||||
return false, nil, err
|
return false, nil, err
|
||||||
}
|
}
|
||||||
return true, nil, nil
|
return false, nil, nil
|
||||||
|
}
|
||||||
|
return true, s, nil
|
||||||
|
},
|
||||||
|
)
|
||||||
|
return handler
|
||||||
|
}
|
||||||
|
|
||||||
|
// WaitForUserWaitHandler will wait for instance creation
|
||||||
|
func WaitForUserWaitHandler(
|
||||||
|
ctx context.Context,
|
||||||
|
a APIClientInterface,
|
||||||
|
projectId, instanceId, region, userName string,
|
||||||
|
) *wait.AsyncActionHandler[sqlserverflex.ListUserResponse] {
|
||||||
|
startTime := time.Now()
|
||||||
|
timeOut := 2 * time.Minute
|
||||||
|
|
||||||
|
handler := wait.New(
|
||||||
|
func() (waitFinished bool, response *sqlserverflex.ListUserResponse, err error) {
|
||||||
|
if time.Since(startTime) > timeOut {
|
||||||
|
return false, nil, errors.New("ran into timeout")
|
||||||
|
}
|
||||||
|
s, err := a.ListUsersRequest(ctx, projectId, region, instanceId).Size(100).Execute()
|
||||||
|
if err != nil {
|
||||||
|
var oapiErr *oapierror.GenericOpenAPIError
|
||||||
|
ok := errors.As(err, &oapiErr)
|
||||||
|
if !ok {
|
||||||
|
return false, nil, fmt.Errorf("Wait (list users) could not convert error to oapierror.GenericOpenAPIError: %s", err.Error())
|
||||||
|
}
|
||||||
|
if oapiErr.StatusCode != http.StatusNotFound {
|
||||||
|
return false, nil, err
|
||||||
|
}
|
||||||
|
tflog.Info(
|
||||||
|
ctx, "Wait (list users) still waiting", map[string]interface{}{},
|
||||||
|
)
|
||||||
|
|
||||||
|
return false, nil, nil
|
||||||
|
}
|
||||||
|
users, ok := s.GetUsersOk()
|
||||||
|
if !ok {
|
||||||
|
return false, nil, errors.New("no users found")
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, u := range users {
|
||||||
|
if u.GetUsername() == userName {
|
||||||
|
return true, s, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tflog.Info(
|
||||||
|
ctx, "Wait (list users) user still not present", map[string]interface{}{},
|
||||||
|
)
|
||||||
|
return false, nil, nil
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
return handler
|
return handler
|
||||||
|
|
@ -209,13 +350,13 @@ func CreateDatabaseWaitHandler(
|
||||||
// DeleteUserWaitHandler will wait for instance deletion
|
// DeleteUserWaitHandler will wait for instance deletion
|
||||||
func DeleteUserWaitHandler(
|
func DeleteUserWaitHandler(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
a APIClientUserInterface,
|
a APIClientInterface,
|
||||||
projectId, instanceId, region string,
|
projectId, region, instanceId string,
|
||||||
userId int64,
|
userId int64,
|
||||||
) *wait.AsyncActionHandler[struct{}] {
|
) *wait.AsyncActionHandler[struct{}] {
|
||||||
handler := wait.New(
|
handler := wait.New(
|
||||||
func() (waitFinished bool, response *struct{}, err error) {
|
func() (waitFinished bool, response *struct{}, err error) {
|
||||||
err = a.DeleteUserRequestExecute(ctx, projectId, region, instanceId, userId)
|
_, err = a.GetUserRequestExecute(ctx, projectId, region, instanceId, userId)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return false, nil, nil
|
return false, nil, nil
|
||||||
}
|
}
|
||||||
|
|
@ -228,9 +369,6 @@ func DeleteUserWaitHandler(
|
||||||
switch oapiErr.StatusCode {
|
switch oapiErr.StatusCode {
|
||||||
case http.StatusNotFound:
|
case http.StatusNotFound:
|
||||||
return true, nil, nil
|
return true, nil, nil
|
||||||
case http.StatusInternalServerError:
|
|
||||||
tflog.Warn(ctx, "Wait handler got error 500")
|
|
||||||
return false, nil, nil
|
|
||||||
default:
|
default:
|
||||||
return false, nil, err
|
return false, nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue