Skip to content
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

Remove anyuid SCC requirement for OpenShift #3813

Merged
merged 1 commit into from
Apr 2, 2024
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
3 changes: 3 additions & 0 deletions .changelog/3813.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:improvement
control-plane: Remove anyuid Security Context Constraints (SCC) requirement in OpenShift.
```
252 changes: 174 additions & 78 deletions acceptance/framework/consul/helm_cluster.go

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,10 @@ func TestAPIGateway_KitchenSink(t *testing.T) {
checkStatusCondition(r, gateway.Status.Conditions, trueCondition("ConsulAccepted", "Accepted"))
require.Len(r, gateway.Status.Listeners, 2)

// http route checks
err = k8sClient.Get(context.Background(), types.NamespacedName{Name: "http-route", Namespace: "default"}, &httpRoute)
require.NoError(r, err)

require.EqualValues(r, int32(1), gateway.Status.Listeners[0].AttachedRoutes)
checkStatusCondition(r, gateway.Status.Listeners[0].Conditions, trueCondition("Accepted", "Accepted"))
checkStatusCondition(r, gateway.Status.Listeners[0].Conditions, falseCondition("Conflicted", "NoConflicts"))
Expand All @@ -152,10 +156,6 @@ func TestAPIGateway_KitchenSink(t *testing.T) {
// now we know we have an address, set it so we can use it
gatewayAddress = gateway.Status.Addresses[0].Value

// http route checks
err = k8sClient.Get(context.Background(), types.NamespacedName{Name: "http-route", Namespace: "default"}, &httpRoute)
require.NoError(r, err)

// check our finalizers
require.Len(r, httpRoute.Finalizers, 1)
require.EqualValues(r, gatewayFinalizer, httpRoute.Finalizers[0])
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,4 @@ resources:
- secret.yaml
- serviceaccount.yaml
- psp-rolebinding.yaml
- anyuid-scc-rolebinding.yaml
- privileged-scc-rolebinding.yaml
- privileged-scc-rolebinding.yaml

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,4 @@ resources:
- service.yaml
- serviceaccount.yaml
- psp-rolebinding.yaml
- anyuid-scc-rolebinding.yaml
- privileged-scc-rolebinding.yaml
- privileged-scc-rolebinding.yaml

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,4 @@ resources:
- service.yaml
- serviceaccount.yaml
- psp-rolebinding.yaml
- anyuid-scc-rolebinding.yaml
- privileged-scc-rolebinding.yaml
- privileged-scc-rolebinding.yaml

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,4 @@ resources:
- serviceaccount.yaml
- servicedefaults.yaml
- psp-rolebinding.yaml
- anyuid-scc-rolebinding.yaml
- privileged-scc-rolebinding.yaml
- privileged-scc-rolebinding.yaml

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,4 @@ resources:
- service.yaml
- serviceaccount.yaml
- psp-rolebinding.yaml
- anyuid-scc-rolebinding.yaml
- privileged-scc-rolebinding.yaml
- privileged-scc-rolebinding.yaml

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,4 @@ resources:
- secret.yaml
- serviceaccount.yaml
- psp-rolebinding.yaml
- anyuid-scc-rolebinding.yaml
- privileged-scc-rolebinding.yaml
- privileged-scc-rolebinding.yaml
130 changes: 130 additions & 0 deletions control-plane/connect-inject/common/openshift.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0

// Function copied from:
// https://github.com/openshift/apiserver-library-go/blob/release-4.17/pkg/securitycontextconstraints/sccmatching/matcher.go
// Apache 2.0 license: https://github.com/openshift/apiserver-library-go/blob/release-4.17/LICENSE

// A namespace in OpenShift has the following annotations:
// Annotations: openshift.io/sa.scc.mcs: s0:c27,c4
// openshift.io/sa.scc.uid-range: 1000710000/10000
// openshift.io/sa.scc.supplemental-groups: 1000710000/10000
//
// Note: Even though the annotation is named 'range', it is not a range but the ID you should use. All pods in a
// namespace should use the same UID/GID. (1000710000/1000710000 above)

package common

import (
"fmt"
"strconv"
"strings"

"github.com/hashicorp/consul-k8s/control-plane/connect-inject/constants"
corev1 "k8s.io/api/core/v1"
)

// GetOpenShiftUID gets the user id from the OpenShift annotation 'openshift.io/sa.scc.uid-range'.
func GetOpenShiftUID(ns *corev1.Namespace) (int64, error) {
curtbushko marked this conversation as resolved.
Show resolved Hide resolved
annotation, ok := ns.Annotations[constants.AnnotationOpenShiftUIDRange]
if !ok {
return 0, fmt.Errorf("unable to find annotation %s", constants.AnnotationOpenShiftUIDRange)
}
if len(annotation) == 0 {
return 0, fmt.Errorf("found annotation %s but it was empty", constants.AnnotationOpenShiftUIDRange)
}

uid, err := parseOpenShiftUID(annotation)
if err != nil {
return 0, err
}

return uid, nil
}

// parseOpenShiftUID parses the UID "range" from the annotation string. The annotation can either have a '/' or '-'
// as a separator. '-' is the old style of UID from when it used to be an actual range.
// Example annotation value: "1000700000/100000".
func parseOpenShiftUID(val string) (int64, error) {
curtbushko marked this conversation as resolved.
Show resolved Hide resolved
var uid int64
var err error
if strings.Contains(val, "/") {
str := strings.Split(val, "/")
uid, err = strconv.ParseInt(str[0], 10, 64)
if err != nil {
return 0, err
}
}
if strings.Contains(val, "-") {
str := strings.Split(val, "-")
uid, err = strconv.ParseInt(str[0], 10, 64)
if err != nil {
return 0, err
}
}

if !strings.Contains(val, "/") && !strings.Contains(val, "-") {
return 0, fmt.Errorf(
"annotation %s contains an invalid format for value %s",
constants.AnnotationOpenShiftUIDRange,
val,
)
}

return uid, nil
}

// GetOpenShiftGroup gets the group from OpenShift annotation 'openshift.io/sa.scc.supplemental-groups'
// Fall back to the UID annotation if the group annotation does not exist. The values should
// be the same.
func GetOpenShiftGroup(ns *corev1.Namespace) (int64, error) {
annotation, ok := ns.Annotations[constants.AnnotationOpenShiftGroups]
if !ok {
// fall back to UID annotation
annotation, ok = ns.Annotations[constants.AnnotationOpenShiftUIDRange]
if !ok {
return 0, fmt.Errorf(
"unable to find annotation %s or %s",
constants.AnnotationOpenShiftGroups,
constants.AnnotationOpenShiftUIDRange,
)
}
}
if len(annotation) == 0 {
return 0, fmt.Errorf("found annotation %s but it was empty", constants.AnnotationOpenShiftGroups)
}

uid, err := parseOpenShiftGroup(annotation)
if err != nil {
return 0, err
}

return uid, nil
}

// parseOpenShiftGroup parses the group from the annotation string. The annotation can either have a '/' or ','
// as a separator. ',' is the old style of UID from when it used to be an actual range.
func parseOpenShiftGroup(val string) (int64, error) {
var group int64
var err error
if strings.Contains(val, "/") {
str := strings.Split(val, "/")
group, err = strconv.ParseInt(str[0], 10, 64)
if err != nil {
return 0, err
}
}
if strings.Contains(val, ",") {
str := strings.Split(val, ",")
group, err = strconv.ParseInt(str[0], 10, 64)
if err != nil {
return 0, err
}
}

if !strings.Contains(val, "/") && !strings.Contains(val, ",") {
return 0, fmt.Errorf("annotation %s contains an invalid format for value %s", constants.AnnotationOpenShiftGroups, val)
}

return group, nil
}
Loading
Loading