|
| 1 | +/* |
| 2 | +Copyright The Kubernetes Authors. |
| 3 | +
|
| 4 | +Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | +you may not use this file except in compliance with the License. |
| 6 | +You may obtain a copy of the License at |
| 7 | +
|
| 8 | + http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | +
|
| 10 | +Unless required by applicable law or agreed to in writing, software |
| 11 | +distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | +See the License for the specific language governing permissions and |
| 14 | +limitations under the License. |
| 15 | +*/ |
| 16 | + |
| 17 | +package v1 |
| 18 | + |
| 19 | +import ( |
| 20 | + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" |
| 21 | +) |
| 22 | + |
| 23 | +// Protocol defines network protocols supported for GCP firewall. |
| 24 | +type Protocol string |
| 25 | + |
| 26 | +// CIDR defines a IP block. |
| 27 | +// TODO(sugangli) Modify the validation to include IPv6 CIDRs with FW 3.0 support. |
| 28 | +// +kubebuilder:validation:Pattern=`^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(/(3[0-2]|2[0-9]|1[0-9]|[0-9]))?$` |
| 29 | +type CIDR string |
| 30 | + |
| 31 | +// +genclient |
| 32 | +// +genclient:nonNamespaced |
| 33 | +// +kubebuilder:storageversion |
| 34 | +// +kubebuilder:object:root=true |
| 35 | +// +kubebuilder:resource:shortName=gf,scope=Cluster |
| 36 | + |
| 37 | +// GCPFirewall describes a GCP firewall spec that can be used to configure GCE |
| 38 | +// firewalls. A GCPFirewallSpec will correspond 1:1 with a GCE firewall rule. |
| 39 | +type GCPFirewall struct { |
| 40 | + metav1.TypeMeta `json:",inline"` |
| 41 | + metav1.ObjectMeta `json:"metadata,omitempty"` |
| 42 | + |
| 43 | + // Spec is the desired configuration for GCP firewall |
| 44 | + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status |
| 45 | + Spec GCPFirewallSpec `json:"spec,omitempty"` |
| 46 | + |
| 47 | + // Status is the runtime status of this GCP firewall |
| 48 | + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status |
| 49 | + // +kubebuilder:default={conditions: {{type: "Enforced", status: "Unknown", reason:"Pending", message:"Waiting for controller", lastTransitionTime: "1970-01-01T00:00:00Z"}}} |
| 50 | + Status GCPFirewallStatus `json:"status,omitempty"` |
| 51 | +} |
| 52 | + |
| 53 | +// Action defines the rule action of the firewall rule. |
| 54 | +type Action string |
| 55 | + |
| 56 | +const ( |
| 57 | + // ActionAllow is the Allow Action of GCP Firewall Rule |
| 58 | + ActionAllow Action = "ALLOW" |
| 59 | + // ActionDeny is the Deny Action of GCP Firewall Rule. For now, only Allow is supported. |
| 60 | + ActionDeny Action = "DENY" |
| 61 | + // ProtocolTCP is the TCP protocol. |
| 62 | + ProtocolTCP Protocol = "TCP" |
| 63 | + // ProtocolUDP is the UDP protocol. |
| 64 | + ProtocolUDP Protocol = "UDP" |
| 65 | + // ProtocolICMP is the ICMP protocol. |
| 66 | + ProtocolICMP Protocol = "ICMP" |
| 67 | +) |
| 68 | + |
| 69 | +// GCPFirewallSpec provides the specification of a GCPFirewall. |
| 70 | +// The firewall rule apply to the cluster associated targets (network tags or |
| 71 | +// secure tags) which are deduced by the controller. As a result, the specified |
| 72 | +// rule applies to ALL nodes and pods in the cluster. |
| 73 | +type GCPFirewallSpec struct { |
| 74 | + // Rule action of the firewall rule. Only allow action is supported. If not |
| 75 | + // specified, defaults to ALLOW. |
| 76 | + // +optional |
| 77 | + // +kubebuilder:validation:Enum=ALLOW |
| 78 | + // +kubebuilder:default=ALLOW |
| 79 | + Action Action `json:"action"` |
| 80 | + |
| 81 | + // If set to true, the GCPFirewall is not synced by the controller. |
| 82 | + Disabled bool `json:"disabled,omitempty"` |
| 83 | + |
| 84 | + // List of protocol/ ports which needs to be selected by this rule. |
| 85 | + // If this field is empty or missing, this rule matches all protocol/ ports. |
| 86 | + // If this field is present and contains at least one item, then this rule |
| 87 | + // allows traffic only if the traffic matches at least one port in the list. |
| 88 | + // +optional |
| 89 | + Ports []ProtocolPort `json:"ports,omitempty"` |
| 90 | + |
| 91 | + // A collection of sources and destinations to determine which ingress traffic is allowed. |
| 92 | + // If source is nil or empty, the traffic is allowed from all sources (0.0.0.0/0). |
| 93 | + // If destination is nil or empty, the traffic is allowed to all kubernetes cluster entities |
| 94 | + // (nodes, pods and services) from the specified sources. |
| 95 | + // If both are nil, the traffic is allowed from all sources (0.0.00/0) to the cluster entities. |
| 96 | + // +optional |
| 97 | + Ingress *GCPFirewallIngress `json:"ingress,omitempty"` |
| 98 | +} |
| 99 | + |
| 100 | +// GCPFirewallIngress describes a source and a destination for the ingress firewall rule. |
| 101 | +type GCPFirewallIngress struct { |
| 102 | + // Source describes a peer to allow traffic from. |
| 103 | + // +optional |
| 104 | + Source *IngressSource `json:"source,omitempty"` |
| 105 | + // Destination specifies the target of the firewall rule. If this field is empty, |
| 106 | + // this rule allows traffic from specified sources to all kubernetes cluster entities. |
| 107 | + // +optional |
| 108 | + Destination *IngressDestination `json:"destination,omitempty"` |
| 109 | +} |
| 110 | + |
| 111 | +// IngressSource specifies the source of the firewall rules. |
| 112 | +type IngressSource struct { |
| 113 | + // IPBlocks specify the set of source CIDR ranges that the rule applies to. If this field |
| 114 | + // is present and contains at least one item, this rule allows traffic only if |
| 115 | + // the traffic matches at least one item in the list. If this field is empty, |
| 116 | + // this rule allows all sources. |
| 117 | + // Valid example list items are "192.168.1.1/24" or "2001:db9::/64". |
| 118 | + // +optional |
| 119 | + // +kubebuilder:validation:MinItems=1 |
| 120 | + // +kubebuilder:validation:MaxItems=256 |
| 121 | + IPBlocks []CIDR `json:"ipBlocks,omitempty"` |
| 122 | +} |
| 123 | + |
| 124 | +// IngressDestination specifies the target of the firewall rules. The destination entities specified |
| 125 | +// are ANDed with GCE node network tags of the kubernetes cluster. In other words, the traffic |
| 126 | +// is allowed to a destination IP address only if it belongs to one of the cluster nodes. |
| 127 | +type IngressDestination struct { |
| 128 | + // IPBlocks specify the set of destination CIDRs that the rule applies to. If this field |
| 129 | + // is present and contains at least one item, this rule allows traffic only if |
| 130 | + // the traffic matches at least one item in the list. If this field is empty, |
| 131 | + // this rule allows all destinations. |
| 132 | + // Valid example list items are "192.168.1.1/24" or "2001:db9::/64". |
| 133 | + // +optional |
| 134 | + // +kubebuilder:validation:MinItems=1 |
| 135 | + // +kubebuilder:validation:MaxItems=256 |
| 136 | + IPBlocks []CIDR `json:"ipBlocks,omitempty"` |
| 137 | +} |
| 138 | + |
| 139 | +// ProtocolPort describes the protocol and ports to allow traffic on. |
| 140 | +type ProtocolPort struct { |
| 141 | + // The protocol which the traffic must match. |
| 142 | + // +kubebuilder:validation:Enum=TCP;UDP;ICMP;SCTP;AH;ESP |
| 143 | + Protocol Protocol `json:"protocol"` |
| 144 | + |
| 145 | + // StartPort is the starting port of the port range that is selected on the |
| 146 | + // firewall rule targets for the specified protocol. If EndPort is not |
| 147 | + // specified, this is the only port selected. |
| 148 | + // If StartPort is not provided, all ports are matched. |
| 149 | + // +optional |
| 150 | + // +kubebuilder:validation:Minimum=1 |
| 151 | + // +kubebuilder:validation:Maximum=65535 |
| 152 | + StartPort *int32 `json:"startPort,omitempty"` |
| 153 | + |
| 154 | + // EndPort is the last port of the port range that is selected on the firewall |
| 155 | + // rule targets. If StartPort is not specified or greater than this value, then |
| 156 | + // this field is ignored. |
| 157 | + // +optional |
| 158 | + // +kubebuilder:validation:Minimum=1 |
| 159 | + // +kubebuilder:validation:Maximum=65535 |
| 160 | + EndPort *int32 `json:"endPort,omitempty"` |
| 161 | +} |
| 162 | + |
| 163 | +// GCPFirewallStatus is the runtime status of a GCP firewall |
| 164 | +type GCPFirewallStatus struct { |
| 165 | + // Type specifies the underlying GCE firewall implementation type. |
| 166 | + // Takes one of the values from [VPC, REGIONAL, GLOBAL] |
| 167 | + // +optional |
| 168 | + // +kubebuilder:validation:Enum=VPC;REGIONAL;GLOBAL |
| 169 | + Type string `json:"type,omitempty"` |
| 170 | + |
| 171 | + // Resource link for the GCE firewall rule. In case of FW 3.0, this is the GCE |
| 172 | + // Network Firewall Policy resource. |
| 173 | + // +optional |
| 174 | + ResourceURL string `json:"resourceURL"` |
| 175 | + |
| 176 | + // Priority of the GCP firewall rule. |
| 177 | + // +optional |
| 178 | + Priority uint32 `json:"priority"` |
| 179 | + |
| 180 | + // Conditions describe the current condition of the firewall rule. |
| 181 | + // +optional |
| 182 | + // +listType=map |
| 183 | + // +listMapKey=type |
| 184 | + // +kubebuilder:validation:MaxItems=8 |
| 185 | + // +kubebuilder:default={{type: "Enforced", status: "Unknown", reason:"Pending", message:"Waiting for controller", lastTransitionTime: "1970-01-01T00:00:00Z"}} |
| 186 | + Conditions []metav1.Condition `json:"conditions"` |
| 187 | +} |
| 188 | + |
| 189 | +// FirewallRuleConditionType describes a state of a GCE firewall rule. |
| 190 | +type FirewallRuleConditionType string |
| 191 | + |
| 192 | +// FirewallRuleConditionReason specifies the reason for the GCE firewall rule |
| 193 | +// to be in the specified state. |
| 194 | +type FirewallRuleConditionReason string |
| 195 | + |
| 196 | +const ( |
| 197 | + // FirewallRuleConditionEnforced indicates if the firewall rule is enforced. |
| 198 | + FirewallRuleConditionEnforced FirewallRuleConditionType = "Enforced" |
| 199 | + |
| 200 | + // FirewallRuleReasonInvalid is used when the specified configuration is not valid. |
| 201 | + FirewallRuleReasonInvalid FirewallRuleConditionReason = "Invalid" |
| 202 | + |
| 203 | + // FirewallRuleReasonSyncError is used if the sync fails due to an error. |
| 204 | + FirewallRuleReasonSyncError FirewallRuleConditionReason = "SyncError" |
| 205 | + |
| 206 | + // FirewallRuleReasonPending is used when the firewall rule is not synced to |
| 207 | + // GCP and enforced yet. |
| 208 | + FirewallRuleReasonPending FirewallRuleConditionReason = "Pending" |
| 209 | + |
| 210 | + // FirewallRuleReasonXPNPermissionError is used when the controller does not |
| 211 | + // have permission to configure firewalls in the shared VPC project. |
| 212 | + FirewallRuleReasonXPNPermissionError FirewallRuleConditionReason = "XPNPermissionError" |
| 213 | + |
| 214 | + // FirewallRuleReasonSynchronized is used if the firewall rule is synchronized |
| 215 | + // to GCP. |
| 216 | + FirewallRuleReasonSynchronized FirewallRuleConditionReason = "Synchronized" |
| 217 | +) |
| 218 | + |
| 219 | +// +kubebuilder:object:root=true |
| 220 | +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object |
| 221 | + |
| 222 | +// GCPFirewallList contains a list of GCPFirewall resources. |
| 223 | +type GCPFirewallList struct { |
| 224 | + metav1.TypeMeta `json:",inline"` |
| 225 | + // Standard list metadata. |
| 226 | + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata |
| 227 | + // +optional |
| 228 | + metav1.ListMeta `json:"metadata,omitempty"` |
| 229 | + |
| 230 | + // Items is a list of GCP Firewalls. |
| 231 | + Items []GCPFirewall `json:"items"` |
| 232 | +} |
0 commit comments