github.com/darmach/terratest@v0.34.8-0.20210517103231-80931f95e3ff/test/kubernetes_rbac_example_test.go (about)

     1  // +build kubeall kubernetes
     2  
     3  // NOTE: we have build tags to differentiate kubernetes tests from non-kubernetes tests. This is done because minikube
     4  // is heavy and can interfere with docker related tests in terratest. Specifically, many of the tests start to fail with
     5  // `connection refused` errors from `minikube`. To avoid overloading the system, we run the kubernetes tests and helm
     6  // tests separately from the others. This may not be necessary if you have a sufficiently powerful machine.  We
     7  // recommend at least 4 cores and 16GB of RAM if you want to run all the tests together.
     8  
     9  package test
    10  
    11  import (
    12  	"os"
    13  	"path/filepath"
    14  	"testing"
    15  
    16  	"github.com/stretchr/testify/require"
    17  	authv1 "k8s.io/api/authorization/v1"
    18  
    19  	"github.com/gruntwork-io/terratest/modules/k8s"
    20  )
    21  
    22  // An example of how to test the Kubernetes resource config in examples/kubernetes-rbac-example using Terratest,
    23  // including whether or not the permissions are set correctly.
    24  func TestKubernetesRBACExample(t *testing.T) {
    25  	t.Parallel()
    26  
    27  	// These are pulled from the kubernetes resource config
    28  	const serviceAccountName = "terratest-rbac-example-service-account"
    29  	const namespaceName = "terratest-rbac-example-namespace"
    30  
    31  	// Path to the Kubernetes resource config we will test
    32  	kubeResourcePath, err := filepath.Abs("../examples/kubernetes-rbac-example/namespace-service-account.yml")
    33  	require.NoError(t, err)
    34  
    35  	// Setup the kubectl config and context. Here we choose to create a new one because we will be manipulating the
    36  	// entries to be able to add a new authentication option.
    37  	tmpConfigPath := k8s.CopyHomeKubeConfigToTemp(t)
    38  	defer os.Remove(tmpConfigPath)
    39  	options := k8s.NewKubectlOptions("", tmpConfigPath, namespaceName)
    40  
    41  	// At the end of the test, run `kubectl delete -f RESOURCE_CONFIG` to clean up any resources that were created.
    42  	defer k8s.KubectlDelete(t, options, kubeResourcePath)
    43  
    44  	// This will run `kubectl apply -f RESOURCE_CONFIG` and fail the test if there are any errors
    45  	k8s.KubectlApply(t, options, kubeResourcePath)
    46  
    47  	// Retrieve authentication token for the newly created ServiceAccount
    48  	token := k8s.GetServiceAccountAuthToken(t, options, serviceAccountName)
    49  
    50  	// Now update the configuration to add a new context that can be used to make requests as that service account
    51  	require.NoError(t, k8s.AddConfigContextForServiceAccountE(
    52  		t,
    53  		options,
    54  		serviceAccountName, // for this test we will name the context after the ServiceAccount
    55  		serviceAccountName,
    56  		token,
    57  	))
    58  	serviceAccountKubectlOptions := k8s.NewKubectlOptions(serviceAccountName, tmpConfigPath, namespaceName)
    59  
    60  	// At this point all requests made with serviceAccountKubectlOptions will be auth'd as that ServiceAccount. So let's
    61  	// verify that! We will check:
    62  	// - we can't access the kube-system namespace
    63  	adminListPodAction := authv1.ResourceAttributes{
    64  		Namespace: "kube-system",
    65  		Verb:      "list",
    66  		Resource:  "pod",
    67  	}
    68  	require.False(t, k8s.CanIDo(t, serviceAccountKubectlOptions, adminListPodAction))
    69  	// - we can access the namespace the service account is in
    70  	namespaceListPodAction := authv1.ResourceAttributes{
    71  		Namespace: namespaceName,
    72  		Verb:      "list",
    73  		Resource:  "pod",
    74  	}
    75  	require.True(t, k8s.CanIDo(t, serviceAccountKubectlOptions, namespaceListPodAction))
    76  }