github.com/sacloud/iaas-api-go@v1.12.0/internal/define/ops/operations.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 ops
    16  
    17  import (
    18  	"net/http"
    19  
    20  	"github.com/sacloud/iaas-api-go/internal/define/names"
    21  	"github.com/sacloud/iaas-api-go/internal/dsl"
    22  	"github.com/sacloud/iaas-api-go/internal/dsl/meta"
    23  	"github.com/sacloud/iaas-api-go/naked"
    24  )
    25  
    26  func find(resourceName string, nakedType meta.Type, findParam, result *dsl.Model, payloadName string) *dsl.Operation {
    27  	if payloadName == "" {
    28  		payloadName = names.ResourceFieldName(resourceName, dsl.PayloadForms.Plural)
    29  	}
    30  
    31  	return &dsl.Operation{
    32  		ResourceName:     resourceName,
    33  		Name:             "Find",
    34  		PathFormat:       dsl.DefaultPathFormat,
    35  		Method:           http.MethodGet,
    36  		UseWrappedResult: true,
    37  		RequestEnvelope:  dsl.RequestEnvelopeFromModel(findParam),
    38  		Arguments: dsl.Arguments{
    39  			dsl.PassthroughModelArgument("conditions", findParam),
    40  		},
    41  		ResponseEnvelope: dsl.ResponseEnvelopePlural(&dsl.EnvelopePayloadDesc{
    42  			Type: nakedType,
    43  			Name: payloadName,
    44  		}),
    45  		Results: dsl.Results{
    46  			{
    47  				SourceField: payloadName,
    48  				DestField:   names.ResourceFieldName(resourceName, dsl.PayloadForms.Plural),
    49  				IsPlural:    true,
    50  				Model:       result,
    51  			},
    52  		},
    53  	}
    54  }
    55  
    56  // Find Find操作を定義
    57  func Find(resourceName string, nakedType meta.Type, findParam, result *dsl.Model) *dsl.Operation {
    58  	return find(resourceName, nakedType, findParam, result, "")
    59  }
    60  
    61  // FindAppliance Find操作を定義
    62  func FindAppliance(resourceName string, nakedType meta.Type, findParam, result *dsl.Model) *dsl.Operation {
    63  	return find(resourceName, nakedType, findParam, result, "Appliances")
    64  }
    65  
    66  // FindCommonServiceItem Find操作を定義
    67  func FindCommonServiceItem(resourceName string, nakedType meta.Type, findParam, result *dsl.Model) *dsl.Operation {
    68  	return find(resourceName, nakedType, findParam, result, "CommonServiceItems")
    69  }
    70  
    71  // List List操作(パラメータのないFind)を定義
    72  func List(resourceName string, nakedType meta.Type, result *dsl.Model) *dsl.Operation {
    73  	return &dsl.Operation{
    74  		ResourceName:     resourceName,
    75  		Name:             "List",
    76  		PathFormat:       dsl.DefaultPathFormat,
    77  		Method:           http.MethodGet,
    78  		UseWrappedResult: true,
    79  		ResponseEnvelope: dsl.ResponseEnvelopePlural(&dsl.EnvelopePayloadDesc{
    80  			Type: nakedType,
    81  			Name: names.ResourceFieldName(resourceName, dsl.PayloadForms.Plural),
    82  		}),
    83  		Results: dsl.Results{
    84  			{
    85  				SourceField: names.ResourceFieldName(resourceName, dsl.PayloadForms.Plural),
    86  				DestField:   names.ResourceFieldName(resourceName, dsl.PayloadForms.Plural),
    87  				IsPlural:    true,
    88  				Model:       result,
    89  			},
    90  		},
    91  	}
    92  }
    93  
    94  func create(resourceName string, nakedType meta.Type, createParam, result *dsl.Model, payloadName string) *dsl.Operation {
    95  	if payloadName == "" {
    96  		payloadName = names.ResourceFieldName(resourceName, dsl.PayloadForms.Singular)
    97  	}
    98  
    99  	return &dsl.Operation{
   100  		ResourceName: resourceName,
   101  		Name:         "Create",
   102  		PathFormat:   dsl.DefaultPathFormat,
   103  		Method:       http.MethodPost,
   104  		RequestEnvelope: dsl.RequestEnvelope(&dsl.EnvelopePayloadDesc{
   105  			Type: nakedType,
   106  			Name: payloadName,
   107  		}),
   108  		Arguments: dsl.Arguments{
   109  			dsl.MappableArgument("param", createParam, payloadName),
   110  		},
   111  		ResponseEnvelope: dsl.ResponseEnvelope(&dsl.EnvelopePayloadDesc{
   112  			Type: result.NakedType,
   113  			Name: payloadName,
   114  		}),
   115  		Results: dsl.Results{
   116  			{
   117  				SourceField: payloadName,
   118  				DestField:   result.Name,
   119  				IsPlural:    false,
   120  				Model:       result,
   121  			},
   122  		},
   123  	}
   124  }
   125  
   126  // Create Create操作を定義
   127  func Create(resourceName string, nakedType meta.Type, createParam, result *dsl.Model) *dsl.Operation {
   128  	return create(resourceName, nakedType, createParam, result, "")
   129  }
   130  
   131  // CreateAppliance Create操作を定義
   132  func CreateAppliance(resourceName string, nakedType meta.Type, createParam, result *dsl.Model) *dsl.Operation {
   133  	return create(resourceName, nakedType, createParam, result, "Appliance")
   134  }
   135  
   136  // CreateCommonServiceItem Create操作を定義
   137  func CreateCommonServiceItem(resourceName string, nakedType meta.Type, createParam, result *dsl.Model) *dsl.Operation {
   138  	return create(resourceName, nakedType, createParam, result, "CommonServiceItem")
   139  }
   140  
   141  func read(resourceName string, nakedType meta.Type, result *dsl.Model, payloadName string) *dsl.Operation {
   142  	if payloadName == "" {
   143  		payloadName = names.ResourceFieldName(resourceName, dsl.PayloadForms.Singular)
   144  	}
   145  
   146  	return &dsl.Operation{
   147  		ResourceName: resourceName,
   148  		Name:         "Read",
   149  		PathFormat:   dsl.DefaultPathFormatWithID,
   150  		Method:       http.MethodGet,
   151  		Arguments: dsl.Arguments{
   152  			dsl.ArgumentID,
   153  		},
   154  		ResponseEnvelope: dsl.ResponseEnvelope(&dsl.EnvelopePayloadDesc{
   155  			Type: nakedType,
   156  			Name: payloadName,
   157  		}),
   158  		Results: dsl.Results{
   159  			{
   160  				SourceField: payloadName,
   161  				DestField:   result.Name,
   162  				IsPlural:    false,
   163  				Model:       result,
   164  			},
   165  		},
   166  	}
   167  }
   168  
   169  // Read Read操作を定義
   170  func Read(resourceName string, nakedType meta.Type, result *dsl.Model) *dsl.Operation {
   171  	return read(resourceName, nakedType, result, "")
   172  }
   173  
   174  // ReadAppliance Read操作を定義
   175  func ReadAppliance(resourceName string, nakedType meta.Type, result *dsl.Model) *dsl.Operation {
   176  	return read(resourceName, nakedType, result, "Appliance")
   177  }
   178  
   179  // ReadCommonServiceItem Read操作を定義
   180  func ReadCommonServiceItem(resourceName string, nakedType meta.Type, result *dsl.Model) *dsl.Operation {
   181  	return read(resourceName, nakedType, result, "CommonServiceItem")
   182  }
   183  
   184  func update(resourceName string, nakedType meta.Type, updateParam, result *dsl.Model, payloadName string) *dsl.Operation {
   185  	return updateInternal(resourceName, nakedType, updateParam, result, payloadName, "Update")
   186  }
   187  
   188  func updateSettings(resourceName string, nakedType meta.Type, updateParam, result *dsl.Model, payloadName string) *dsl.Operation {
   189  	return updateInternal(resourceName, nakedType, updateParam, result, payloadName, "UpdateSettings")
   190  }
   191  
   192  func updateInternal(resourceName string, nakedType meta.Type, updateParam, result *dsl.Model, payloadName, opName string) *dsl.Operation {
   193  	if payloadName == "" {
   194  		payloadName = names.ResourceFieldName(resourceName, dsl.PayloadForms.Singular)
   195  	}
   196  
   197  	return &dsl.Operation{
   198  		ResourceName: resourceName,
   199  		Name:         opName,
   200  		PathFormat:   dsl.DefaultPathFormatWithID,
   201  		Method:       http.MethodPut,
   202  		RequestEnvelope: dsl.RequestEnvelope(&dsl.EnvelopePayloadDesc{
   203  			Type: nakedType,
   204  			Name: payloadName,
   205  		}),
   206  		Arguments: dsl.Arguments{
   207  			dsl.ArgumentID,
   208  			dsl.MappableArgument("param", updateParam, payloadName),
   209  		},
   210  		ResponseEnvelope: dsl.ResponseEnvelope(&dsl.EnvelopePayloadDesc{
   211  			Type: result.NakedType,
   212  			Name: payloadName,
   213  		}),
   214  		Results: dsl.Results{
   215  			{
   216  				SourceField: payloadName,
   217  				DestField:   result.Name,
   218  				IsPlural:    false,
   219  				Model:       result,
   220  			},
   221  		},
   222  	}
   223  }
   224  
   225  // Update Update操作を定義
   226  func Update(resourceName string, nakedType meta.Type, updateParam, result *dsl.Model) *dsl.Operation {
   227  	return update(resourceName, nakedType, updateParam, result, "")
   228  }
   229  
   230  // UpdateAppliance Update操作を定義
   231  func UpdateAppliance(resourceName string, nakedType meta.Type, updateParam, result *dsl.Model) *dsl.Operation {
   232  	return update(resourceName, nakedType, updateParam, result, "Appliance")
   233  }
   234  
   235  // UpdateCommonServiceItem Update操作を定義
   236  func UpdateCommonServiceItem(resourceName string, nakedType meta.Type, updateParam, result *dsl.Model) *dsl.Operation {
   237  	return update(resourceName, nakedType, updateParam, result, "CommonServiceItem")
   238  }
   239  
   240  // UpdateApplianceSettings UpdateSettings操作を定義
   241  func UpdateApplianceSettings(resourceName string, nakedType meta.Type, updateParam, result *dsl.Model) *dsl.Operation {
   242  	return updateSettings(resourceName, nakedType, updateParam, result, "Appliance")
   243  }
   244  
   245  // UpdateCommonServiceItemSettings UpdateSettings操作を定義
   246  func UpdateCommonServiceItemSettings(resourceName string, nakedType meta.Type, updateParam, result *dsl.Model) *dsl.Operation {
   247  	return updateSettings(resourceName, nakedType, updateParam, result, "CommonServiceItem")
   248  }
   249  
   250  // Delete Delete操作を定義
   251  func Delete(resourceName string) *dsl.Operation {
   252  	return &dsl.Operation{
   253  		ResourceName: resourceName,
   254  		Name:         "Delete",
   255  		PathFormat:   dsl.DefaultPathFormatWithID,
   256  		Method:       http.MethodDelete,
   257  		Arguments: dsl.Arguments{
   258  			dsl.ArgumentID,
   259  		},
   260  	}
   261  }
   262  
   263  // Config Config操作を定義
   264  func Config(resourceName string) *dsl.Operation {
   265  	return &dsl.Operation{
   266  		ResourceName: resourceName,
   267  		Name:         "Config",
   268  		PathFormat:   dsl.IDAndSuffixPathFormat("config"),
   269  		Method:       http.MethodPut,
   270  		Arguments: dsl.Arguments{
   271  			dsl.ArgumentID,
   272  		},
   273  	}
   274  }
   275  
   276  // Boot リソースに対するBoot操作を定義
   277  func Boot(resourceName string) *dsl.Operation {
   278  	return &dsl.Operation{
   279  		ResourceName: resourceName,
   280  		Name:         "Boot",
   281  		PathFormat:   dsl.IDAndSuffixPathFormat("power"),
   282  		Method:       http.MethodPut,
   283  		LockLevel:    dsl.LockLevelGlobal,
   284  		Arguments: dsl.Arguments{
   285  			dsl.ArgumentID,
   286  		},
   287  	}
   288  }
   289  
   290  // Shutdown リソースに対するシャットダウン操作を定義
   291  func Shutdown(resourceName string) *dsl.Operation {
   292  	param := &dsl.Model{
   293  		Name: "ShutdownOption",
   294  		Fields: []*dsl.FieldDesc{
   295  			{
   296  				Name: "Force",
   297  				Type: meta.TypeFlag,
   298  			},
   299  		},
   300  	}
   301  	return &dsl.Operation{
   302  		ResourceName:    resourceName,
   303  		Name:            "Shutdown",
   304  		PathFormat:      dsl.IDAndSuffixPathFormat("power"),
   305  		Method:          http.MethodDelete,
   306  		LockLevel:       dsl.LockLevelGlobal,
   307  		RequestEnvelope: dsl.RequestEnvelopeFromModel(param),
   308  		Arguments: dsl.Arguments{
   309  			dsl.ArgumentID,
   310  			dsl.PassthroughModelArgument("shutdownOption", param),
   311  		},
   312  	}
   313  }
   314  
   315  // Reset リソースに対するリセット操作を定義
   316  func Reset(resourceName string) *dsl.Operation {
   317  	return &dsl.Operation{
   318  		ResourceName: resourceName,
   319  		Name:         "Reset",
   320  		PathFormat:   dsl.IDAndSuffixPathFormat("reset"),
   321  		LockLevel:    dsl.LockLevelGlobal,
   322  		Method:       http.MethodPut,
   323  		Arguments: dsl.Arguments{
   324  			dsl.ArgumentID,
   325  		},
   326  	}
   327  }
   328  
   329  // Status ステータス取得操作を定義
   330  func Status(resourceName string, nakedType meta.Type, result *dsl.Model) *dsl.Operation {
   331  	payloadName := names.ResourceFieldName(resourceName, dsl.PayloadForms.Singular)
   332  	return &dsl.Operation{
   333  		ResourceName:     resourceName,
   334  		Name:             "Status",
   335  		UseWrappedResult: true,
   336  		Arguments: dsl.Arguments{
   337  			dsl.ArgumentID,
   338  		},
   339  		PathFormat: dsl.IDAndSuffixPathFormat("status"),
   340  		Method:     http.MethodGet,
   341  		ResponseEnvelope: dsl.ResponseEnvelopePlural(&dsl.EnvelopePayloadDesc{
   342  			Type: nakedType,
   343  			Name: payloadName,
   344  		}),
   345  		Results: dsl.Results{
   346  			{
   347  				SourceField: payloadName,
   348  				DestField:   "Status",
   349  				IsPlural:    true,
   350  				Model:       result,
   351  			},
   352  		},
   353  	}
   354  }
   355  
   356  // HealthStatus ステータス取得操作を定義(シンプル監視)
   357  func HealthStatus(resourceName string, nakedType meta.Type, result *dsl.Model) *dsl.Operation {
   358  	payloadName := names.ResourceFieldName(resourceName, dsl.PayloadForms.Singular)
   359  	return &dsl.Operation{
   360  		ResourceName: resourceName,
   361  		Name:         "HealthStatus",
   362  		Arguments: dsl.Arguments{
   363  			dsl.ArgumentID,
   364  		},
   365  		PathFormat: dsl.IDAndSuffixPathFormat("health"),
   366  		Method:     http.MethodGet,
   367  		ResponseEnvelope: dsl.ResponseEnvelope(&dsl.EnvelopePayloadDesc{
   368  			Type: nakedType,
   369  			Name: payloadName,
   370  		}),
   371  		Results: dsl.Results{
   372  			{
   373  				SourceField: payloadName,
   374  				DestField:   result.Name,
   375  				IsPlural:    false,
   376  				Model:       result,
   377  			},
   378  		},
   379  	}
   380  }
   381  
   382  // OpenFTP FTPオープン操作を定義
   383  func OpenFTP(resourceName string, openParam, result *dsl.Model) *dsl.Operation {
   384  	return &dsl.Operation{
   385  		ResourceName:    resourceName,
   386  		Name:            "OpenFTP",
   387  		PathFormat:      dsl.IDAndSuffixPathFormat("ftp"),
   388  		Method:          http.MethodPut,
   389  		RequestEnvelope: dsl.RequestEnvelopeFromModel(openParam),
   390  		Arguments: dsl.Arguments{
   391  			dsl.ArgumentID,
   392  			dsl.PassthroughModelArgument("openOption", openParam),
   393  		},
   394  		ResponseEnvelope: dsl.ResponseEnvelope(&dsl.EnvelopePayloadDesc{
   395  			Name: result.Name,
   396  			Type: meta.Static(naked.OpeningFTPServer{}),
   397  		}),
   398  		Results: dsl.Results{
   399  			{
   400  				SourceField: result.Name,
   401  				DestField:   result.Name,
   402  				IsPlural:    false,
   403  				Model:       result,
   404  			},
   405  		},
   406  	}
   407  }
   408  
   409  // CloseFTP FTPクローズ操作を定義
   410  func CloseFTP(resourceName string) *dsl.Operation {
   411  	return &dsl.Operation{
   412  		ResourceName: resourceName,
   413  		Name:         "CloseFTP",
   414  		Arguments: dsl.Arguments{
   415  			dsl.ArgumentID,
   416  		},
   417  		PathFormat: dsl.IDAndSuffixPathFormat("ftp"),
   418  		Method:     http.MethodDelete,
   419  	}
   420  }
   421  
   422  // WithIDAction ID+αのみを引数にとるシンプルなオペレーションを定義
   423  func WithIDAction(resourceName, opName, method, pathSuffix string, arguments ...*dsl.Argument) *dsl.Operation {
   424  	args := dsl.Arguments{dsl.ArgumentID}
   425  	args = append(args, arguments...)
   426  	return &dsl.Operation{
   427  		ResourceName: resourceName,
   428  		Name:         opName,
   429  		PathFormat:   dsl.IDAndSuffixPathFormat(pathSuffix),
   430  		Method:       method,
   431  		Arguments:    args,
   432  	}
   433  }
   434  
   435  // Monitor アクティビティモニタ取得操作を定義
   436  func Monitor(resourceName string, monitorParam, result *dsl.Model) *dsl.Operation {
   437  	return MonitorChild(resourceName, "", "", monitorParam, result)
   438  }
   439  
   440  // MonitorChild アクティビティモニタ取得操作を定義
   441  func MonitorChild(resourceName, funcNameSuffix, childResourceName string, monitorParam, result *dsl.Model) *dsl.Operation {
   442  	pathFormat := "monitor"
   443  	if childResourceName != "" {
   444  		pathFormat = childResourceName + "/monitor"
   445  	}
   446  	return &dsl.Operation{
   447  		ResourceName:    resourceName,
   448  		Name:            "Monitor" + funcNameSuffix,
   449  		PathFormat:      dsl.IDAndSuffixPathFormat(pathFormat),
   450  		Method:          http.MethodGet,
   451  		RequestEnvelope: dsl.RequestEnvelopeFromModel(monitorParam),
   452  		Arguments: dsl.Arguments{
   453  			dsl.ArgumentID,
   454  			dsl.PassthroughModelArgument("condition", monitorParam),
   455  		},
   456  		ResponseEnvelope: dsl.ResponseEnvelope(&dsl.EnvelopePayloadDesc{
   457  			Type: meta.Static(naked.MonitorValues{}),
   458  			Name: "Data",
   459  		}),
   460  		Results: dsl.Results{
   461  			{
   462  				SourceField: "Data",
   463  				DestField:   result.Name,
   464  				IsPlural:    false,
   465  				Model:       result,
   466  			},
   467  		},
   468  	}
   469  }
   470  
   471  // MonitorChildBy アプライアンスなどでの内部リソースインデックスを持つアクティビティモニタ取得操作を定義
   472  func MonitorChildBy(resourceName, funcNameSuffix, childResourceName string, monitorParam, result *dsl.Model) *dsl.Operation {
   473  	pathSuffix := childResourceName + "{{if ne .index 0}}/{{.index}}{{end}}/monitor"
   474  	return &dsl.Operation{
   475  		ResourceName:    resourceName,
   476  		Name:            "Monitor" + funcNameSuffix,
   477  		PathFormat:      dsl.IDAndSuffixPathFormat(pathSuffix),
   478  		Method:          http.MethodGet,
   479  		RequestEnvelope: dsl.RequestEnvelopeFromModel(monitorParam),
   480  		Arguments: dsl.Arguments{
   481  			dsl.ArgumentID,
   482  			{
   483  				Name: "index",
   484  				Type: meta.TypeInt,
   485  			},
   486  			dsl.PassthroughModelArgument("condition", monitorParam),
   487  		},
   488  		ResponseEnvelope: dsl.ResponseEnvelope(&dsl.EnvelopePayloadDesc{
   489  			Type: meta.Static(naked.MonitorValues{}),
   490  			Name: "Data",
   491  		}),
   492  		Results: dsl.Results{
   493  			{
   494  				SourceField: "Data",
   495  				DestField:   result.Name,
   496  				IsPlural:    false,
   497  				Model:       result,
   498  			},
   499  		},
   500  	}
   501  }