Repository: metallb/metallb
Pull request #1864 (2023-03-20 03:00:59)

Bump actions/setup-go from 3 to 4
Bumps [actions/setup-go](https://github.com/actions/setup-go) from 3 to 4.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/actions/setup-go/releases">actions/setup-go's releases</a>.</em></p>
<blockquote>
<h2>v4.0.0</h2>
<p>In scope of release we enable cache by default. The action won’t throw an error if the cache can’t be restored or saved. The action will throw a warning message but it won’t stop a build process. The cache can be disabled by specifying <code>cache: false</code>.</p>
<pre lang="yaml"><code>steps:
  - uses: actions/checkout@v3
  - uses: actions/setup-go@v4
    with:
      go-version: ‘1.19’
  - run: go run hello.go
</code></pre>
<p>Besides, we introduce such changes as</p>
<ul>
<li><a href="https://redirect.github.com/actions/setup-go/pull/305">Allow to use only GOCACHE for cache</a></li>
<li><a href="https://redirect.github.com/actions/setup-go/pull/315">Bump json5 from 2.2.1 to 2.2.3</a></li>
<li><a href="https://redirect.github.com/actions/setup-go/pull/323">Use proper version for primary key in cache</a></li>
<li><a href="https://redirect.github.com/actions/setup-go/pull/351">Always add Go bin to the PATH</a></li>
<li><a href="https://redirect.github.com/actions/setup-go/pull/350">Add step warning if go-version input is empty</a></li>
</ul>
<h2>Add support for stable and oldstable aliases</h2>
<p>In scope of this release we introduce aliases for the <code>go-version</code> input. The <code>stable</code> alias instals the latest stable version of Go. The <code>oldstable</code> alias installs previous latest minor release (the stable is 1.19.x -&gt; the oldstable is 1.18.x).</p>
<h3>Stable</h3>
<pre lang="yaml"><code>steps:
  - uses: actions/checkout@v3
  - uses: actions/setup-go@v3
    with:
      go-version: 'stable'
  - run: go run hello.go
</code></pre>
<h3>OldStable</h3>
<pre lang="yaml"><code>steps:
  - uses: actions/checkout@v3
  - uses: actions/setup-go@v3
    with:
      go-version: 'oldstable'
  - run: go run hello.go
</code></pre>
<h2>Add support for go.work and pass the token input through on GHES</h2>
<p>In scope of this release we added <a href="https://redirect.github.com/actions/setup-go/pull/283">support for go.work file to pass it in go-version-file input</a>.</p>
<pre lang="yaml"><code>steps:
  - uses: actions/checkout@v3
  - uses: actions/setup-go@v3
&lt;/tr&gt;&lt;/table&gt; 
</code></pre>
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/actions/setup-go/commit/4d34df0c2316fe8122ab82dc22947d607c0c91f9"><code>4d34df0</code></a> Update configuration files (<a href="https://redirect.github.com/actions/setup-go/issues/348">#348</a>)</li>
<li><a href="https://github.com/actions/setup-go/commit/fdc0d672a12b8fc05ef4c549c3fd5b0f03ebeb4c"><code>fdc0d67</code></a> Add Go bin if go-version input is empty (<a href="https://redirect.github.com/actions/setup-go/issues/351">#351</a>)</li>
<li><a href="https://github.com/actions/setup-go/commit/ebfdf6ac95bce0e7e743a60aba7adf59b400885b"><code>ebfdf6a</code></a> add warning if go-version is empty (<a href="https://redirect.github.com/actions/setup-go/issues/350">#350</a>)</li>
<li><a href="https://github.com/actions/setup-go/commit/b27d76912e7cb72b7262b5be2ec903b6cfaf358a"><code>b27d769</code></a> fix lockfileVersion (<a href="https://redirect.github.com/actions/setup-go/issues/349">#349</a>)</li>
<li><a href="https://github.com/actions/setup-go/commit/c51a7207680f1bee06f4a751214aab70667f9e25"><code>c51a720</code></a> Enable caching by default with default input (<a href="https://redirect.github.com/actions/setup-go/issues/332">#332</a>)</li>
<li><a href="https://github.com/actions/setup-go/commit/6b848af622919e18822928df24a57044dc6ea9ab"><code>6b848af</code></a> Merge pull request <a href="https://redirect.github.com/actions/setup-go/issues/343">#343</a> from akv-platform/reusable-workflow</li>
<li><a href="https://github.com/actions/setup-go/commit/12741cc20952a981105f1dc8366d69f1d24ed472"><code>12741cc</code></a> Format update-config-files.yml</li>
<li><a href="https://github.com/actions/setup-go/commit/7a77a6aab66a15178e313f5908f5ed9b8500894c"><code>7a77a6a</code></a> Merge branch 'main' into reusable-workflow</li>
<li><a href="https://github.com/actions/setup-go/commit/42a0cc8e1491c14a0e9486c3a895d2124f51af1a"><code>42a0cc8</code></a> Add update-config-files.yml</li>
<li><a href="https://github.com/actions/setup-go/commit/7406d654ad8f517886f6c77135494c2b99355381"><code>7406d65</code></a> Add and configure ESLint and update configuration for Prettier (<a href="https://redirect.github.com/actions/setup-go/issues/341">#341</a>)</li>
<li>Additional commits viewable in <a href="https://github.com/actions/setup-go/compare/v3...v4">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/setup-go&package-manager=github_actions&previous-version=3&new-version=4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>


Patch:
diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index ae08778d..a22cb0b1 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -56,7 +56,7 @@ jobs:
       - name: Checkout
         uses: actions/checkout@v3
 
-      - uses: actions/setup-go@v3
+      - uses: actions/setup-go@v4
         with:
           go-version-file: "go.mod"
           cache: true
@@ -96,7 +96,7 @@ jobs:
         uses: docker/setup-buildx-action@v2
 
       - name: Build and export ${{ matrix.image }}
-        uses: docker/build-push-action@v3
+        uses: docker/build-push-action@v4
         with:
           context: .
           tags: quay.io/metallb/${{ matrix.image }}:dev-amd64
diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml
index 86fe71f1..599caf3b 100644
--- a/.github/workflows/publish.yaml
+++ b/.github/workflows/publish.yaml
@@ -19,7 +19,7 @@ jobs:
       - name: Checkout
         uses: actions/checkout@v3
 
-      - uses: actions/setup-go@v3
+      - uses: actions/setup-go@v4
         with:
           go-version-file: "go.mod"
           cache: true
@@ -94,7 +94,7 @@ jobs:
             org.opencontainers.image.description=${{ matrix.image }} for metallb, a network load-balancer implementation for Kubernetes using standard routing protocols
 
       - name: Build and push ${{ matrix.image }}
-        uses: docker/build-push-action@v3
+        uses: docker/build-push-action@v4
         id: build-and-push
         with:
           context: .
diff --git a/charts/metallb/templates/servicemonitor.yaml b/charts/metallb/templates/servicemonitor.yaml
index 5c2ab422..43825b46 100644
--- a/charts/metallb/templates/servicemonitor.yaml
+++ b/charts/metallb/templates/servicemonitor.yaml
@@ -58,14 +58,6 @@ spec:
   selector:
     matchLabels:
       name: {{ template "metallb.fullname" . }}-speaker-monitor-service
-{{- if .Values.prometheus.serviceMonitor.metricRelabelings }}
-  metricRelabelings:
-{{- toYaml .Values.prometheus.serviceMonitor.metricRelabelings | nindent 4 }}
-{{- end }}
-{{- if .Values.prometheus.serviceMonitor.relabelings }}
-  relabelings:
-{{- toYaml .Values.prometheus.serviceMonitor.relabelings | nindent 4 }}
-{{- end }}      
 ---
 apiVersion: v1
 kind: Service
@@ -112,6 +104,14 @@ metadata:
 spec:
   endpoints:
     - port: {{ template "metrics.exposedportname" . }}
+      {{- if .Values.prometheus.serviceMonitor.metricRelabelings }}
+      metricRelabelings:
+      {{- toYaml .Values.prometheus.serviceMonitor.metricRelabelings | nindent 8 }}
+      {{- end -}}
+      {{- if .Values.prometheus.serviceMonitor.relabelings }}
+      relabelings:
+      {{- toYaml .Values.prometheus.serviceMonitor.relabelings | nindent 8 }}
+      {{- end }}
       {{- if .Values.prometheus.serviceMonitor.interval }}
       interval: {{ .Values.prometheus.serviceMonitor.interval }}
       {{- end }}
@@ -131,14 +131,6 @@ spec:
   selector:
     matchLabels:
       name: {{ template "metallb.fullname" . }}-controller-monitor-service
-{{- if .Values.prometheus.serviceMonitor.metricRelabelings }}
-  metricRelabelings:
-{{- toYaml .Values.prometheus.serviceMonitor.metricRelabelings | nindent 4 }}
-{{- end }}
-{{- if .Values.prometheus.serviceMonitor.relabelings }}
-  relabelings:
-{{- toYaml .Values.prometheus.serviceMonitor.relabelings | nindent 4 }}
-{{- end }}      
 ---
 apiVersion: v1
 kind: Service
diff --git a/controller/service.go b/controller/service.go
index f78f6ebc..e6ccdae7 100644
--- a/controller/service.go
+++ b/controller/service.go
@@ -96,6 +96,7 @@ func (c *controller) convergeBalancer(l log.Logger, key string, svc *v1.Service)
 		// otherwise it'll fail and tell us why.
 		if err = c.ips.Assign(key, svc, lbIPs, k8salloc.Ports(svc), k8salloc.SharingKey(svc), k8salloc.BackendKey(svc)); err != nil {
 			level.Info(l).Log("event", "clearAssignment", "error", err, "msg", "current IP not allowed by config, clearing")
+			c.client.Infof(svc, "ClearAssignment", "current IP for %q not allowed by config, will attempt for new IP assignment: %s", key, err)
 			c.clearServiceState(key, svc)
 			lbIPs = []net.IP{}
 		}
diff --git a/go.mod b/go.mod
index 3ce21dae..f780fa6e 100644
--- a/go.mod
+++ b/go.mod
@@ -23,11 +23,11 @@ require (
 	github.com/prometheus/client_model v0.3.0
 	github.com/prometheus/common v0.39.0
 	golang.org/x/sync v0.1.0
-	golang.org/x/sys v0.4.0
+	golang.org/x/sys v0.6.0
 	k8s.io/api v0.26.1
 	k8s.io/apiextensions-apiserver v0.26.1
 	k8s.io/apimachinery v0.26.1
-	k8s.io/client-go v1.5.2
+	k8s.io/client-go v0.26.1
 	k8s.io/klog v1.0.0
 	k8s.io/kubernetes v1.26.1
 	k8s.io/pod-security-admission v0.0.0
diff --git a/go.sum b/go.sum
index 11b6d18b..460a1197 100644
--- a/go.sum
+++ b/go.sum
@@ -753,8 +753,8 @@ golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18=
-golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
diff --git a/internal/bgp/native/native.go b/internal/bgp/native/native.go
index a67b957f..d6084775 100644
--- a/internal/bgp/native/native.go
+++ b/internal/bgp/native/native.go
@@ -15,7 +15,6 @@ import (
 	"sync"
 	"syscall"
 	"time"
-	"unsafe"
 
 	"github.com/go-kit/log"
 	"github.com/go-kit/log/level"
@@ -489,25 +488,6 @@ func (s *session) Close() error {
 	return nil
 }
 
-const (
-	// TCP MD5 Signature (RFC2385).
-	tcpMD5SIG = 14
-)
-
-// This  struct is defined at; linux-kernel: include/uapi/linux/tcp.h,
-// It  must be kept in sync with that definition, see current version:
-// https://github.com/torvalds/linux/blob/v4.16/include/uapi/linux/tcp.h#L253.
-
-//nolint:structcheck
-type tcpmd5sig struct {
-	ssFamily uint16
-	ss       [126]byte
-	pad1     uint16
-	keylen   uint16
-	pad2     uint32
-	key      [80]byte
-}
-
 // DialTCP does the part of creating a connection manually,  including setting the
 // proper TCP MD5 options when the password is not empty. Works by manupulating
 // the low level FD's, skipping the net.Conn API as it has not hooks to set
@@ -592,9 +572,8 @@ func dialMD5(ctx context.Context, addr string, srcAddr net.IP, password string)
 
 	if password != "" {
 		sig := buildTCPMD5Sig(raddr.IP, password)
-		b := *(*[unsafe.Sizeof(sig)]byte)(unsafe.Pointer(&sig))
 		// Better way may be available in  Go 1.11, see go-review.googlesource.com/c/go/+/72810
-		if err = os.NewSyscallError("setsockopt", unix.SetsockoptString(fd, unix.IPPROTO_TCP, tcpMD5SIG, string(b[:]))); err != nil {
+		if err = os.NewSyscallError("setsockopt", unix.SetsockoptTCPMD5Sig(fd, unix.IPPROTO_TCP, unix.TCP_MD5SIG, sig)); err != nil {
 			return nil, err
 		}
 	}
@@ -665,20 +644,20 @@ func dialMD5(ctx context.Context, addr string, srcAddr net.IP, password string)
 	}
 }
 
-func buildTCPMD5Sig(addr net.IP, key string) tcpmd5sig {
-	t := tcpmd5sig{}
+func buildTCPMD5Sig(addr net.IP, key string) *unix.TCPMD5Sig {
+	t := unix.TCPMD5Sig{}
 	if addr.To4() != nil {
-		t.ssFamily = unix.AF_INET
-		copy(t.ss[2:], addr.To4())
+		t.Addr.Family = unix.AF_INET
+		copy(t.Addr.Data[2:], addr.To4())
 	} else {
-		t.ssFamily = unix.AF_INET6
-		copy(t.ss[6:], addr.To16())
+		t.Addr.Family = unix.AF_INET6
+		copy(t.Addr.Data[6:], addr.To16())
 	}
 
-	t.keylen = uint16(len(key))
-	copy(t.key[0:], []byte(key))
+	t.Keylen = uint16(len(key))
+	copy(t.Key[0:], []byte(key))
 
-	return t
+	return &t
 }
 
 // localAddressExists returns true if the address addr exists on any of the
diff --git a/internal/config/config.go b/internal/config/config.go
index dfd2600f..83b6f67d 100644
--- a/internal/config/config.go
+++ b/internal/config/config.go
@@ -524,8 +524,22 @@ func addressPoolServiceAllocationsFromCR(p metallbv1beta1.IPAddressPool, namespa
 	if p.Spec.AllocateTo == nil {
 		return nil, nil
 	}
-	serviceAllocations := &ServiceAllocation{Priority: p.Spec.AllocateTo.Priority,
-		Namespaces: sets.New(p.Spec.AllocateTo.Namespaces...)}
+	poolNamespaces := sets.Set[string]{}
+	for _, poolNs := range p.Spec.AllocateTo.Namespaces {
+		if poolNamespaces.Has(poolNs) {
+			return nil, errors.New("duplicate definition in namespaces field")
+		}
+		poolNamespaces.Insert(poolNs)
+	}
+	err := validateLabelSelectorDuplicate(p.Spec.AllocateTo.NamespaceSelectors, "namespaceSelectors")
+	if err != nil {
+		return nil, err
+	}
+	err = validateLabelSelectorDuplicate(p.Spec.AllocateTo.ServiceSelectors, "serviceSelectors")
+	if err != nil {
+		return nil, err
+	}
+	serviceAllocations := &ServiceAllocation{Priority: p.Spec.AllocateTo.Priority, Namespaces: poolNamespaces}
 	for i := range p.Spec.AllocateTo.NamespaceSelectors {
 		l, err := metav1.LabelSelectorAsSelector(&p.Spec.AllocateTo.NamespaceSelectors[i])
 		if err != nil {


Test patch:
diff --git a/internal/config/config_test.go b/internal/config/config_test.go
index a1a66ba5..37542bbd 100644
--- a/internal/config/config_test.go
+++ b/internal/config/config_test.go
@@ -416,6 +416,70 @@ func TestParse(t *testing.T) {
 			},
 		},
 
+		{
+			desc: "ip address pool with duplicate namespace selection",
+			crs: ClusterResources{
+				Pools: []v1beta1.IPAddressPool{
+					{
+						ObjectMeta: v1.ObjectMeta{
+							Name: "pool1",
+						},
+						Spec: v1beta1.IPAddressPoolSpec{
+							Addresses: []string{
+								"10.20.0.0/16",
+								"10.50.0.0/24",
+							},
+							AvoidBuggyIPs: true,
+							AutoAssign:    pointer.BoolPtr(false),
+							AllocateTo: &v1beta1.ServiceAllocation{Priority: 1,
+								Namespaces: []string{"test-ns1", "test-ns1"}},
+						},
+					},
+				},
+				Namespaces: []corev1.Namespace{
+					{
+						ObjectMeta: v1.ObjectMeta{
+							Name: "test-ns1",
+						},
+					},
+				},
+			},
+		},
+
+		{
+			desc: "ip address pool with duplicate namespace selectors",
+			crs: ClusterResources{
+				Pools: []v1beta1.IPAddressPool{
+					{
+						ObjectMeta: v1.ObjectMeta{
+							Name: "pool1",
+						},
+						Spec: v1beta1.IPAddressPoolSpec{
+							Addresses: []string{
+								"10.20.0.0/16",
+								"10.50.0.0/24",
+							},
+							AvoidBuggyIPs: true,
+							AutoAssign:    pointer.BoolPtr(false),
+							AllocateTo: &v1beta1.ServiceAllocation{
+								Priority: 1,
+								NamespaceSelectors: []v1.LabelSelector{{MatchLabels: map[string]string{"foo": "bar"}},
+									{MatchLabels: map[string]string{"foo": "bar"}}},
+							},
+						},
+					},
+				},
+				Namespaces: []corev1.Namespace{
+					{
+						ObjectMeta: v1.ObjectMeta{
+							Name:   "test-ns1",
+							Labels: map[string]string{"foo": "bar"},
+						},
+					},
+				},
+			},
+		},
+
 		{
 			desc: "ip address pool with service selection",
 			crs: ClusterResources{
@@ -467,6 +531,32 @@ func TestParse(t *testing.T) {
 			},
 		},
 
+		{
+			desc: "ip address pool with duplicate service selection",
+			crs: ClusterResources{
+				Pools: []v1beta1.IPAddressPool{
+					{
+						ObjectMeta: v1.ObjectMeta{
+							Name: "pool1",
+						},
+						Spec: v1beta1.IPAddressPoolSpec{
+							Addresses: []string{
+								"30.0.0.0/8",
+							},
+							AllocateTo: &v1beta1.ServiceAllocation{Priority: 2,
+								ServiceSelectors: []v1.LabelSelector{{MatchExpressions: []metav1.LabelSelectorRequirement{
+									{
+										Key:      "foo",
+										Operator: metav1.LabelSelectorOpIn,
+										Values:   []string{"bar", "bar"},
+									},
+								}}}},
+						},
+					},
+				},
+			},
+		},
+
 		{
 			desc: "ip address pool with namespace and service selection",
 			crs: ClusterResources{