github.com/sacloud/libsacloud/v2@v2.32.3/helper/service/database/update_request.go (about)

     1  // Copyright 2016-2022 The Libsacloud Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package database
    16  
    17  import (
    18  	"context"
    19  	"fmt"
    20  	"strconv"
    21  	"strings"
    22  
    23  	"github.com/sacloud/libsacloud/v2/helper/service"
    24  
    25  	"github.com/sacloud/libsacloud/v2/helper/validate"
    26  	"github.com/sacloud/libsacloud/v2/sacloud"
    27  	"github.com/sacloud/libsacloud/v2/sacloud/types"
    28  )
    29  
    30  type UpdateRequest struct {
    31  	Zone string   `validate:"required"`
    32  	ID   types.ID `validate:"required"`
    33  
    34  	Name        *string     `request:",omitempty" validate:"omitempty,min=1"`
    35  	Description *string     `request:",omitempty" validate:"omitempty,min=1,max=512"`
    36  	Tags        *types.Tags `request:",omitempty"`
    37  	IconID      *types.ID   `request:",omitempty"`
    38  
    39  	SourceNetwork         *[]string                   `request:",omitempty" validate:"omitempty,dive,cidrv4"`
    40  	EnableReplication     *bool                       `request:",omitempty"`
    41  	ReplicaUserPassword   *string                     `request:",omitempty" validate:"omitempty,required_with=EnableReplication"`
    42  	EnableWebUI           *bool                       `request:",omitempty"`
    43  	EnableBackup          *bool                       `request:",omitempty"`
    44  	BackupWeekdays        *[]types.EBackupSpanWeekday `request:",omitempty" validate:"omitempty,required_with=EnableBackup,max=7"`
    45  	BackupStartTimeHour   *int                        `request:",omitempty" validate:"omitempty,min=0,max=23"`
    46  	BackupStartTimeMinute *int                        `request:",omitempty" validate:"omitempty,oneof=0 15 30 45"`
    47  	Parameters            *map[string]interface{}     `request:",omitempty"`
    48  
    49  	SettingsHash string
    50  	NoWait       bool
    51  }
    52  
    53  func (req *UpdateRequest) Validate() error {
    54  	return validate.Struct(req)
    55  }
    56  
    57  func (req *UpdateRequest) ApplyRequest(ctx context.Context, caller sacloud.APICaller) (*ApplyRequest, error) {
    58  	dbOp := sacloud.NewDatabaseOp(caller)
    59  	current, err := dbOp.Read(ctx, req.Zone, req.ID)
    60  	if err != nil {
    61  		return nil, err
    62  	}
    63  
    64  	if current.Availability != types.Availabilities.Available {
    65  		return nil, fmt.Errorf("target has invalid Availability: Zone=%s ID=%s Availability=%v", req.Zone, req.ID.String(), current.Availability)
    66  	}
    67  
    68  	var bkHour, bkMinute int
    69  	var bkWeekdays []types.EBackupSpanWeekday
    70  	if current.BackupSetting != nil {
    71  		bkWeekdays = current.BackupSetting.DayOfWeek
    72  		if current.BackupSetting.Time != "" {
    73  			timeStrings := strings.Split(current.BackupSetting.Time, ":")
    74  			if len(timeStrings) == 2 {
    75  				hour, err := strconv.ParseInt(timeStrings[0], 10, 64)
    76  				if err != nil {
    77  					return nil, err
    78  				}
    79  				bkHour = int(hour)
    80  
    81  				minute, err := strconv.ParseInt(timeStrings[1], 10, 64)
    82  				if err != nil {
    83  					return nil, err
    84  				}
    85  				bkMinute = int(minute)
    86  			}
    87  		}
    88  	}
    89  
    90  	applyRequest := &ApplyRequest{
    91  		Zone:                  req.Zone,
    92  		ID:                    req.ID,
    93  		Name:                  current.Name,
    94  		Description:           current.Description,
    95  		Tags:                  current.Tags,
    96  		IconID:                current.IconID,
    97  		PlanID:                current.PlanID,
    98  		SwitchID:              current.SwitchID,
    99  		IPAddresses:           current.IPAddresses,
   100  		NetworkMaskLen:        current.NetworkMaskLen,
   101  		DefaultRoute:          current.DefaultRoute,
   102  		Port:                  current.CommonSetting.ServicePort,
   103  		SourceNetwork:         current.CommonSetting.SourceNetwork,
   104  		DatabaseType:          current.Conf.DatabaseName,
   105  		Username:              current.CommonSetting.DefaultUser,
   106  		Password:              current.CommonSetting.UserPassword,
   107  		EnableReplication:     current.ReplicationSetting != nil,
   108  		ReplicaUserPassword:   current.CommonSetting.ReplicaPassword,
   109  		EnableWebUI:           current.CommonSetting.WebUI.Bool(),
   110  		EnableBackup:          current.BackupSetting != nil,
   111  		BackupWeekdays:        bkWeekdays,
   112  		BackupStartTimeHour:   bkHour,
   113  		BackupStartTimeMinute: bkMinute,
   114  		NoWait:                false,
   115  	}
   116  
   117  	if err := service.RequestConvertTo(req, applyRequest); err != nil {
   118  		return nil, err
   119  	}
   120  
   121  	// パラメータは手動マージ
   122  	parameter, err := dbOp.GetParameter(ctx, req.Zone, req.ID)
   123  	if err != nil {
   124  		return nil, err
   125  	}
   126  	// パラメータ設定をLabelをキーにするように正規化
   127  	ps := make(map[string]interface{})
   128  	for k, v := range parameter.Settings {
   129  		for _, meta := range parameter.MetaInfo {
   130  			if meta.Name == k {
   131  				ps[meta.Label] = v
   132  			}
   133  		}
   134  	}
   135  	if req.Parameters != nil {
   136  		for k, v := range *req.Parameters {
   137  			key := k
   138  			for _, meta := range parameter.MetaInfo {
   139  				if meta.Name == key {
   140  					key = meta.Label
   141  					break
   142  				}
   143  			}
   144  			ps[key] = v
   145  		}
   146  	}
   147  	applyRequest.Parameters = ps
   148  
   149  	return applyRequest, nil
   150  }