github.com/sacloud/iaas-api-go@v1.12.0/helper/query/database_plan.go (about)

     1  // Copyright 2016-2022 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 query
    16  
    17  import (
    18  	"context"
    19  	"encoding/json"
    20  	"errors"
    21  	"fmt"
    22  
    23  	"github.com/sacloud/iaas-api-go"
    24  	"github.com/sacloud/iaas-api-go/search"
    25  	"github.com/sacloud/iaas-api-go/search/keys"
    26  	"github.com/sacloud/iaas-api-go/types"
    27  	"github.com/sacloud/packages-go/size"
    28  )
    29  
    30  type databaseSystemInfoEnvelope struct {
    31  	Products []interface{}   // 利用しない
    32  	Backup   interface{}     // 利用しない
    33  	Plans    []*DatabasePlan `json:"AppliancePlans"`
    34  }
    35  
    36  type DatabasePlan struct {
    37  	Class     string
    38  	Model     string
    39  	CPU       int
    40  	MemoryMB  int
    41  	DiskSizes []*DatabaseDiskPlan
    42  }
    43  
    44  type DatabaseDiskPlan struct {
    45  	SizeMB       int // 実際のディスクのサイズ? DisplaySizeとは必ずしも一致しない(例: SizeMB:102400, DisplaySize: 90)
    46  	DisplaySize  int // GB単位、コンパネに表示されるのはこの値
    47  	PlanID       types.ID
    48  	ServiceClass string
    49  }
    50  
    51  // ListDatabasePlan データベースアプライアンスのプラン情報一覧を取得
    52  //
    53  // modelには以下を指定
    54  //   - Standard	: 標準プラン(非冗長化)
    55  //   - Proxy	: 冗長化プラン
    56  func ListDatabasePlan(ctx context.Context, finder NoteFinder, model string) ([]*DatabasePlan, error) {
    57  	return listDatabasePlan(ctx, finder, model)
    58  }
    59  
    60  // GetProxyDatabasePlan 冗長化プランの指定のモデル/CPU/メモリ(GB)/ディスクサイズ(GB)からプランID/サービスクラスを返す
    61  //
    62  // cpu/memoryGB/diskSizeGBに対応するプランが存在しない場合はゼロ値を返す(errorは返さない)
    63  //
    64  // diskSizeGBはDatabaseDiskPlanのDisplaySizeと比較される
    65  func GetProxyDatabasePlan(ctx context.Context, finder NoteFinder, cpu int, memoryGB int, diskSizeGB int) (types.ID, string, error) {
    66  	plans, err := ListDatabasePlan(ctx, finder, "Proxy")
    67  	if err != nil {
    68  		return types.ID(0), "", err
    69  	}
    70  	for _, plan := range plans {
    71  		if plan.CPU == cpu && plan.MemoryMB == memoryGB*size.GiB {
    72  			for _, diskPlan := range plan.DiskSizes {
    73  				if diskPlan.DisplaySize == diskSizeGB {
    74  					return diskPlan.PlanID, diskPlan.ServiceClass, nil
    75  				}
    76  			}
    77  		}
    78  	}
    79  	return types.ID(0), "", nil // plan not found
    80  }
    81  
    82  func listDatabasePlan(ctx context.Context, finder NoteFinder, model string) ([]*DatabasePlan, error) {
    83  	if model != "Standard" && model != "Proxy" {
    84  		return nil, fmt.Errorf("unsupported database plan model: %s", model)
    85  	}
    86  
    87  	// find note
    88  	searched, err := finder.Find(ctx, &iaas.FindCondition{
    89  		Filter: search.Filter{
    90  			search.Key(keys.Name): "sys-database",
    91  			search.Key("Class"):   "json",
    92  			search.Key("Scope"):   "shared",
    93  		},
    94  	})
    95  	if err != nil {
    96  		return nil, err
    97  	}
    98  	if searched.Count == 0 || len(searched.Notes) == 0 {
    99  		return nil, errors.New("note[sys-database] not found")
   100  	}
   101  	note := searched.Notes[0]
   102  
   103  	// parse note's content
   104  	var envelope databaseSystemInfoEnvelope
   105  	if err := json.Unmarshal([]byte(note.Content), &envelope); err != nil {
   106  		return nil, err
   107  	}
   108  
   109  	var plans []*DatabasePlan
   110  	for i := range envelope.Plans {
   111  		if envelope.Plans[i].Model == model {
   112  			plans = append(plans, envelope.Plans[i])
   113  		}
   114  	}
   115  	return plans, nil
   116  }