Compare commits
7 Commits
unset
...
pf_mongo_t
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
26955d749e | ||
|
|
3e678d9056 | ||
|
|
ec9423330d | ||
|
|
c5b6443179 | ||
|
|
a228757e0b | ||
|
|
8f2e464d0e | ||
|
|
9d547bfe0c |
@@ -152,7 +152,7 @@ func pfDeploymentCheckCmd(q *qliksense.Qliksense) *cobra.Command {
|
||||
}
|
||||
var pfDeploymentCheckCmd = &cobra.Command{
|
||||
Use: "deployment",
|
||||
Short: "perform preflight deploymwnt check",
|
||||
Short: "perform preflight deployment check",
|
||||
Long: `perform preflight deployment check to ensure that we can create deployments in the cluster`,
|
||||
Example: `qliksense preflight deployment`,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
@@ -337,7 +337,7 @@ func pfCreateServiceAccountCheckCmd(q *qliksense.Qliksense) *cobra.Command {
|
||||
|
||||
var preflightServiceAccountCmd = &cobra.Command{
|
||||
Use: "serviceaccount",
|
||||
Short: "preflight create ServiceAccount check",
|
||||
Short: "preflight create serviceaccount check",
|
||||
Long: `perform preflight serviceaccount check to ensure we are able to create a service account in the cluster`,
|
||||
Example: `qliksense preflight serviceaccount`,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
|
||||
@@ -16,9 +16,18 @@ Examples:
|
||||
qliksense preflight <preflight_check_to_run>
|
||||
|
||||
Available Commands:
|
||||
all perform all checks
|
||||
dns perform preflight dns check
|
||||
k8s-version check k8s version
|
||||
all perform all checks
|
||||
authcheck preflight authcheck
|
||||
clean perform preflight clean
|
||||
deployment perform preflight deployment check
|
||||
dns perform preflight dns check
|
||||
kube-version check kubernetes version
|
||||
mongo preflight mongo OR preflight mongo --url=<url>
|
||||
pod perform preflight pod check
|
||||
role preflight create role check
|
||||
rolebinding preflight create rolebinding check
|
||||
service perform preflight service check
|
||||
serviceaccount preflight create ServiceAccount check
|
||||
|
||||
Flags:
|
||||
-h, --help help for preflight
|
||||
@@ -200,8 +209,8 @@ We can check if we are able to connect to an instance of mongodb on the cluster
|
||||
qliksense preflight mongo --url=<url> -v OR
|
||||
qliksense preflight mongo -v
|
||||
qliksense preflight mongo --url=<mongo-server url> --ca-cert=<path to ca-cert file> -v
|
||||
|
||||
|
||||
```
|
||||
```shell
|
||||
Preflight mongo check
|
||||
---------------------
|
||||
Preflight mongodb check:
|
||||
@@ -217,7 +226,29 @@ Deleted pod: pf-mongo-pod
|
||||
Completed preflight mongodb check
|
||||
```
|
||||
|
||||
#### Mongodb check with mutual tls
|
||||
In order to perform mutual tls with mongo we need to:
|
||||
- append client certificate to the beginning/end of CA certificate. Make sure to include the beginning and end tags on each certificate.
|
||||
The CA certificate file should look like this in the end:
|
||||
```shell
|
||||
<existing contents of CA cert>
|
||||
...
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
<private key>
|
||||
-----END RSA PRIVATE KEY-----
|
||||
-----BEGIN CERTIFICATE-----
|
||||
<public key>
|
||||
-----END CERTIFICATE-----
|
||||
```
|
||||
- Run the command below to set the ca certificate into the CR
|
||||
```shell
|
||||
cat <path_to_ca.crt> | base64 | qliksense config set-secrets qliksense.caCertificates --base64
|
||||
```
|
||||
|
||||
Next, run:
|
||||
```shell
|
||||
qliksense preflight mongo -v
|
||||
```
|
||||
|
||||
### Running all checks
|
||||
Run the command shown below to execute all preflight checks.
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package preflight
|
||||
|
||||
import (
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
@@ -74,8 +75,35 @@ func (qp *QliksensePreflight) CheckMongo(kubeConfigContents []byte, namespace st
|
||||
return errors.New("MongoDbUrl is empty")
|
||||
}
|
||||
}
|
||||
if err := qp.mongoConnCheck(kubeConfigContents, namespace, preflightOpts, cleanup); err != nil {
|
||||
return err
|
||||
var privKeys []string
|
||||
var err error
|
||||
if preflightOpts.MongoOptions.CaCertFile != "" && preflightOpts.MongoOptions.ClientCertFile == "" {
|
||||
privKeys, err = qp.extractPrivateKeysFromCA(preflightOpts.MongoOptions.CaCertFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to parse CA cert: %v", err)
|
||||
}
|
||||
}
|
||||
privKeyCount := len(privKeys)
|
||||
if privKeyCount == 0 {
|
||||
api.LogDebugMessage("no private keys extrated from CA, hence proceeding with usual flow\n")
|
||||
if err := qp.mongoConnCheck(kubeConfigContents, namespace, preflightOpts, cleanup); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
api.LogDebugMessage("found %d private keys\n", privKeyCount)
|
||||
successCount := 0
|
||||
for _, privKey := range privKeys {
|
||||
preflightOpts.MongoOptions.ClientCertFile = privKey
|
||||
if err1 := qp.mongoConnCheck(kubeConfigContents, namespace, preflightOpts, cleanup); err1 != nil {
|
||||
err = err1
|
||||
continue
|
||||
}
|
||||
successCount++
|
||||
break
|
||||
}
|
||||
if successCount == 0 {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if !cleanup {
|
||||
qp.P.LogVerboseMessage("Completed preflight mongodb check\n")
|
||||
@@ -247,3 +275,41 @@ func (qp *QliksensePreflight) runMongoCleanup(clientset *kubernetes.Clientset, n
|
||||
qp.deleteK8sSecret(clientset, namespace, caCertSecretName)
|
||||
qp.deleteK8sSecret(clientset, namespace, clientCertSecretName)
|
||||
}
|
||||
|
||||
func (qp *QliksensePreflight) extractPrivateKeysFromCA(cafile string) ([]string, error) {
|
||||
api.LogDebugMessage("extracting private keys from CA file: %s\n", cafile)
|
||||
raw, err := ioutil.ReadFile(cafile)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dirPath := os.TempDir()
|
||||
count := 0
|
||||
var files []string
|
||||
for {
|
||||
block, rest := pem.Decode(raw)
|
||||
if block == nil {
|
||||
break
|
||||
}
|
||||
if block.Type != "CERTIFICATE" {
|
||||
api.LogDebugMessage("found a private key\n")
|
||||
privFile := filepath.Join(dirPath, fmt.Sprintf("mongo_priv_%d.key", count+1))
|
||||
api.LogDebugMessage("creating a private key file: %s\n", privFile)
|
||||
keyData := pem.EncodeToMemory(block)
|
||||
block, rest = pem.Decode(rest)
|
||||
if block != nil && block.Type == "CERTIFICATE" {
|
||||
api.LogDebugMessage("block type: %s\n", block.Type)
|
||||
keyData = append(keyData, pem.EncodeToMemory(block)...)
|
||||
}
|
||||
api.LogDebugMessage("key data: %s\n", keyData)
|
||||
if err := ioutil.WriteFile(privFile, keyData, 0600); err != nil {
|
||||
return nil, fmt.Errorf("error writing private key to file: \"%s\"", privFile)
|
||||
}
|
||||
api.LogDebugMessage("successfully wrote contents to the private key file\n")
|
||||
files = append(files, privFile)
|
||||
count++
|
||||
}
|
||||
raw = rest
|
||||
}
|
||||
api.LogDebugMessage("extracted private key files: %v\n", files)
|
||||
return files, nil
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/mitchellh/go-homedir"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/qlik-oss/sense-installer/pkg/api"
|
||||
"github.com/qlik-oss/sense-installer/pkg/qliksense"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
@@ -115,13 +114,13 @@ func getK8SClientSet(kubeconfig []byte, contextName string) (*kubernetes.Clients
|
||||
if len(kubeconfig) == 0 {
|
||||
clientConfig, err = rest.InClusterConfig()
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, "Unable to load in-cluster kubeconfig")
|
||||
err = fmt.Errorf("Unable to load in-cluster kubeconfig: %w", err)
|
||||
return nil, nil, err
|
||||
}
|
||||
} else {
|
||||
config, err := clientcmd.Load(kubeconfig)
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, "Unable to load kubeconfig")
|
||||
err = fmt.Errorf("Unable to load kubeconfig: %w", err)
|
||||
return nil, nil, err
|
||||
}
|
||||
if contextName != "" {
|
||||
@@ -129,13 +128,13 @@ func getK8SClientSet(kubeconfig []byte, contextName string) (*kubernetes.Clients
|
||||
}
|
||||
clientConfig, err = clientcmd.NewDefaultClientConfig(*config, &clientcmd.ConfigOverrides{}).ClientConfig()
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, "Unable to create client config from config")
|
||||
err = fmt.Errorf("Unable to create client config from config: %w", err)
|
||||
return nil, nil, err
|
||||
}
|
||||
}
|
||||
clientset, err := kubernetes.NewForConfig(clientConfig)
|
||||
if err != nil {
|
||||
err = errors.Wrap(err, "Unable to create clientset")
|
||||
err = fmt.Errorf("Unable to create clientset: %w", err)
|
||||
return nil, nil, err
|
||||
}
|
||||
return clientset, clientConfig, nil
|
||||
@@ -186,7 +185,7 @@ func (qp *QliksensePreflight) createPreflightTestDeployment(clientset *kubernete
|
||||
result, err = deploymentsClient.Create(deployment)
|
||||
return err
|
||||
}); err != nil {
|
||||
err = errors.Wrapf(err, "unable to create deployments in the %s namespace", namespace)
|
||||
err = fmt.Errorf("unable to create deployments in the %s namespace: %w", namespace, err)
|
||||
return nil, err
|
||||
}
|
||||
qp.P.LogVerboseMessage("Created deployment %q\n", result.GetObjectMeta().GetName())
|
||||
@@ -201,7 +200,7 @@ func getDeployment(clientset *kubernetes.Clientset, namespace, depName string) (
|
||||
deployment, err = deploymentsClient.Get(depName, v1.GetOptions{})
|
||||
return err
|
||||
}); err != nil {
|
||||
err = errors.Wrapf(err, "unable to get deployments in the %s namespace", namespace)
|
||||
err = fmt.Errorf("unable to get deployments in the %s namespace: %w", namespace, err)
|
||||
api.LogDebugMessage("%v\n", err)
|
||||
return nil, err
|
||||
}
|
||||
@@ -271,7 +270,7 @@ func getService(clientset *kubernetes.Clientset, namespace, svcName string) (*ap
|
||||
svc, err = servicesClient.Get(svcName, v1.GetOptions{})
|
||||
return err
|
||||
}); err != nil {
|
||||
err = errors.Wrapf(err, "unable to get services in the %s namespace", namespace)
|
||||
err = fmt.Errorf("unable to get services in the %s namespace: %w", namespace, err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user