diff --git a/cluster/gce/gci/configure-helper.sh b/cluster/gce/gci/configure-helper.sh index 0b46fe965..2c3b1749a 100755 --- a/cluster/gce/gci/configure-helper.sh +++ b/cluster/gce/gci/configure-helper.sh @@ -958,6 +958,14 @@ EOF use_cloud_config="true" cat <>/etc/gce.conf regional = ${MULTIMASTER} +EOF + fi +# FirewallRulesManagement indicates whethere the firewall rules are +# managed (enabled) or not (disabled) for the provider. + if [[ -n "${FIREWALLRULESMANAGEMENT:-}" ]]; then + use_cloud_config="true" + cat <>/etc/gce.conf +firewall-rules-management = ${FIREWALLRULESMANAGEMENT} EOF fi if [[ -n "${GCE_ALPHA_FEATURES:-}" ]]; then diff --git a/cluster/gce/util.sh b/cluster/gce/util.sh index 5ac51c69a..b20685e99 100755 --- a/cluster/gce/util.sh +++ b/cluster/gce/util.sh @@ -1172,6 +1172,7 @@ KUBE_DOCKER_REGISTRY: $(yaml-quote "${KUBE_DOCKER_REGISTRY:-}") KUBE_ADDON_REGISTRY: $(yaml-quote "${KUBE_ADDON_REGISTRY:-}") MULTIZONE: $(yaml-quote "${MULTIZONE:-}") MULTIMASTER: $(yaml-quote "${MULTIMASTER:-}") +FIREWALLRULESMANAGEMENT: $(yaml-quote "${FIREWALLRULESMANAGEMENT:-}") NON_MASQUERADE_CIDR: $(yaml-quote "${NON_MASQUERADE_CIDR:-}") ENABLE_DEFAULT_STORAGE_CLASS: $(yaml-quote "${ENABLE_DEFAULT_STORAGE_CLASS:-}") # (TODO/cloud-provider-gcp): Need to figure out how to inject this diff --git a/go.work.sum b/go.work.sum index 712e01e5a..626428a87 100644 --- a/go.work.sum +++ b/go.work.sum @@ -1,2 +1,107 @@ +bitbucket.org/bertimus9/systemstat v0.5.0/go.mod h1:EkUWPp8lKFPMXP8vnbpT5JDI0W/sTiLZAvN8ONWErHY= cloud.google.com/go v0.115.1 h1:Jo0SM9cQnSkYfp44+v+NQXHpcHqlnRJk2qxh6yvxxxQ= +cloud.google.com/go v0.115.1/go.mod h1:DuujITeaufu3gL68/lOFIirVNJwQeyf5UXyi+Wbgknc= cloud.google.com/go/compute v1.23.1 h1:V97tBoDaZHb6leicZ1G6DLK2BAaZLJ/7+9BB/En3hR0= +cloud.google.com/go/compute v1.23.1/go.mod h1:CqB3xpmPKKt3OJpW2ndFIXnA9A4xAy/F3Xp1ixncW78= +cloud.google.com/go/longrunning v0.5.6/go.mod h1:vUaDrWYOMKRuhiv6JBnn49YxCPz2Ayn9GqyjaBT8/mA= +cloud.google.com/go/translate v1.10.3/go.mod h1:GW0vC1qvPtd3pgtypCv4k4U8B7EdgK9/QEF2aJEUovs= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.26.0/go.mod h1:2bIszWvQRlJVmJLiuLhukLImRjKPcYdzzsx6darK02A= +github.com/JeffAshton/win_pdh v0.0.0-20161109143554-76bb4ee9f0ab/go.mod h1:3VYc5hodBMJ5+l/7J4xAyMeuM2PNuepvHlGs8yilUCA= +github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= +github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= +github.com/Microsoft/hnslib v0.1.1/go.mod h1:DRQR4IjLae6WHYVhW7uqe44hmFUiNhmaWA+jwMbz5tM= +github.com/alecthomas/kingpin/v2 v2.4.0/go.mod h1:0gyi0zQnjuFk8xrkNKamJoyUo382HRL7ATRpFZCw6tE= +github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/armon/circbuf v0.0.0-20190214190532-5111143e8da2/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/chai2010/gettext-go v1.0.2/go.mod h1:y+wnP2cHYaVj19NZhYKAwEMH2CI1gNHeQQ+5AjwawxA= +github.com/cncf/xds/go v0.0.0-20250121191232-2f005788dc42/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= +github.com/container-storage-interface/spec v1.9.0/go.mod h1:ZfDu+3ZRyeVqxZM0Ds19MVLkN2d1XJ5MAfi1L3VjlT0= +github.com/containerd/containerd/api v1.8.0/go.mod h1:dFv4lt6S20wTu/hMcP4350RL87qPWLVa/OHOwmmdnYc= +github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M= +github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk= +github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= +github.com/containerd/ttrpc v1.2.6/go.mod h1:YCXHsb32f+Sq5/72xHubdiJRQY9inL4a4ZQrAbN1q9o= +github.com/containerd/typeurl/v2 v2.2.2/go.mod h1:95ljDnPfD3bAbDJRugOiShd/DlAAsxGtUBhJxIn7SCk= +github.com/coredns/caddy v1.1.1/go.mod h1:A6ntJQlAWuQfFlsd9hvigKbo2WS0VUs2l1e2F+BawD4= +github.com/coredns/corefile-migration v1.0.26/go.mod h1:56DPqONc3njpVPsdilEnfijCwNGC3/kTJLl7i7SPavY= +github.com/coreos/go-oidc v2.3.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= +github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= +github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= +github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/envoyproxy/go-control-plane v0.13.4/go.mod h1:kDfuBlDVsSj2MjrLEtRWtHlsWIFcGyB2RMO44Dc5GZA= +github.com/envoyproxy/go-control-plane/envoy v1.32.4/go.mod h1:Gzjc5k8JcJswLjAx1Zm+wSYE20UrLtt7JZMWiWQXQEw= +github.com/envoyproxy/go-control-plane/ratelimit v0.1.0/go.mod h1:Wk+tMFAFbCXaJPzVVHnPgRKdUdwW/KdbRt94AzgRee4= +github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU= +github.com/euank/go-kmsg-parser v2.0.0+incompatible/go.mod h1:MhmAMZ8V4CYH4ybgdRwPr2TU5ThnS43puaKEMpja1uw= +github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f/go.mod h1:OSYXu++VVOHnXeitef/D8n/6y4QV8uLHSFXX4NeXMGc= +github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= +github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= +github.com/go-jose/go-jose/v4 v4.0.4/go.mod h1:NKb5HO1EZccyMpiZNbdUw/14tiXNyUJh188dfnMCAfc= +github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/golang/glog v1.2.4/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= +github.com/google/cadvisor v0.52.1/go.mod h1:OAhPcx1nOm5YwMh/JhpUOMKyv1YKLRtS9KgzWPndHmA= +github.com/google/go-pkcs11 v0.3.0/go.mod h1:6eQoGcuNJpa7jnd5pMGdkSaQpNDYvPlXWMcjXXThLlY= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/ishidawataru/sctp v0.0.0-20250521072954-ae8eb7fa7995/go.mod h1:co9pwDoBCm1kGxawmb4sPq0cSIOOWNPT4KnHotMP1Zg= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/karrick/godirwalk v1.17.0/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= +github.com/libopenstorage/openstorage v1.0.0/go.mod h1:Sp1sIObHjat1BeXhfMqLZ14wnOzEhNx2YQedreMcUyc= +github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE= +github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= +github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= +github.com/moby/ipvs v1.1.0/go.mod h1:4VJMWuf098bsUMmZEiD4Tjk/O7mOn3l1PTD3s4OoYAs= +github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI= +github.com/moby/sys/mountinfo v0.7.2/go.mod h1:1YOa8w8Ih7uW0wALDUgT1dTTSBrZ+HiBLGws92L2RU4= +github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28= +github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= +github.com/monochromegane/go-gitignore v0.0.0-20200626010858-205db1a8cc00/go.mod h1:Pm3mSP3c5uWn86xMLZ5Sa7JB9GsEZySvHYXCTK4E9q4= +github.com/mrunalp/fileutils v0.5.1/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/opencontainers/cgroups v0.0.1/go.mod h1:s8lktyhlGUqM7OSRL5P7eAW6Wb+kWPNvt4qvVfzA5vs= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M= +github.com/opencontainers/runtime-spec v1.2.0/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/selinux v1.11.1/go.mod h1:E5dMC3VPuVvVHDYmi78qvhJp8+M586T4DlDRYpFkyec= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= +github.com/pquerna/cachecontrol v0.1.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI= +github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/spiffe/go-spiffe/v2 v2.5.0/go.mod h1:P+NxobPc6wXhVtINNtFjNWGBTreew1GBUCwT2wPmb7g= +github.com/vishvananda/netlink v1.3.1/go.mod h1:ARtKouGSTGchR8aMwmkzC0qiNPrrWO5JS/XMVl45+b4= +github.com/vishvananda/netns v0.0.5/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM= +github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU= +github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/zeebo/errs v1.4.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4= +go.opentelemetry.io/contrib/detectors/gcp v1.34.0/go.mod h1:cV4BMFcscUR/ckqLkbfQmF0PRsq8w/lMGzdbCSveBHo= +go.opentelemetry.io/contrib/instrumentation/github.com/emicklei/go-restful/otelrestful v0.44.0/go.mod h1:uq8DrRaen3suIWTpdR/JNHCGpurSvMv9D5Nr5CU5TXc= +golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0= +google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= +google.golang.org/genproto v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:hL97c3SYopEHblzpxRL4lSs523++l8DYxGM1FQiYmb4= +google.golang.org/genproto/googleapis/bytestream v0.0.0-20240903143218-8af14fe29dc1/go.mod h1:q0eWNnCW04EJlyrmLT+ZHsjuoUiZ36/eAEdCCezZoco= +gopkg.in/go-jose/go-jose.v2 v2.6.3/go.mod h1:zzZDPkNNw/c9IE7Z9jr11mBZQhKQTMzoEEIoEdZlFBI= +k8s.io/cli-runtime v0.34.2/go.mod h1:X13tsrYexYUCIq8MarCBy8lrm0k0weFPTpcaNo7lms4= +k8s.io/cluster-bootstrap v0.34.2/go.mod h1:f21byPR7X5nt12ivZi+J3pb4sG4SH6VySX8KAAJA8BY= +k8s.io/cri-api v0.34.2/go.mod h1:4qVUjidMg7/Z9YGZpqIDygbkPWkg3mkS1PvOx/kpHTE= +k8s.io/csi-translation-lib v0.34.2/go.mod h1:un/6pCiR5QgE6HD16i2AY11+wSFbeVksolat1zntCZY= +k8s.io/kube-aggregator v0.34.2/go.mod h1:/tp4cc/1p2AvICsS4mjjSJakdrbhcGbRmj0mdHTdR2Q= +k8s.io/kube-proxy v0.34.2/go.mod h1:Hxq2f+IQGwx4plSFaXkqAjkIH6LEhHjNGI0s6hU9G2Y= +k8s.io/kube-scheduler v0.34.2/go.mod h1:PTn4QYiSet8/00VQ2qGO/HWdo5iNJlVRCXz/7R3Ut5I= +k8s.io/kubectl v0.34.2/go.mod h1:X2KTOdtZZNrTWmUD4oHApJ836pevSl+zvC5sI6oO2YQ= +k8s.io/mount-utils v0.34.2/go.mod h1:MIjjYlqJ0ziYQg0MO09kc9S96GIcMkhF/ay9MncF0GA= +k8s.io/pod-security-admission v0.34.2/go.mod h1:lXfDNwD9y0fZM/g1deG7gY/yjED4rcoLrQL2X6BiJgw= +k8s.io/sample-apiserver v0.34.2/go.mod h1:OPwuRiVQ33+SO9PQNOkTXFCsAuWu9VyGOPNRZwvuRrg= +k8s.io/system-validators v1.10.2/go.mod h1:awfSS706v9R12VC7u7K89FKfqVy44G+E0L1A0FX9Wmw= +sigs.k8s.io/knftables v0.0.17/go.mod h1:f/5ZLKYEUPUhVjUCg6l80ACdL7CIIyeL0DxfgojGRTk= +sigs.k8s.io/kustomize/api v0.20.1/go.mod h1:t6hUFxO+Ph0VxIk1sKp1WS0dOjbPCtLJ4p8aADLwqjM= +sigs.k8s.io/kustomize/kustomize/v5 v5.7.1/go.mod h1:+5/SrBcJ4agx1SJknGuR/c9thwRSKLxnKoI5BzXFaLU= +sigs.k8s.io/kustomize/kyaml v0.20.1/go.mod h1:0EmkQHRUsJxY8Ug9Niig1pUMSCGHxQ5RklbpV/Ri6po= +sigs.k8s.io/structured-merge-diff/v4 v4.4.2/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4= diff --git a/providers/gce/gce.go b/providers/gce/gce.go index 0b7ae1d79..ceda7c475 100644 --- a/providers/gce/gce.go +++ b/providers/gce/gce.go @@ -118,6 +118,17 @@ const clusterStackIPV4 StackType = "IPV4" // The underlying VPC's stack type could be either IPV6 or dual stack IPV4_IPV6. const clusterStackIPV6 StackType = "IPV6" +// FirewallRulesManagement indicates how firewall rules are managed by the provider. +type FirewallRulesManagement string + +// firewallRulesManagementEnabled indicates that the firewall rules should be managed by the provider. +// This includes firewall rule creation, deletion, and updates. +const firewallRulesManagementEnabled FirewallRulesManagement = "Enabled" + +// firewallRulesManagementDisabled indicates that the firewall rules should not be managed by the provider. +// This includes firewall rule creation, deletion, and updates. +const firewallRulesManagementDisabled FirewallRulesManagement = "Disabled" + // Cloud is an implementation of Interface, LoadBalancer and Instances for Google Compute Engine. type Cloud struct { // ClusterID contains functionality for getting (and initializing) the ingress-uid. Call Cloud.Initialize() @@ -217,6 +228,8 @@ type Cloud struct { // enableL4DenyFirewallRollbackCleanup enableL4DenyFirewallRollbackCleanup bool + + firewallRulesManagement FirewallRulesManagement } // ConfigGlobal is the in memory representation of the gce.conf config data @@ -254,6 +267,10 @@ type ConfigGlobal struct { // Default to none. // For example: MyFeatureFlag AlphaFeatures []string `gcfg:"alpha-features"` + + // FirewallRulesManagement indicates whether the provider should handle all firewall + // operations, such as creation, deletion, and updates. + FirewallRulesManagement string `gcfg:"firewall-rules-management"` } // ConfigFile is the struct used to parse the /etc/gce.conf configuration file. @@ -281,13 +298,14 @@ type CloudConfig struct { SubnetworkName string SubnetworkURL string // DEPRECATED: Do not rely on this value as it may be incorrect. - SecondaryRangeName string - NodeTags []string - NodeInstancePrefix string - TokenSource oauth2.TokenSource - UseMetadataServer bool - AlphaFeatureGate *AlphaFeatureGate - StackType string + SecondaryRangeName string + NodeTags []string + NodeInstancePrefix string + TokenSource oauth2.TokenSource + UseMetadataServer bool + AlphaFeatureGate *AlphaFeatureGate + StackType string + FirewallRulesManagement string } func init() { @@ -378,6 +396,7 @@ func generateCloudConfig(configFile *ConfigFile) (cloudConfig *CloudConfig, err cloudConfig.NodeTags = configFile.Global.NodeTags cloudConfig.NodeInstancePrefix = configFile.Global.NodeInstancePrefix cloudConfig.AlphaFeatureGate = NewAlphaFeatureGate(configFile.Global.AlphaFeatures) + cloudConfig.FirewallRulesManagement = configFile.Global.FirewallRulesManagement } // retrieve projectID and zone @@ -581,6 +600,7 @@ func CreateGCECloud(config *CloudConfig) (*Cloud, error) { metricsCollector: newLoadBalancerMetrics(), projectsBasePath: getProjectsBasePath(service.BasePath), stackType: StackType(config.StackType), + firewallRulesManagement: FirewallRulesManagement(config.FirewallRulesManagement), } gce.manager = &gceServiceManager{gce} diff --git a/providers/gce/gce_fake.go b/providers/gce/gce_fake.go index dfafcc216..5ff83154d 100644 --- a/providers/gce/gce_fake.go +++ b/providers/gce/gce_fake.go @@ -30,30 +30,32 @@ import ( // TestClusterValues holds the config values for the fake/test gce cloud object. type TestClusterValues struct { - ProjectID string - Region string - ZoneName string - SecondaryZoneName string - ClusterID string - ClusterName string - OnXPN bool - Regional bool - NetworkURL string - SubnetworkURL string - StackType StackType + ProjectID string + Region string + ZoneName string + SecondaryZoneName string + ClusterID string + ClusterName string + OnXPN bool + Regional bool + NetworkURL string + SubnetworkURL string + StackType StackType + FirewallRulesManagement FirewallRulesManagement } // DefaultTestClusterValues Creates a reasonable set of default cluster values // for generating a new test fake GCE cloud instance. func DefaultTestClusterValues() TestClusterValues { return TestClusterValues{ - ProjectID: "test-project", - Region: "us-central1", - ZoneName: "us-central1-b", - SecondaryZoneName: "us-central1-c", - ClusterID: "test-cluster-id", - ClusterName: "Test-Cluster-Name", - StackType: clusterStackIPV4, + ProjectID: "test-project", + Region: "us-central1", + ZoneName: "us-central1-b", + SecondaryZoneName: "us-central1-c", + ClusterID: "test-cluster-id", + ClusterName: "Test-Cluster-Name", + StackType: clusterStackIPV4, + FirewallRulesManagement: firewallRulesManagementEnabled, } } @@ -75,20 +77,21 @@ func NewFakeGCECloud(vals TestClusterValues) *Cloud { panic(err) } gce := &Cloud{ - region: vals.Region, - service: service, - managedZones: []string{vals.ZoneName}, - localZone: vals.ZoneName, - projectID: vals.ProjectID, - networkProjectID: vals.ProjectID, - ClusterID: fakeClusterID(vals.ClusterID), - onXPN: vals.OnXPN, - metricsCollector: newLoadBalancerMetrics(), - projectsBasePath: getProjectsBasePath(service.BasePath), - regional: vals.Regional, - networkURL: vals.NetworkURL, - unsafeSubnetworkURL: vals.SubnetworkURL, - stackType: vals.StackType, + region: vals.Region, + service: service, + managedZones: []string{vals.ZoneName}, + localZone: vals.ZoneName, + projectID: vals.ProjectID, + networkProjectID: vals.ProjectID, + ClusterID: fakeClusterID(vals.ClusterID), + onXPN: vals.OnXPN, + metricsCollector: newLoadBalancerMetrics(), + projectsBasePath: getProjectsBasePath(service.BasePath), + regional: vals.Regional, + networkURL: vals.NetworkURL, + unsafeSubnetworkURL: vals.SubnetworkURL, + stackType: vals.StackType, + firewallRulesManagement: vals.FirewallRulesManagement, } c := cloud.NewMockGCE(&gceProjectRouter{gce}) gce.c = c diff --git a/providers/gce/gce_firewall.go b/providers/gce/gce_firewall.go index afb59fe6c..ac2d167ef 100644 --- a/providers/gce/gce_firewall.go +++ b/providers/gce/gce_firewall.go @@ -32,6 +32,10 @@ func newFirewallMetricContext(request string) *metricContext { // GetFirewall returns the Firewall by name. func (g *Cloud) GetFirewall(name string) (*compute.Firewall, error) { + if g.firewallRulesManagement == firewallRulesManagementDisabled { + return nil, nil + } + ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() @@ -42,6 +46,10 @@ func (g *Cloud) GetFirewall(name string) (*compute.Firewall, error) { // CreateFirewall creates the passed firewall func (g *Cloud) CreateFirewall(f *compute.Firewall) error { + if g.firewallRulesManagement == firewallRulesManagementDisabled { + return nil + } + ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() @@ -51,6 +59,10 @@ func (g *Cloud) CreateFirewall(f *compute.Firewall) error { // DeleteFirewall deletes the given firewall rule. func (g *Cloud) DeleteFirewall(name string) error { + if g.firewallRulesManagement == firewallRulesManagementDisabled { + return nil + } + ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() @@ -60,6 +72,10 @@ func (g *Cloud) DeleteFirewall(name string) error { // UpdateFirewall applies the given firewall as an update to an existing service. func (g *Cloud) UpdateFirewall(f *compute.Firewall) error { + if g.firewallRulesManagement == firewallRulesManagementDisabled { + return nil + } + ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() @@ -69,6 +85,10 @@ func (g *Cloud) UpdateFirewall(f *compute.Firewall) error { // PatchFirewall applies the given firewall as an update to an existing service. func (g *Cloud) PatchFirewall(f *compute.Firewall) error { + if g.firewallRulesManagement == firewallRulesManagementDisabled { + return nil + } + ctx, cancel := cloud.ContextWithCallTimeout() defer cancel() diff --git a/providers/gce/gce_loadbalancer_external.go b/providers/gce/gce_loadbalancer_external.go index e9e785ee7..d5c48a112 100644 --- a/providers/gce/gce_loadbalancer_external.go +++ b/providers/gce/gce_loadbalancer_external.go @@ -971,6 +971,11 @@ func translateAffinityType(affinityType v1.ServiceAffinity) string { } func (g *Cloud) firewallNeedsUpdate(name, serviceName, ipAddress string, ports []v1.ServicePort, sourceRanges utilnet.IPNetSet, priority int64) (exists bool, needsUpdate bool, err error) { + if g.firewallRulesManagement == firewallRulesManagementDisabled { + klog.V(2).Infof("firewallNeedsUpdate(%v): firewall rules are unmanaged", name) + return false, false, nil + } + fw, err := g.GetFirewall(MakeFirewallName(name)) if err != nil { if isHTTPErrorCode(err, http.StatusNotFound) { @@ -1020,6 +1025,11 @@ func (g *Cloud) firewallNeedsUpdate(name, serviceName, ipAddress string, ports [ } func (g *Cloud) ensureHTTPHealthCheckFirewall(svc *v1.Service, serviceName, ipAddress, region, clusterID string, hosts []*gceInstance, hcName string, hcPort int32, isNodesHealthCheck bool) error { + if g.firewallRulesManagement == firewallRulesManagementDisabled { + klog.V(2).Infof("ensureHTTPHealthCheckFirewall(%v): firewall rules are unmanaged", hcName) + return nil + } + // Prepare the firewall params for creating / checking. desc := fmt.Sprintf(`{"kubernetes.io/cluster-id":"%s"}`, clusterID) if !isNodesHealthCheck { @@ -1097,6 +1107,17 @@ func (g *Cloud) createFirewall(svc *v1.Service, name, desc, destinationIP string if err != nil { return err } + + if g.firewallRulesManagement == firewallRulesManagementDisabled { + klog.V(2).Infof("createFirewall(%v): firewall rules are unmanaged", name) + project := g.NetworkProjectID() + if project == "" { + project = g.ProjectID() + } + g.raiseFirewallChangeNeededEvent(svc, FirewallToGCloudCreateCmd(firewall, project)) + return nil + } + if err = g.CreateFirewall(firewall); err != nil { if isHTTPErrorCode(err, http.StatusConflict) { return nil diff --git a/providers/gce/gce_loadbalancer_external_test.go b/providers/gce/gce_loadbalancer_external_test.go index 4d7d72012..dedb5195d 100644 --- a/providers/gce/gce_loadbalancer_external_test.go +++ b/providers/gce/gce_loadbalancer_external_test.go @@ -1734,6 +1734,104 @@ func TestFirewallNeedsUpdate(t *testing.T) { } } +func TestDisabledFirewallOperations(t *testing.T) { + vals := DefaultTestClusterValues() + vals.FirewallRulesManagement = firewallRulesManagementDisabled + gce, err := fakeGCECloud(vals) + require.NoError(t, err) + + fw, err := gce.GetFirewall(MakeFirewallName("test")) + assert.NoError(t, err) + assert.Nil(t, fw) + + ipnet, err := utilnet.ParseIPNets("0.0.0.0/0") + require.NoError(t, err) + + ports := []v1.ServicePort{ + {Name: "port1", Protocol: v1.ProtocolTCP, Port: int32(80), TargetPort: intstr.FromInt(80)}, + {Name: "port2", Protocol: v1.ProtocolTCP, Port: int32(81), TargetPort: intstr.FromInt(81)}, + {Name: "port3", Protocol: v1.ProtocolTCP, Port: int32(82), TargetPort: intstr.FromInt(82)}, + {Name: "port4", Protocol: v1.ProtocolTCP, Port: int32(84), TargetPort: intstr.FromInt(84)}, + {Name: "port5", Protocol: v1.ProtocolTCP, Port: int32(85), TargetPort: intstr.FromInt(85)}, + {Name: "port6", Protocol: v1.ProtocolTCP, Port: int32(86), TargetPort: intstr.FromInt(86)}, + {Name: "port7", Protocol: v1.ProtocolTCP, Port: int32(88), TargetPort: intstr.FromInt(87)}, + } + + firewall, err := gce.firewallObject(MakeFirewallName("test"), "Test Description", "0.0.0.0/0", ipnet, ports, nil) + + err = gce.CreateFirewall(firewall) + assert.NoError(t, err) + + err = gce.UpdateFirewall(firewall) + assert.NoError(t, err) + + err = gce.PatchFirewall(firewall) + assert.NoError(t, err) + + err = gce.DeleteFirewall(MakeFirewallName("test")) + assert.NoError(t, err) +} + +func TestDisabledFirewallNeedsUpdate(t *testing.T) { + t.Parallel() + + vals := DefaultTestClusterValues() + vals.FirewallRulesManagement = firewallRulesManagementDisabled + gce, err := fakeGCECloud(vals) + require.NoError(t, err) + svc := fakeLoadbalancerService("") + + svc, err = gce.client.CoreV1().Services(svc.Namespace).Create(context.TODO(), svc, metav1.CreateOptions{}) + require.NoError(t, err) + + svc.Spec.Ports = []v1.ServicePort{ + {Name: "port1", Protocol: v1.ProtocolTCP, Port: int32(80), TargetPort: intstr.FromInt(80)}, + {Name: "port2", Protocol: v1.ProtocolTCP, Port: int32(81), TargetPort: intstr.FromInt(81)}, + {Name: "port3", Protocol: v1.ProtocolTCP, Port: int32(82), TargetPort: intstr.FromInt(82)}, + {Name: "port4", Protocol: v1.ProtocolTCP, Port: int32(84), TargetPort: intstr.FromInt(84)}, + {Name: "port5", Protocol: v1.ProtocolTCP, Port: int32(85), TargetPort: intstr.FromInt(85)}, + {Name: "port6", Protocol: v1.ProtocolTCP, Port: int32(86), TargetPort: intstr.FromInt(86)}, + {Name: "port7", Protocol: v1.ProtocolTCP, Port: int32(88), TargetPort: intstr.FromInt(87)}, + } + + status, err := createExternalLoadBalancer(gce, svc, []string{"test-node-1"}, vals.ClusterName, vals.ClusterID, vals.ZoneName) + require.NotNil(t, status) + require.NoError(t, err) + svcName := "/" + svc.ObjectMeta.Name + + ipAddr := status.Ingress[0].IP + lbName := gce.GetLoadBalancerName(context.TODO(), "", svc) + + ipnet, err := utilnet.ParseIPNets("0.0.0.0/0") + require.NoError(t, err) + + fw, err := gce.GetFirewall(MakeFirewallName(lbName)) + require.NoError(t, err) + + for desc := range map[string]struct { + hasErr bool + }{ + "need to update port-ranges ": {}, + } { + t.Run(desc, func(t *testing.T) { + fw, err = gce.GetFirewall(MakeFirewallName(lbName)) + assert.NoError(t, err) + assert.Nil(t, fw) + + exists, needsUpdate, err := gce.firewallNeedsUpdate( + lbName, + svcName, + ipAddr, + svc.Spec.Ports, + ipnet) + + assert.Equal(t, false, exists, "firewall should not exist") + assert.Equal(t, false, needsUpdate, "firewall should not exist, no update needed") + assert.NoError(t, err) + }) + } +} + func TestDeleteWrongNetworkTieredResourcesSucceedsWhenNotFound(t *testing.T) { t.Parallel() diff --git a/providers/gce/gce_loadbalancer_internal.go b/providers/gce/gce_loadbalancer_internal.go index 21eab518b..cc04877e1 100644 --- a/providers/gce/gce_loadbalancer_internal.go +++ b/providers/gce/gce_loadbalancer_internal.go @@ -411,6 +411,10 @@ func (g *Cloud) ensureInternalLoadBalancerDeleted(clusterName, clusterID string, } deleteFunc := func(fwName string) error { + if g.firewallRulesManagement == firewallRulesManagementDisabled { + klog.V(2).Infof("ensureInternalLoadBalancerDeleted(%v): firewall rules are unmanaged", fwName) + return nil + } if err := ignoreNotFound(g.DeleteFirewall(fwName)); err != nil { if isForbidden(err) && g.OnXPN() { klog.V(2).Infof("ensureInternalLoadBalancerDeleted(%v): could not delete traffic firewall on XPN cluster. Raising event.", loadBalancerName) @@ -486,6 +490,11 @@ func (g *Cloud) teardownInternalHealthCheckAndFirewall(svc *v1.Service, hcName s } klog.V(2).Infof("teardownInternalHealthCheckAndFirewall(%v): health check deleted", hcName) + if g.firewallRulesManagement == firewallRulesManagementDisabled { + klog.V(2).Infof("teardownInternalHealthCheckAndFirewall(%v): unmanaged firewall rules", hcName) + return nil + } + hcFirewallName := makeHealthCheckFirewallNameFromHC(hcName) if err := ignoreNotFound(g.DeleteFirewall(hcFirewallName)); err != nil { if isForbidden(err) && g.OnXPN() { @@ -502,6 +511,11 @@ func (g *Cloud) teardownInternalHealthCheckAndFirewall(svc *v1.Service, hcName s func (g *Cloud) ensureInternalFirewall(svc *v1.Service, fwName, fwDesc, destinationIP string, sourceRanges []string, portRanges []string, protocol v1.Protocol, nodes []*v1.Node, legacyFwName string) error { klog.V(2).Infof("ensureInternalFirewall(%v): checking existing firewall", fwName) + if g.firewallRulesManagement == firewallRulesManagementDisabled { + klog.V(2).Infof("ensureInternalFirewall(%v): firewall rules are unmanaged", fwName) + return nil + } + targetTags, err := g.GetNodeTags(nodeNames(nodes)) if err != nil { return err