github.com/sacloud/iaas-api-go@v1.12.0/test/proxylb_op_test.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 test
    16  
    17  import (
    18  	"context"
    19  	"fmt"
    20  	"os"
    21  	"strings"
    22  	"testing"
    23  	"time"
    24  
    25  	"github.com/sacloud/iaas-api-go"
    26  	"github.com/sacloud/iaas-api-go/testutil"
    27  	"github.com/sacloud/iaas-api-go/types"
    28  	"github.com/stretchr/testify/assert"
    29  )
    30  
    31  func TestProxyLBOp_CRUD(t *testing.T) {
    32  	initProxyLBVariables()
    33  
    34  	testutil.RunCRUD(t, &testutil.CRUDTestCase{
    35  		Parallel: true,
    36  
    37  		PreCheck: testutil.PreCheckEnvsFunc("SAKURACLOUD_PROXYLB_SERVER0", "SAKURACLOUD_PROXYLB_SERVER1", "SAKURACLOUD_PROXYLB_SERVER2"),
    38  
    39  		SetupAPICallerFunc: singletonAPICaller,
    40  
    41  		Create: &testutil.CRUDTestFunc{
    42  			Func: testProxyLBCreate,
    43  			CheckFunc: testutil.AssertEqualWithExpected(&testutil.CRUDTestExpect{
    44  				ExpectValue:  createProxyLBExpected,
    45  				IgnoreFields: ignoreProxyLBFields,
    46  			}),
    47  		},
    48  
    49  		Read: &testutil.CRUDTestFunc{
    50  			Func: testProxyLBRead,
    51  			CheckFunc: testutil.AssertEqualWithExpected(&testutil.CRUDTestExpect{
    52  				ExpectValue:  createProxyLBExpected,
    53  				IgnoreFields: ignoreProxyLBFields,
    54  			}),
    55  		},
    56  
    57  		Updates: []*testutil.CRUDTestFunc{
    58  			{
    59  				Func: testProxyLBUpdate,
    60  				CheckFunc: testutil.AssertEqualWithExpected(&testutil.CRUDTestExpect{
    61  					ExpectValue:  updateProxyLBExpected,
    62  					IgnoreFields: ignoreProxyLBFields,
    63  				}),
    64  			},
    65  			{
    66  				Func: testProxyLBUpdatePlan,
    67  				CheckFunc: testutil.AssertEqualWithExpected(&testutil.CRUDTestExpect{
    68  					ExpectValue:  updateProxyLBPlanExpected,
    69  					IgnoreFields: ignoreProxyLBFields,
    70  				}),
    71  			},
    72  			{
    73  				Func: testProxyLBUpdateSettings,
    74  				CheckFunc: testutil.AssertEqualWithExpected(&testutil.CRUDTestExpect{
    75  					ExpectValue:  updateProxyLBSettingsExpected,
    76  					IgnoreFields: ignoreProxyLBFields,
    77  				}),
    78  			},
    79  			{
    80  				Func: testProxyLBUpdateToMin,
    81  				CheckFunc: testutil.AssertEqualWithExpected(&testutil.CRUDTestExpect{
    82  					ExpectValue:  updateProxyLBToMinExpected,
    83  					IgnoreFields: ignoreProxyLBFields,
    84  				}),
    85  			},
    86  		},
    87  
    88  		Delete: &testutil.CRUDTestDeleteFunc{
    89  			Func: testProxyLBDelete,
    90  		},
    91  	})
    92  }
    93  
    94  var (
    95  	ignoreProxyLBFields           []string
    96  	createProxyLBParam            *iaas.ProxyLBCreateRequest
    97  	createProxyLBExpected         *iaas.ProxyLB
    98  	updateProxyLBParam            *iaas.ProxyLBUpdateRequest
    99  	updateProxyLBExpected         *iaas.ProxyLB
   100  	updateProxyLBPlanExpected     *iaas.ProxyLB
   101  	updateProxyLBSettingsParam    *iaas.ProxyLBUpdateSettingsRequest
   102  	updateProxyLBSettingsExpected *iaas.ProxyLB
   103  	updateProxyLBToMinParam       *iaas.ProxyLBUpdateRequest
   104  	updateProxyLBToMinExpected    *iaas.ProxyLB
   105  
   106  	createProxyLBForACMEParam *iaas.ProxyLBCreateRequest
   107  	updateProxyLBForACMEParam *iaas.ProxyLBUpdateRequest
   108  )
   109  
   110  func initProxyLBVariables() {
   111  	ignoreProxyLBFields = []string{
   112  		"ID",
   113  		"CreatedAt",
   114  		"ModifiedAt",
   115  		"Class",
   116  		"SettingsHash",
   117  		"Region",
   118  		"ProxyNetworks",
   119  		"FQDN",
   120  	}
   121  
   122  	createProxyLBParam = &iaas.ProxyLBCreateRequest{
   123  		Name:        testutil.ResourceName("proxylb"),
   124  		Description: "desc",
   125  		Tags:        []string{"tag1", "tag2"},
   126  		Plan:        types.ProxyLBPlans.CPS100,
   127  		HealthCheck: &iaas.ProxyLBHealthCheck{
   128  			Protocol:  types.ProxyLBProtocols.HTTP,
   129  			Path:      "/",
   130  			DelayLoop: 10,
   131  		},
   132  		SorryServer: &iaas.ProxyLBSorryServer{
   133  			IPAddress: os.Getenv("SAKURACLOUD_PROXYLB_SERVER0"),
   134  			Port:      80,
   135  		},
   136  		BindPorts: []*iaas.ProxyLBBindPort{
   137  			{
   138  				ProxyMode:       types.ProxyLBProxyModes.HTTP,
   139  				Port:            80,
   140  				RedirectToHTTPS: true,
   141  				AddResponseHeader: []*iaas.ProxyLBResponseHeader{
   142  					{
   143  						Header: "Cache-Control",
   144  						Value:  "public, max-age=60",
   145  					},
   146  				},
   147  			},
   148  			{
   149  				ProxyMode:    types.ProxyLBProxyModes.HTTPS,
   150  				Port:         443,
   151  				SupportHTTP2: true,
   152  				SSLPolicy:    "TLS-1-3-2021-06",
   153  			},
   154  		},
   155  		Servers: []*iaas.ProxyLBServer{
   156  			{
   157  				IPAddress:   os.Getenv("SAKURACLOUD_PROXYLB_SERVER1"),
   158  				Port:        80,
   159  				ServerGroup: "group1",
   160  				Enabled:     true,
   161  			},
   162  			{
   163  				IPAddress:   os.Getenv("SAKURACLOUD_PROXYLB_SERVER2"),
   164  				Port:        80,
   165  				ServerGroup: "group2",
   166  				Enabled:     true,
   167  			},
   168  		},
   169  		Rules: []*iaas.ProxyLBRule{
   170  			{
   171  				Host:        "www.usacloud.jp",
   172  				Path:        "/path1",
   173  				SourceIPs:   "192.168.0.1,192.168.1.0/24",
   174  				ServerGroup: "group1",
   175  				Action:      types.ProxyLBRuleActions.Forward,
   176  			},
   177  			{
   178  				Host:        "www.usacloud.jp",
   179  				Path:        "/path2",
   180  				ServerGroup: "group2",
   181  				Action:      types.ProxyLBRuleActions.Forward,
   182  			},
   183  			{
   184  				RequestHeaderName:            "User-Agent",
   185  				RequestHeaderValue:           "*badbot",
   186  				RequestHeaderValueIgnoreCase: false,
   187  				RequestHeaderValueNotMatch:   false,
   188  				ServerGroup:                  "group1",
   189  				Action:                       types.ProxyLBRuleActions.Forward,
   190  			},
   191  			{
   192  				Host:             "www.usacloud.jp",
   193  				Path:             "/fixed-response",
   194  				Action:           types.ProxyLBRuleActions.Fixed,
   195  				FixedStatusCode:  types.ProxyLBFixedStatusCodes.OK,
   196  				FixedContentType: types.ProxyLBFixedContentTypes.Plain,
   197  				FixedMessageBody: "foobar",
   198  			},
   199  			{
   200  				Host:               "www.usacloud.jp",
   201  				Path:               "/redirect",
   202  				Action:             types.ProxyLBRuleActions.Redirect,
   203  				RedirectLocation:   "https://redirect.usacloud.jp",
   204  				RedirectStatusCode: types.ProxyLBRedirectStatusCodes.Found,
   205  			},
   206  		},
   207  		LetsEncrypt: &iaas.ProxyLBACMESetting{
   208  			Enabled: false,
   209  		},
   210  		StickySession: &iaas.ProxyLBStickySession{
   211  			Method:  "cookie",
   212  			Enabled: true,
   213  		},
   214  		Gzip: &iaas.ProxyLBGzip{
   215  			Enabled: true,
   216  		},
   217  		BackendHttpKeepAlive: &iaas.ProxyLBBackendHttpKeepAlive{
   218  			Mode: types.ProxyLBBackendHttpKeepAlive.Aggressive,
   219  		},
   220  		ProxyProtocol: &iaas.ProxyLBProxyProtocol{
   221  			Enabled: true,
   222  		},
   223  		Syslog: &iaas.ProxyLBSyslog{
   224  			Server: "133.242.0.1",
   225  			Port:   514,
   226  		},
   227  		Timeout: &iaas.ProxyLBTimeout{
   228  			InactiveSec: 30,
   229  		},
   230  		UseVIPFailover: true,
   231  		Region:         types.ProxyLBRegions.Anycast,
   232  	}
   233  	createProxyLBExpected = &iaas.ProxyLB{
   234  		Name:         createProxyLBParam.Name,
   235  		Description:  createProxyLBParam.Description,
   236  		Tags:         createProxyLBParam.Tags,
   237  		Availability: types.Availabilities.Available,
   238  
   239  		Plan:                 createProxyLBParam.Plan,
   240  		HealthCheck:          createProxyLBParam.HealthCheck,
   241  		SorryServer:          createProxyLBParam.SorryServer,
   242  		BindPorts:            createProxyLBParam.BindPorts,
   243  		Servers:              createProxyLBParam.Servers,
   244  		Rules:                createProxyLBParam.Rules,
   245  		LetsEncrypt:          createProxyLBParam.LetsEncrypt,
   246  		StickySession:        createProxyLBParam.StickySession,
   247  		Gzip:                 createProxyLBParam.Gzip,
   248  		BackendHttpKeepAlive: createProxyLBParam.BackendHttpKeepAlive,
   249  		ProxyProtocol:        createProxyLBParam.ProxyProtocol,
   250  		Syslog:               createProxyLBParam.Syslog,
   251  		Timeout:              createProxyLBParam.Timeout,
   252  		UseVIPFailover:       createProxyLBParam.UseVIPFailover,
   253  		Region:               createProxyLBParam.Region,
   254  	}
   255  	updateProxyLBParam = &iaas.ProxyLBUpdateRequest{
   256  		Name:        testutil.ResourceName("proxylb-upd"),
   257  		Description: "desc-upd",
   258  		Tags:        []string{"tag1-upd", "tag2-upd"},
   259  		IconID:      testIconID,
   260  		HealthCheck: &iaas.ProxyLBHealthCheck{
   261  			Protocol:  types.ProxyLBProtocols.HTTP,
   262  			Path:      "/index.html",
   263  			DelayLoop: 20,
   264  		},
   265  		SorryServer: &iaas.ProxyLBSorryServer{
   266  			IPAddress: os.Getenv("SAKURACLOUD_PROXYLB_SERVER0"),
   267  			Port:      8080,
   268  		},
   269  		BindPorts: []*iaas.ProxyLBBindPort{
   270  			{
   271  				ProxyMode:       types.ProxyLBProxyModes.HTTP,
   272  				Port:            8080,
   273  				RedirectToHTTPS: true,
   274  			},
   275  			{
   276  				ProxyMode:    types.ProxyLBProxyModes.HTTPS,
   277  				Port:         8443,
   278  				SupportHTTP2: true,
   279  				SSLPolicy:    "TLS-1-3-2021-06",
   280  			},
   281  		},
   282  		Servers: []*iaas.ProxyLBServer{
   283  			{
   284  				IPAddress:   os.Getenv("SAKURACLOUD_PROXYLB_SERVER1"),
   285  				Port:        8080,
   286  				ServerGroup: "group1upd",
   287  				Enabled:     true,
   288  			},
   289  			{
   290  				IPAddress:   os.Getenv("SAKURACLOUD_PROXYLB_SERVER2"),
   291  				Port:        8080,
   292  				ServerGroup: "group2upd",
   293  				Enabled:     true,
   294  			},
   295  		},
   296  		Rules: []*iaas.ProxyLBRule{
   297  			{
   298  				Host:        "www-upd.usacloud.jp",
   299  				Path:        "/path1-upd",
   300  				ServerGroup: "group1upd",
   301  				Action:      types.ProxyLBRuleActions.Forward,
   302  			},
   303  			{
   304  				Host:        "www-upd.usacloud.jp",
   305  				Path:        "/path2-upd",
   306  				ServerGroup: "group2upd",
   307  				Action:      types.ProxyLBRuleActions.Forward,
   308  			},
   309  			{
   310  				RequestHeaderName:            "User-Agent",
   311  				RequestHeaderValue:           "*badbot",
   312  				RequestHeaderValueIgnoreCase: false,
   313  				RequestHeaderValueNotMatch:   false,
   314  				ServerGroup:                  "group1upd",
   315  				Action:                       types.ProxyLBRuleActions.Forward,
   316  			},
   317  			{
   318  				Host:             "www-upd.usacloud.jp",
   319  				Path:             "/fixed-response-upd",
   320  				Action:           types.ProxyLBRuleActions.Fixed,
   321  				FixedStatusCode:  types.ProxyLBFixedStatusCodes.Forbidden,
   322  				FixedContentType: types.ProxyLBFixedContentTypes.HTML,
   323  				FixedMessageBody: "foobar-upd",
   324  			},
   325  			{
   326  				Host:               "www-upd.usacloud.jp",
   327  				Path:               "/redirect-upd",
   328  				Action:             types.ProxyLBRuleActions.Redirect,
   329  				RedirectLocation:   "https://redirect.usacloud.jp/upd",
   330  				RedirectStatusCode: types.ProxyLBRedirectStatusCodes.MovedPermanently,
   331  			},
   332  		},
   333  		// LetsEncryptのテストはA or CNAMEレコードの登録が必要なため別ケースで行う
   334  		LetsEncrypt: &iaas.ProxyLBACMESetting{
   335  			Enabled: false,
   336  		},
   337  		StickySession: &iaas.ProxyLBStickySession{
   338  			Enabled: false,
   339  		},
   340  		Gzip: &iaas.ProxyLBGzip{
   341  			Enabled: false,
   342  		},
   343  		BackendHttpKeepAlive: &iaas.ProxyLBBackendHttpKeepAlive{
   344  			Mode: types.ProxyLBBackendHttpKeepAlive.Safe,
   345  		},
   346  		ProxyProtocol: &iaas.ProxyLBProxyProtocol{
   347  			Enabled: false,
   348  		},
   349  		Syslog: &iaas.ProxyLBSyslog{
   350  			Server: "",
   351  			Port:   514,
   352  		},
   353  		Timeout: &iaas.ProxyLBTimeout{
   354  			InactiveSec: 10,
   355  		},
   356  	}
   357  	updateProxyLBExpected = &iaas.ProxyLB{
   358  		Name:          updateProxyLBParam.Name,
   359  		Description:   updateProxyLBParam.Description,
   360  		Tags:          updateProxyLBParam.Tags,
   361  		IconID:        testIconID,
   362  		Availability:  types.Availabilities.Available,
   363  		Plan:          createProxyLBParam.Plan,
   364  		HealthCheck:   updateProxyLBParam.HealthCheck,
   365  		SorryServer:   updateProxyLBParam.SorryServer,
   366  		BindPorts:     updateProxyLBParam.BindPorts,
   367  		Servers:       updateProxyLBParam.Servers,
   368  		Rules:         updateProxyLBParam.Rules,
   369  		LetsEncrypt:   updateProxyLBParam.LetsEncrypt,
   370  		StickySession: updateProxyLBParam.StickySession,
   371  		Timeout: &iaas.ProxyLBTimeout{
   372  			InactiveSec: 10,
   373  		},
   374  		Gzip:                 updateProxyLBParam.Gzip,
   375  		BackendHttpKeepAlive: updateProxyLBParam.BackendHttpKeepAlive,
   376  		ProxyProtocol:        updateProxyLBParam.ProxyProtocol,
   377  		Syslog:               updateProxyLBParam.Syslog,
   378  		UseVIPFailover:       createProxyLBParam.UseVIPFailover,
   379  		Region:               createProxyLBParam.Region,
   380  	}
   381  	updateProxyLBPlanExpected = &iaas.ProxyLB{
   382  		Name:          updateProxyLBParam.Name,
   383  		Description:   updateProxyLBParam.Description,
   384  		Tags:          updateProxyLBParam.Tags,
   385  		IconID:        testIconID,
   386  		Availability:  types.Availabilities.Available,
   387  		Plan:          types.ProxyLBPlans.CPS500,
   388  		HealthCheck:   updateProxyLBParam.HealthCheck,
   389  		SorryServer:   updateProxyLBParam.SorryServer,
   390  		BindPorts:     updateProxyLBParam.BindPorts,
   391  		Servers:       updateProxyLBParam.Servers,
   392  		Rules:         updateProxyLBParam.Rules,
   393  		LetsEncrypt:   updateProxyLBParam.LetsEncrypt,
   394  		StickySession: updateProxyLBParam.StickySession,
   395  		Timeout: &iaas.ProxyLBTimeout{
   396  			InactiveSec: 10,
   397  		},
   398  		Gzip:                 updateProxyLBParam.Gzip,
   399  		BackendHttpKeepAlive: updateProxyLBParam.BackendHttpKeepAlive,
   400  		ProxyProtocol:        updateProxyLBParam.ProxyProtocol,
   401  		Syslog:               updateProxyLBParam.Syslog,
   402  		UseVIPFailover:       createProxyLBParam.UseVIPFailover,
   403  		Region:               createProxyLBParam.Region,
   404  	}
   405  	updateProxyLBSettingsParam = &iaas.ProxyLBUpdateSettingsRequest{
   406  		HealthCheck: &iaas.ProxyLBHealthCheck{
   407  			Protocol:  types.ProxyLBProtocols.TCP,
   408  			DelayLoop: 20,
   409  		},
   410  		SorryServer: &iaas.ProxyLBSorryServer{
   411  			IPAddress: os.Getenv("SAKURACLOUD_PROXYLB_SERVER0"),
   412  			Port:      8080,
   413  		},
   414  		BindPorts: []*iaas.ProxyLBBindPort{
   415  			{
   416  				ProxyMode: types.ProxyLBProxyModes.HTTP, Port: 8081,
   417  				RedirectToHTTPS: true,
   418  			},
   419  			{
   420  				ProxyMode:    types.ProxyLBProxyModes.HTTPS,
   421  				Port:         8443,
   422  				SupportHTTP2: true,
   423  				SSLPolicy:    "TLS-1-3-2021-06",
   424  			},
   425  		},
   426  		Servers: []*iaas.ProxyLBServer{
   427  			{
   428  				IPAddress:   os.Getenv("SAKURACLOUD_PROXYLB_SERVER1"),
   429  				Port:        8081,
   430  				ServerGroup: "group1upd2",
   431  				Enabled:     true,
   432  			},
   433  			{
   434  				IPAddress:   os.Getenv("SAKURACLOUD_PROXYLB_SERVER2"),
   435  				Port:        8081,
   436  				ServerGroup: "group2upd2",
   437  				Enabled:     true,
   438  			},
   439  		},
   440  		Rules: []*iaas.ProxyLBRule{
   441  			{
   442  				Host:        "www-upd2.usacloud.jp",
   443  				Path:        "/path1-upd2",
   444  				ServerGroup: "group1upd2",
   445  				Action:      types.ProxyLBRuleActions.Forward,
   446  			},
   447  			{
   448  				Host:        "www-upd2.usacloud.jp",
   449  				Path:        "/path2-upd2",
   450  				ServerGroup: "group2upd2",
   451  				Action:      types.ProxyLBRuleActions.Forward,
   452  			},
   453  		},
   454  		// LetsEncryptのテストはA or CNAMEレコードの登録が必要なため別ケースで行う
   455  		LetsEncrypt: &iaas.ProxyLBACMESetting{
   456  			Enabled: false,
   457  		},
   458  		StickySession: &iaas.ProxyLBStickySession{
   459  			Method:  "cookie",
   460  			Enabled: true,
   461  		},
   462  		Timeout: &iaas.ProxyLBTimeout{
   463  			InactiveSec: 10,
   464  		},
   465  		Gzip: &iaas.ProxyLBGzip{
   466  			Enabled: false,
   467  		},
   468  		ProxyProtocol: &iaas.ProxyLBProxyProtocol{
   469  			Enabled: false,
   470  		},
   471  		Syslog: &iaas.ProxyLBSyslog{
   472  			Server: "",
   473  			Port:   514,
   474  		},
   475  	}
   476  	updateProxyLBSettingsExpected = &iaas.ProxyLB{
   477  		Name:          updateProxyLBParam.Name,
   478  		Description:   updateProxyLBParam.Description,
   479  		Tags:          updateProxyLBParam.Tags,
   480  		IconID:        testIconID,
   481  		Availability:  types.Availabilities.Available,
   482  		Plan:          updateProxyLBPlanExpected.Plan,
   483  		HealthCheck:   updateProxyLBSettingsParam.HealthCheck,
   484  		SorryServer:   updateProxyLBSettingsParam.SorryServer,
   485  		BindPorts:     updateProxyLBSettingsParam.BindPorts,
   486  		Servers:       updateProxyLBSettingsParam.Servers,
   487  		Rules:         updateProxyLBSettingsParam.Rules,
   488  		LetsEncrypt:   updateProxyLBSettingsParam.LetsEncrypt,
   489  		StickySession: updateProxyLBSettingsParam.StickySession,
   490  		Timeout: &iaas.ProxyLBTimeout{
   491  			InactiveSec: 10,
   492  		},
   493  		Gzip:                 updateProxyLBSettingsParam.Gzip,
   494  		BackendHttpKeepAlive: updateProxyLBSettingsParam.BackendHttpKeepAlive,
   495  		ProxyProtocol:        updateProxyLBSettingsParam.ProxyProtocol,
   496  		Syslog:               updateProxyLBSettingsParam.Syslog,
   497  		UseVIPFailover:       createProxyLBParam.UseVIPFailover,
   498  		Region:               createProxyLBParam.Region,
   499  	}
   500  
   501  	updateProxyLBToMinParam = &iaas.ProxyLBUpdateRequest{
   502  		Name: testutil.ResourceName("proxylb-to-min"),
   503  		HealthCheck: &iaas.ProxyLBHealthCheck{
   504  			Protocol:  types.ProxyLBProtocols.TCP,
   505  			DelayLoop: 10,
   506  		},
   507  		LetsEncrypt: &iaas.ProxyLBACMESetting{
   508  			Enabled: false,
   509  		},
   510  		StickySession: &iaas.ProxyLBStickySession{
   511  			Enabled: false,
   512  		},
   513  		Timeout: &iaas.ProxyLBTimeout{
   514  			InactiveSec: 10,
   515  		},
   516  		Gzip: &iaas.ProxyLBGzip{
   517  			Enabled: false,
   518  		},
   519  		BackendHttpKeepAlive: &iaas.ProxyLBBackendHttpKeepAlive{
   520  			Mode: types.ProxyLBBackendHttpKeepAlive.Safe,
   521  		},
   522  		ProxyProtocol: &iaas.ProxyLBProxyProtocol{
   523  			Enabled: false,
   524  		},
   525  		Syslog: &iaas.ProxyLBSyslog{
   526  			Server: "",
   527  			Port:   514,
   528  		},
   529  		BindPorts: []*iaas.ProxyLBBindPort{},
   530  		Rules:     []*iaas.ProxyLBRule{},
   531  		Servers:   []*iaas.ProxyLBServer{},
   532  	}
   533  	updateProxyLBToMinExpected = &iaas.ProxyLB{
   534  		Name:         updateProxyLBToMinParam.Name,
   535  		Availability: types.Availabilities.Available,
   536  		Plan:         updateProxyLBPlanExpected.Plan,
   537  		HealthCheck:  updateProxyLBToMinParam.HealthCheck,
   538  		SorryServer:  &iaas.ProxyLBSorryServer{},
   539  		LetsEncrypt: &iaas.ProxyLBACMESetting{
   540  			Enabled: false,
   541  		},
   542  		StickySession: &iaas.ProxyLBStickySession{
   543  			Enabled: false,
   544  		},
   545  		Timeout: &iaas.ProxyLBTimeout{
   546  			InactiveSec: 10,
   547  		},
   548  		BindPorts:            updateProxyLBToMinParam.BindPorts,
   549  		Rules:                updateProxyLBToMinParam.Rules,
   550  		Servers:              updateProxyLBToMinParam.Servers,
   551  		Gzip:                 updateProxyLBToMinParam.Gzip,
   552  		BackendHttpKeepAlive: updateProxyLBToMinParam.BackendHttpKeepAlive,
   553  		ProxyProtocol:        updateProxyLBToMinParam.ProxyProtocol,
   554  		Syslog:               updateProxyLBToMinParam.Syslog,
   555  		UseVIPFailover:       createProxyLBParam.UseVIPFailover,
   556  		Region:               createProxyLBParam.Region,
   557  	}
   558  
   559  	createProxyLBForACMEParam = &iaas.ProxyLBCreateRequest{
   560  		Name: testutil.ResourceName("proxylb-acme"),
   561  		Plan: types.ProxyLBPlans.CPS100,
   562  		HealthCheck: &iaas.ProxyLBHealthCheck{
   563  			Protocol:  types.ProxyLBProtocols.HTTP,
   564  			Path:      "/",
   565  			DelayLoop: 20,
   566  		},
   567  		BindPorts: []*iaas.ProxyLBBindPort{
   568  			{
   569  				ProxyMode:       types.ProxyLBProxyModes.HTTP,
   570  				Port:            80,
   571  				RedirectToHTTPS: true,
   572  			},
   573  			{
   574  				ProxyMode:    types.ProxyLBProxyModes.HTTPS,
   575  				Port:         443,
   576  				SupportHTTP2: true,
   577  			},
   578  		},
   579  		Servers: []*iaas.ProxyLBServer{
   580  			{
   581  				IPAddress: os.Getenv("SAKURACLOUD_PROXYLB_SERVER0"),
   582  				Port:      80,
   583  				Enabled:   true,
   584  			},
   585  			{
   586  				IPAddress: os.Getenv("SAKURACLOUD_PROXYLB_SERVER1"),
   587  				Port:      80,
   588  				Enabled:   true,
   589  			},
   590  		},
   591  		LetsEncrypt: &iaas.ProxyLBACMESetting{
   592  			Enabled: false,
   593  		},
   594  		Timeout: &iaas.ProxyLBTimeout{
   595  			InactiveSec: 10,
   596  		},
   597  		UseVIPFailover: true,
   598  	}
   599  
   600  	updateProxyLBForACMEParam = &iaas.ProxyLBUpdateRequest{
   601  		Name: testutil.ResourceName("proxylb-acme"),
   602  		HealthCheck: &iaas.ProxyLBHealthCheck{
   603  			Protocol:  types.ProxyLBProtocols.HTTP,
   604  			Path:      "/",
   605  			DelayLoop: 20,
   606  		},
   607  		BindPorts: []*iaas.ProxyLBBindPort{
   608  			{
   609  				ProxyMode:       types.ProxyLBProxyModes.HTTP,
   610  				Port:            80,
   611  				RedirectToHTTPS: true,
   612  			},
   613  			{
   614  				ProxyMode:    types.ProxyLBProxyModes.HTTPS,
   615  				Port:         443,
   616  				SupportHTTP2: true,
   617  			},
   618  		},
   619  		Servers: []*iaas.ProxyLBServer{
   620  			{
   621  				IPAddress: os.Getenv("SAKURACLOUD_PROXYLB_SERVER0"),
   622  				Port:      80,
   623  				Enabled:   true,
   624  			},
   625  			{
   626  				IPAddress: os.Getenv("SAKURACLOUD_PROXYLB_SERVER1"),
   627  				Port:      80,
   628  				Enabled:   true,
   629  			},
   630  		},
   631  		LetsEncrypt: &iaas.ProxyLBACMESetting{
   632  			CommonName:      os.Getenv("SAKURACLOUD_PROXYLB_COMMON_NAME"),
   633  			Enabled:         true,
   634  			SubjectAltNames: []string{os.Getenv("SAKURACLOUD_PROXYLB_ALT_NAME")},
   635  		},
   636  		Timeout: &iaas.ProxyLBTimeout{
   637  			InactiveSec: 10,
   638  		},
   639  	}
   640  }
   641  
   642  func testProxyLBCreate(ctx *testutil.CRUDTestContext, caller iaas.APICaller) (interface{}, error) {
   643  	client := iaas.NewProxyLBOp(caller)
   644  	return client.Create(ctx, createProxyLBParam)
   645  }
   646  
   647  func testProxyLBRead(ctx *testutil.CRUDTestContext, caller iaas.APICaller) (interface{}, error) {
   648  	client := iaas.NewProxyLBOp(caller)
   649  	return client.Read(ctx, ctx.ID)
   650  }
   651  
   652  func testProxyLBUpdate(ctx *testutil.CRUDTestContext, caller iaas.APICaller) (interface{}, error) {
   653  	client := iaas.NewProxyLBOp(caller)
   654  	return client.Update(ctx, ctx.ID, updateProxyLBParam)
   655  }
   656  
   657  func testProxyLBUpdatePlan(ctx *testutil.CRUDTestContext, caller iaas.APICaller) (interface{}, error) {
   658  	client := iaas.NewProxyLBOp(caller)
   659  	return client.ChangePlan(ctx, ctx.ID, &iaas.ProxyLBChangePlanRequest{
   660  		ServiceClass: types.ProxyLBServiceClass(types.ProxyLBPlans.CPS500, types.ProxyLBRegions.Anycast),
   661  	})
   662  }
   663  
   664  func testProxyLBUpdateSettings(ctx *testutil.CRUDTestContext, caller iaas.APICaller) (interface{}, error) {
   665  	client := iaas.NewProxyLBOp(caller)
   666  	return client.UpdateSettings(ctx, ctx.ID, updateProxyLBSettingsParam)
   667  }
   668  
   669  func testProxyLBUpdateToMin(ctx *testutil.CRUDTestContext, caller iaas.APICaller) (interface{}, error) {
   670  	client := iaas.NewProxyLBOp(caller)
   671  	return client.Update(ctx, ctx.ID, updateProxyLBToMinParam)
   672  }
   673  
   674  func testProxyLBDelete(ctx *testutil.CRUDTestContext, caller iaas.APICaller) error {
   675  	client := iaas.NewProxyLBOp(caller)
   676  	return client.Delete(ctx, ctx.ID)
   677  }
   678  
   679  func TestProxyLBOpLetsEncryptAndHealth(t *testing.T) {
   680  	if !isAccTest() {
   681  		t.Skip("TestProxyLBOpLetsEncrypt only exec at Acceptance Test")
   682  	}
   683  
   684  	t.Parallel()
   685  	initProxyLBVariables()
   686  	testutil.PreCheckEnvsFunc(
   687  		"SAKURACLOUD_PROXYLB_SERVER0",
   688  		"SAKURACLOUD_PROXYLB_SERVER1",
   689  		"SAKURACLOUD_PROXYLB_COMMON_NAME",
   690  		"SAKURACLOUD_PROXYLB_ALT_NAME",
   691  		"SAKURACLOUD_PROXYLB_ZONE_NAME",
   692  	)(t)
   693  
   694  	// prepare variables
   695  	commonName := os.Getenv("SAKURACLOUD_PROXYLB_COMMON_NAME")
   696  	altName := os.Getenv("SAKURACLOUD_PROXYLB_ALT_NAME")
   697  	zoneName := os.Getenv("SAKURACLOUD_PROXYLB_ZONE_NAME")
   698  	if !strings.HasSuffix(commonName, zoneName) {
   699  		t.Fatal("$SAKURACLOUD_PROXYLB_COMMON_NAME does not have suffix $SAKURACLOUD_PROXYLB_ZONE_NAME")
   700  	}
   701  	if !strings.HasSuffix(altName, zoneName) {
   702  		t.Fatal("$SAKURACLOUD_PROXYLB_ALT_NAME does not have suffix $SAKURACLOUD_PROXYLB_ZONE_NAME")
   703  	}
   704  	recordName1 := strings.ReplaceAll(commonName, "."+zoneName, "")
   705  	recordName2 := strings.ReplaceAll(altName, "."+zoneName, "")
   706  
   707  	ctx := context.Background()
   708  	proxyLBOp := iaas.NewProxyLBOp(singletonAPICaller())
   709  
   710  	// create proxyLB
   711  	proxyLB, err := proxyLBOp.Create(ctx, createProxyLBForACMEParam)
   712  	if !assert.NoError(t, err) {
   713  		return
   714  	}
   715  	defer func() {
   716  		proxyLBOp.Delete(ctx, proxyLB.ID) //nolint:errcheck
   717  	}()
   718  
   719  	// read DNS
   720  	dns, err := lookupDNSByName(singletonAPICaller(), os.Getenv("SAKURACLOUD_PROXYLB_ZONE_NAME"))
   721  	if !assert.NoError(t, err) {
   722  		return
   723  	}
   724  
   725  	dns.Records = append(dns.Records, &iaas.DNSRecord{
   726  		Name:  recordName1,
   727  		Type:  types.DNSRecordTypes.CNAME,
   728  		RData: fmt.Sprintf("%s.", proxyLB.FQDN),
   729  		TTL:   10,
   730  	})
   731  	dns.Records = append(dns.Records, &iaas.DNSRecord{
   732  		Name:  recordName2,
   733  		Type:  types.DNSRecordTypes.CNAME,
   734  		RData: fmt.Sprintf("%s.", proxyLB.FQDN),
   735  		TTL:   10,
   736  	})
   737  
   738  	// update DNS record
   739  	dnsOp := iaas.NewDNSOp(singletonAPICaller())
   740  	dns, err = dnsOp.Update(ctx, dns.ID, &iaas.DNSUpdateRequest{
   741  		Records: dns.Records,
   742  	})
   743  	if !assert.NoError(t, err) {
   744  		return
   745  	}
   746  	defer func() {
   747  		var records []*iaas.DNSRecord
   748  		for i, r := range dns.Records {
   749  			if r.Name != recordName1 && r.Name != recordName2 {
   750  				records = append(records, dns.Records[i])
   751  			}
   752  		}
   753  		dnsOp.Update(ctx, dns.ID, &iaas.DNSUpdateRequest{Records: records}) //nolint:errcheck
   754  	}()
   755  
   756  	time.Sleep(time.Minute)
   757  
   758  	// update proxyLB
   759  	retryMax := 10
   760  	done := false
   761  
   762  	for retryMax >= 0 {
   763  		proxyLB, err = proxyLBOp.Update(ctx, proxyLB.ID, updateProxyLBForACMEParam)
   764  		if err != nil {
   765  			t.Log("Update Let's encrypt setting is failed. retry after 10 sec.")
   766  			time.Sleep(10 * time.Second)
   767  			retryMax--
   768  			continue
   769  		}
   770  		done = true
   771  		break
   772  	}
   773  	if !done {
   774  		t.Error("Update Let's encrypt settings was failed: given up after 10 retries")
   775  		return
   776  	}
   777  
   778  	// renew certs
   779  	err = proxyLBOp.RenewLetsEncryptCert(ctx, proxyLB.ID)
   780  	if !assert.NoError(t, err) {
   781  		return
   782  	}
   783  
   784  	time.Sleep(time.Minute)
   785  
   786  	// get cert
   787  	certs, err := proxyLBOp.GetCertificates(ctx, proxyLB.ID)
   788  
   789  	if !assert.NoError(t, err) {
   790  		return
   791  	}
   792  	assert.NotNil(t, certs.PrimaryCert)
   793  	assert.NotEmpty(t, certs.PrimaryCert.ServerCertificate)
   794  	assert.NotEmpty(t, certs.PrimaryCert.IntermediateCertificate)
   795  	assert.NotEmpty(t, certs.PrimaryCert.PrivateKey)
   796  	assert.NotEmpty(t, certs.PrimaryCert.CertificateCommonName)
   797  	assert.NotEmpty(t, certs.PrimaryCert.CertificateAltNames)
   798  	assert.NotEmpty(t, certs.PrimaryCert.CertificateEndDate)
   799  
   800  	// check health status
   801  	status, err := proxyLBOp.HealthStatus(ctx, proxyLB.ID)
   802  	if !assert.NoError(t, err) {
   803  		return
   804  	}
   805  	assert.NotEmpty(t, status.CurrentVIP)
   806  }