Skip to content

Commit

Permalink
Add shared VPC networking
Browse files Browse the repository at this point in the history
  • Loading branch information
bighiro committed Jul 27, 2023
1 parent 56c32ce commit 53a8cb0
Show file tree
Hide file tree
Showing 12 changed files with 95 additions and 4 deletions.
3 changes: 3 additions & 0 deletions api/v1beta1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ type NetworkSpec struct {
// +optional
Name *string `json:"name,omitempty"`

// HostProject is the name of the host project hosting the shared VPC network
HostProject *string `json:"hostProject,omitempty"`

// AutoCreateSubnetworks: When set to true, the VPC network is created
// in "auto" mode. When set to false, the VPC network is created in
// "custom" mode.
Expand Down
3 changes: 3 additions & 0 deletions cloud/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ type ReconcilerWithResult interface {
// Client is an interface which can get cloud client.
type Client interface {
Cloud() Cloud
NetworkCloud() Cloud
}

// ClusterGetter is an interface which can get cluster information.
Expand All @@ -56,6 +57,8 @@ type ClusterGetter interface {
Name() string
Namespace() string
NetworkName() string
NetworkProject() string
IsSharedVpc() bool
Network() *infrav1.Network
AdditionalLabels() infrav1.Labels
FailureDomains() clusterv1.FailureDomains
Expand Down
20 changes: 19 additions & 1 deletion cloud/scope/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,11 @@ func (s *ClusterScope) Cloud() cloud.Cloud {
return newCloud(s.Project(), s.GCPServices)
}

// NetworkCloud returns initialized cloud.
func (s *ClusterScope) NetworkCloud() cloud.Cloud {
return newCloud(s.NetworkProject(), s.GCPServices)
}

// Project returns the current project name.
func (s *ClusterScope) Project() string {
return s.GCPCluster.Spec.Project
Expand All @@ -115,9 +120,22 @@ func (s *ClusterScope) NetworkName() string {
return pointer.StringDeref(s.GCPCluster.Spec.Network.Name, "default")
}

// NetworkProject returns the cluster network unique identifier.
func (s *ClusterScope) NetworkProject() string {
return pointer.StringDeref(s.GCPCluster.Spec.Network.HostProject, s.GCPCluster.Spec.Project)
}

// IsSharedVpc returns true If sharedVPC used else , returns false.
func (s *ClusterScope) IsSharedVpc() bool {
if s.NetworkProject() != s.Project() {

Check failure on line 130 in cloud/scope/cluster.go

View workflow job for this annotation

GitHub Actions / lint

S1008: should use 'return s.NetworkProject() != s.Project()' instead of 'if s.NetworkProject() != s.Project() { return true }; return false' (gosimple)
return true
}
return false
}

// NetworkLink returns the partial URL for the network.
func (s *ClusterScope) NetworkLink() string {
return fmt.Sprintf("projects/%s/global/networks/%s", s.Project(), s.NetworkName())
return fmt.Sprintf("projects/%s/global/networks/%s", s.NetworkProject(), s.NetworkName())
}

// Network returns the cluster network object.
Expand Down
9 changes: 7 additions & 2 deletions cloud/scope/machine.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,11 @@ func (m *MachineScope) Cloud() cloud.Cloud {
return m.ClusterGetter.Cloud()
}

// NetworkCloud returns initialized network cloud

Check failure on line 97 in cloud/scope/machine.go

View workflow job for this annotation

GitHub Actions / lint

Comment should end in a period (godot)
func (m *MachineScope) NetworkCloud() cloud.Cloud {
return m.ClusterGetter.NetworkCloud()
}

// Zone returns the FailureDomain for the GCPMachine.
func (m *MachineScope) Zone() string {
if m.Machine.Spec.FailureDomain == nil {
Expand Down Expand Up @@ -276,7 +281,7 @@ func (m *MachineScope) InstanceAdditionalDiskSpec() []*compute.AttachedDisk {
// InstanceNetworkInterfaceSpec returns compute network interface spec.
func (m *MachineScope) InstanceNetworkInterfaceSpec() *compute.NetworkInterface {
networkInterface := &compute.NetworkInterface{
Network: path.Join("projects", m.ClusterGetter.Project(), "global", "networks", m.ClusterGetter.NetworkName()),
Network: path.Join("projects", m.ClusterGetter.NetworkProject(), "global", "networks", m.ClusterGetter.NetworkName()),
}

if m.GCPMachine.Spec.PublicIP != nil && *m.GCPMachine.Spec.PublicIP {
Expand All @@ -289,7 +294,7 @@ func (m *MachineScope) InstanceNetworkInterfaceSpec() *compute.NetworkInterface
}

if m.GCPMachine.Spec.Subnet != nil {
networkInterface.Subnetwork = path.Join("regions", m.ClusterGetter.Region(), "subnetworks", *m.GCPMachine.Spec.Subnet)
networkInterface.Subnetwork = path.Join("projects", m.ClusterGetter.NetworkProject(), "regions", m.ClusterGetter.Region(), "subnetworks", *m.GCPMachine.Spec.Subnet)
}

return networkInterface
Expand Down
20 changes: 19 additions & 1 deletion cloud/scope/managedcluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,11 @@ func (s *ManagedClusterScope) Cloud() cloud.Cloud {
return newCloud(s.Project(), s.GCPServices)
}

// NetworkCloud returns initialized cloud.
func (s *ManagedClusterScope) NetworkCloud() cloud.Cloud {
return newCloud(s.NetworkProject(), s.GCPServices)
}

// Project returns the current project name.
func (s *ManagedClusterScope) Project() string {
return s.GCPManagedCluster.Spec.Project
Expand All @@ -118,9 +123,22 @@ func (s *ManagedClusterScope) NetworkName() string {
return pointer.StringDeref(s.GCPManagedCluster.Spec.Network.Name, "default")
}

// NetworkProject returns the cluster network unique identifier.
func (s *ManagedClusterScope) NetworkProject() string {
return pointer.StringDeref(s.GCPManagedCluster.Spec.Network.HostProject, s.GCPManagedCluster.Spec.Project)
}

// IsSharedVpc returns the cluster network unique identifier.
func (s *ManagedClusterScope) IsSharedVpc() bool {
if s.NetworkProject() != s.Project() {

Check failure on line 133 in cloud/scope/managedcluster.go

View workflow job for this annotation

GitHub Actions / lint

S1008: should use 'return s.NetworkProject() != s.Project()' instead of 'if s.NetworkProject() != s.Project() { return true }; return false' (gosimple)
return true
}
return false
}

// NetworkLink returns the partial URL for the network.
func (s *ManagedClusterScope) NetworkLink() string {
return fmt.Sprintf("projects/%s/global/networks/%s", s.Project(), s.NetworkName())
return fmt.Sprintf("projects/%s/global/networks/%s", s.NetworkProject(), s.NetworkName())
}

// Network returns the cluster network object.
Expand Down
8 changes: 8 additions & 0 deletions cloud/services/compute/firewalls/reconcile.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ import (
// Reconcile reconcile cluster firewall compoenents.
func (s *Service) Reconcile(ctx context.Context) error {
log := log.FromContext(ctx)
if s.scope.IsSharedVpc() {
log.Info("VPC enabled. Ignore Reconciling firewall resources")
return nil
}
log.Info("Reconciling firewall resources")
for _, spec := range s.scope.FirewallRulesSpec() {
log.V(2).Info("Looking firewall", "name", spec.Name)
Expand All @@ -49,6 +53,10 @@ func (s *Service) Reconcile(ctx context.Context) error {
// Delete delete cluster firewall compoenents.
func (s *Service) Delete(ctx context.Context) error {
log := log.FromContext(ctx)
if s.scope.IsSharedVpc() {
log.Info("VPC enabled. Ignore Deleting firewall resources")
return nil
}
log.Info("Deleting firewall resources")
for _, spec := range s.scope.FirewallRulesSpec() {
log.V(2).Info("Deleting firewall", "name", spec.Name)
Expand Down
9 changes: 9 additions & 0 deletions cloud/services/compute/networks/reconcile.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,11 @@ func (s *Service) Reconcile(ctx context.Context) error {
// Delete delete cluster network components.
func (s *Service) Delete(ctx context.Context) error {
log := log.FromContext(ctx)
if s.scope.IsSharedVpc() {
s.scope.Network().Router = nil
s.scope.Network().SelfLink = nil
return nil
}
log.Info("Deleting network resources")
networkKey := meta.GlobalKey(s.scope.NetworkName())
log.V(2).Info("Looking for network before deleting", "name", networkKey)
Expand Down Expand Up @@ -101,6 +106,10 @@ func (s *Service) createOrGetNetwork(ctx context.Context) (*compute.Network, err
log.Error(err, "Error looking for network", "name", s.scope.NetworkName())
return nil, err
}
if s.scope.IsSharedVpc() {
log.Error(err, "VPC is enabled. Error looking for network", "name", s.scope.NetworkName())
return nil, err
}

log.V(2).Info("Creating a network", "name", s.scope.NetworkName())
if err := s.networks.Insert(ctx, networkKey, s.scope.NetworkSpec()); err != nil {
Expand Down
7 changes: 7 additions & 0 deletions cloud/services/compute/networks/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ var _ cloud.Reconciler = &Service{}

// New returns Service from given scope.
func New(scope Scope) *Service {
if scope.IsSharedVpc() {
return &Service{
scope: scope,
networks: scope.NetworkCloud().Networks(),
routers: scope.NetworkCloud().Routers(),
}
}
return &Service{
scope: scope,
networks: scope.Cloud().Networks(),
Expand Down
8 changes: 8 additions & 0 deletions cloud/services/compute/subnets/reconcile.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ func (s *Service) Reconcile(ctx context.Context) error {
// Delete deletes cluster subnetwork components.
func (s *Service) Delete(ctx context.Context) error {
logger := log.FromContext(ctx)
if s.scope.IsSharedVpc() {
return nil
}
for _, subnetSpec := range s.scope.SubnetSpecs() {
logger.V(2).Info("Deleting a subnet", "name", subnetSpec.Name)
subnetKey := meta.RegionalKey(subnetSpec.Name, s.scope.Region())
Expand Down Expand Up @@ -68,6 +71,11 @@ func (s *Service) createOrGetSubnets(ctx context.Context) ([]*compute.Subnetwork
return subnets, err
}

if s.scope.IsSharedVpc() {
logger.Error(err, "VPC is enabled. Error looking for subnetwork", "name", subnetSpec.Name)
return nil, err
}

// Subnet was not found, let's create it
logger.V(2).Info("Creating a subnet", "name", subnetSpec.Name)
if err := s.subnets.Insert(ctx, subnetKey, subnetSpec); err != nil {
Expand Down
6 changes: 6 additions & 0 deletions cloud/services/compute/subnets/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ var _ cloud.Reconciler = &Service{}

// New returns Service from given scope.
func New(scope Scope) *Service {
if scope.IsSharedVpc() {
return &Service{
scope: scope,
subnets: scope.NetworkCloud().Subnetworks(),
}
}
return &Service{
scope: scope,
subnets: scope.Cloud().Subnetworks(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -563,6 +563,9 @@ spec:
name:
description: Name is the name of the network to be used.
type: string
hostProject:
description: Network host project is the name need of the host project hosting the shared VPC network.
type: string
subnets:
description: Subnets configuration.
items:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,9 @@ spec:
name:
description: Name is the name of the network to be used.
type: string
hostProject:
description: Network host project is the name need of the host project hosting the shared VPC network.
type: string
subnets:
description: Subnets configuration.
items:
Expand Down

0 comments on commit 53a8cb0

Please sign in to comment.