Skip to content

Commit

Permalink
Merge branch 'main' into renaming-tool
Browse files Browse the repository at this point in the history
  • Loading branch information
bnshr authored Aug 28, 2024
2 parents 825b81c + 44340c8 commit eb1f783
Show file tree
Hide file tree
Showing 15 changed files with 185 additions and 84 deletions.
5 changes: 1 addition & 4 deletions .github/workflows/pre-main.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ env:
OCT_IMAGE_NAME: redhat-best-practices-for-k8s/oct
OCT_IMAGE_TAG: latest
PROBE_IMAGE_NAME: redhat-best-practices-for-k8s/certsuite-probe
PROBE_IMAGE_TAG: v0.0.6
PROBE_IMAGE_TAG: v0.0.7
CERTSUITE_CONFIG_DIR: /tmp/certsuite/config
CERTSUITE_OUTPUT_DIR: /tmp/certsuite/output
SMOKE_TESTS_LOG_LEVEL: debug
Expand Down Expand Up @@ -244,9 +244,6 @@ jobs:
path: |
certsuite-out/*.tar.gz
- name: Remove tarball(s) to save disk space.
run: rm -f certsuite-out/*.tar.gz

- name: Check the smoke test results against the expected results template
run: ./certsuite check results --log-file="certsuite-out/certsuite.log"

Expand Down
2 changes: 1 addition & 1 deletion cmd/certsuite/run/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func NewCommand() *cobra.Command {
runCmd.PersistentFlags().Bool("enable-data-collection", false, "Allow sending test results to an external data collector")
runCmd.PersistentFlags().Bool("create-xml-junit-file", false, "Create a JUnit file with the test results")
runCmd.PersistentFlags().String("certsuite-image-repository", "quay.io/redhat-best-practices-for-k8s", "The repository where Certsuite images are stored")
runCmd.PersistentFlags().String("certsuite-debug-image", "certsuite-probe:v0.0.6", "Name of the certsuite-probe image")
runCmd.PersistentFlags().String("certsuite-debug-image", "certsuite-probe:v0.0.7", "Name of the certsuite-probe image")
runCmd.PersistentFlags().String("daemonset-cpu-req", "100m", "CPU request for the debug DaemonSet container")
runCmd.PersistentFlags().String("daemonset-cpu-lim", "100m", "CPU limit for the debug DaemonSet container")
runCmd.PersistentFlags().String("daemonset-mem-req", "100M", "Memory request for the debug DaemonSet container")
Expand Down
2 changes: 1 addition & 1 deletion docs/runtime-env.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,4 @@ See more about this variable [here](https://github.com/redhat-openshift-ecosyste
against a private container registry that has self-signed certificates.

Note that you can also specify the debug pod image to use with `SUPPORT_IMAGE`
environment variable, default to `certsuite-probe:v0.0.6`.
environment variable, default to `certsuite-probe:v0.0.7`.
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ go 1.22.6

require (
github.com/Masterminds/semver/v3 v3.2.1
github.com/redhat-best-practices-for-k8s/certsuite-claim v1.0.45
github.com/redhat-best-practices-for-k8s/certsuite-claim v1.0.46
github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.8.1
github.com/stretchr/testify v1.9.0
Expand Down Expand Up @@ -215,8 +215,8 @@ require (
github.com/gorilla/websocket v1.5.3
github.com/k8snetworkplumbingwg/network-attachment-definition-client v1.7.1
github.com/manifoldco/promptui v0.9.0
github.com/redhat-best-practices-for-k8s/oct v0.0.19
github.com/redhat-best-practices-for-k8s/privileged-daemonset v1.0.31
github.com/redhat-best-practices-for-k8s/oct v0.0.20
github.com/redhat-best-practices-for-k8s/privileged-daemonset v1.0.33
github.com/redhat-openshift-ecosystem/openshift-preflight v0.0.0-20240715111135-c9048da99aae
github.com/robert-nix/ansihtml v1.0.1
golang.org/x/term v0.23.0
Expand Down
12 changes: 6 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -373,12 +373,12 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT
github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
github.com/redhat-best-practices-for-k8s/certsuite-claim v1.0.45 h1:lvsPZBl4owH80mX2fU879iIz0vYVbjj37CPnMifz5jw=
github.com/redhat-best-practices-for-k8s/certsuite-claim v1.0.45/go.mod h1:ymD8Lckn+C1k/QFalRv5srVro6w1GdcwtyRoSE4XWKM=
github.com/redhat-best-practices-for-k8s/oct v0.0.19 h1:4oy6ebgSFZs6OkNz+wvBbf9JWcDo34JOENpKDQjL+Hc=
github.com/redhat-best-practices-for-k8s/oct v0.0.19/go.mod h1:ucn2BTjdhHWZ7/c0tLmrxCvRedtV8FpjffsD8L233ro=
github.com/redhat-best-practices-for-k8s/privileged-daemonset v1.0.31 h1:LBb6aB2zGUPyROM/C5LOOLvVtGfM4PxvLI5rW0q4ja4=
github.com/redhat-best-practices-for-k8s/privileged-daemonset v1.0.31/go.mod h1:OGSlK+KdZ050HazHfs+9iQbv7fIqtaidNXgWRq5zMbg=
github.com/redhat-best-practices-for-k8s/certsuite-claim v1.0.46 h1:FIMxVB4qGIDIuvQ/oKgbMZoKqC2j6H9vorSGjcL441c=
github.com/redhat-best-practices-for-k8s/certsuite-claim v1.0.46/go.mod h1:zl22noTFxcP05POwr1aMNa13j4M1Fitq8TsxLrw/mJE=
github.com/redhat-best-practices-for-k8s/oct v0.0.20 h1:u2HhR6ilkHYVf1TaHaFstMz5AxnalmhvQ5gcKwO6058=
github.com/redhat-best-practices-for-k8s/oct v0.0.20/go.mod h1:BMcFp+p6SMrtjmkrl+eedhlaHZp1O7ZGuvs2TWhNrJI=
github.com/redhat-best-practices-for-k8s/privileged-daemonset v1.0.33 h1:ZOfbO2vycaV2B154ddLmSszgp8jvcsz9VV0vLslDEXk=
github.com/redhat-best-practices-for-k8s/privileged-daemonset v1.0.33/go.mod h1:56S8vOnBhuSLJ/39uh3NWy5FgsazOB+vId0h1EmVfUs=
github.com/redhat-openshift-ecosystem/openshift-preflight v0.0.0-20240715111135-c9048da99aae h1:ztCHw10EtpMfX1d9Xz/TenJ6XsZrwkGd2uetdrAAMkg=
github.com/redhat-openshift-ecosystem/openshift-preflight v0.0.0-20240715111135-c9048da99aae/go.mod h1:e2SE87xDQYxted00f0zoB4ZhlnGiwaj90kpOcL2J/eA=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
Expand Down
11 changes: 10 additions & 1 deletion pkg/autodiscover/autodiscover.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ type DiscoveredTestData struct {
RoleBindings []rbacv1.RoleBinding // Contains all rolebindings from all namespaces
Roles []rbacv1.Role // Contains all roles from all namespaces
Services []*corev1.Service
ServiceAccounts []*corev1.ServiceAccount
AllServiceAccounts []*corev1.ServiceAccount
Hpas []*scalingv1.HorizontalPodAutoscaler
Subscriptions []olmv1Alpha.Subscription
AllSubscriptions []olmv1Alpha.Subscription
Expand Down Expand Up @@ -250,7 +252,14 @@ func DoAutoDiscover(config *configuration.TestConfiguration) DiscoveredTestData
if err != nil {
log.Fatal("Cannot get list of services, err: %v", err)
}

data.ServiceAccounts, err = getServiceAccounts(oc.K8sClient.CoreV1(), data.Namespaces)
if err != nil {
log.Fatal("Cannot get list of service accounts under test, err: %v", err)
}
data.AllServiceAccounts, err = getServiceAccounts(oc.K8sClient.CoreV1(), []string{metav1.NamespaceAll})
if err != nil {
log.Fatal("Cannot get list of all service accounts, err: %v", err)
}
data.ExecutedBy = config.ExecutedBy
data.PartnerName = config.PartnerName
data.CollectorAppPassword = config.CollectorAppPassword
Expand Down
37 changes: 37 additions & 0 deletions pkg/autodiscover/autodiscover_service_accounts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright (C) 2022-2024 Red Hat, Inc.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
package autodiscover

import (
"context"

corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
)

func getServiceAccounts(oc corev1client.CoreV1Interface, namespaces []string) (servicesAccounts []*corev1.ServiceAccount, err error) {
for _, ns := range namespaces {
s, err := oc.ServiceAccounts(ns).List(context.TODO(), metav1.ListOptions{})
if err != nil {
return servicesAccounts, err
}
for i := range s.Items {
servicesAccounts = append(servicesAccounts, &s.Items[i])
}
}
return servicesAccounts, nil
}
65 changes: 65 additions & 0 deletions pkg/autodiscover/autodiscover_services_accounts_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
// Copyright (C) 2020-2024 Red Hat, Inc.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
package autodiscover

import (
"testing"

"github.com/redhat-best-practices-for-k8s/certsuite/internal/clientsholder"
"github.com/stretchr/testify/assert"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
)

func TestGetServiceAccounts(t *testing.T) {
generateServiceAccount := func(name, namespace string) *corev1.ServiceAccount {
return &corev1.ServiceAccount{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
},
}
}

testCases := []struct {
serviceAccountName string
serviceAccountNamespace string
expectedServiceAccounts []*corev1.ServiceAccount
}{
{
serviceAccountName: "testServiceAccount",
serviceAccountNamespace: "tnf",
expectedServiceAccounts: []*corev1.ServiceAccount{
{
ObjectMeta: metav1.ObjectMeta{
Name: "testServiceAccount",
Namespace: "tnf",
},
},
},
},
}

for _, tc := range testCases {
var testRuntimeObjects []runtime.Object
testRuntimeObjects = append(testRuntimeObjects, generateServiceAccount(tc.serviceAccountName, tc.serviceAccountNamespace))
oc := clientsholder.GetTestClientsHolder(testRuntimeObjects)
services, err := getServiceAccounts(oc.K8sClient.CoreV1(), []string{tc.serviceAccountNamespace})
assert.Nil(t, err)
assert.Equal(t, tc.expectedServiceAccounts, services)
}
}
15 changes: 15 additions & 0 deletions pkg/provider/pods.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ const (

type Pod struct {
*corev1.Pod
AllServiceAccountsMap *map[string]*corev1.ServiceAccount
Containers []*Container
MultusNetworkInterfaces map[string]CniNetworkInterface
MultusPCIs []string
Expand Down Expand Up @@ -416,3 +417,17 @@ func (p *Pod) IsRunAsNonRoot() bool {
func (p *Pod) GetTopOwner() (topOwners map[string]podhelper.TopOwner, err error) {
return podhelper.GetPodTopOwner(p.Namespace, p.OwnerReferences)
}

// AutomountServiceAccountSetOnSA checks if the AutomountServiceAccountToken field is set on the pod's ServiceAccount.
// Returns:
// - A boolean pointer indicating whether the AutomountServiceAccountToken field is set.
// - An error if any occurred during the operation.
func (p *Pod) IsAutomountServiceAccountSetOnSA() (isSet *bool, err error) {
if p.AllServiceAccountsMap == nil {
return isSet, fmt.Errorf("AllServiceAccountsMap is not initialized for pod with ns: %s and name %s", p.Namespace, p.Name)
}
if _, ok := (*p.AllServiceAccountsMap)[p.Namespace+p.Spec.ServiceAccountName]; !ok {
return isSet, fmt.Errorf("could not find a service account with ns: %s and name %s", p.Namespace, p.Spec.ServiceAccountName)
}
return (*p.AllServiceAccountsMap)[p.Namespace+p.Spec.ServiceAccountName].AutomountServiceAccountToken, nil
}
25 changes: 20 additions & 5 deletions pkg/provider/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,11 +100,14 @@ type TestEnvironment struct { // rename this with testTarget

HorizontalScaler []*scalingv1.HorizontalPodAutoscaler `json:"testHorizontalScaler"`
Services []*corev1.Service `json:"testServices"`
Nodes map[string]Node `json:"-"`
K8sVersion string `json:"-"`
OpenshiftVersion string `json:"-"`
OCPStatus string `json:"-"`
HelmChartReleases []*release.Release `json:"testHelmChartReleases"`
ServiceAccounts []*corev1.ServiceAccount `json:"testServiceAccounts"`
AllServiceAccounts []*corev1.ServiceAccount `json:"AllServiceAccounts"`
AllServiceAccountsMap map[string]*corev1.ServiceAccount
Nodes map[string]Node `json:"-"`
K8sVersion string `json:"-"`
OpenshiftVersion string `json:"-"`
OCPStatus string `json:"-"`
HelmChartReleases []*release.Release `json:"testHelmChartReleases"`
ResourceQuotas []corev1.ResourceQuota
PodDisruptionBudgets []policyv1.PodDisruptionBudget
NetworkPolicies []networkingv1.NetworkPolicy
Expand Down Expand Up @@ -240,16 +243,27 @@ func buildTestEnvironment() { //nolint:funlen
aEvent := NewEvent(&data.AbnormalEvents[i])
env.AbnormalEvents = append(env.AbnormalEvents, &aEvent)
}
// Service accounts
env.ServiceAccounts = data.ServiceAccounts
env.AllServiceAccounts = data.AllServiceAccounts
env.AllServiceAccountsMap = make(map[string]*corev1.ServiceAccount)
for i := 0; i < len(data.AllServiceAccounts); i++ {
mapIndex := data.AllServiceAccounts[i].ObjectMeta.Namespace + data.AllServiceAccounts[i].ObjectMeta.Name
env.AllServiceAccountsMap[mapIndex] = data.AllServiceAccounts[i]
}
// Pods
pods := data.Pods
for i := 0; i < len(pods); i++ {
aNewPod := NewPod(&pods[i])
aNewPod.AllServiceAccountsMap = &env.AllServiceAccountsMap
env.Pods = append(env.Pods, &aNewPod)
// Note: 'getPodContainers' is returning a filtered list of Container objects.
env.Containers = append(env.Containers, getPodContainers(&pods[i], true)...)
}
pods = data.AllPods
for i := 0; i < len(pods); i++ {
aNewPod := NewPod(&pods[i])
aNewPod.AllServiceAccountsMap = &env.AllServiceAccountsMap
env.AllPods = append(env.AllPods, &aNewPod)
}
env.DebugPods = make(map[string]*corev1.Pod)
Expand All @@ -263,6 +277,7 @@ func buildTestEnvironment() { //nolint:funlen
var pods []*Pod
for i := 0; i < len(podList); i++ {
aNewPod := NewPod(podList[i])
aNewPod.AllServiceAccountsMap = &env.AllServiceAccountsMap
pods = append(pods, &aNewPod)
}
env.CSVToPodListMap[k] = pods
Expand Down
2 changes: 1 addition & 1 deletion tests/accesscontrol/suite.go
Original file line number Diff line number Diff line change
Expand Up @@ -730,7 +730,7 @@ func testAutomountServiceToken(check *checksdb.Check, env *provider.TestEnvironm

// Evaluate the pod's automount service tokens and any attached service accounts
client := clientsholder.GetClientsHolder()
podPassed, newMsg := rbac.EvaluateAutomountTokens(client.K8sClient.CoreV1(), put.Pod)
podPassed, newMsg := rbac.EvaluateAutomountTokens(client.K8sClient.CoreV1(), put)
if !podPassed {
//nolint:govet
check.LogError(newMsg)
Expand Down
24 changes: 4 additions & 20 deletions tests/common/rbac/automount.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,36 +17,20 @@
package rbac

import (
"context"
"fmt"

"github.com/redhat-best-practices-for-k8s/certsuite/internal/log"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/redhat-best-practices-for-k8s/certsuite/pkg/provider"
corev1typed "k8s.io/client-go/kubernetes/typed/core/v1"
)

// AutomountServiceAccountSetOnSA checks if the AutomountServiceAccountToken field is set on a ServiceAccount.
// Returns:
// - A boolean pointer indicating whether the AutomountServiceAccountToken field is set.
// - An error if any occurred during the operation.
func AutomountServiceAccountSetOnSA(client corev1typed.CoreV1Interface, serviceAccountName, podNamespace string) (*bool, error) {
sa, err := client.ServiceAccounts(podNamespace).Get(context.TODO(), serviceAccountName, metav1.GetOptions{})
if err != nil {
log.Error("executing serviceaccount command failed with error: %v", err)
return nil, err
}
return sa.AutomountServiceAccountToken, nil
}

// EvaluateAutomountTokens evaluates whether the automountServiceAccountToken is correctly configured for the given Pod.
// Checks if the token is explicitly set in the Pod's spec or if it is inherited from the associated ServiceAccount.
// Returns:
// - bool: Indicates whether the Pod passed all checks. if yes- return true, otherwise return false.
// - string: Error message if the Pod is misconfigured, otherwise an empty string.
//
//nolint:gocritic
func EvaluateAutomountTokens(client corev1typed.CoreV1Interface, put *corev1.Pod) (bool, string) {
func EvaluateAutomountTokens(client corev1typed.CoreV1Interface, put *provider.Pod) (bool, string) {
// The token can be specified in the pod directly
// or it can be specified in the service account of the pod
// if no service account is configured, then the pod will use the configuration
Expand All @@ -59,9 +43,9 @@ func EvaluateAutomountTokens(client corev1typed.CoreV1Interface, put *corev1.Pod
}

// Collect information about the service account attached to the pod.
saAutomountServiceAccountToken, err := AutomountServiceAccountSetOnSA(client, put.Spec.ServiceAccountName, put.Namespace)
saAutomountServiceAccountToken, err := put.IsAutomountServiceAccountSetOnSA()
if err != nil {
return false, ""
return false, err.Error()
}

// The pod token is false means the pod is configured properly
Expand Down
Loading

0 comments on commit eb1f783

Please sign in to comment.