github.com/Racer159/jackal@v0.32.7-0.20240401174413-0bd2339e4f2e/src/test/e2e/22_git_and_gitops_test.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // SPDX-FileCopyrightText: 2021-Present The Jackal Authors
     3  
     4  // Package test provides e2e tests for Jackal.
     5  package test
     6  
     7  import (
     8  	"encoding/base64"
     9  	"encoding/json"
    10  	"fmt"
    11  	"net/http"
    12  	"path/filepath"
    13  	"testing"
    14  
    15  	"github.com/Racer159/jackal/src/internal/packager/git"
    16  	"github.com/Racer159/jackal/src/pkg/cluster"
    17  	"github.com/Racer159/jackal/src/types"
    18  	"github.com/stretchr/testify/require"
    19  )
    20  
    21  func TestGit(t *testing.T) {
    22  	t.Log("E2E: Git")
    23  	e2e.SetupWithCluster(t)
    24  
    25  	buildPath := filepath.Join("src", "test", "packages", "22-git-data")
    26  	stdOut, stdErr, err := e2e.Jackal("package", "create", buildPath, "-o=build", "--confirm")
    27  	require.NoError(t, err, stdOut, stdErr)
    28  
    29  	path := fmt.Sprintf("build/jackal-package-git-data-test-%s-1.0.0.tar.zst", e2e.Arch)
    30  	defer e2e.CleanFiles(path)
    31  
    32  	// Deploy the git data example (with component globbing to test that as well)
    33  	stdOut, stdErr, err = e2e.Jackal("package", "deploy", path, "--components=full-repo,specific-*", "--confirm")
    34  	require.NoError(t, err, stdOut, stdErr)
    35  
    36  	c, err := cluster.NewCluster()
    37  	require.NoError(t, err)
    38  	tunnelGit, err := c.Connect(cluster.JackalGit)
    39  	require.NoError(t, err)
    40  	defer tunnelGit.Close()
    41  
    42  	testGitServerConnect(t, tunnelGit.HTTPEndpoint())
    43  	testGitServerReadOnly(t, tunnelGit.HTTPEndpoint())
    44  	testGitServerTagAndHash(t, tunnelGit.HTTPEndpoint())
    45  }
    46  
    47  func TestGitOpsFlux(t *testing.T) {
    48  	t.Log("E2E: GitOps / Flux")
    49  	e2e.SetupWithCluster(t)
    50  
    51  	waitFluxPodInfoDeployment(t)
    52  }
    53  
    54  func TestGitOpsArgoCD(t *testing.T) {
    55  	t.Log("E2E: ArgoCD / Flux")
    56  	e2e.SetupWithCluster(t)
    57  
    58  	waitArgoDeployment(t)
    59  }
    60  
    61  func testGitServerConnect(t *testing.T, gitURL string) {
    62  	// Make sure Gitea comes up cleanly
    63  	resp, err := http.Get(gitURL + "/explore/repos")
    64  	require.NoError(t, err)
    65  	require.Equal(t, 200, resp.StatusCode)
    66  }
    67  
    68  func testGitServerReadOnly(t *testing.T, gitURL string) {
    69  	// Init the state variable
    70  	state, err := cluster.NewClusterOrDie().LoadJackalState()
    71  	require.NoError(t, err)
    72  
    73  	gitCfg := git.New(state.GitServer)
    74  
    75  	// Get the repo as the readonly user
    76  	repoName := "jackal-public-test-2469062884"
    77  	getRepoRequest, _ := http.NewRequest("GET", fmt.Sprintf("%s/api/v1/repos/%s/%s", gitURL, state.GitServer.PushUsername, repoName), nil)
    78  	getRepoResponseBody, _, err := gitCfg.DoHTTPThings(getRepoRequest, types.JackalGitReadUser, state.GitServer.PullPassword)
    79  	require.NoError(t, err)
    80  
    81  	// Make sure the only permissions are pull (read)
    82  	var bodyMap map[string]interface{}
    83  	err = json.Unmarshal(getRepoResponseBody, &bodyMap)
    84  	require.NoError(t, err)
    85  	permissionsMap := bodyMap["permissions"].(map[string]interface{})
    86  	require.False(t, permissionsMap["admin"].(bool))
    87  	require.False(t, permissionsMap["push"].(bool))
    88  	require.True(t, permissionsMap["pull"].(bool))
    89  }
    90  
    91  func testGitServerTagAndHash(t *testing.T, gitURL string) {
    92  	// Init the state variable
    93  	state, err := cluster.NewClusterOrDie().LoadJackalState()
    94  	require.NoError(t, err, "Failed to load Jackal state")
    95  	repoName := "jackal-public-test-2469062884"
    96  
    97  	gitCfg := git.New(state.GitServer)
    98  
    99  	// Get the Jackal repo tag
   100  	repoTag := "v0.0.1"
   101  	getRepoTagsRequest, _ := http.NewRequest("GET", fmt.Sprintf("%s/api/v1/repos/%s/%s/tags/%s", gitURL, types.JackalGitPushUser, repoName, repoTag), nil)
   102  	getRepoTagsResponseBody, _, err := gitCfg.DoHTTPThings(getRepoTagsRequest, types.JackalGitReadUser, state.GitServer.PullPassword)
   103  	require.NoError(t, err)
   104  
   105  	// Make sure the pushed tag exists
   106  	var tagMap map[string]interface{}
   107  	err = json.Unmarshal(getRepoTagsResponseBody, &tagMap)
   108  	require.NoError(t, err)
   109  	require.Equal(t, repoTag, tagMap["name"])
   110  
   111  	// Get the Jackal repo commit
   112  	repoHash := "01a23218923f24194133b5eb11268cf8d73ff1bb"
   113  	getRepoCommitsRequest, _ := http.NewRequest("GET", fmt.Sprintf("%s/api/v1/repos/%s/%s/git/commits/%s", gitURL, types.JackalGitPushUser, repoName, repoHash), nil)
   114  	getRepoCommitsResponseBody, _, err := gitCfg.DoHTTPThings(getRepoCommitsRequest, types.JackalGitReadUser, state.GitServer.PullPassword)
   115  	require.NoError(t, err)
   116  	require.Contains(t, string(getRepoCommitsResponseBody), repoHash)
   117  }
   118  
   119  func waitFluxPodInfoDeployment(t *testing.T) {
   120  	// Deploy the flux example and verify that it works
   121  	path := fmt.Sprintf("build/jackal-package-podinfo-flux-%s.tar.zst", e2e.Arch)
   122  	stdOut, stdErr, err := e2e.Jackal("package", "deploy", path, "--confirm")
   123  	require.NoError(t, err, stdOut, stdErr)
   124  
   125  	// Tests the URL mutation for GitRepository CRD for Flux.
   126  	stdOut, stdErr, err = e2e.Kubectl("get", "gitrepositories", "podinfo", "-n", "flux-system", "-o", "jsonpath={.spec.url}")
   127  	require.NoError(t, err, stdOut, stdErr)
   128  	expectedMutatedRepoURL := fmt.Sprintf("%s/%s/podinfo-1646971829.git", types.JackalInClusterGitServiceURL, types.JackalGitPushUser)
   129  	require.Equal(t, expectedMutatedRepoURL, stdOut)
   130  
   131  	// Remove the flux example when deployment completes
   132  	stdOut, stdErr, err = e2e.Jackal("package", "remove", "podinfo-flux", "--confirm")
   133  	require.NoError(t, err, stdOut, stdErr)
   134  
   135  	// Prune the flux images to reduce disk pressure
   136  	stdOut, stdErr, err = e2e.Jackal("tools", "registry", "prune", "--confirm")
   137  	require.NoError(t, err, stdOut, stdErr)
   138  }
   139  
   140  func waitArgoDeployment(t *testing.T) {
   141  	// Deploy the argocd example and verify that it works
   142  	path := fmt.Sprintf("build/jackal-package-argocd-%s.tar.zst", e2e.Arch)
   143  	stdOut, stdErr, err := e2e.Jackal("package", "deploy", path, "--components=argocd-apps", "--confirm")
   144  	require.NoError(t, err, stdOut, stdErr)
   145  
   146  	expectedMutatedRepoURL := fmt.Sprintf("%s/%s/podinfo-1646971829.git", types.JackalInClusterGitServiceURL, types.JackalGitPushUser)
   147  
   148  	// Tests the mutation of the private repository Secret for ArgoCD.
   149  	stdOut, stdErr, err = e2e.Kubectl("get", "secret", "argocd-repo-github-podinfo", "-n", "argocd", "-o", "jsonpath={.data.url}")
   150  	require.NoError(t, err, stdOut, stdErr)
   151  
   152  	expectedMutatedPrivateRepoURLSecret, err := base64.StdEncoding.DecodeString(stdOut)
   153  	require.NoError(t, err, stdOut, stdErr)
   154  	require.Equal(t, expectedMutatedRepoURL, string(expectedMutatedPrivateRepoURLSecret))
   155  
   156  	// Tests the mutation of the repoURL for Application CRD source(s) for ArgoCD.
   157  	stdOut, stdErr, err = e2e.Kubectl("get", "application", "apps", "-n", "argocd", "-o", "jsonpath={.spec.sources[0].repoURL}")
   158  	require.NoError(t, err, stdOut, stdErr)
   159  	require.Equal(t, expectedMutatedRepoURL, stdOut)
   160  
   161  	// Remove the argocd example when deployment completes
   162  	stdOut, stdErr, err = e2e.Jackal("package", "remove", "argocd", "--confirm")
   163  	require.NoError(t, err, stdOut, stdErr)
   164  
   165  	// Prune the ArgoCD images to reduce disk pressure
   166  	stdOut, stdErr, err = e2e.Jackal("tools", "registry", "prune", "--confirm")
   167  	require.NoError(t, err, stdOut, stdErr)
   168  }