github.com/sacloud/iaas-api-go@v1.12.0/fake/ops_database.go (about)

     1  // Copyright 2022-2023 The sacloud/iaas-api-go 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 fake
    16  
    17  import (
    18  	"context"
    19  	"time"
    20  
    21  	"github.com/sacloud/iaas-api-go"
    22  	"github.com/sacloud/iaas-api-go/types"
    23  )
    24  
    25  // Find is fake implementation
    26  func (o *DatabaseOp) Find(ctx context.Context, zone string, conditions *iaas.FindCondition) (*iaas.DatabaseFindResult, error) {
    27  	results, _ := find(o.key, zone, conditions)
    28  	var values []*iaas.Database
    29  	for _, res := range results {
    30  		dest := &iaas.Database{}
    31  		copySameNameField(res, dest)
    32  		values = append(values, dest)
    33  	}
    34  	return &iaas.DatabaseFindResult{
    35  		Total:     len(results),
    36  		Count:     len(results),
    37  		From:      0,
    38  		Databases: values,
    39  	}, nil
    40  }
    41  
    42  // Create is fake implementation
    43  func (o *DatabaseOp) Create(ctx context.Context, zone string, param *iaas.DatabaseCreateRequest) (*iaas.Database, error) {
    44  	result := &iaas.Database{}
    45  	copySameNameField(param, result)
    46  	fill(result, fillID, fillCreatedAt)
    47  
    48  	result.Class = "database"
    49  	result.Availability = types.Availabilities.Available
    50  	if result.Conf != nil {
    51  		if result.Conf.DatabaseVersion == "" {
    52  			result.Conf.DatabaseVersion = "1"
    53  		}
    54  		if result.Conf.DatabaseRevision == "" {
    55  			result.Conf.DatabaseRevision = "1"
    56  		}
    57  	}
    58  
    59  	putDatabase(zone, result)
    60  
    61  	id := result.ID
    62  	startPowerOn(o.key, zone, func() (interface{}, error) {
    63  		return o.Read(context.Background(), zone, id)
    64  	})
    65  	return result, nil
    66  }
    67  
    68  // Read is fake implementation
    69  func (o *DatabaseOp) Read(ctx context.Context, zone string, id types.ID) (*iaas.Database, error) {
    70  	value := getDatabaseByID(zone, id)
    71  	if value == nil {
    72  		return nil, newErrorNotFound(o.key, id)
    73  	}
    74  	dest := &iaas.Database{}
    75  	copySameNameField(value, dest)
    76  	return dest, nil
    77  }
    78  
    79  // Update is fake implementation
    80  func (o *DatabaseOp) Update(ctx context.Context, zone string, id types.ID, param *iaas.DatabaseUpdateRequest) (*iaas.Database, error) {
    81  	value, err := o.Read(ctx, zone, id)
    82  	if err != nil {
    83  		return nil, err
    84  	}
    85  	copySameNameField(param, value)
    86  	fill(value, fillModifiedAt)
    87  
    88  	putDatabase(zone, value)
    89  	return value, nil
    90  }
    91  
    92  // UpdateSettings is fake implementation
    93  func (o *DatabaseOp) UpdateSettings(ctx context.Context, zone string, id types.ID, param *iaas.DatabaseUpdateSettingsRequest) (*iaas.Database, error) {
    94  	value, err := o.Read(ctx, zone, id)
    95  	if err != nil {
    96  		return nil, err
    97  	}
    98  	copySameNameField(param, value)
    99  	fill(value, fillModifiedAt)
   100  
   101  	putDatabase(zone, value)
   102  	return value, nil
   103  }
   104  
   105  // Delete is fake implementation
   106  func (o *DatabaseOp) Delete(ctx context.Context, zone string, id types.ID) error {
   107  	_, err := o.Read(ctx, zone, id)
   108  	if err != nil {
   109  		return err
   110  	}
   111  
   112  	ds().Delete(o.key, zone, id)
   113  	return nil
   114  }
   115  
   116  // Config is fake implementation
   117  func (o *DatabaseOp) Config(ctx context.Context, zone string, id types.ID) error {
   118  	_, err := o.Read(ctx, zone, id)
   119  	if err != nil {
   120  		return err
   121  	}
   122  	return nil
   123  }
   124  
   125  // Boot is fake implementation
   126  func (o *DatabaseOp) Boot(ctx context.Context, zone string, id types.ID) error {
   127  	value, err := o.Read(ctx, zone, id)
   128  	if err != nil {
   129  		return err
   130  	}
   131  	if value.InstanceStatus.IsUp() {
   132  		return newErrorConflict(o.key, id, "Boot is failed")
   133  	}
   134  
   135  	startPowerOn(o.key, zone, func() (interface{}, error) {
   136  		return o.Read(context.Background(), zone, id)
   137  	})
   138  
   139  	return err
   140  }
   141  
   142  // Shutdown is fake implementation
   143  func (o *DatabaseOp) Shutdown(ctx context.Context, zone string, id types.ID, shutdownOption *iaas.ShutdownOption) error {
   144  	value, err := o.Read(ctx, zone, id)
   145  	if err != nil {
   146  		return err
   147  	}
   148  	if !value.InstanceStatus.IsUp() {
   149  		return newErrorConflict(o.key, id, "Shutdown is failed")
   150  	}
   151  
   152  	startPowerOff(o.key, zone, func() (interface{}, error) {
   153  		return o.Read(context.Background(), zone, id)
   154  	})
   155  
   156  	return err
   157  }
   158  
   159  // Reset is fake implementation
   160  func (o *DatabaseOp) Reset(ctx context.Context, zone string, id types.ID) error {
   161  	value, err := o.Read(ctx, zone, id)
   162  	if err != nil {
   163  		return err
   164  	}
   165  	if !value.InstanceStatus.IsUp() {
   166  		return newErrorConflict(o.key, id, "Reset is failed")
   167  	}
   168  
   169  	startPowerOn(o.key, zone, func() (interface{}, error) {
   170  		return o.Read(context.Background(), zone, id)
   171  	})
   172  
   173  	return nil
   174  }
   175  
   176  // MonitorCPU is fake implementation
   177  func (o *DatabaseOp) MonitorCPU(ctx context.Context, zone string, id types.ID, condition *iaas.MonitorCondition) (*iaas.CPUTimeActivity, error) {
   178  	_, err := o.Read(ctx, zone, id)
   179  	if err != nil {
   180  		return nil, err
   181  	}
   182  
   183  	now := time.Now().Truncate(time.Second)
   184  	m := now.Minute() % 5
   185  	if m != 0 {
   186  		now.Add(time.Duration(m) * time.Minute)
   187  	}
   188  
   189  	res := &iaas.CPUTimeActivity{}
   190  	for i := 0; i < 5; i++ {
   191  		res.Values = append(res.Values, &iaas.MonitorCPUTimeValue{
   192  			Time:    now.Add(time.Duration(i*-5) * time.Minute),
   193  			CPUTime: float64(random(1000)),
   194  		})
   195  	}
   196  
   197  	return res, nil
   198  }
   199  
   200  // MonitorDisk is fake implementation
   201  func (o *DatabaseOp) MonitorDisk(ctx context.Context, zone string, id types.ID, condition *iaas.MonitorCondition) (*iaas.DiskActivity, error) {
   202  	_, err := o.Read(ctx, zone, id)
   203  	if err != nil {
   204  		return nil, err
   205  	}
   206  
   207  	now := time.Now().Truncate(time.Second)
   208  	m := now.Minute() % 5
   209  	if m != 0 {
   210  		now.Add(time.Duration(m) * time.Minute)
   211  	}
   212  
   213  	res := &iaas.DiskActivity{}
   214  	for i := 0; i < 5; i++ {
   215  		res.Values = append(res.Values, &iaas.MonitorDiskValue{
   216  			Time:  now.Add(time.Duration(i*-5) * time.Minute),
   217  			Read:  float64(random(1000)),
   218  			Write: float64(random(1000)),
   219  		})
   220  	}
   221  
   222  	return res, nil
   223  }
   224  
   225  // MonitorInterface is fake implementation
   226  func (o *DatabaseOp) MonitorInterface(ctx context.Context, zone string, id types.ID, condition *iaas.MonitorCondition) (*iaas.InterfaceActivity, error) {
   227  	_, err := o.Read(ctx, zone, id)
   228  	if err != nil {
   229  		return nil, err
   230  	}
   231  
   232  	now := time.Now().Truncate(time.Second)
   233  	m := now.Minute() % 5
   234  	if m != 0 {
   235  		now.Add(time.Duration(m) * time.Minute)
   236  	}
   237  
   238  	res := &iaas.InterfaceActivity{}
   239  	for i := 0; i < 5; i++ {
   240  		res.Values = append(res.Values, &iaas.MonitorInterfaceValue{
   241  			Time:    now.Add(time.Duration(i*-5) * time.Minute),
   242  			Receive: float64(random(1000)),
   243  			Send:    float64(random(1000)),
   244  		})
   245  	}
   246  
   247  	return res, nil
   248  }
   249  
   250  // MonitorDatabase is fake implementation
   251  func (o *DatabaseOp) MonitorDatabase(ctx context.Context, zone string, id types.ID, condition *iaas.MonitorCondition) (*iaas.DatabaseActivity, error) {
   252  	_, err := o.Read(ctx, zone, id)
   253  	if err != nil {
   254  		return nil, err
   255  	}
   256  
   257  	now := time.Now().Truncate(time.Second)
   258  	m := now.Minute() % 5
   259  	if m != 0 {
   260  		now.Add(time.Duration(m) * time.Minute)
   261  	}
   262  
   263  	res := &iaas.DatabaseActivity{}
   264  	for i := 0; i < 5; i++ {
   265  		res.Values = append(res.Values, &iaas.MonitorDatabaseValue{
   266  			Time:              now.Add(time.Duration(i*-5) * time.Minute),
   267  			TotalMemorySize:   float64(random(1000)),
   268  			UsedMemorySize:    float64(random(1000)),
   269  			TotalDisk1Size:    float64(random(1000)),
   270  			UsedDisk1Size:     float64(random(1000)),
   271  			TotalDisk2Size:    float64(random(1000)),
   272  			UsedDisk2Size:     float64(random(1000)),
   273  			BinlogUsedSizeKiB: float64(random(1000)),
   274  			DelayTimeSec:      float64(random(1000)),
   275  		})
   276  	}
   277  
   278  	return res, nil
   279  }
   280  
   281  // Status is fake implementation
   282  func (o *DatabaseOp) Status(ctx context.Context, zone string, id types.ID) (*iaas.DatabaseStatus, error) {
   283  	value, err := o.Read(ctx, zone, id)
   284  	if err != nil {
   285  		return nil, err
   286  	}
   287  
   288  	return &iaas.DatabaseStatus{
   289  		Status:        value.InstanceStatus,
   290  		IsFatal:       false,
   291  		MariaDBStatus: "running",
   292  		Version: &iaas.DatabaseVersionInfo{
   293  			LastModified: value.ModifiedAt.String(),
   294  			CommitHash:   "foobar",
   295  			Status:       "up",
   296  			Tag:          "stable",
   297  		},
   298  	}, nil
   299  }
   300  
   301  func (o *DatabaseOp) GetParameter(ctx context.Context, zone string, id types.ID) (*iaas.DatabaseParameter, error) {
   302  	v, err := o.Read(ctx, zone, id)
   303  	if err != nil {
   304  		return nil, err
   305  	}
   306  
   307  	var settings map[string]interface{}
   308  	raw := ds().Get(ResourceDatabase+"Parameter", zone, id)
   309  	if raw != nil {
   310  		settings = raw.(map[string]interface{})
   311  	}
   312  
   313  	meta := fakeDatabaseParameterMetaForMariaDB
   314  	if v.Conf.DatabaseName == "postgres" {
   315  		meta = fakeDatabaseParameterMetaForPostgreSQL
   316  	}
   317  	return &iaas.DatabaseParameter{
   318  		Settings: settings,
   319  		MetaInfo: meta,
   320  	}, nil
   321  }
   322  
   323  var (
   324  	fakeDatabaseParameterMetaForMariaDB = []*iaas.DatabaseParameterMeta{
   325  		{
   326  			Type:    "number",
   327  			Name:    "MariaDB/server.cnf/mysqld/max_connections",
   328  			Label:   "max_connections",
   329  			Text:    "同時クライアント接続の最大数を設定します。",
   330  			Example: "100",
   331  			Min:     10,
   332  			Max:     1000,
   333  			MaxLen:  0,
   334  			Reboot:  "static",
   335  		},
   336  		{
   337  			Type:    "string",
   338  			Name:    "MariaDB/server.cnf/mysqld/event_scheduler",
   339  			Label:   "event_scheduler",
   340  			Text:    "イベントスケジュールの有効無効を設定します。",
   341  			Example: "ON",
   342  			Min:     0,
   343  			Max:     0,
   344  			MaxLen:  0,
   345  			Reboot:  "dynamic",
   346  		},
   347  	}
   348  	fakeDatabaseParameterMetaForPostgreSQL = []*iaas.DatabaseParameterMeta{
   349  		{
   350  			Type:    "number",
   351  			Name:    "postgres/postgresql.conf/max_connections",
   352  			Label:   "max_connections",
   353  			Text:    "同時クライアント接続の最大数を設定します。",
   354  			Example: "100",
   355  			Min:     10,
   356  			Max:     1000,
   357  			MaxLen:  0,
   358  			Reboot:  "static",
   359  		},
   360  		{
   361  			Type:    "number",
   362  			Name:    "postgres/postgresql.conf/work_mem",
   363  			Label:   "work_mem",
   364  			Text:    "クエリワークスペースに使用するメモリの最大量を設定します。",
   365  			Example: "4096",
   366  			Min:     64,
   367  			Max:     2147483647,
   368  			MaxLen:  10,
   369  			Reboot:  "dynamic",
   370  		},
   371  	}
   372  )
   373  
   374  func (o *DatabaseOp) SetParameter(ctx context.Context, zone string, id types.ID, param map[string]interface{}) error {
   375  	_, err := o.Read(ctx, zone, id)
   376  	if err != nil {
   377  		return err
   378  	}
   379  
   380  	var settings map[string]interface{}
   381  	raw := ds().Get(ResourceDatabase+"Parameter", zone, id)
   382  	if raw != nil {
   383  		settings = raw.(map[string]interface{})
   384  	} else {
   385  		settings = make(map[string]interface{})
   386  	}
   387  	for k, v := range param {
   388  		if v == nil {
   389  			delete(settings, k)
   390  		} else {
   391  			switch v := v.(type) {
   392  			case int:
   393  				settings[k] = float64(v)
   394  			default:
   395  				settings[k] = v
   396  			}
   397  		}
   398  	}
   399  
   400  	ds().Put(ResourceDatabase+"Parameter", zone, id, settings)
   401  	return nil
   402  }