Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions api/v1beta1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,36 @@ type Network struct {
APIInternalForwardingRule *string `json:"apiInternalForwardingRule,omitempty"`
}

// FirewallSpec contains configuration for the firewall.
type FirewallSpec struct {
// DefaultRulesManagement determines the management policy for the default firewall rules
// created by the controller. DefaultRulesManagement has no effect on user specified firewall
// rules. DefaultRulesManagement has no effect when a HostProject is specified.
// "Managed": The controller will create and manage firewall rules.
// "Unmanaged": The controller will not create or modify any firewall rules. If
// the RulesManagement is changed from Managed to Unmanaged after the firewall rules
// have been created, then the firewall rules will not be deleted.
//
// Defaults to "Managed".
// +optional
// +kubebuilder:default:="Managed"
DefaultRulesManagement RulesManagementPolicy `json:"defaultRulesManagement,omitempty"`
}

// RulesManagementPolicy is a string enum type for managing firewall rules.
// +kubebuilder:validation:Enum=Managed;Unmanaged
type RulesManagementPolicy string

const (
// RulesManagementManaged indicates that the controller should create and manage
// firewall rules. This is the default behavior.
RulesManagementManaged RulesManagementPolicy = "Managed"

// RulesManagementUnmanaged indicates that the controller should not create or manage
// any firewall rules. If rules already exist, they will be left as-is.
RulesManagementUnmanaged RulesManagementPolicy = "Unmanaged"
)

// NetworkSpec encapsulates all things related to a GCP network.
type NetworkSpec struct {
// Name is the name of the network to be used.
Expand Down Expand Up @@ -137,6 +167,10 @@ type NetworkSpec struct {
// +optional
HostProject *string `json:"hostProject,omitempty"`

// Firewall configuration.
// +optional
Firewall FirewallSpec `json:"firewall,omitempty,omitzero"`

// Mtu: Maximum Transmission Unit in bytes. The minimum value for this field is
// 1300 and the maximum value is 8896. The suggested value is 1500, which is
// the default MTU used on the Internet, or 8896 if you want to use Jumbo
Expand Down
16 changes: 16 additions & 0 deletions api/v1beta1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions cloud/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ type ClusterGetter interface {
NetworkName() string
NetworkProject() string
IsSharedVpc() bool
SkipFirewallRuleCreation() bool
Network() *infrav1.Network
AdditionalLabels() infrav1.Labels
FailureDomains() clusterv1.FailureDomains
Expand Down
8 changes: 8 additions & 0 deletions cloud/scope/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,14 @@ func (s *ClusterScope) NetworkProject() string {
return ptr.Deref(s.GCPCluster.Spec.Network.HostProject, s.Project())
}

// SkipFirewallRuleCreation returns whether the spec indicates that firewall rules
// should be created or not. If the RulesManagement for the default firewall rules is
// set to unmanaged or when the cluster will include a shared VPC, the default firewall
// rule creation will be skipped.
func (s *ClusterScope) SkipFirewallRuleCreation() bool {
return (s.GCPCluster.Spec.Network.Firewall.DefaultRulesManagement == infrav1.RulesManagementUnmanaged) || s.IsSharedVpc()
}

// IsSharedVpc returns true If sharedVPC used else , returns false.
func (s *ClusterScope) IsSharedVpc() bool {
return s.NetworkProject() != s.Project()
Expand Down
8 changes: 8 additions & 0 deletions cloud/scope/managedcluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,14 @@ func (s *ManagedClusterScope) NetworkProject() string {
return ptr.Deref(s.GCPManagedCluster.Spec.Network.HostProject, s.Project())
}

// SkipFirewallRuleCreation returns whether the spec indicates that firewall rules
// should be created or not. If the RulesManagement for the default firewall rules is
// set to unmanaged or when the cluster will include a shared VPC, the default firewall
// rule creation will be skipped.
func (s *ManagedClusterScope) SkipFirewallRuleCreation() bool {
return (s.GCPManagedCluster.Spec.Network.Firewall.DefaultRulesManagement == infrav1.RulesManagementUnmanaged) || s.IsSharedVpc()
}

// IsSharedVpc returns true If sharedVPC used else , returns false.
func (s *ManagedClusterScope) IsSharedVpc() bool {
return s.NetworkProject() != s.Project()
Expand Down
4 changes: 2 additions & 2 deletions cloud/services/compute/firewalls/reconcile.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ import (
// Reconcile reconcile cluster firewall compoenents.
func (s *Service) Reconcile(ctx context.Context) error {
log := log.FromContext(ctx)
if s.scope.IsSharedVpc() {
log.V(2).Info("Shared VPC enabled. Ignore Reconciling firewall resources")
if s.scope.SkipFirewallRuleCreation() {
log.V(2).Info("Ignore Reconciling firewall resources")
return nil
}
log.Info("Reconciling firewall resources")
Expand Down
50 changes: 50 additions & 0 deletions cloud/services/compute/firewalls/reconcile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,34 @@ var fakeGCPClusterSharedVPC = &infrav1.GCPCluster{
},
}

var fakeGCPClusterUnmanagedFirewalls = &infrav1.GCPCluster{
ObjectMeta: metav1.ObjectMeta{
Name: "my-cluster",
Namespace: "default",
},
Spec: infrav1.GCPClusterSpec{
Project: "my-proj",
Region: "us-central1",
Network: infrav1.NetworkSpec{
Name: ptr.To("my-network"),
Subnets: infrav1.Subnets{
infrav1.SubnetSpec{
Name: "workers",
CidrBlock: "10.0.0.1/28",
Region: "us-central1",
Purpose: ptr.To[string]("INTERNAL_HTTPS_LOAD_BALANCER"),
},
},
Firewall: infrav1.FirewallSpec{
DefaultRulesManagement: infrav1.RulesManagementUnmanaged,
},
},
},
Status: infrav1.GCPClusterStatus{
Network: infrav1.Network{},
},
}

type testCase struct {
name string
scope func() Scope
Expand Down Expand Up @@ -146,6 +174,18 @@ func TestService_Reconcile(t *testing.T) {
t.Fatal(err)
}

clusterScopeUnmanagedFirewalls, err := scope.NewClusterScope(context.TODO(), scope.ClusterScopeParams{
Client: fakec,
Cluster: fakeCluster,
GCPCluster: fakeGCPClusterUnmanagedFirewalls,
GCPServices: scope.GCPServices{
Compute: &compute.Service{},
},
})
if err != nil {
t.Fatal(err)
}

tests := []testCase{
{
name: "firewall rule does not exist successful create",
Expand Down Expand Up @@ -211,6 +251,16 @@ func TestService_Reconcile(t *testing.T) {
},
},
},
{
name: "firewall return no error using unmanaged firewall settings",
scope: func() Scope { return clusterScopeUnmanagedFirewalls },
mockFirewalls: &cloud.MockFirewalls{
ProjectRouter: &cloud.SingleProjectRouter{ID: "my-proj"},
Objects: map[meta.Key]*cloud.MockFirewallsObj{
*meta.GlobalKey(fmt.Sprintf("allow-%s-healthchecks", fakeGCPCluster.Name)): {},
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Expand Down
20 changes: 20 additions & 0 deletions config/crd/bases/infrastructure.cluster.x-k8s.io_gcpclusters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,26 @@ spec:

Defaults to true.
type: boolean
firewall:
description: Firewall configuration.
properties:
defaultRulesManagement:
default: Managed
description: |-
DefaultRulesManagement determines the management policy for the default firewall rules
created by the controller. DefaultRulesManagement has no effect on user specified firewall
rules. DefaultRulesManagement has no effect when a HostProject is specified.
"Managed": The controller will create and manage firewall rules.
"Unmanaged": The controller will not create or modify any firewall rules. If
the RulesManagement is changed from Managed to Unmanaged after the firewall rules
have been created, then the firewall rules will not be deleted.

Defaults to "Managed".
enum:
- Managed
- Unmanaged
type: string
type: object
hostProject:
description: HostProject is the name of the project hosting the
shared VPC network resources.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,26 @@ spec:

Defaults to true.
type: boolean
firewall:
description: Firewall configuration.
properties:
defaultRulesManagement:
default: Managed
description: |-
DefaultRulesManagement determines the management policy for the default firewall rules
created by the controller. DefaultRulesManagement has no effect on user specified firewall
rules. DefaultRulesManagement has no effect when a HostProject is specified.
"Managed": The controller will create and manage firewall rules.
"Unmanaged": The controller will not create or modify any firewall rules. If
the RulesManagement is changed from Managed to Unmanaged after the firewall rules
have been created, then the firewall rules will not be deleted.

Defaults to "Managed".
enum:
- Managed
- Unmanaged
type: string
type: object
hostProject:
description: HostProject is the name of the project hosting
the shared VPC network resources.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,26 @@ spec:

Defaults to true.
type: boolean
firewall:
description: Firewall configuration.
properties:
defaultRulesManagement:
default: Managed
description: |-
DefaultRulesManagement determines the management policy for the default firewall rules
created by the controller. DefaultRulesManagement has no effect on user specified firewall
rules. DefaultRulesManagement has no effect when a HostProject is specified.
"Managed": The controller will create and manage firewall rules.
"Unmanaged": The controller will not create or modify any firewall rules. If
the RulesManagement is changed from Managed to Unmanaged after the firewall rules
have been created, then the firewall rules will not be deleted.

Defaults to "Managed".
enum:
- Managed
- Unmanaged
type: string
type: object
hostProject:
description: HostProject is the name of the project hosting the
shared VPC network resources.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,26 @@ spec:

Defaults to true.
type: boolean
firewall:
description: Firewall configuration.
properties:
defaultRulesManagement:
default: Managed
description: |-
DefaultRulesManagement determines the management policy for the default firewall rules
created by the controller. DefaultRulesManagement has no effect on user specified firewall
rules. DefaultRulesManagement has no effect when a HostProject is specified.
"Managed": The controller will create and manage firewall rules.
"Unmanaged": The controller will not create or modify any firewall rules. If
the RulesManagement is changed from Managed to Unmanaged after the firewall rules
have been created, then the firewall rules will not be deleted.

Defaults to "Managed".
enum:
- Managed
- Unmanaged
type: string
type: object
hostProject:
description: HostProject is the name of the project hosting
the shared VPC network resources.
Expand Down