diff --git a/pkg/client/router.go b/pkg/client/router.go index 2b6d467..b0f980d 100644 --- a/pkg/client/router.go +++ b/pkg/client/router.go @@ -38,8 +38,8 @@ func (r *RouterAPIService) GetAllRouter( func (r *RouterAPIService) GetSpecificRouter( ctx context.Context, routerID int, -) (models.GetSpecificRouterResp, error) { - routerResp := models.GetSpecificRouterResp{} +) (models.GetNetworkRouter, error) { + routerResp := models.GetNetworkRouter{} serverAPI := &api{ method: "GET", path: fmt.Sprintf("%s/%s/%s/%s/%d", r.Cfg.Host, consts.VmaasCmpAPIBasePath, @@ -73,6 +73,26 @@ func (r *RouterAPIService) CreateRouter( return routerResp, err } +func (r *RouterAPIService) UpdateRouter( + ctx context.Context, + routerID int, + request models.CreateRouterRequest, +) (models.SuccessOrErrorMessage, error) { + routerResp := models.SuccessOrErrorMessage{} + serverAPI := &api{ + method: "PUT", + path: fmt.Sprintf("%s/%s/%s/%s/%d", r.Cfg.Host, consts.VmaasCmpAPIBasePath, + consts.NetworksPath, consts.NetworkRouterPath, routerID), + client: r.Client, + jsonParser: func(body []byte) error { + return json.Unmarshal(body, &routerResp) + }, + } + err := serverAPI.do(ctx, request, nil) + + return routerResp, err +} + func (r *RouterAPIService) DeleteRouter( ctx context.Context, routerID int, diff --git a/pkg/client/router_test.go b/pkg/client/router_test.go new file mode 100644 index 0000000..40017ea --- /dev/null +++ b/pkg/client/router_test.go @@ -0,0 +1,472 @@ +// (C) Copyright 2021 Hewlett Packard Enterprise Development LP + +package client + +import ( + "bytes" + "context" + "errors" + "io/ioutil" + "net/http" + "net/url" + "reflect" + "testing" + + "github.com/HewlettPackard/hpegl-vmaas-cmp-go-sdk/pkg/models" + gomock "github.com/golang/mock/gomock" +) + +func TestRouterAPIService_GetAllRouters(t *testing.T) { + ctx := context.Background() + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + templateName := "test_template_get_all_routers" + + tests := []struct { + name string + param map[string]string + given func(m *MockAPIClientHandler) + want models.GetAllNetworkRouter + wantErr bool + }{ + { + name: "Normal Test case 1: Get all Routers", + param: map[string]string{ + "name": templateName, + }, + given: func(m *MockAPIClientHandler) { + path := mockHost + "/v1/networks/routers" + method := "GET" + headers := getDefaultHeaders() + req, _ := http.NewRequest(method, path, nil) + respBody := ioutil.NopCloser(bytes.NewReader([]byte(` + { + "networkRouters": [{ + "id": 1, + "name": "test_template_get_all_routers" + }] + } + `))) + m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, + getURLValues(map[string]string{ + "name": templateName, + }), url.Values{}, "", nil).Return(req, nil) + + m.EXPECT().callAPI(req).Return(&http.Response{ + StatusCode: 200, + Body: respBody, + }, nil) + }, + want: models.GetAllNetworkRouter{ + NetworkRouters: []models.GetNetworkRouter{ + { + ID: 1, + Name: templateName, + }, + }, + }, + wantErr: false, + }, + { + name: "Failed Test case 2: Error in prepare request", + param: map[string]string{ + "name": templateName, + }, + given: func(m *MockAPIClientHandler) { + path := mockHost + "/v1/networks/routers" + method := "GET" + headers := getDefaultHeaders() + m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, + getURLValues(map[string]string{ + "name": templateName, + }), url.Values{}, "", nil).Return(nil, errors.New("prepare error request")) + }, + want: models.GetAllNetworkRouter{}, + wantErr: true, + }, + { + name: "Failed Test case 3: Error in callAPI", + param: map[string]string{ + "name": templateName, + }, + given: func(m *MockAPIClientHandler) { + path := mockHost + "/v1/networks/routers" + method := "GET" + headers := getDefaultHeaders() + req, _ := http.NewRequest(method, path, nil) + respBody := ioutil.NopCloser(bytes.NewReader([]byte(` + { + "message": "Internal Server Error", + "recommendedActions": [ + "Unknown error occurred. Please contact the administrator" + ] + } + `))) + m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, + getURLValues(map[string]string{ + "name": templateName, + }), url.Values{}, "", nil).Return(req, nil) + + m.EXPECT().callAPI(req).Return(&http.Response{ + StatusCode: 500, + Body: respBody, + }, nil) + }, + want: models.GetAllNetworkRouter{}, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mockAPIClient := NewMockAPIClientHandler(ctrl) + n := RouterAPIService{ + Client: mockAPIClient, + Cfg: Configuration{ + Host: mockHost, + }, + } + tt.given(mockAPIClient) + got, err := n.GetAllRouter(ctx, tt.param) + if (err != nil) != tt.wantErr { + t.Errorf("RouterAPIService.GetAllRouter() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("RouterAPIService.GetAllRouter() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestRouterAPIService_GetNetworkRouterTypes(t *testing.T) { + ctx := context.Background() + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + templateName := "test_template_get_all_router_types" + + tests := []struct { + name string + param map[string]string + given func(m *MockAPIClientHandler) + want models.GetNetworlRouterTypes + wantErr bool + }{ + { + name: "Normal Test case 1: Get all Router Types", + param: map[string]string{ + "name": templateName, + }, + given: func(m *MockAPIClientHandler) { + path := mockHost + "/v1/network-router-types" + method := "GET" + headers := getDefaultHeaders() + req, _ := http.NewRequest(method, path, nil) + respBody := ioutil.NopCloser(bytes.NewReader([]byte(` + { + "networkRouterTypes": [{ + "id": 1, + "name": "test_template_get_all_router_types" + }] + } + `))) + m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, + getURLValues(map[string]string{ + "name": templateName, + }), url.Values{}, "", nil).Return(req, nil) + + m.EXPECT().callAPI(req).Return(&http.Response{ + StatusCode: 200, + Body: respBody, + }, nil) + }, + want: models.GetNetworlRouterTypes{ + NetworkRouterTypes: []models.NetworkRouterTypes{ + { + ID: 1, + Name: templateName, + }, + }, + }, + wantErr: false, + }, + { + name: "Failed Test case 2: Error in prepare request", + param: map[string]string{ + "name": templateName, + }, + given: func(m *MockAPIClientHandler) { + path := mockHost + "/v1/network-router-types" + method := "GET" + headers := getDefaultHeaders() + m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, + getURLValues(map[string]string{ + "name": templateName, + }), url.Values{}, "", nil).Return(nil, errors.New("prepare error request")) + }, + want: models.GetNetworlRouterTypes{}, + wantErr: true, + }, + { + name: "Failed Test case 3: Error in callAPI", + param: map[string]string{ + "name": templateName, + }, + given: func(m *MockAPIClientHandler) { + path := mockHost + "/v1/network-router-types" + method := "GET" + headers := getDefaultHeaders() + req, _ := http.NewRequest(method, path, nil) + respBody := ioutil.NopCloser(bytes.NewReader([]byte(` + { + "message": "Internal Server Error", + "recommendedActions": [ + "Unknown error occurred. Please contact the administrator" + ] + } + `))) + m.EXPECT().prepareRequest(gomock.Any(), path, method, nil, headers, + getURLValues(map[string]string{ + "name": templateName, + }), url.Values{}, "", nil).Return(req, nil) + + m.EXPECT().callAPI(req).Return(&http.Response{ + StatusCode: 500, + Body: respBody, + }, nil) + }, + want: models.GetNetworlRouterTypes{}, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mockAPIClient := NewMockAPIClientHandler(ctrl) + n := RouterAPIService{ + Client: mockAPIClient, + Cfg: Configuration{ + Host: mockHost, + }, + } + tt.given(mockAPIClient) + got, err := n.GetRouterTypes(ctx, tt.param) + if (err != nil) != tt.wantErr { + t.Errorf("RouterAPIService.GetRouterTypes() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("RouterAPIService.GetRouterTypes() = %v, want %v", got, tt.want) + } + }) + } +} +func TestRouterAPIService_CreateRouter(t *testing.T) { + ctrl := gomock.NewController(t) + defer ctrl.Finish() + + tests := []struct { + name string + args models.CreateRouterRequest + given func(m *MockAPIClientHandler) + want models.CreateRouterResp + wantErr bool + }{ + { + name: "Normal test case 1: Create Router", + args: models.CreateRouterRequest{ + NetworkRouter: models.CreateRouterRequestRouter{ + Name: "tf_router", + }, + }, + given: func(m *MockAPIClientHandler) { + path := mockHost + "/v1/networks/routers" + method := "POST" + headers := getDefaultHeaders() + req, _ := http.NewRequest(method, path, nil) + + m.EXPECT().prepareRequest(gomock.Any(), path, method, + models.CreateRouterRequest{ + NetworkRouter: models.CreateRouterRequestRouter{ + Name: "tf_router", + }, + }, + headers, url.Values{}, url.Values{}, "", nil).Return(req, nil) + + m.EXPECT().callAPI(req).Return(&http.Response{ + StatusCode: 200, + Body: ioutil.NopCloser(bytes.NewReader([]byte(` + { + "success": true, + "id": 16 + } + `))), + }, nil) + }, + want: models.CreateRouterResp{ + Success: true, + ID: 16, + }, + wantErr: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mockAPIClient := NewMockAPIClientHandler(ctrl) + tt.given(mockAPIClient) + n := RouterAPIService{ + Client: mockAPIClient, + Cfg: Configuration{ + Host: mockHost, + }, + } + got, err := n.CreateRouter(context.Background(), tt.args) + if (err != nil) != tt.wantErr { + t.Errorf("RouterAPIService.CreateRouter() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("RouterAPIService.CreateRouter() = %v, want %v", got, tt.want) + } + }) + } +} + +func TestRouterAPIService_UpdateRouter(t *testing.T) { + ctx := context.Background() + ctrl := gomock.NewController(t) + headers := getDefaultHeaders() + defer ctrl.Finish() + tests := []struct { + name string + routerID int + param models.CreateRouterRequest + given func(m *MockAPIClientHandler) + want models.SuccessOrErrorMessage + wantErr bool + }{ + { + name: "Normal Test case 1: Update a Router", + routerID: 1, + param: models.CreateRouterRequest{ + NetworkRouter: models.CreateRouterRequestRouter{ + Name: "test_update_router_name", + }, + }, + given: func(m *MockAPIClientHandler) { + path := mockHost + "/v1/networks/routers/1" + method := "PUT" + postBody := ioutil.NopCloser(bytes.NewReader([]byte(` + { + "networkRouter": { + "name": "test_update_router_name" + } + }`))) + req, _ := http.NewRequest(method, path, postBody) + respBody := ioutil.NopCloser(bytes.NewReader([]byte(`{ + "success": true + }`))) + pBody := models.CreateRouterRequest{ + NetworkRouter: models.CreateRouterRequestRouter{ + Name: "test_update_router_name", + }, + } + m.EXPECT().prepareRequest(gomock.Any(), path, method, pBody, headers, url.Values{}, + url.Values{}, "", nil).Return(req, nil) + m.EXPECT().callAPI(req).Return(&http.Response{ + StatusCode: 200, + Body: respBody, + }, nil) + }, + want: models.SuccessOrErrorMessage{ + Success: true, + }, + wantErr: false, + }, + { + name: "Failed test case 2: error in prepare request", + routerID: 1, + param: models.CreateRouterRequest{ + NetworkRouter: models.CreateRouterRequestRouter{ + Name: "test_update_router_name", + }, + }, + given: func(m *MockAPIClientHandler) { + path := mockHost + "/v1/networks/routers/1" + method := "PUT" + + pBody := models.CreateRouterRequest{ + NetworkRouter: models.CreateRouterRequestRouter{ + Name: "test_update_router_name", + }, + } + m.EXPECT().prepareRequest(gomock.Any(), path, method, pBody, headers, url.Values{}, + url.Values{}, "", nil).Return(nil, errors.New("prepare request error")) + }, + want: models.SuccessOrErrorMessage{}, + wantErr: true, + }, + { + name: "Failed test case 3: error in callAPI", + routerID: 1, + param: models.CreateRouterRequest{ + NetworkRouter: models.CreateRouterRequestRouter{ + Name: "test_update_router_name", + }, + }, + given: func(m *MockAPIClientHandler) { + path := mockHost + "/v1/networks/routers/1" + method := "PUT" + postBody := ioutil.NopCloser(bytes.NewReader([]byte(` + { + "networkRouter": { + "name": "test_update_router_name" + } + }`))) + req, _ := http.NewRequest(method, path, postBody) + respBody := ioutil.NopCloser(bytes.NewReader([]byte(`{ + { + "message": "Internal Server Error", + "recommendedActions": [ + "Unknown error occurred. Please contact the administrator" + ] + } + }`))) + pBody := models.CreateRouterRequest{ + NetworkRouter: models.CreateRouterRequestRouter{ + Name: "test_update_router_name", + }, + } + m.EXPECT().prepareRequest(gomock.Any(), path, method, pBody, headers, url.Values{}, + url.Values{}, "", nil).Return(req, nil) + m.EXPECT().callAPI(req).Return(&http.Response{ + StatusCode: 500, + Body: respBody, + }, nil) + }, + want: models.SuccessOrErrorMessage{}, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mockAPIClient := NewMockAPIClientHandler(ctrl) + a := RouterAPIService{ + Client: mockAPIClient, + Cfg: Configuration{ + Host: mockHost, + }, + } + tt.given(mockAPIClient) + got, err := a.UpdateRouter(ctx, tt.routerID, tt.param) + if (err != nil) != tt.wantErr { + t.Errorf("RouterAPIService.UpdateRouter() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("RouterAPIService.UpdateRouter() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/models/router.go b/pkg/models/router.go index b7f417d..f652a40 100644 --- a/pkg/models/router.go +++ b/pkg/models/router.go @@ -14,11 +14,11 @@ type GetSpecificRouterResp struct { type CreateRouterResp struct { Success bool `json:"success"` - ID int `json:"id"` + ID int `json:"id" tf:"id,computed"` } type GetNetworkRouter struct { - ID int `json:"id"` + ID int `json:"id" tf:"id,computed"` Code string `json:"code"` Name string `json:"name"` Description interface{} `json:"description"` @@ -30,7 +30,7 @@ type GetNetworkRouter struct { Enabled bool `json:"enabled"` ExternalIP interface{} `json:"externalIp"` ExternalID string `json:"externalId"` - ProviderID string `json:"providerId"` + ProviderID string `json:"providerId" tf:"provider_id,computed"` Type IDModel `json:"type"` NetworkServer IDModel `json:"networkServer"` Zone IDModel `json:"zone"` @@ -45,14 +45,16 @@ type CreateRouterRequest struct { } type CreateRouterRequestRouter struct { + ID int `json:"-" tf:"id,computed"` Name string `json:"name" tf:"name"` - Type IDModel `json:"type"` + Type IDModel `json:"type,omitempty"` TypeID int `json:"-" tf:"type_id,computed"` Enabled bool `json:"enabled" tf:"enable"` - Site IDStringModel `json:"site"` + Site IDStringModel `json:"site,omitempty"` GroupID string `json:"-" tf:"group_id"` - NetworkServer IDModel `json:"networkServer"` + NetworkServer IDModel `json:"networkServer,omitempty"` NetworkServerID int `json:"-" tf:"network_server_id,computed"` + EnableBGP bool `json:"enableBgp"` Config CreateRouterRequestConfig `json:"config"` // for tftags parsing @@ -64,8 +66,7 @@ type CreateRouterRequestConfig struct { EdgeCluster string `json:"edgeCluster,omitempty"` HaMode string `json:"haMode,omitempty"` FailOver string `json:"failOver,omitempty"` - Tier0Gateways string `json:"tier0_gateway"` - EnableBgp bool `json:"enableBgp"` + Tier0Gateways string `json:"tier0Gateway,omitempty"` CreateRouterTier0Config } @@ -77,7 +78,6 @@ type CreateRouterTier0Config struct { TfEdgeCluster string `json:"-" tf:"edge_cluster"` TfHaMode string `json:"-" tf:"ha_mode"` TfFailOver string `json:"-" tf:"fail_over"` - TfEnableBgp bool `json:"-" tf:"enable_bgp"` TfBGP Bgp `json:"-" tf:"bgp,sub"` TfRRTier0 RouteRedistributionTier0 `json:"-" tf:"route_redistribution_tier0,sub"` TfRRTier1 RouteRedistributionTier1 `json:"-" tf:"route_redistribution_tier1,sub"` @@ -85,47 +85,55 @@ type CreateRouterTier0Config struct { type CreateRouterTier1Config struct { TfEdgeCluster string `json:"-" tf:"edge_cluster"` - TfTier0Gateways string `json:"-" tf:"tier0_gateway"` + TfTier0Gateways string `json:"-" tf:"tier0_gateway,omitempty"` TfRouteAdvertisement RouteAdvertisement `json:"-" tf:"route_advertisement,sub"` } type RouteRedistributionTier0 struct { - TIER0STATIC bool `json:"TIER0_STATIC,omitempty" tf:"tier0_static"` - TIER0NAT bool `json:"TIER0_NAT,omitempty" tf:"tier0_nat"` - TIER0IPSECLOCALIP bool `json:"TIER0_IPSEC_LOCAL_IP,omitempty" tf:"tier0_ipsec_local_ip"` - TIER0DNSFORWARDERIP bool `json:"TIER0_DNS_FORWARDER_IP,omitempty" tf:"tier0_dns_forwarder_ip"` - TIER0SERVICEINTERFACE bool `json:"TIER0_SERVICE_INTERFACE,omitempty" tf:"tier0_service_interface"` - TIER0EXTERNALINTERFACE bool `json:"TIER0_EXTERNAL_INTERFACE,omitempty" tf:"tier0_external_interface"` - TIER0LOOPBACKINTERFACE bool `json:"TIER0_LOOPBACK_INTERFACE,omitempty" tf:"tier0_loopback_interface"` - TIER0SEGMENT bool `json:"TIER0_SEGMENT,omitempty" tf:"tier0_segment"` -} - -type RouteAdvertisement struct { - Tier1Connected bool `json:"TIER1_CONNECTED,omitempty" tf:"tier1_connected"` - Tier1StaticRoutes bool `json:"TIER1_STATIC_ROUTES,omitempty" tf:"tier1_static_routes"` - Tier0Gateway string `json:"tier0Gateway,omitempty" tf:"tier0gateway"` - TIER1DNSFORWARDERIP bool `json:"TIER1_DNS_FORWARDER_IP,omitempty" tf:"tier1_dns_forwarder_ip"` - TIER1STATIC bool `json:"TIER1_STATIC,omitempty" tf:"tier1_static"` - TIER1LBVIP bool `json:"TIER1_LB_VIP,omitempty" tf:"tier1_lb_vip"` - TIER1NAT bool `json:"TIER1_NAT,omitempty" tf:"tier1_nat"` - TIER1LBSNAT bool `json:"TIER1_LB_SNAT,omitempty" tf:"tier1_lb_snat"` - TIER1IPSECLOCALENDPOINT bool `json:"TIER1_IPSEC_LOCAL_ENDPOINT,omitempty" tf:"tier1_ipsec_local_endpoint"` + TIER0STATIC bool `json:"TIER0_STATIC" tf:"tier0_static"` + TIER0NAT bool `json:"TIER0_NAT" tf:"tier0_nat"` + TIER0IPSECLOCALIP bool `json:"TIER0_IPSEC_LOCAL_IP" tf:"tier0_ipsec_local_ip"` + TIER0DNSFORWARDERIP bool `json:"TIER0_DNS_FORWARDER_IP" tf:"tier0_dns_forwarder_ip"` + TIER0SERVICEINTERFACE bool `json:"TIER0_SERVICE_INTERFACE" tf:"tier0_service_interface"` + TIER0EXTERNALINTERFACE bool `json:"TIER0_EXTERNAL_INTERFACE" tf:"tier0_external_interface"` + TIER0LOOPBACKINTERFACE bool `json:"TIER0_LOOPBACK_INTERFACE" tf:"tier0_loopback_interface"` + TIER0SEGMENT bool `json:"TIER0_SEGMENT" tf:"tier0_segment"` } type RouteRedistributionTier1 struct { - TIER1SERVICEINTERFACE bool `json:"TIER1_SERVICE_INTERFACE,omitempty" tf:"tier1_service_interface"` - TIER1SEGMENT bool `json:"TIER1_SEGMENT,omitempty" tf:"tier1_segment"` + TIER1SERVICEINTERFACE bool `json:"TIER1_SERVICE_INTERFACE," tf:"tier1_service_interface"` + TIER1SEGMENT bool `json:"TIER1_SEGMENT" tf:"tier1_segment"` RouteAdvertisement + Tier1Connected bool `json:"-" tf:"tier1_connected"` + Tier1StaticRoutes bool `json:"-" tf:"tier1_static_routes"` + TIER1DNSFORWARDERIP bool `json:"-" tf:"tier1_dns_forwarder_ip"` + TIER1STATIC bool `json:"-" tf:"tier1_static"` + TIER1LBVIP bool `json:"-" tf:"tier1_lb_vip"` + TIER1NAT bool `json:"-" tf:"tier1_nat"` + TIER1LBSNAT bool `json:"-" tf:"tier1_lb_snat"` + TIER1IPSECLOCALENDPOINT bool `json:"-" tf:"tier1_ipsec_local_endpoint"` +} + +type RouteAdvertisement struct { + Tier1Connected bool `json:"TIER1_CONNECTED" tf:"tier1_connected"` + Tier1StaticRoutes bool `json:"TIER1_STATIC_ROUTES" tf:"tier1_static_routes"` + TIER1DNSFORWARDERIP bool `json:"TIER1_DNS_FORWARDER_IP" tf:"tier1_dns_forwarder_ip"` + TIER1STATIC bool `json:"TIER1_STATIC" tf:"tier1_static"` + TIER1LBVIP bool `json:"TIER1_LB_VIP" tf:"tier1_lb_vip"` + TIER1NAT bool `json:"TIER1_NAT" tf:"tier1_nat"` + TIER1LBSNAT bool `json:"TIER1_LB_SNAT" tf:"tier1_lb_snat"` + TIER1IPSECLOCALENDPOINT bool `json:"TIER1_IPSEC_LOCAL_ENDPOINT" tf:"tier1_ipsec_local_endpoint"` } type Bgp struct { LOCALASNUM int `json:"LOCAL_AS_NUM,omitempty" tf:"local_as_num"` - ECMP bool `json:"ECMP,omitempty" tf:"ecmp"` - MULTIPATHRELAX bool `json:"MULTIPATH_RELAX,omitempty" tf:"multipath_relax"` - INTERSRIBGP bool `json:"INTER_SR_IBGP,omitempty" tf:"inter_sr_ibgp"` + ECMP bool `json:"ECMP" tf:"ecmp"` + MULTIPATHRELAX bool `json:"MULTIPATH_RELAX" tf:"multipath_relax"` + INTERSRIBGP bool `json:"INTER_SR_IBGP" tf:"inter_sr_ibgp"` RESTARTMODE string `json:"RESTART_MODE,omitempty" tf:"restart_mode"` RESTARTTIME int `json:"RESTART_TIME,omitempty" tf:"restart_time"` STALEROUTETIME int `json:"STALE_ROUTE_TIME,omitempty" tf:"stale_route_time"` + TfEnableBgp bool `json:"-" tf:"enable_bgp"` } type GetNetworlRouterTypes struct {