Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
K
k3s
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Jacklull
k3s
Commits
2cdaf1f3
Commit
2cdaf1f3
authored
Jun 01, 2017
by
Nick Sardo
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Refactor compute API calls
parent
b631061f
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
281 additions
and
84 deletions
+281
-84
gce.go
pkg/cloudprovider/providers/gce/gce.go
+2
-0
gce_addresses.go
pkg/cloudprovider/providers/gce/gce_addresses.go
+44
-14
gce_backendservice.go
pkg/cloudprovider/providers/gce/gce_backendservice.go
+20
-20
gce_forwardingrule.go
pkg/cloudprovider/providers/gce/gce_forwardingrule.go
+43
-14
gce_healthchecks.go
pkg/cloudprovider/providers/gce/gce_healthchecks.go
+2
-19
gce_instancegroup.go
pkg/cloudprovider/providers/gce/gce_instancegroup.go
+7
-16
gce_instances.go
pkg/cloudprovider/providers/gce/gce_instances.go
+33
-0
gce_targetpool.go
pkg/cloudprovider/providers/gce/gce_targetpool.go
+84
-0
gce_util.go
pkg/cloudprovider/providers/gce/gce_util.go
+15
-0
gce_zones.go
pkg/cloudprovider/providers/gce/gce_zones.go
+31
-1
No files found.
pkg/cloudprovider/providers/gce/gce.go
View file @
2cdaf1f3
...
@@ -78,6 +78,8 @@ const (
...
@@ -78,6 +78,8 @@ const (
// GCECloud is an implementation of Interface, LoadBalancer and Instances for Google Compute Engine.
// GCECloud is an implementation of Interface, LoadBalancer and Instances for Google Compute Engine.
type
GCECloud
struct
{
type
GCECloud
struct
{
// ClusterID contains functionality for getting (and initializing) the ingress-uid. Call GCECloud.Initialize()
// for the cloudprovider to start watching the configmap.
ClusterID
ClusterID
ClusterID
ClusterID
service
*
compute
.
Service
service
*
compute
.
Service
...
...
pkg/cloudprovider/providers/gce/gce_addresses.go
View file @
2cdaf1f3
...
@@ -22,21 +22,20 @@ import (
...
@@ -22,21 +22,20 @@ import (
compute
"google.golang.org/api/compute/v1"
compute
"google.golang.org/api/compute/v1"
)
)
func
new
StaticIPMetricContext
(
request
string
)
*
metricContext
{
func
new
AddressMetricContext
(
request
,
region
string
)
*
metricContext
{
return
&
metricContext
{
return
&
metricContext
{
start
:
time
.
Now
(),
start
:
time
.
Now
(),
attributes
:
[]
string
{
"
staticip_"
+
request
,
unusedMetricLabel
,
unusedMetricLabel
},
attributes
:
[]
string
{
"
address_"
+
request
,
region
,
unusedMetricLabel
},
}
}
}
}
// ReserveGlobal
StaticIP creates a global static IP
.
// ReserveGlobal
Address creates a global address
.
// Caller is allocated a random IP if they do not specify an ipAddress. If an
// Caller is allocated a random IP if they do not specify an ipAddress. If an
// ipAddress is specified, it must belong to the current project, eg: an
// ipAddress is specified, it must belong to the current project, eg: an
// ephemeral IP associated with a global forwarding rule.
// ephemeral IP associated with a global forwarding rule.
func
(
gce
*
GCECloud
)
ReserveGlobalStaticIP
(
name
,
ipAddress
string
)
(
address
*
compute
.
Address
,
err
error
)
{
func
(
gce
*
GCECloud
)
ReserveGlobalAddress
(
addr
*
compute
.
Address
)
(
*
compute
.
Address
,
error
)
{
mc
:=
newStaticIPMetricContext
(
"reserve"
)
mc
:=
newAddressMetricContext
(
"reserve"
,
""
)
op
,
err
:=
gce
.
service
.
GlobalAddresses
.
Insert
(
gce
.
projectID
,
&
compute
.
Address
{
Name
:
name
,
Address
:
ipAddress
})
.
Do
()
op
,
err
:=
gce
.
service
.
GlobalAddresses
.
Insert
(
gce
.
projectID
,
addr
)
.
Do
()
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
mc
.
Observe
(
err
)
return
nil
,
mc
.
Observe
(
err
)
}
}
...
@@ -45,12 +44,12 @@ func (gce *GCECloud) ReserveGlobalStaticIP(name, ipAddress string) (address *com
...
@@ -45,12 +44,12 @@ func (gce *GCECloud) ReserveGlobalStaticIP(name, ipAddress string) (address *com
return
nil
,
err
return
nil
,
err
}
}
return
gce
.
service
.
GlobalAddresses
.
Get
(
gce
.
projectID
,
name
)
.
Do
(
)
return
gce
.
GetGlobalAddress
(
addr
.
Name
)
}
}
// DeleteGlobal
StaticIP deletes a global static IP
by name.
// DeleteGlobal
Address deletes a global address
by name.
func
(
gce
*
GCECloud
)
DeleteGlobal
StaticIP
(
name
string
)
error
{
func
(
gce
*
GCECloud
)
DeleteGlobal
Address
(
name
string
)
error
{
mc
:=
new
StaticIPMetricContext
(
"delete
"
)
mc
:=
new
AddressMetricContext
(
"delete"
,
"
"
)
op
,
err
:=
gce
.
service
.
GlobalAddresses
.
Delete
(
gce
.
projectID
,
name
)
.
Do
()
op
,
err
:=
gce
.
service
.
GlobalAddresses
.
Delete
(
gce
.
projectID
,
name
)
.
Do
()
if
err
!=
nil
{
if
err
!=
nil
{
return
mc
.
Observe
(
err
)
return
mc
.
Observe
(
err
)
...
@@ -58,9 +57,40 @@ func (gce *GCECloud) DeleteGlobalStaticIP(name string) error {
...
@@ -58,9 +57,40 @@ func (gce *GCECloud) DeleteGlobalStaticIP(name string) error {
return
gce
.
waitForGlobalOp
(
op
,
mc
)
return
gce
.
waitForGlobalOp
(
op
,
mc
)
}
}
// GetGlobal
StaticIP returns the global static IP
by name.
// GetGlobal
Address returns the global address
by name.
func
(
gce
*
GCECloud
)
GetGlobal
StaticIP
(
name
string
)
(
*
compute
.
Address
,
error
)
{
func
(
gce
*
GCECloud
)
GetGlobal
Address
(
name
string
)
(
*
compute
.
Address
,
error
)
{
mc
:=
new
StaticIPMetricContext
(
"get
"
)
mc
:=
new
AddressMetricContext
(
"get"
,
"
"
)
v
,
err
:=
gce
.
service
.
GlobalAddresses
.
Get
(
gce
.
projectID
,
name
)
.
Do
()
v
,
err
:=
gce
.
service
.
GlobalAddresses
.
Get
(
gce
.
projectID
,
name
)
.
Do
()
return
v
,
mc
.
Observe
(
err
)
return
v
,
mc
.
Observe
(
err
)
}
}
// ReserveRegionAddress creates a region address
func
(
gce
*
GCECloud
)
ReserveRegionAddress
(
addr
*
compute
.
Address
,
region
string
)
(
*
compute
.
Address
,
error
)
{
mc
:=
newAddressMetricContext
(
"reserve"
,
region
)
op
,
err
:=
gce
.
service
.
Addresses
.
Insert
(
gce
.
projectID
,
region
,
addr
)
.
Do
()
if
err
!=
nil
{
return
nil
,
mc
.
Observe
(
err
)
}
if
err
:=
gce
.
waitForRegionOp
(
op
,
region
,
mc
);
err
!=
nil
{
return
nil
,
err
}
return
gce
.
GetRegionAddress
(
addr
.
Name
,
region
)
}
// DeleteRegionAddress deletes a region address by name.
func
(
gce
*
GCECloud
)
DeleteRegionAddress
(
name
,
region
string
)
error
{
mc
:=
newAddressMetricContext
(
"delete"
,
region
)
op
,
err
:=
gce
.
service
.
Addresses
.
Delete
(
gce
.
projectID
,
region
,
name
)
.
Do
()
if
err
!=
nil
{
return
mc
.
Observe
(
err
)
}
return
gce
.
waitForRegionOp
(
op
,
region
,
mc
)
}
// GetRegionAddress returns the region address by name
func
(
gce
*
GCECloud
)
GetRegionAddress
(
name
,
region
string
)
(
*
compute
.
Address
,
error
)
{
mc
:=
newAddressMetricContext
(
"get"
,
region
)
v
,
err
:=
gce
.
service
.
Addresses
.
Get
(
gce
.
projectID
,
region
,
name
)
.
Do
()
return
v
,
mc
.
Observe
(
err
)
}
pkg/cloudprovider/providers/gce/gce_backendservice.go
View file @
2cdaf1f3
...
@@ -23,23 +23,23 @@ import (
...
@@ -23,23 +23,23 @@ import (
compute
"google.golang.org/api/compute/v1"
compute
"google.golang.org/api/compute/v1"
)
)
func
newBackendServiceMetricContext
(
request
string
)
*
metricContext
{
func
newBackendServiceMetricContext
(
request
,
region
string
)
*
metricContext
{
return
&
metricContext
{
return
&
metricContext
{
start
:
time
.
Now
(),
start
:
time
.
Now
(),
attributes
:
[]
string
{
"backendservice_"
+
request
,
unusedMetricLabel
,
unusedMetricLabel
},
attributes
:
[]
string
{
"backendservice_"
+
request
,
region
,
unusedMetricLabel
},
}
}
}
}
// GetGlobalBackendService retrieves a backend by name.
// GetGlobalBackendService retrieves a backend by name.
func
(
gce
*
GCECloud
)
GetGlobalBackendService
(
name
string
)
(
*
compute
.
BackendService
,
error
)
{
func
(
gce
*
GCECloud
)
GetGlobalBackendService
(
name
string
)
(
*
compute
.
BackendService
,
error
)
{
mc
:=
newBackendServiceMetricContext
(
"get"
)
mc
:=
newBackendServiceMetricContext
(
"get"
,
""
)
v
,
err
:=
gce
.
service
.
BackendServices
.
Get
(
gce
.
projectID
,
name
)
.
Do
()
v
,
err
:=
gce
.
service
.
BackendServices
.
Get
(
gce
.
projectID
,
name
)
.
Do
()
return
v
,
mc
.
Observe
(
err
)
return
v
,
mc
.
Observe
(
err
)
}
}
// UpdateGlobalBackendService applies the given BackendService as an update to an existing service.
// UpdateGlobalBackendService applies the given BackendService as an update to an existing service.
func
(
gce
*
GCECloud
)
UpdateGlobalBackendService
(
bg
*
compute
.
BackendService
)
error
{
func
(
gce
*
GCECloud
)
UpdateGlobalBackendService
(
bg
*
compute
.
BackendService
)
error
{
mc
:=
newBackendServiceMetricContext
(
"update"
)
mc
:=
newBackendServiceMetricContext
(
"update"
,
""
)
op
,
err
:=
gce
.
service
.
BackendServices
.
Update
(
gce
.
projectID
,
bg
.
Name
,
bg
)
.
Do
()
op
,
err
:=
gce
.
service
.
BackendServices
.
Update
(
gce
.
projectID
,
bg
.
Name
,
bg
)
.
Do
()
if
err
!=
nil
{
if
err
!=
nil
{
return
mc
.
Observe
(
err
)
return
mc
.
Observe
(
err
)
...
@@ -50,7 +50,7 @@ func (gce *GCECloud) UpdateGlobalBackendService(bg *compute.BackendService) erro
...
@@ -50,7 +50,7 @@ func (gce *GCECloud) UpdateGlobalBackendService(bg *compute.BackendService) erro
// DeleteGlobalBackendService deletes the given BackendService by name.
// DeleteGlobalBackendService deletes the given BackendService by name.
func
(
gce
*
GCECloud
)
DeleteGlobalBackendService
(
name
string
)
error
{
func
(
gce
*
GCECloud
)
DeleteGlobalBackendService
(
name
string
)
error
{
mc
:=
newBackendServiceMetricContext
(
"delete"
)
mc
:=
newBackendServiceMetricContext
(
"delete"
,
""
)
op
,
err
:=
gce
.
service
.
BackendServices
.
Delete
(
gce
.
projectID
,
name
)
.
Do
()
op
,
err
:=
gce
.
service
.
BackendServices
.
Delete
(
gce
.
projectID
,
name
)
.
Do
()
if
err
!=
nil
{
if
err
!=
nil
{
if
isHTTPErrorCode
(
err
,
http
.
StatusNotFound
)
{
if
isHTTPErrorCode
(
err
,
http
.
StatusNotFound
)
{
...
@@ -64,7 +64,7 @@ func (gce *GCECloud) DeleteGlobalBackendService(name string) error {
...
@@ -64,7 +64,7 @@ func (gce *GCECloud) DeleteGlobalBackendService(name string) error {
// CreateGlobalBackendService creates the given BackendService.
// CreateGlobalBackendService creates the given BackendService.
func
(
gce
*
GCECloud
)
CreateGlobalBackendService
(
bg
*
compute
.
BackendService
)
error
{
func
(
gce
*
GCECloud
)
CreateGlobalBackendService
(
bg
*
compute
.
BackendService
)
error
{
mc
:=
newBackendServiceMetricContext
(
"create"
)
mc
:=
newBackendServiceMetricContext
(
"create"
,
""
)
op
,
err
:=
gce
.
service
.
BackendServices
.
Insert
(
gce
.
projectID
,
bg
)
.
Do
()
op
,
err
:=
gce
.
service
.
BackendServices
.
Insert
(
gce
.
projectID
,
bg
)
.
Do
()
if
err
!=
nil
{
if
err
!=
nil
{
return
mc
.
Observe
(
err
)
return
mc
.
Observe
(
err
)
...
@@ -75,7 +75,7 @@ func (gce *GCECloud) CreateGlobalBackendService(bg *compute.BackendService) erro
...
@@ -75,7 +75,7 @@ func (gce *GCECloud) CreateGlobalBackendService(bg *compute.BackendService) erro
// ListGlobalBackendServices lists all backend services in the project.
// ListGlobalBackendServices lists all backend services in the project.
func
(
gce
*
GCECloud
)
ListGlobalBackendServices
()
(
*
compute
.
BackendServiceList
,
error
)
{
func
(
gce
*
GCECloud
)
ListGlobalBackendServices
()
(
*
compute
.
BackendServiceList
,
error
)
{
mc
:=
newBackendServiceMetricContext
(
"list"
)
mc
:=
newBackendServiceMetricContext
(
"list"
,
""
)
// TODO: use PageToken to list all not just the first 500
// TODO: use PageToken to list all not just the first 500
v
,
err
:=
gce
.
service
.
BackendServices
.
List
(
gce
.
projectID
)
.
Do
()
v
,
err
:=
gce
.
service
.
BackendServices
.
List
(
gce
.
projectID
)
.
Do
()
return
v
,
mc
.
Observe
(
err
)
return
v
,
mc
.
Observe
(
err
)
...
@@ -85,7 +85,7 @@ func (gce *GCECloud) ListGlobalBackendServices() (*compute.BackendServiceList, e
...
@@ -85,7 +85,7 @@ func (gce *GCECloud) ListGlobalBackendServices() (*compute.BackendServiceList, e
// name, in the given instanceGroup. The instanceGroupLink is the fully
// name, in the given instanceGroup. The instanceGroupLink is the fully
// qualified self link of an instance group.
// qualified self link of an instance group.
func
(
gce
*
GCECloud
)
GetGlobalBackendServiceHealth
(
name
string
,
instanceGroupLink
string
)
(
*
compute
.
BackendServiceGroupHealth
,
error
)
{
func
(
gce
*
GCECloud
)
GetGlobalBackendServiceHealth
(
name
string
,
instanceGroupLink
string
)
(
*
compute
.
BackendServiceGroupHealth
,
error
)
{
mc
:=
newBackendServiceMetricContext
(
"get_health"
)
mc
:=
newBackendServiceMetricContext
(
"get_health"
,
""
)
groupRef
:=
&
compute
.
ResourceGroupReference
{
Group
:
instanceGroupLink
}
groupRef
:=
&
compute
.
ResourceGroupReference
{
Group
:
instanceGroupLink
}
v
,
err
:=
gce
.
service
.
BackendServices
.
GetHealth
(
gce
.
projectID
,
name
,
groupRef
)
.
Do
()
v
,
err
:=
gce
.
service
.
BackendServices
.
GetHealth
(
gce
.
projectID
,
name
,
groupRef
)
.
Do
()
return
v
,
mc
.
Observe
(
err
)
return
v
,
mc
.
Observe
(
err
)
...
@@ -93,25 +93,25 @@ func (gce *GCECloud) GetGlobalBackendServiceHealth(name string, instanceGroupLin
...
@@ -93,25 +93,25 @@ func (gce *GCECloud) GetGlobalBackendServiceHealth(name string, instanceGroupLin
// GetRegionBackendService retrieves a backend by name.
// GetRegionBackendService retrieves a backend by name.
func
(
gce
*
GCECloud
)
GetRegionBackendService
(
name
,
region
string
)
(
*
compute
.
BackendService
,
error
)
{
func
(
gce
*
GCECloud
)
GetRegionBackendService
(
name
,
region
string
)
(
*
compute
.
BackendService
,
error
)
{
mc
:=
newBackendServiceMetricContext
(
"get"
)
mc
:=
newBackendServiceMetricContext
(
"get"
,
region
)
v
,
err
:=
gce
.
service
.
RegionBackendServices
.
Get
(
gce
.
projectID
,
region
,
name
)
.
Do
()
v
,
err
:=
gce
.
service
.
RegionBackendServices
.
Get
(
gce
.
projectID
,
region
,
name
)
.
Do
()
return
v
,
mc
.
Observe
(
err
)
return
v
,
mc
.
Observe
(
err
)
}
}
// UpdateRegionBackendService applies the given BackendService as an update to an existing service.
// UpdateRegionBackendService applies the given BackendService as an update to an existing service.
func
(
gce
*
GCECloud
)
UpdateRegionBackendService
(
bg
*
compute
.
BackendService
)
error
{
func
(
gce
*
GCECloud
)
UpdateRegionBackendService
(
bg
*
compute
.
BackendService
,
region
string
)
error
{
mc
:=
newBackendServiceMetricContext
(
"update"
)
mc
:=
newBackendServiceMetricContext
(
"update"
,
region
)
op
,
err
:=
gce
.
service
.
RegionBackendServices
.
Update
(
gce
.
projectID
,
bg
.
R
egion
,
bg
.
Name
,
bg
)
.
Do
()
op
,
err
:=
gce
.
service
.
RegionBackendServices
.
Update
(
gce
.
projectID
,
r
egion
,
bg
.
Name
,
bg
)
.
Do
()
if
err
!=
nil
{
if
err
!=
nil
{
return
mc
.
Observe
(
err
)
return
mc
.
Observe
(
err
)
}
}
return
gce
.
waitForRegionOp
(
op
,
bg
.
R
egion
,
mc
)
return
gce
.
waitForRegionOp
(
op
,
r
egion
,
mc
)
}
}
// DeleteRegionBackendService deletes the given BackendService by name.
// DeleteRegionBackendService deletes the given BackendService by name.
func
(
gce
*
GCECloud
)
DeleteRegionBackendService
(
name
,
region
string
)
error
{
func
(
gce
*
GCECloud
)
DeleteRegionBackendService
(
name
,
region
string
)
error
{
mc
:=
newBackendServiceMetricContext
(
"delete"
)
mc
:=
newBackendServiceMetricContext
(
"delete"
,
region
)
op
,
err
:=
gce
.
service
.
RegionBackendServices
.
Delete
(
gce
.
projectID
,
region
,
name
)
.
Do
()
op
,
err
:=
gce
.
service
.
RegionBackendServices
.
Delete
(
gce
.
projectID
,
region
,
name
)
.
Do
()
if
err
!=
nil
{
if
err
!=
nil
{
if
isHTTPErrorCode
(
err
,
http
.
StatusNotFound
)
{
if
isHTTPErrorCode
(
err
,
http
.
StatusNotFound
)
{
...
@@ -124,19 +124,19 @@ func (gce *GCECloud) DeleteRegionBackendService(name, region string) error {
...
@@ -124,19 +124,19 @@ func (gce *GCECloud) DeleteRegionBackendService(name, region string) error {
}
}
// CreateRegionBackendService creates the given BackendService.
// CreateRegionBackendService creates the given BackendService.
func
(
gce
*
GCECloud
)
CreateRegionBackendService
(
bg
*
compute
.
BackendService
)
error
{
func
(
gce
*
GCECloud
)
CreateRegionBackendService
(
bg
*
compute
.
BackendService
,
region
string
)
error
{
mc
:=
newBackendServiceMetricContext
(
"create"
)
mc
:=
newBackendServiceMetricContext
(
"create"
,
region
)
op
,
err
:=
gce
.
service
.
RegionBackendServices
.
Insert
(
gce
.
projectID
,
bg
.
R
egion
,
bg
)
.
Do
()
op
,
err
:=
gce
.
service
.
RegionBackendServices
.
Insert
(
gce
.
projectID
,
r
egion
,
bg
)
.
Do
()
if
err
!=
nil
{
if
err
!=
nil
{
return
mc
.
Observe
(
err
)
return
mc
.
Observe
(
err
)
}
}
return
gce
.
waitForRegionOp
(
op
,
bg
.
R
egion
,
mc
)
return
gce
.
waitForRegionOp
(
op
,
r
egion
,
mc
)
}
}
// ListRegionBackendServices lists all backend services in the project.
// ListRegionBackendServices lists all backend services in the project.
func
(
gce
*
GCECloud
)
ListRegionBackendServices
(
region
string
)
(
*
compute
.
BackendServiceList
,
error
)
{
func
(
gce
*
GCECloud
)
ListRegionBackendServices
(
region
string
)
(
*
compute
.
BackendServiceList
,
error
)
{
mc
:=
newBackendServiceMetricContext
(
"list"
)
mc
:=
newBackendServiceMetricContext
(
"list"
,
region
)
// TODO: use PageToken to list all not just the first 500
// TODO: use PageToken to list all not just the first 500
v
,
err
:=
gce
.
service
.
RegionBackendServices
.
List
(
gce
.
projectID
,
region
)
.
Do
()
v
,
err
:=
gce
.
service
.
RegionBackendServices
.
List
(
gce
.
projectID
,
region
)
.
Do
()
return
v
,
mc
.
Observe
(
err
)
return
v
,
mc
.
Observe
(
err
)
...
@@ -146,7 +146,7 @@ func (gce *GCECloud) ListRegionBackendServices(region string) (*compute.BackendS
...
@@ -146,7 +146,7 @@ func (gce *GCECloud) ListRegionBackendServices(region string) (*compute.BackendS
// name, in the given instanceGroup. The instanceGroupLink is the fully
// name, in the given instanceGroup. The instanceGroupLink is the fully
// qualified self link of an instance group.
// qualified self link of an instance group.
func
(
gce
*
GCECloud
)
GetRegionalBackendServiceHealth
(
name
,
region
string
,
instanceGroupLink
string
)
(
*
compute
.
BackendServiceGroupHealth
,
error
)
{
func
(
gce
*
GCECloud
)
GetRegionalBackendServiceHealth
(
name
,
region
string
,
instanceGroupLink
string
)
(
*
compute
.
BackendServiceGroupHealth
,
error
)
{
mc
:=
newBackendServiceMetricContext
(
"get_health"
)
mc
:=
newBackendServiceMetricContext
(
"get_health"
,
region
)
groupRef
:=
&
compute
.
ResourceGroupReference
{
Group
:
instanceGroupLink
}
groupRef
:=
&
compute
.
ResourceGroupReference
{
Group
:
instanceGroupLink
}
v
,
err
:=
gce
.
service
.
RegionBackendServices
.
GetHealth
(
gce
.
projectID
,
region
,
name
,
groupRef
)
.
Do
()
v
,
err
:=
gce
.
service
.
RegionBackendServices
.
GetHealth
(
gce
.
projectID
,
region
,
name
,
groupRef
)
.
Do
()
return
v
,
mc
.
Observe
(
err
)
return
v
,
mc
.
Observe
(
err
)
...
...
pkg/cloudprovider/providers/gce/gce_forwardingrule.go
View file @
2cdaf1f3
...
@@ -17,7 +17,6 @@ limitations under the License.
...
@@ -17,7 +17,6 @@ limitations under the License.
package
gce
package
gce
import
(
import
(
"net/http"
"time"
"time"
compute
"google.golang.org/api/compute/v1"
compute
"google.golang.org/api/compute/v1"
...
@@ -44,8 +43,7 @@ func (gce *GCECloud) CreateGlobalForwardingRule(targetProxyLink, ip, name, portR
...
@@ -44,8 +43,7 @@ func (gce *GCECloud) CreateGlobalForwardingRule(targetProxyLink, ip, name, portR
}
}
op
,
err
:=
gce
.
service
.
GlobalForwardingRules
.
Insert
(
gce
.
projectID
,
rule
)
.
Do
()
op
,
err
:=
gce
.
service
.
GlobalForwardingRules
.
Insert
(
gce
.
projectID
,
rule
)
.
Do
()
if
err
!=
nil
{
if
err
!=
nil
{
mc
.
Observe
(
err
)
return
nil
,
mc
.
Observe
(
err
)
return
nil
,
err
}
}
if
err
=
gce
.
waitForGlobalOp
(
op
,
mc
);
err
!=
nil
{
if
err
=
gce
.
waitForGlobalOp
(
op
,
mc
);
err
!=
nil
{
return
nil
,
err
return
nil
,
err
...
@@ -56,13 +54,12 @@ func (gce *GCECloud) CreateGlobalForwardingRule(targetProxyLink, ip, name, portR
...
@@ -56,13 +54,12 @@ func (gce *GCECloud) CreateGlobalForwardingRule(targetProxyLink, ip, name, portR
// SetProxyForGlobalForwardingRule links the given TargetHttp(s)Proxy with the given GlobalForwardingRule.
// SetProxyForGlobalForwardingRule links the given TargetHttp(s)Proxy with the given GlobalForwardingRule.
// targetProxyLink is the SelfLink of a TargetHttp(s)Proxy.
// targetProxyLink is the SelfLink of a TargetHttp(s)Proxy.
func
(
gce
*
GCECloud
)
SetProxyForGlobalForwardingRule
(
f
w
*
compute
.
ForwardingRul
e
,
targetProxyLink
string
)
error
{
func
(
gce
*
GCECloud
)
SetProxyForGlobalForwardingRule
(
f
orwardingRuleNam
e
,
targetProxyLink
string
)
error
{
mc
:=
newForwardingRuleMetricContext
(
"set_proxy"
,
""
)
mc
:=
newForwardingRuleMetricContext
(
"set_proxy"
,
""
)
op
,
err
:=
gce
.
service
.
GlobalForwardingRules
.
SetTarget
(
op
,
err
:=
gce
.
service
.
GlobalForwardingRules
.
SetTarget
(
gce
.
projectID
,
f
w
.
Name
,
&
compute
.
TargetReference
{
Target
:
targetProxyLink
})
.
Do
()
gce
.
projectID
,
f
orwardingRule
Name
,
&
compute
.
TargetReference
{
Target
:
targetProxyLink
})
.
Do
()
if
err
!=
nil
{
if
err
!=
nil
{
mc
.
Observe
(
err
)
return
mc
.
Observe
(
err
)
return
err
}
}
return
gce
.
waitForGlobalOp
(
op
,
mc
)
return
gce
.
waitForGlobalOp
(
op
,
mc
)
...
@@ -73,13 +70,7 @@ func (gce *GCECloud) DeleteGlobalForwardingRule(name string) error {
...
@@ -73,13 +70,7 @@ func (gce *GCECloud) DeleteGlobalForwardingRule(name string) error {
mc
:=
newForwardingRuleMetricContext
(
"delete"
,
""
)
mc
:=
newForwardingRuleMetricContext
(
"delete"
,
""
)
op
,
err
:=
gce
.
service
.
GlobalForwardingRules
.
Delete
(
gce
.
projectID
,
name
)
.
Do
()
op
,
err
:=
gce
.
service
.
GlobalForwardingRules
.
Delete
(
gce
.
projectID
,
name
)
.
Do
()
if
err
!=
nil
{
if
err
!=
nil
{
if
isHTTPErrorCode
(
err
,
http
.
StatusNotFound
)
{
return
mc
.
Observe
(
err
)
mc
.
Observe
(
nil
)
return
nil
}
mc
.
Observe
(
err
)
return
err
}
}
return
gce
.
waitForGlobalOp
(
op
,
mc
)
return
gce
.
waitForGlobalOp
(
op
,
mc
)
...
@@ -99,3 +90,41 @@ func (gce *GCECloud) ListGlobalForwardingRules() (*compute.ForwardingRuleList, e
...
@@ -99,3 +90,41 @@ func (gce *GCECloud) ListGlobalForwardingRules() (*compute.ForwardingRuleList, e
v
,
err
:=
gce
.
service
.
GlobalForwardingRules
.
List
(
gce
.
projectID
)
.
Do
()
v
,
err
:=
gce
.
service
.
GlobalForwardingRules
.
List
(
gce
.
projectID
)
.
Do
()
return
v
,
mc
.
Observe
(
err
)
return
v
,
mc
.
Observe
(
err
)
}
}
// GetRegionForwardingRule returns the RegionalForwardingRule by name & region.
func
(
gce
*
GCECloud
)
GetRegionForwardingRule
(
name
,
region
string
)
(
*
compute
.
ForwardingRule
,
error
)
{
mc
:=
newForwardingRuleMetricContext
(
"get"
,
region
)
v
,
err
:=
gce
.
service
.
ForwardingRules
.
Get
(
gce
.
projectID
,
region
,
name
)
.
Do
()
return
v
,
mc
.
Observe
(
err
)
}
// ListRegionForwardingRules lists all RegionalForwardingRules in the project & region.
func
(
gce
*
GCECloud
)
ListRegionForwardingRules
(
region
string
)
(
*
compute
.
ForwardingRuleList
,
error
)
{
mc
:=
newForwardingRuleMetricContext
(
"list"
,
region
)
// TODO: use PageToken to list all not just the first 500
v
,
err
:=
gce
.
service
.
ForwardingRules
.
List
(
gce
.
projectID
,
region
)
.
Do
()
return
v
,
mc
.
Observe
(
err
)
}
// CreateRegionForwardingRule creates and returns a
// RegionalForwardingRule that points to the given BackendService
func
(
gce
*
GCECloud
)
CreateRegionForwardingRule
(
rule
*
compute
.
ForwardingRule
,
region
string
)
error
{
mc
:=
newForwardingRuleMetricContext
(
"create"
,
region
)
op
,
err
:=
gce
.
service
.
ForwardingRules
.
Insert
(
gce
.
projectID
,
region
,
rule
)
.
Do
()
if
err
!=
nil
{
return
mc
.
Observe
(
err
)
}
return
gce
.
waitForRegionOp
(
op
,
region
,
mc
)
}
// DeleteRegionForwardingRule deletes the RegionalForwardingRule by name & region.
func
(
gce
*
GCECloud
)
DeleteRegionForwardingRule
(
name
,
region
string
)
error
{
mc
:=
newForwardingRuleMetricContext
(
"delete"
,
region
)
op
,
err
:=
gce
.
service
.
ForwardingRules
.
Delete
(
gce
.
projectID
,
region
,
name
)
.
Do
()
if
err
!=
nil
{
return
mc
.
Observe
(
err
)
}
return
gce
.
waitForRegionOp
(
op
,
region
,
mc
)
}
pkg/cloudprovider/providers/gce/gce_healthchecks.go
View file @
2cdaf1f3
...
@@ -17,7 +17,6 @@ limitations under the License.
...
@@ -17,7 +17,6 @@ limitations under the License.
package
gce
package
gce
import
(
import
(
"fmt"
"time"
"time"
"k8s.io/kubernetes/pkg/api/v1"
"k8s.io/kubernetes/pkg/api/v1"
...
@@ -208,28 +207,12 @@ func GetNodesHealthCheckPort() int32 {
...
@@ -208,28 +207,12 @@ func GetNodesHealthCheckPort() int32 {
return
lbNodesHealthCheckPort
return
lbNodesHealthCheckPort
}
}
//
g
etNodesHealthCheckPath returns the health check path used by the GCE load
//
G
etNodesHealthCheckPath returns the health check path used by the GCE load
// balancers (l4) for performing health checks on nodes.
// balancers (l4) for performing health checks on nodes.
func
g
etNodesHealthCheckPath
()
string
{
func
G
etNodesHealthCheckPath
()
string
{
return
nodesHealthCheckPath
return
nodesHealthCheckPath
}
}
// makeNodesHealthCheckName returns name of the health check resource used by
// the GCE load balancers (l4) for performing health checks on nodes.
func
makeNodesHealthCheckName
(
clusterID
string
)
string
{
return
fmt
.
Sprintf
(
"k8s-%v-node"
,
clusterID
)
}
// MakeHealthCheckFirewallName returns the firewall name used by the GCE load
// balancers (l4) for performing health checks.
func
MakeHealthCheckFirewallName
(
clusterID
,
hcName
string
,
isNodesHealthCheck
bool
)
string
{
if
isNodesHealthCheck
{
// TODO: Change below fwName to match the proposed schema: k8s-{clusteriD}-{namespace}-{name}-{shortid}-hc.
return
makeNodesHealthCheckName
(
clusterID
)
+
"-http-hc"
}
return
"k8s-"
+
hcName
+
"-http-hc"
}
// isAtLeastMinNodesHealthCheckVersion checks if a version is higher than
// isAtLeastMinNodesHealthCheckVersion checks if a version is higher than
// `minNodesHealthCheckVersion`.
// `minNodesHealthCheckVersion`.
func
isAtLeastMinNodesHealthCheckVersion
(
vstring
string
)
bool
{
func
isAtLeastMinNodesHealthCheckVersion
(
vstring
string
)
bool
{
...
...
pkg/cloudprovider/providers/gce/gce_instancegroup.go
View file @
2cdaf1f3
...
@@ -81,20 +81,16 @@ func (gce *GCECloud) ListInstancesInInstanceGroup(name string, zone string, stat
...
@@ -81,20 +81,16 @@ func (gce *GCECloud) ListInstancesInInstanceGroup(name string, zone string, stat
// AddInstancesToInstanceGroup adds the given instances to the given
// AddInstancesToInstanceGroup adds the given instances to the given
// instance group.
// instance group.
func
(
gce
*
GCECloud
)
AddInstancesToInstanceGroup
(
name
string
,
zone
string
,
instance
Names
[]
string
)
error
{
func
(
gce
*
GCECloud
)
AddInstancesToInstanceGroup
(
name
string
,
zone
string
,
instance
Refs
[]
*
compute
.
InstanceReference
)
error
{
mc
:=
newInstanceGroupMetricContext
(
"add_instances"
,
zone
)
mc
:=
newInstanceGroupMetricContext
(
"add_instances"
,
zone
)
if
len
(
instance
Name
s
)
==
0
{
if
len
(
instance
Ref
s
)
==
0
{
return
nil
return
nil
}
}
// Adding the same instance twice will result in a 4xx error
instances
:=
[]
*
compute
.
InstanceReference
{}
for
_
,
ins
:=
range
instanceNames
{
instances
=
append
(
instances
,
&
compute
.
InstanceReference
{
Instance
:
makeHostURL
(
gce
.
projectID
,
zone
,
ins
)})
}
op
,
err
:=
gce
.
service
.
InstanceGroups
.
AddInstances
(
op
,
err
:=
gce
.
service
.
InstanceGroups
.
AddInstances
(
gce
.
projectID
,
zone
,
name
,
gce
.
projectID
,
zone
,
name
,
&
compute
.
InstanceGroupsAddInstancesRequest
{
&
compute
.
InstanceGroupsAddInstancesRequest
{
Instances
:
instances
,
Instances
:
instance
Ref
s
,
})
.
Do
()
})
.
Do
()
if
err
!=
nil
{
if
err
!=
nil
{
return
mc
.
Observe
(
err
)
return
mc
.
Observe
(
err
)
...
@@ -105,21 +101,16 @@ func (gce *GCECloud) AddInstancesToInstanceGroup(name string, zone string, insta
...
@@ -105,21 +101,16 @@ func (gce *GCECloud) AddInstancesToInstanceGroup(name string, zone string, insta
// RemoveInstancesFromInstanceGroup removes the given instances from
// RemoveInstancesFromInstanceGroup removes the given instances from
// the instance group.
// the instance group.
func
(
gce
*
GCECloud
)
RemoveInstancesFromInstanceGroup
(
name
string
,
zone
string
,
instance
Names
[]
string
)
error
{
func
(
gce
*
GCECloud
)
RemoveInstancesFromInstanceGroup
(
name
string
,
zone
string
,
instance
Refs
[]
*
compute
.
InstanceReference
)
error
{
mc
:=
newInstanceGroupMetricContext
(
"remove_instances"
,
zone
)
mc
:=
newInstanceGroupMetricContext
(
"remove_instances"
,
zone
)
if
len
(
instance
Name
s
)
==
0
{
if
len
(
instance
Ref
s
)
==
0
{
return
nil
return
nil
}
}
instances
:=
[]
*
compute
.
InstanceReference
{}
for
_
,
ins
:=
range
instanceNames
{
instanceLink
:=
makeHostURL
(
gce
.
projectID
,
zone
,
ins
)
instances
=
append
(
instances
,
&
compute
.
InstanceReference
{
Instance
:
instanceLink
})
}
op
,
err
:=
gce
.
service
.
InstanceGroups
.
RemoveInstances
(
op
,
err
:=
gce
.
service
.
InstanceGroups
.
RemoveInstances
(
gce
.
projectID
,
zone
,
name
,
gce
.
projectID
,
zone
,
name
,
&
compute
.
InstanceGroupsRemoveInstancesRequest
{
&
compute
.
InstanceGroupsRemoveInstancesRequest
{
Instances
:
instances
,
Instances
:
instance
Ref
s
,
})
.
Do
()
})
.
Do
()
if
err
!=
nil
{
if
err
!=
nil
{
return
mc
.
Observe
(
err
)
return
mc
.
Observe
(
err
)
...
...
pkg/cloudprovider/providers/gce/gce_instances.go
View file @
2cdaf1f3
...
@@ -28,6 +28,7 @@ import (
...
@@ -28,6 +28,7 @@ import (
computealpha
"google.golang.org/api/compute/v0.beta"
computealpha
"google.golang.org/api/compute/v0.beta"
compute
"google.golang.org/api/compute/v1"
compute
"google.golang.org/api/compute/v1"
metav1
"k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apimachinery/pkg/util/wait"
"k8s.io/apimachinery/pkg/util/wait"
...
@@ -35,6 +36,10 @@ import (
...
@@ -35,6 +36,10 @@ import (
"k8s.io/kubernetes/pkg/cloudprovider"
"k8s.io/kubernetes/pkg/cloudprovider"
)
)
const
(
defaultZone
=
""
)
func
newInstancesMetricContext
(
request
,
zone
string
)
*
metricContext
{
func
newInstancesMetricContext
(
request
,
zone
string
)
*
metricContext
{
return
&
metricContext
{
return
&
metricContext
{
start
:
time
.
Now
(),
start
:
time
.
Now
(),
...
@@ -42,6 +47,34 @@ func newInstancesMetricContext(request, zone string) *metricContext {
...
@@ -42,6 +47,34 @@ func newInstancesMetricContext(request, zone string) *metricContext {
}
}
}
}
func
splitNodesByZone
(
nodes
[]
*
v1
.
Node
)
map
[
string
][]
*
v1
.
Node
{
zones
:=
make
(
map
[
string
][]
*
v1
.
Node
)
for
_
,
n
:=
range
nodes
{
z
:=
getZone
(
n
)
if
z
!=
defaultZone
{
zones
[
z
]
=
append
(
zones
[
z
],
n
)
}
}
return
zones
}
func
getZone
(
n
*
v1
.
Node
)
string
{
zone
,
ok
:=
n
.
Labels
[
metav1
.
LabelZoneFailureDomain
]
if
!
ok
{
return
defaultZone
}
return
zone
}
// ToInstanceReferences returns instance references by links
func
(
gce
*
GCECloud
)
ToInstanceReferences
(
zone
string
,
instanceNames
[]
string
)
(
refs
[]
*
compute
.
InstanceReference
)
{
for
_
,
ins
:=
range
instanceNames
{
instanceLink
:=
makeHostURL
(
gce
.
projectID
,
zone
,
ins
)
refs
=
append
(
refs
,
&
compute
.
InstanceReference
{
Instance
:
instanceLink
})
}
return
refs
}
// NodeAddresses is an implementation of Instances.NodeAddresses.
// NodeAddresses is an implementation of Instances.NodeAddresses.
func
(
gce
*
GCECloud
)
NodeAddresses
(
_
types
.
NodeName
)
([]
v1
.
NodeAddress
,
error
)
{
func
(
gce
*
GCECloud
)
NodeAddresses
(
_
types
.
NodeName
)
([]
v1
.
NodeAddress
,
error
)
{
internalIP
,
err
:=
metadata
.
Get
(
"instance/network-interfaces/0/ip"
)
internalIP
,
err
:=
metadata
.
Get
(
"instance/network-interfaces/0/ip"
)
...
...
pkg/cloudprovider/providers/gce/gce_targetpool.go
0 → 100644
View file @
2cdaf1f3
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package
gce
import
(
"time"
compute
"google.golang.org/api/compute/v1"
)
func
newTargetPoolMetricContext
(
request
,
region
string
)
*
metricContext
{
return
&
metricContext
{
start
:
time
.
Now
(),
attributes
:
[]
string
{
"targetpool_"
+
request
,
region
,
unusedMetricLabel
},
}
}
// GetTargetPool returns the TargetPool by name.
func
(
gce
*
GCECloud
)
GetTargetPool
(
name
,
region
string
)
(
*
compute
.
TargetPool
,
error
)
{
mc
:=
newTargetPoolMetricContext
(
"get"
,
region
)
v
,
err
:=
gce
.
service
.
TargetPools
.
Get
(
gce
.
projectID
,
region
,
name
)
.
Do
()
return
v
,
mc
.
Observe
(
err
)
}
// CreateTargetPool creates the passed TargetPool
func
(
gce
*
GCECloud
)
CreateTargetPool
(
tp
*
compute
.
TargetPool
,
region
string
)
(
*
compute
.
TargetPool
,
error
)
{
mc
:=
newTargetPoolMetricContext
(
"create"
,
region
)
op
,
err
:=
gce
.
service
.
TargetPools
.
Insert
(
gce
.
projectID
,
region
,
tp
)
.
Do
()
if
err
!=
nil
{
return
nil
,
mc
.
Observe
(
err
)
}
if
err
:=
gce
.
waitForRegionOp
(
op
,
region
,
mc
);
err
!=
nil
{
return
nil
,
err
}
return
gce
.
GetTargetPool
(
tp
.
Name
,
region
)
}
// DeleteTargetPool deletes TargetPool by name.
func
(
gce
*
GCECloud
)
DeleteTargetPool
(
name
,
region
string
)
error
{
mc
:=
newTargetPoolMetricContext
(
"delete"
,
region
)
op
,
err
:=
gce
.
service
.
TargetPools
.
Delete
(
gce
.
projectID
,
region
,
name
)
.
Do
()
if
err
!=
nil
{
return
mc
.
Observe
(
err
)
}
return
gce
.
waitForRegionOp
(
op
,
region
,
mc
)
}
// AddInstancesToTargetPool adds instances by link to the TargetPool
func
(
gce
*
GCECloud
)
AddInstancesToTargetPool
(
name
,
region
string
,
instanceRefs
[]
*
compute
.
InstanceReference
)
error
{
add
:=
&
compute
.
TargetPoolsAddInstanceRequest
{
Instances
:
instanceRefs
}
mc
:=
newTargetPoolMetricContext
(
"add_instances"
,
region
)
op
,
err
:=
gce
.
service
.
TargetPools
.
AddInstance
(
gce
.
projectID
,
region
,
name
,
add
)
.
Do
()
if
err
!=
nil
{
return
mc
.
Observe
(
err
)
}
return
gce
.
waitForRegionOp
(
op
,
region
,
mc
)
}
// RemoveInstancesToTargetPool removes instances by link to the TargetPool
func
(
gce
*
GCECloud
)
RemoveInstancesFromTargetPool
(
name
,
region
string
,
instanceRefs
[]
*
compute
.
InstanceReference
)
error
{
remove
:=
&
compute
.
TargetPoolsRemoveInstanceRequest
{
Instances
:
instanceRefs
}
mc
:=
newTargetPoolMetricContext
(
"remove_instances"
,
region
)
op
,
err
:=
gce
.
service
.
TargetPools
.
RemoveInstance
(
gce
.
projectID
,
region
,
name
,
remove
)
.
Do
()
if
err
!=
nil
{
return
mc
.
Observe
(
err
)
}
return
gce
.
waitForRegionOp
(
op
,
region
,
mc
)
}
pkg/cloudprovider/providers/gce/gce_util.go
View file @
2cdaf1f3
...
@@ -134,3 +134,18 @@ func equalStringSets(x, y []string) bool {
...
@@ -134,3 +134,18 @@ func equalStringSets(x, y []string) bool {
yString
:=
sets
.
NewString
(
y
...
)
yString
:=
sets
.
NewString
(
y
...
)
return
xString
.
Equal
(
yString
)
return
xString
.
Equal
(
yString
)
}
}
func
isNotFound
(
err
error
)
bool
{
return
isHTTPErrorCode
(
err
,
http
.
StatusNotFound
)
}
func
ignoreNotFound
(
err
error
)
error
{
if
err
==
nil
||
isNotFound
(
err
)
{
return
nil
}
return
err
}
func
isNotFoundOrInUse
(
err
error
)
bool
{
return
isNotFound
(
err
)
||
isInUsedByError
(
err
)
}
pkg/cloudprovider/providers/gce/gce_zones.go
View file @
2cdaf1f3
...
@@ -16,11 +16,41 @@ limitations under the License.
...
@@ -16,11 +16,41 @@ limitations under the License.
package
gce
package
gce
import
"k8s.io/kubernetes/pkg/cloudprovider"
import
(
"fmt"
"time"
compute
"google.golang.org/api/compute/v1"
"k8s.io/kubernetes/pkg/cloudprovider"
)
func
newZonesMetricContext
(
request
,
region
string
)
*
metricContext
{
return
&
metricContext
{
start
:
time
.
Now
(),
attributes
:
[]
string
{
"zones_"
+
request
,
region
,
unusedMetricLabel
},
}
}
// GetZone creates a cloudprovider.Zone of the current zone and region
func
(
gce
*
GCECloud
)
GetZone
()
(
cloudprovider
.
Zone
,
error
)
{
func
(
gce
*
GCECloud
)
GetZone
()
(
cloudprovider
.
Zone
,
error
)
{
return
cloudprovider
.
Zone
{
return
cloudprovider
.
Zone
{
FailureDomain
:
gce
.
localZone
,
FailureDomain
:
gce
.
localZone
,
Region
:
gce
.
region
,
Region
:
gce
.
region
,
},
nil
},
nil
}
}
// ListZonesInRegion returns all zones in a GCP region
func
(
gce
*
GCECloud
)
ListZonesInRegion
(
region
string
)
([]
*
compute
.
Zone
,
error
)
{
mc
:=
newZonesMetricContext
(
"list"
,
region
)
filter
:=
fmt
.
Sprintf
(
"region eq %v"
,
gce
.
getRegionLink
(
region
))
list
,
err
:=
gce
.
service
.
Zones
.
List
(
gce
.
projectID
)
.
Filter
(
filter
)
.
Do
()
if
err
!=
nil
{
return
nil
,
mc
.
Observe
(
err
)
}
return
list
.
Items
,
mc
.
Observe
(
err
)
}
func
(
gce
*
GCECloud
)
getRegionLink
(
region
string
)
string
{
return
fmt
.
Sprintf
(
"https://www.googleapis.com/compute/v1/projects/%v/regions/%v"
,
gce
.
projectID
,
region
)
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment