Skip to content

Nsgs feature #421

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Jun 6, 2025
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
1 change: 1 addition & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,7 @@ generate-e2e-templates: $(KUSTOMIZE)
$(KUSTOMIZE) build $(OCI_TEMPLATES)/v1beta2/cluster-template-managed-self-managed-nodes --load-restrictor LoadRestrictionsNone > $(OCI_TEMPLATES)/v1beta2/cluster-template-managed-self-managed-nodes.yaml
$(KUSTOMIZE) build $(OCI_TEMPLATES)/v1beta2/cluster-template-machine-with-ipv6 --load-restrictor LoadRestrictionsNone > $(OCI_TEMPLATES)/v1beta2/cluster-template-machine-with-ipv6.yaml
$(KUSTOMIZE) build $(OCI_TEMPLATES)/v1beta2/cluster-template-with-paravirt-bv --load-restrictor LoadRestrictionsNone > $(OCI_TEMPLATES)/v1beta2/cluster-template-with-paravirt-bv.yaml
$(KUSTOMIZE) build $(OCI_TEMPLATES)/v1beta2/cluster-template-self-manage-nsg --load-restrictor LoadRestrictionsNone > $(OCI_TEMPLATES)/v1beta2/cluster-template-self-manage-nsg.yaml

.PHONY: test-e2e-run
test-e2e-run: generate-e2e-templates $(GINKGO) $(ENVSUBST) ## Run e2e tests
Expand Down
10 changes: 10 additions & 0 deletions api/v1beta1/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -854,6 +854,10 @@ type Subnet struct {
ID *string `json:"id,omitempty"`
// Subnet Name.
Name string `json:"name"`
// Skip specifies whether to skip creating subnets. If set to true (default: false) the ID
// must be specified by the user to a valid Subnet ID.
// +optional
Skip bool `json:"skip,omitempty"`
// Subnet CIDR.
// +optional
CIDR string `json:"cidr,omitempty"`
Expand Down Expand Up @@ -906,6 +910,12 @@ type VCN struct {
// +optional
Name string `json:"name"`

// Skip specifies whether to skip creating VCN.
// When is set to true, InternetGateway, NatGateway, ServiceGateway, RouteTable must have also Skip set to true
// If set to true(default: false) the ID must be specified by the user to a valid VCN ID.
// +optional
Skip bool `json:"skip,omitempty"`

// VCN CIDR.
// +optional
// Deprecated, please use NetworkDetails.cidrs
Expand Down
4 changes: 4 additions & 0 deletions api/v1beta1/zz_generated.conversion.go

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

102 changes: 102 additions & 0 deletions api/v1beta2/ocicluster_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,57 @@ func (c *OCICluster) ValidateCreate() (admission.Warnings, error) {
}
}

// If Skip field is true, ID field of VCN should be specified
if c.Spec.NetworkSpec.Vcn.Skip == *common.Bool(true) {
if c.Spec.NetworkSpec.Vcn.ID == common.String("") || c.Spec.NetworkSpec.Vcn.ID == nil {
allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "NetworkSpec.Vcn.ID"), c.Spec.NetworkSpec.Vcn.ID, "field is required"))
}

// If Skip field is True, Skip field of InternetGateway should be true
if c.Spec.NetworkSpec.Vcn.InternetGateway.Skip != *common.Bool(true) {
allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "NetworkSpec.Vcn.InternetGateway.Skip"), c.Spec.NetworkSpec.Vcn.InternetGateway.Skip, "field requires to be true when VCN is skipped"))
}

// If Skip field is True, Skip field of ServiceGateway should be true
if c.Spec.NetworkSpec.Vcn.ServiceGateway.Skip != *common.Bool(true) {
allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "NetworkSpec.Vcn.ServiceGateway.Skip"), c.Spec.NetworkSpec.Vcn.ServiceGateway.Skip, "field requires to be true when VCN is skipped"))
}

// If Skip field is True, Skip field of NATGateway should be true
if c.Spec.NetworkSpec.Vcn.NATGateway.Skip != *common.Bool(true) {
allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "NetworkSpec.Vcn.NATGateway.Skip"), c.Spec.NetworkSpec.Vcn.NATGateway.Skip, "field requires to be true when VCN is skipped"))
}

// If Skip field is True, Skip field of RouteTable should be true
if c.Spec.NetworkSpec.Vcn.RouteTable.Skip != *common.Bool(true) {
allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "NetworkSpec.Vcn.RouteTable.Skip"), c.Spec.NetworkSpec.Vcn.RouteTable.Skip, "field requires to be true when VCN is skipped"))
}

// For each subnet
for _, subnet := range c.Spec.NetworkSpec.Vcn.Subnets {

// if Skip field is true, ID field of Subnet should also be specified
if subnet.Skip == *common.Bool(true) {
if subnet.ID == common.String("") || subnet.ID == nil {
allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "subnet.ID"), subnet.ID, "field is required"))
}
}
// if ID field is specified, Skip field of Subnet should also be true
if subnet.ID != common.String("") {
if subnet.Skip != *common.Bool(true) {
allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "subnet.Skip"), subnet.Skip, "field requires to be true if Subnet ID is specified"))
}
}
}
} else {
// If Skip field of VCN is false, for each subnet in that VCN the Skip field of Subnet cannot be true
for _, subnet := range c.Spec.NetworkSpec.Vcn.Subnets {
if subnet.Skip == *common.Bool(true) {
allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "subnet.Skip"), subnet.Skip, "field cannot be true when VCN is not skipped"))
}
}
}

allErrs = append(allErrs, c.validate(nil)...)

if len(allErrs) == 0 {
Expand Down Expand Up @@ -133,6 +184,57 @@ func (c *OCICluster) ValidateUpdate(old runtime.Object) (admission.Warnings, err
allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "compartmentId"), c.Spec.CompartmentId, "field is immutable"))
}

// If Skip field is true, ID field of VCN should be specified
if c.Spec.NetworkSpec.Vcn.Skip == *common.Bool(true) {
if c.Spec.NetworkSpec.Vcn.ID == common.String("") || c.Spec.NetworkSpec.Vcn.ID == nil {
allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "NetworkSpec.Vcn.ID"), c.Spec.NetworkSpec.Vcn.ID, "field is required"))
}

// If Skip field is True, Skip field of InternetGateway should be true
if c.Spec.NetworkSpec.Vcn.InternetGateway.Skip != *common.Bool(true) {
allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "NetworkSpec.Vcn.InternetGateway.Skip"), c.Spec.NetworkSpec.Vcn.InternetGateway.Skip, "field requires to be true when VCN is skipped"))
}

// If Skip field is True, Skip field of ServiceGateway should be true
if c.Spec.NetworkSpec.Vcn.ServiceGateway.Skip != *common.Bool(true) {
allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "NetworkSpec.Vcn.ServiceGateway.Skip"), c.Spec.NetworkSpec.Vcn.ServiceGateway.Skip, "field requires to be true when VCN is skipped"))
}

// If Skip field is True, Skip field of NATGateway should be true
if c.Spec.NetworkSpec.Vcn.NATGateway.Skip != *common.Bool(true) {
allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "NetworkSpec.Vcn.NATGateway.Skip"), c.Spec.NetworkSpec.Vcn.NATGateway.Skip, "field requires to be true when VCN is skipped"))
}

// If Skip field is True, Skip field of RouteTable should be true
if c.Spec.NetworkSpec.Vcn.RouteTable.Skip != *common.Bool(true) {
allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "NetworkSpec.Vcn.RouteTable.Skip"), c.Spec.NetworkSpec.Vcn.RouteTable.Skip, "field requires to be true when VCN is skipped"))
}

// For each subnet
for _, subnet := range c.Spec.NetworkSpec.Vcn.Subnets {

// if Skip field is true, ID field of Subnet should also be specified
if subnet.Skip == *common.Bool(true) {
if subnet.ID == common.String("") || subnet.ID == nil {
allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "subnet.ID"), subnet.ID, "field is required"))
}
}
// if ID field is specified, Skip field of Subnet should also be true
if subnet.ID != common.String("") {
if subnet.Skip != *common.Bool(true) {
allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "subnet.Skip"), subnet.Skip, "field requires to be true if Subnet ID is specified"))
}
}
}
} else {
// If Skip field of VCN is false, for each subnet in that VCN the Skip field of Subnet cannot be true
for _, subnet := range c.Spec.NetworkSpec.Vcn.Subnets {
if subnet.Skip == *common.Bool(true) {
allErrs = append(allErrs, field.Invalid(field.NewPath("spec", "subnet.Skip"), subnet.Skip, "field cannot be true when VCN is not skipped"))
}
}
}

allErrs = append(allErrs, c.validate(oldCluster)...)

if len(allErrs) == 0 {
Expand Down
14 changes: 14 additions & 0 deletions api/v1beta2/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -854,6 +854,10 @@ type Subnet struct {
ID *string `json:"id,omitempty"`
// Subnet Name.
Name string `json:"name"`
// Skip specifies whether to skip creating subnets. If set to true(default: false) the ID
// must be specified by the user to a valid Subnet ID.
// +optional
Skip bool `json:"skip,omitempty"`
// Subnet CIDR.
// +optional
CIDR string `json:"cidr,omitempty"`
Expand Down Expand Up @@ -906,6 +910,12 @@ type VCN struct {
// +optional
Name string `json:"name"`

// Skip specifies whether to skip creating VCN.
// When is set to true, InternetGateway, NatGateway, ServiceGateway, RouteTable must have also Skip set to true
// If set to true(default: false) the ID must be specified by the user to a valid VCN ID.
// +optional
Skip bool `json:"skip,omitempty"`

// VCN CIDR.
// +optional
// Deprecated, please use NetworkDetails.cidrs
Expand Down Expand Up @@ -1125,6 +1135,7 @@ type RemotePeeringConnection struct {
// InternetGateway is used to specify the options for creating internet gateway.
type InternetGateway struct {
// Skip specifies whether to skip creating internet gateway even if any one Subnet is public.
// In case of VCN being Skipped (Skip field of VCN set to true), this field must be true also
// +optional
Skip bool `json:"skip,omitempty"`

Expand All @@ -1136,6 +1147,7 @@ type InternetGateway struct {
// NATGateway is used to specify the options for creating NAT gateway.
type NATGateway struct {
// Skip specifies whether to skip creating NAT gateway even if any one Subnet is private.
// In case of VCN being Skipped (Skip field of VCN set to true), this field must be true also
// +optional
Skip bool `json:"skip,omitempty"`

Expand All @@ -1147,6 +1159,7 @@ type NATGateway struct {
// ServiceGateway is used to specify the options for creating Service gateway.
type ServiceGateway struct {
// Skip specifies whether to skip creating Service gateway.
// In case of VCN being Skipped (Skip field of VCN set to true), this field must be true also
// +optional
Skip bool `json:"skip,omitempty"`

Expand All @@ -1158,6 +1171,7 @@ type ServiceGateway struct {
// RouteTable is used to specify the options for creating Route table.
type RouteTable struct {
// Skip specifies whether to skip creating Route table.
// In case of VCN being Skipped (Skip field of VCN set to true), this field must be true also
// +optional
Skip bool `json:"skip,omitempty"`

Expand Down
8 changes: 8 additions & 0 deletions cloud/scope/nsg_reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ import (
)

func (s *ClusterScope) ReconcileNSG(ctx context.Context) error {
if s.OCIClusterAccessor.GetNetworkSpec().Vcn.NetworkSecurityGroup.Skip {
s.Logger.Info("Skipping Network Security Group reconciliation as per spec")
return nil
}
desiredNSGs := s.OCIClusterAccessor.GetNetworkSpec().Vcn.NetworkSecurityGroup
for _, desiredNSG := range desiredNSGs.List {
nsg, err := s.GetNSG(ctx, *desiredNSG)
Expand Down Expand Up @@ -124,6 +128,10 @@ func (s *ClusterScope) GetNSG(ctx context.Context, spec infrastructurev1beta2.NS
}

func (s *ClusterScope) DeleteNSGs(ctx context.Context) error {
if s.OCIClusterAccessor.GetNetworkSpec().Vcn.NetworkSecurityGroup.Skip {
s.Logger.Info("Skipping Network Security Group reconciliation as per spec")
return nil
}
desiredNSGs := s.OCIClusterAccessor.GetNetworkSpec().Vcn.NetworkSecurityGroup
for _, desiredNSG := range desiredNSGs.List {
nsg, err := s.GetNSG(ctx, *desiredNSG)
Expand Down
8 changes: 8 additions & 0 deletions cloud/scope/service_gateway_reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ import (
)

func (s *ClusterScope) ReconcileServiceGateway(ctx context.Context) error {
if s.OCIClusterAccessor.GetNetworkSpec().Vcn.ServiceGateway.Skip {
s.Logger.Info("Skipping Service Gateway reconciliation as per spec")
return nil
}
if s.IsAllSubnetsPublic() {
s.Logger.Info("All subnets are public, we don't need service gateway")
return nil
Expand Down Expand Up @@ -86,6 +90,10 @@ func (s *ClusterScope) CreateServiceGateway(ctx context.Context) (*string, error
}

func (s *ClusterScope) DeleteServiceGateway(ctx context.Context) error {
if s.OCIClusterAccessor.GetNetworkSpec().Vcn.ServiceGateway.Skip {
s.Logger.Info("Skipping Service Gateway reconciliation as per spec")
return nil
}
sgw, err := s.GetServiceGateway(ctx)
if err != nil && !ociutil.IsNotFound(err) {
return err
Expand Down
8 changes: 8 additions & 0 deletions cloud/scope/subnet_reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ import (
func (s *ClusterScope) ReconcileSubnet(ctx context.Context) error {
desiredSubnets := s.OCIClusterAccessor.GetNetworkSpec().Vcn.Subnets
for _, desiredSubnet := range desiredSubnets {
if desiredSubnet.Skip {
s.Logger.Info("Skipping Subnet reconciliation as per spec")
continue
}
subnet, err := s.GetSubnet(ctx, *desiredSubnet)
if err != nil {
return err
Expand Down Expand Up @@ -188,6 +192,10 @@ func (s *ClusterScope) UpdateSubnet(ctx context.Context, spec infrastructurev1be
func (s *ClusterScope) DeleteSubnets(ctx context.Context) error {
desiredSubnets := s.GetSubnetsSpec()
for _, desiredSubnet := range desiredSubnets {
if desiredSubnet.Skip {
s.Logger.Info("Skipping Subnet reconciliation as per spec")
continue
}
subnet, err := s.GetSubnet(ctx, *desiredSubnet)
if err != nil && !ociutil.IsNotFound(err) {
return err
Expand Down
8 changes: 8 additions & 0 deletions cloud/scope/vcn_reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ import (
)

func (s *ClusterScope) ReconcileVCN(ctx context.Context) error {
if s.OCIClusterAccessor.GetNetworkSpec().Vcn.Skip {
s.Logger.Info("Skipping VCN reconciliation as per spec")
return nil
}
spec := s.OCIClusterAccessor.GetNetworkSpec().Vcn

var err error
Expand Down Expand Up @@ -150,6 +154,10 @@ func (s *ClusterScope) CreateVCN(ctx context.Context, spec infrastructurev1beta2
}

func (s *ClusterScope) DeleteVCN(ctx context.Context) error {
if s.OCIClusterAccessor.GetNetworkSpec().Vcn.Skip {
s.Logger.Info("Skipping VCN reconciliation as per spec")
return nil
}
vcn, err := s.GetVCN(ctx)

if err != nil && !ociutil.IsNotFound(err) {
Expand Down
12 changes: 12 additions & 0 deletions config/crd/bases/infrastructure.cluster.x-k8s.io_ociclusters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,9 @@ spec:
id:
description: VCN OCID.
type: string
skip:
description: Skip specifies whether to skip creating vcn
type: boolean
internetGatewayId:
description: ID of Internet Gateway.
type: string
Expand Down Expand Up @@ -600,6 +603,9 @@ spec:
id:
description: Subnet OCID.
type: string
skip:
description: Skip specifies whether to skip creating subnet
type: boolean
name:
description: Subnet Name.
type: string
Expand Down Expand Up @@ -1408,6 +1414,9 @@ spec:
id:
description: VCN OCID.
type: string
skip:
description: Skip specifies whether to skip creating vcn
type: boolean
internetGateway:
description: Configuration for Internet Gateway.
properties:
Expand Down Expand Up @@ -1881,6 +1890,9 @@ spec:
id:
description: Subnet OCID.
type: string
skip:
description: Skip specifies whether to skip creating subnet
type: boolean
name:
description: Subnet Name.
type: string
Expand Down
Loading