Skip to content

Commit

Permalink
Adding a hint when the APP CR installation fails due to ca certificat…
Browse files Browse the repository at this point in the history
…e not present in kapp controller

Signed-off-by: rohitagg2020 <[email protected]>
  • Loading branch information
rohitagg2020 committed Oct 11, 2023
1 parent e66ee80 commit 89d51fe
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 0 deletions.
15 changes: 15 additions & 0 deletions pkg/app/app_fetch.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,17 @@ import (
"fmt"
"path"
"strconv"
"strings"
"time"

"github.com/vmware-tanzu/carvel-kapp-controller/pkg/exec"
)

const (
addCACertMissingHintMsg = "(hint: The CA Certificate from URL is unknown. Add it to the kapp-controller configuration to reconcile successfully)"
caCertMissingError = "x509: certificate signed by unknown authority"
)

func (a *App) fetch(dstPath string) (string, exec.CmdRunResult) {
if len(a.app.Spec.Fetch) == 0 {
return "", exec.NewCmdRunResultWithErr(fmt.Errorf("Expected at least one fetch option"))
Expand Down Expand Up @@ -67,6 +73,9 @@ func (a *App) fetch(dstPath string) (string, exec.CmdRunResult) {
}
}
if result.Error != nil {
if strings.Contains(result.Stderr, caCertMissingError) {
result.Stderr = fmt.Sprintf("%s%s", result.Stderr, addCACertMissingHintMsg)
}
return "", result
}
}
Expand All @@ -76,6 +85,12 @@ func (a *App) fetch(dstPath string) (string, exec.CmdRunResult) {
dstPath = path.Join(dstPath, "0")
}

if result.Error != nil {
if strings.Contains(result.Stderr, caCertMissingError) {
result.Stderr = fmt.Sprintf("%s%s", result.Stderr, addCACertMissingHintMsg)
}
}

return dstPath, result
}

Expand Down
85 changes: 85 additions & 0 deletions test/e2e/kappcontroller/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,91 @@ spec:
})
}

func TestConfig_NoCACerts(t *testing.T) {
env := e2e.BuildEnv(t)
logger := e2e.Logger{}
kapp := e2e.Kapp{t, env.Namespace, logger}
sas := e2e.ServiceAccounts{env.Namespace}

name := "test-https"
pkgrName := "test-https-pkgr"
httpsServerName := "test-https-server"
configName := "test-config-missing-ca-config"

yaml1 := fmt.Sprintf(`---
apiVersion: kappctrl.k14s.io/v1alpha1
kind: App
metadata:
name: test-https
annotations:
kapp.k14s.io/change-group: kappctrl-e2e.k14s.io/apps
spec:
serviceAccountName: kappctrl-e2e-ns-sa
fetch:
- http:
# use https to exercise CA certificate validation
# When updating address, certs and keys must be regenerated
# for server and added to e2e/assets/https-server
url: https://https-svc.https-server.svc.cluster.local:443/deployment.yml
template:
- ytt: {}
deploy:
- kapp:
inspect: {}
intoNs: %s
`, env.Namespace) + sas.ForNamespaceYAML()

cleanUp := func() {
kapp.Run([]string{"delete", "-a", name})
kapp.Run([]string{"delete", "-a", pkgrName})
kapp.Run([]string{"delete", "-a", configName})
kapp.Run([]string{"delete", "-a", httpsServerName})
}
cleanUp()
defer cleanUp()

logger.Section("deploy controller config with no CA cert", func() {
config := `
apiVersion: v1
kind: Secret
metadata:
name: kapp-controller-config
namespace: kapp-controller
stringData:
# CA Cert is not present
caCerts:
`
kapp.RunWithOpts([]string{"deploy", "-f", "-", "-a", configName},
e2e.RunOpts{StdinReader: strings.NewReader(config)})

// Since config propagation is async, just wait a little bit
time.Sleep(2 * time.Second)
})

logger.Section("deploy https server with self signed certs", func() {
kapp.Run([]string{"deploy", "-f", "../assets/https-server/", "-a", httpsServerName})
})

logger.Section("deploy app that tries to fetch content from https server (whose certs are not uploaded to kapp-controller)", func() {
_, err := kapp.RunWithOpts([]string{"deploy", "-f", "-", "-a", name}, e2e.RunOpts{
StdinReader: strings.NewReader(yaml1),
AllowError: true,
OnErrKubectl: []string{"get", "app/test-https", "-oyaml"},
})
assert.Error(t, err, "Expected fetching error")

var cr v1alpha1.App

out := kapp.Run([]string{"inspect", "-a", name, "--raw", "--tty=false", "--filter-kind=App"})
assert.NoError(t, yaml.Unmarshal([]byte(out), &cr))

assert.NotNil(t, cr.Status.Fetch)
assert.Equal(t, cr.Status.Fetch.ExitCode, 1)
assert.Contains(t, cr.Status.Fetch.Stderr, "x509: certificate signed by unknown authority")
assert.Contains(t, cr.Status.Fetch.Stderr, "(hint: The CA Certificate from URL is unknown. Add it to the kapp-controller configuration to reconcile successfully)")
})
}

func TestConfig_SkipTLSVerify(t *testing.T) {
env := e2e.BuildEnv(t)
logger := e2e.Logger{}
Expand Down

0 comments on commit 89d51fe

Please sign in to comment.