Compare commits

..

29 Commits

Author SHA1 Message Date
Foysal Iqbal
75ce6caa2b random prefix
Signed-off-by: Foysal Iqbal <mqb@qlik.com>
2020-04-06 00:17:54 -04:00
Ashwathi Shiva
d05b119a68 remove namespace from role, rolebinding and SA checks 2020-04-05 23:31:47 -04:00
Ashwathi Shiva
ed26e692c9 Merge branch 'master' into preflight_pretty_print
# Conflicts:
#	pkg/preflight/role_check.go
#	pkg/qliksense/kuz.go
2020-04-05 21:28:05 -04:00
Ashwathi Shiva
5909c728ab - possible fix for restricting role and role binding checks to only install their specific types
- moved kubectl delete to defer to force clean up
2020-04-05 21:25:19 -04:00
Ashwathi Shiva
813bec2377 Preflight commands (#276)
* preflight role, roleBinding, serviceAccount, mongo, all checks working
* Updated readme

Co-authored-by: Foysal Iqbal <mqb@qlik.com>
2020-04-05 19:07:01 -04:00
Ashwathi Shiva
d77654e763 Updated readme 2020-04-05 19:05:03 -04:00
Ashwathi Shiva
73c3ac1d58 Merge branch 'master' into preflight_roles 2020-04-05 17:30:59 -04:00
Ashwathi Shiva
083203128c passed mongo url to preflight all command, addressed some PR comments 2020-04-05 17:27:54 -04:00
Foysal Iqbal
97cbfa050c Fix regex (#278) 2020-04-05 15:32:14 -04:00
Foysal Iqbal
ccc2997745 fix entity creation
Signed-off-by: Foysal Iqbal <mqb@qlik.com>
2020-04-04 13:44:18 -04:00
Ashwathi Shiva
1f5ee3d487 Merge branch 'master' into preflight_roles 2020-04-04 01:37:58 -04:00
Ashwathi Shiva
87ace81dee renamed some commands and cleaned up some messages 2020-04-04 01:33:20 -04:00
Foysal Iqbal
44b936a9aa add custom crds (#277)
Signed-off-by: Foysal Iqbal <mqb@qlik.com>
2020-04-04 01:16:13 -04:00
Ashwathi Shiva
2618e72a46 display the mongodb url 2020-04-03 11:18:13 -04:00
Ashwathi Shiva
1aac550f66 mongodbUrl inferred from CR 2020-04-03 08:04:29 -04:00
Ashwathi Shiva
bacaea1b92 Merge branch 'master' into preflight_roles
# Conflicts:
#	pkg/preflight/deployability.go
2020-04-03 01:23:09 -04:00
Ashwathi Shiva
acfa1f16a1 updated readme 2020-04-03 01:18:59 -04:00
Ashwathi Shiva
8b68a4d305 updated qliksense preflight all to update mongodb check 2020-04-03 01:08:06 -04:00
Ashwathi Shiva
114d0a13c8 preflight mongo --url=url working 2020-04-03 00:47:49 -04:00
Ashwathi Shiva
c733d2821e Merge branch 'preflight_roles' of github.com:qlik-oss/sense-installer into preflight_roles 2020-04-02 23:38:11 -04:00
Ashwathi Shiva
69306605a3 preflight createRole, createRoleBinding, createServiceAccount, createRB working 2020-04-02 23:34:55 -04:00
Foysal Iqbal
67ec3105f0 fix yaml trim
Signed-off-by: Foysal Iqbal <mqb@qlik.com>
2020-04-02 20:48:43 -04:00
Ashwathi Shiva
e69149ec64 finished initial functional role check 2020-04-02 19:44:13 -04:00
Ashwathi Shiva
cedb7f8fca WIP - intermediate commit 2020-04-02 19:09:34 -04:00
Ashwathi Shiva
fee81b25a6 WIP preflight createRole 2020-04-02 16:31:48 -04:00
Ashwathi Shiva
b5eea11050 Merge branch 'master' into preflight_roles 2020-04-02 14:44:23 -04:00
Ashwathi Shiva
dbf6f6debc preflight createRB working and updated readme 2020-04-02 00:00:48 -04:00
Ashwathi Shiva
002b0faaa1 Merge branch 'master' into preflight_roles 2020-04-01 23:33:47 -04:00
Ashwathi Shiva
a676d10ed0 preflight role, roleBinding, serviceAccount working 2020-04-01 23:31:28 -04:00
13 changed files with 761 additions and 42 deletions

View File

@@ -37,6 +37,9 @@ func pfDnsCheckCmd(q *qliksense.Qliksense) *cobra.Command {
fmt.Printf("Preflight DNS check FAILED\n")
log.Fatal(err)
}
if namespace == "" {
namespace = "default"
}
if err = qp.CheckDns(namespace, kubeConfigContents); err != nil {
fmt.Println(err)
fmt.Print("Preflight DNS check FAILED\n")
@@ -50,10 +53,10 @@ func pfDnsCheckCmd(q *qliksense.Qliksense) *cobra.Command {
func pfK8sVersionCheckCmd(q *qliksense.Qliksense) *cobra.Command {
var preflightCheckK8sVersionCmd = &cobra.Command{
Use: "k8s-version",
Short: "check k8s version",
Long: `check minimum valid k8s version on the cluster`,
Example: `qliksense preflight k8s-version`,
Use: "kube-version",
Short: "check kubernetes version",
Long: `check minimum valid kubernetes version on the cluster`,
Example: `qliksense preflight kube-version`,
RunE: func(cmd *cobra.Command, args []string) error {
qp := &preflight.QliksensePreflight{Q: q}
@@ -77,6 +80,7 @@ func pfK8sVersionCheckCmd(q *qliksense.Qliksense) *cobra.Command {
}
func pfAllChecksCmd(q *qliksense.Qliksense) *cobra.Command {
var mongodbUrl string
var preflightAllChecksCmd = &cobra.Command{
Use: "all",
Short: "perform all checks",
@@ -93,11 +97,16 @@ func pfAllChecksCmd(q *qliksense.Qliksense) *cobra.Command {
fmt.Printf("Running preflight check suite has FAILED...\n")
log.Fatal()
}
qp.RunAllPreflightChecks(namespace, kubeConfigContents)
if namespace == "" {
namespace = "default"
}
qp.RunAllPreflightChecks(namespace, kubeConfigContents, mongodbUrl)
return nil
},
}
f := preflightAllChecksCmd.Flags()
f.StringVarP(&mongodbUrl, "mongodb-url", "", "", "mongodbUrl to try connecting to")
return preflightAllChecksCmd
}
@@ -118,6 +127,9 @@ func pfDeploymentCheckCmd(q *qliksense.Qliksense) *cobra.Command {
fmt.Printf("Preflight deployment check FAILED\n")
log.Fatal(err)
}
if namespace == "" {
namespace = "default"
}
if err = qp.CheckDeployment(namespace, kubeConfigContents); err != nil {
fmt.Println(err)
fmt.Print("Preflight deploy check FAILED\n")
@@ -146,6 +158,9 @@ func pfServiceCheckCmd(q *qliksense.Qliksense) *cobra.Command {
fmt.Printf("Preflight service check FAILED\n")
log.Fatal(err)
}
if namespace == "" {
namespace = "default"
}
if err = qp.CheckService(namespace, kubeConfigContents); err != nil {
fmt.Println(err)
fmt.Print("Preflight service check FAILED\n")
@@ -174,6 +189,9 @@ func pfPodCheckCmd(q *qliksense.Qliksense) *cobra.Command {
fmt.Printf("Preflight pod check FAILED\n")
log.Fatal(err)
}
if namespace == "" {
namespace = "default"
}
if err = qp.CheckPod(namespace, kubeConfigContents); err != nil {
fmt.Println(err)
fmt.Print("Preflight pod check FAILED\n")
@@ -186,35 +204,147 @@ func pfPodCheckCmd(q *qliksense.Qliksense) *cobra.Command {
}
func pfCreateRoleCheckCmd(q *qliksense.Qliksense) *cobra.Command {
var preflightDnsCmd = &cobra.Command{
Use: "create-role",
var preflightRoleCmd = &cobra.Command{
Use: "role",
Short: "preflight create role check",
Long: `perform preflight role check to ensure we are able to create a role in the cluster`,
Example: `qliksense preflight create-role`,
Example: `qliksense preflight createRole`,
RunE: func(cmd *cobra.Command, args []string) error {
qp := &preflight.QliksensePreflight{Q: q}
// Preflight create-role check
fmt.Printf("Preflight create-role check\n")
// Preflight role check
fmt.Printf("Preflight role check\n")
fmt.Println("---------------------------")
namespace, kubeConfigContents, err := preflight.InitPreflight()
namespace, _, err := preflight.InitPreflight()
if err != nil {
fmt.Printf("Preflight create-role check FAILED\n")
fmt.Printf("Preflight role check FAILED\n")
log.Fatal(err)
}
if err = qp.CreateRoleCheck(namespace, kubeConfigContents); err != nil {
if err = qp.CheckCreateRole(namespace); err != nil {
fmt.Println(err)
fmt.Print("Preflight role-check FAILED\n")
fmt.Print("Preflight role FAILED\n")
log.Fatal()
}
return nil
},
}
return preflightDnsCmd
return preflightRoleCmd
}
// preflightCmd.AddCommand(pfMongoCheckCmd(p))
// preflightCmd.AddCommand(pfServiceCheckCmd(p))
// preflightCmd.AddCommand(pfCreateRoleBindingCheckCmd(p))
// preflightCmd.AddCommand(pfCreateServiceAccountCheckCmd(p))
// preflightCmd.AddCommand(pfCreateRBCheckCmd(p))
func pfCreateRoleBindingCheckCmd(q *qliksense.Qliksense) *cobra.Command {
var preflightRoleBindingCmd = &cobra.Command{
Use: "rolebinding",
Short: "preflight create rolebinding check",
Long: `perform preflight rolebinding check to ensure we are able to create a rolebinding in the cluster`,
Example: `qliksense preflight rolebinding`,
RunE: func(cmd *cobra.Command, args []string) error {
qp := &preflight.QliksensePreflight{Q: q}
// Preflight createRoleBinding check
fmt.Printf("Preflight rolebinding check\n")
fmt.Println("---------------------------")
namespace, _, err := preflight.InitPreflight()
if err != nil {
fmt.Printf("Preflight rolebinding check FAILED\n")
log.Fatal(err)
}
if err = qp.CheckCreateRoleBinding(namespace); err != nil {
fmt.Println(err)
fmt.Print("Preflight rolebinding check FAILED\n")
log.Fatal()
}
return nil
},
}
return preflightRoleBindingCmd
}
func pfCreateServiceAccountCheckCmd(q *qliksense.Qliksense) *cobra.Command {
var preflightServiceAccountCmd = &cobra.Command{
Use: "serviceaccount",
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 {
qp := &preflight.QliksensePreflight{Q: q}
// Preflight createServiceAccount check
fmt.Printf("Preflight ServiceAccount check\n")
fmt.Println("-------------------------------------")
namespace, _, err := preflight.InitPreflight()
if err != nil {
fmt.Printf("Preflight serviceaccount check FAILED\n")
log.Fatal(err)
}
if err = qp.CheckCreateServiceAccount(namespace); err != nil {
fmt.Println(err)
fmt.Print("Preflight serviceaccount check FAILED\n")
log.Fatal()
}
return nil
},
}
return preflightServiceAccountCmd
}
func pfCreateAuthCheckCmd(q *qliksense.Qliksense) *cobra.Command {
var preflightCreateAuthCmd = &cobra.Command{
Use: "authcheck",
Short: "preflight authcheck",
Long: `perform preflight authcheck that combines the role, rolebinding and serviceaccount checks`,
Example: `qliksense preflight authcheck`,
RunE: func(cmd *cobra.Command, args []string) error {
qp := &preflight.QliksensePreflight{Q: q}
// Preflight authcheck
fmt.Printf("Preflight authcheck\n")
fmt.Println("------------------------")
namespace, kubeConfigContents, err := preflight.InitPreflight()
if err != nil {
fmt.Printf("Preflight authcheck FAILED\n")
log.Fatal(err)
}
if err = qp.CheckCreateRB(namespace, kubeConfigContents); err != nil {
fmt.Println(err)
fmt.Print("Preflight authcheck FAILED\n")
log.Fatal()
}
return nil
},
}
return preflightCreateAuthCmd
}
func pfMongoCheckCmd(q *qliksense.Qliksense) *cobra.Command {
var mongodbUrl string
var preflightMongoCmd = &cobra.Command{
Use: "mongo",
Short: "preflight mongo OR preflight mongo --url=<url>",
Long: `perform preflight mongo check to ensure we are able to connect to a mongodb instance in the cluster`,
Example: `qliksense preflight mongo OR preflight mongo --url=<url>`,
RunE: func(cmd *cobra.Command, args []string) error {
qp := &preflight.QliksensePreflight{Q: q}
// Preflight mongo check
fmt.Printf("Preflight mongo check\n")
fmt.Println("-------------------------------------")
namespace, kubeConfigContents, err := preflight.InitPreflight()
if err != nil {
fmt.Printf("Preflight mongo check FAILED\n")
log.Fatal(err)
}
if namespace == "" {
namespace = "default"
}
if err = qp.CheckMongo(kubeConfigContents, namespace, mongodbUrl); err != nil {
fmt.Println(err)
fmt.Print("Preflight mongo check FAILED\n")
log.Fatal()
}
return nil
},
}
f := preflightMongoCmd.Flags()
f.StringVarP(&mongodbUrl, "url", "", "", "mongodbUrl to try connecting to")
return preflightMongoCmd
}

View File

@@ -205,14 +205,14 @@ func rootCmd(p *qliksense.Qliksense) *cobra.Command {
preflightCmd.AddCommand(pfDnsCheckCmd(p))
preflightCmd.AddCommand(pfK8sVersionCheckCmd(p))
preflightCmd.AddCommand(pfAllChecksCmd(p))
// preflightCmd.AddCommand(pfMongoCheckCmd(p))
preflightCmd.AddCommand(pfMongoCheckCmd(p))
preflightCmd.AddCommand(pfDeploymentCheckCmd(p))
preflightCmd.AddCommand(pfServiceCheckCmd(p))
preflightCmd.AddCommand(pfPodCheckCmd(p))
preflightCmd.AddCommand(pfCreateRoleCheckCmd(p))
// preflightCmd.AddCommand(pfCreateRoleBindingCheckCmd(p))
// preflightCmd.AddCommand(pfCreateServiceAccountCheckCmd(p))
// preflightCmd.AddCommand(pfCreateRBCheckCmd(p))
preflightCmd.AddCommand(pfCreateRoleBindingCheckCmd(p))
preflightCmd.AddCommand(pfCreateServiceAccountCheckCmd(p))
preflightCmd.AddCommand(pfCreateAuthCheckCmd(p))
cmd.AddCommand(preflightCmd)
cmd.AddCommand(loadCrFile(p))

View File

@@ -109,9 +109,116 @@ Deleted pod: pod-pf-check
Completed preflight pod check
```
### Create-Role check
We use the command below to test if we are able to create a role in the cluster
```shell
$ qliksense preflight create-role
Preflight create-role check
---------------------------
Preflight create-role check:
Created role: role-preflight-check
Preflight create-role check: PASSED
Cleaning up resources...
Deleted role: role-preflight-check
Completed preflight create-role check
```
### Create-RoleBinding check
We use the command below to test if we are able to create a role binding in the cluster
```shell
$ qliksense preflight createRoleBinding
Preflight create roleBinding check
---------------------------
Preflight createRoleBinding check:
Created RoleBinding: role-binding-preflight-check
Preflight createRoleBinding check: PASSED
Cleaning up resources...
Deleting RoleBinding: role-binding-preflight-check
Deleted RoleBinding: role-binding-preflight-check
Completed preflight createRoleBinding check
```
### Create-ServiceAccount check
We use the command below to test if we are able to create a service account in the cluster
```shell
$ qliksense preflight createServiceAccount
Preflight create ServiceAccount check
-------------------------------------
Preflight createServiceAccount check:
Created Service Account: preflight-check-test-serviceaccount
Preflight createServiceAccount check: PASSED
Cleaning up resources...
Deleting ServiceAccount: preflight-check-test-serviceaccount
Deleted ServiceAccount: preflight-check-test-serviceaccount
Completed preflight createServiceAccount check
```
### CreateRB check
We use the command below to combine creation of role, role binding, and service account tests
```shell
$ qliksense preflight createRB
Preflight createRB check
-------------------------------------
Preflight create-role check:
Created role: role-preflight-check
Preflight create-role check: PASSED
Cleaning up resources...
Deleted role: role-preflight-check
Completed preflight create-role check
Preflight create RoleBinding check:
Created RoleBinding: role-binding-preflight-check
Preflight create RoleBinding check: PASSED
Cleaning up resources...
Deleted RoleBinding: role-binding-preflight-check
Completed preflight create RoleBinding check
Preflight createServiceAccount check:
Created Service Account: preflight-check-test-serviceaccount
Preflight createServiceAccount check: PASSED
Cleaning up resources...
Deleted ServiceAccount: preflight-check-test-serviceaccount
Completed preflight createServiceAccount check
Completed preflight CreateRB check
```
### Mongodb check
We can check if we are able to connect to an instance of mongodb on the cluster by either supplying the mongodbUri as part of the command or infer it from the current context.
```shell
qliksense preflight mongo --url=<url> OR
qliksense preflight mongo
Preflight mongo check
---------------------
Preflight mongodb check:
Created pod: pf-mongo-pod
stdout: MongoDB shell version v4.2.5
connecting to: <url>/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("64f639d3-2c93-4894-80f6-ee14acaf56a5") }
MongoDB server version: 4.2.5
bye
stderr:
Preflight mongo check: PASSED
Deleted pod: pf-mongo-pod
Completed preflight mongodb check
```
### Running all checks
Run the command shown below to execute all preflight checks.
```console
$ qliksense preflight all --mongodb-url=<url> OR
$ qliksense preflight all
Running all preflight checks

View File

@@ -453,6 +453,18 @@ func (cr *QliksenseCR) SetEULA(value string) {
cr.Spec.AddToConfigs("qliksense", "acceptEULA", value)
}
// GetCustomCrdsPath get crds path if exist in the profile dir
func (cr *QliksenseCR) GetCustomCrdsPath() string {
if cr.Spec.ManifestsRoot == "" || cr.Spec.Profile == "" {
return ""
}
crdsPath := filepath.Join(cr.Spec.GetManifestsRoot(), "manifests", cr.Spec.Profile, "crds")
if _, err := os.Lstat(crdsPath); err != nil {
return ""
}
return crdsPath
}
// GetDecryptedCr it decrypts all the encrypted value and return a new CR
func (qc *QliksenseConfig) GetDecryptedCr(cr *QliksenseCR) (*QliksenseCR, error) {
newCr := &QliksenseCR{}

View File

@@ -70,7 +70,7 @@ func ProcessConfigArgs(args []string) ([]*ServiceKeyValue, error) {
return nil, err
}
resultSvcKV := make([]*ServiceKeyValue, len(args))
re1 := regexp.MustCompile(`(\w{1,}).(\w{1,})=("*[\w\-?=_/:0-9\.]+"*)`)
re1 := regexp.MustCompile(`([\w\-]{1,}).([\w\-]{1,})=("*[\w\-?=_/:0-9\.]+"*)`)
for i, arg := range args {
LogDebugMessage("Arg received: %s", arg)
result := re1.FindStringSubmatch(arg)

46
pkg/api/utils_test.go Normal file
View File

@@ -0,0 +1,46 @@
package api
import (
"testing"
)
func TestProcessConfigArgs(t *testing.T) {
args := []string{
"qliksense.mongodb=mongouri://something?ffall",
"test_under.test=value_under",
"test-dash.dash-key=value-dash",
"test-dot.dot-key=127.0.0.1",
"test123.key123=value123",
}
expectedKeys := []string{"mongodb", "test", "dash-key", "dot-key", "key123"}
expectedValue := []string{"mongouri://something?ffall", "value_under", "value-dash", "127.0.0.1", "value123"}
exppectedSvc := []string{"qliksense", "test_under", "test-dash", "test-dot", "test123"}
sv, err := ProcessConfigArgs(args)
if err != nil {
t.Log(err)
t.FailNow()
}
for _, v := range sv {
if !contains(expectedKeys, v.Key) {
t.Fail()
t.Log("expectd key " + v.Key + " not found")
}
if !contains(expectedValue, v.Value) {
t.Fail()
t.Log("expectd Value " + v.Value + " not found")
}
if !contains(exppectedSvc, v.SvcName) {
t.Fail()
t.Log("expectd service " + v.SvcName + " not found")
}
}
}
func contains(arr []string, str string) bool {
for _, a := range arr {
if a == str {
return true
}
}
return false
}

View File

@@ -4,7 +4,7 @@ import (
"fmt"
)
func (qp *QliksensePreflight) RunAllPreflightChecks(namespace string, kubeConfigContents []byte) {
func (qp *QliksensePreflight) RunAllPreflightChecks(namespace string, kubeConfigContents []byte, mongodbUrl string) {
checkCount := 0
// Preflight minimum kuberenetes version check
@@ -18,7 +18,7 @@ func (qp *QliksensePreflight) RunAllPreflightChecks(namespace string, kubeConfig
// Preflight deployment check
fmt.Printf("\nPreflight deployment check\n")
fmt.Println("-----------------------")
fmt.Println("--------------------------")
if err := qp.CheckDeployment(namespace, kubeConfigContents); err != nil {
fmt.Printf("Preflight deployment check: FAILED\n")
} else {
@@ -43,6 +43,42 @@ func (qp *QliksensePreflight) RunAllPreflightChecks(namespace string, kubeConfig
checkCount++
}
// Preflight role check
fmt.Printf("\nPreflight role check\n")
fmt.Println("--------------------------")
if err := qp.CheckCreateRole(namespace); err != nil {
fmt.Printf("Preflight role check: FAILED\n")
} else {
checkCount++
}
// Preflight rolebinding check
fmt.Printf("\nPreflight rolebinding check\n")
fmt.Println("---------------------------------")
if err := qp.CheckCreateRoleBinding(namespace); err != nil {
fmt.Printf("Preflight rolebinding check: FAILED\n")
} else {
checkCount++
}
// Preflight serviceaccount check
fmt.Printf("\nPreflight serviceaccount check\n")
fmt.Println("------------------------------------")
if err := qp.CheckCreateServiceAccount(namespace); err != nil {
fmt.Printf("Preflight serviceaccount check: FAILED\n")
} else {
checkCount++
}
// Preflight mongo check
fmt.Printf("\nPreflight mongo check\n")
fmt.Println("---------------------")
if err := qp.CheckMongo(kubeConfigContents, namespace, mongodbUrl); err != nil {
fmt.Printf("Preflight mongo check: FAILED\n")
} else {
checkCount++
}
// Preflight DNS check
fmt.Printf("\nPreflight DNS check\n")
fmt.Println("-------------------")
@@ -52,7 +88,7 @@ func (qp *QliksensePreflight) RunAllPreflightChecks(namespace string, kubeConfig
checkCount++
}
if checkCount == 5 {
if checkCount == 9 {
fmt.Printf("\nAll preflight checks have PASSED\n")
} else {
fmt.Printf("\n1 or more preflight checks have FAILED\n")

View File

@@ -103,7 +103,6 @@ func checkPfService(clientset *kubernetes.Clientset, namespace string) error {
func (qp *QliksensePreflight) checkPfDeployment(clientset *kubernetes.Clientset, namespace, depName string) error {
// check if we are able to create a deployment
// depName :=
pfDeployment, err := createPreflightTestDeployment(clientset, namespace, depName, qp.GetPreflightConfigObj().GetImageName(nginx))
if err != nil {
err = fmt.Errorf("error: unable to create deployment: %v\n", err)

View File

@@ -0,0 +1,85 @@
package preflight
import (
"fmt"
"strings"
"github.com/qlik-oss/sense-installer/pkg/api"
qapi "github.com/qlik-oss/sense-installer/pkg/api"
)
const (
mongoImage = "mongo"
)
func (qp *QliksensePreflight) CheckMongo(kubeConfigContents []byte, namespace, mongodbUrl string) error {
fmt.Printf("Preflight mongodb check: \n")
if mongodbUrl == "" {
// infer mongoDbUrl from currentCR
fmt.Println("MongoDbUri is empty, infer from CR")
qConfig := qapi.NewQConfig(qp.Q.QliksenseHome)
var currentCR *qapi.QliksenseCR
var err error
qConfig.SetNamespace(namespace)
currentCR, err = qConfig.GetCurrentCR()
if err != nil {
fmt.Printf("Unable to retrieve current CR: %v\n", err)
return err
}
decryptedCR, err := qConfig.GetDecryptedCr(currentCR)
mongodbUrl = decryptedCR.Spec.GetFromSecrets("qliksense", "mongoDbUri")
}
fmt.Printf("mongodbUrl: %s\n", mongodbUrl)
if err := mongoConnCheck(kubeConfigContents, namespace, mongodbUrl); err != nil {
return err
}
fmt.Println("Completed preflight mongodb check")
return nil
}
func mongoConnCheck(kubeConfigContents []byte, namespace, mongodbUrl string) error {
clientset, clientConfig, err := getK8SClientSet(kubeConfigContents, "")
if err != nil {
err = fmt.Errorf("error: unable to create a kubernetes client: %v\n", err)
fmt.Println(err)
return err
}
// create a pod
podName := "pf-mongo-pod"
mongoPod, err := createPreflightTestPod(clientset, namespace, podName, mongoImage)
if err != nil {
err = fmt.Errorf("error: unable to create pod : %s\n", podName)
fmt.Println("Preflight mongo check: FAILED")
return err
}
defer deletePod(clientset, namespace, podName)
if err := waitForPod(clientset, namespace, mongoPod); err != nil {
return err
}
if len(mongoPod.Spec.Containers) == 0 {
err := fmt.Errorf("error: there are no containers in the pod")
fmt.Println(err)
return err
}
api.LogDebugMessage("Exec-ing into the container...")
stdout, stderr, err := executeRemoteCommand(clientset, clientConfig, mongoPod.Name, mongoPod.Spec.Containers[0].Name, namespace, []string{"mongo", mongodbUrl})
if err != nil {
err = fmt.Errorf("error: unable to execute mongo check in the cluster: %v", err)
fmt.Println(err)
return err
}
api.LogDebugMessage("stdout:", stdout)
api.LogDebugMessage("stderr:", stderr)
stringToCheck := "Implicit session"
if strings.Contains(stdout, stringToCheck) || strings.Contains(stderr, stringToCheck) {
fmt.Println("Preflight mongo check: PASSED")
} else {
fmt.Println("Preflight mongo check: FAILED")
}
return nil
}

View File

@@ -5,6 +5,7 @@ import (
"fmt"
"io"
"io/ioutil"
"log"
"net/url"
"path/filepath"
"strings"
@@ -26,6 +27,7 @@ import (
"github.com/qlik-oss/sense-installer/pkg/qliksense"
appsv1 "k8s.io/api/apps/v1"
apiv1 "k8s.io/api/core/v1"
"k8s.io/api/rbac/v1beta1"
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
restclient "k8s.io/client-go/rest"
@@ -315,7 +317,7 @@ func createPreflightTestPod(clientset *kubernetes.Clientset, namespace string, p
Name: podName,
Namespace: namespace,
Labels: map[string]string{
"app": "demo",
"app": "preflight",
},
},
Spec: apiv1.PodSpec{
@@ -505,3 +507,136 @@ OUT:
fmt.Println(err)
return err
}
func createPfRole(clientset *kubernetes.Clientset, namespace, roleName string) (*v1beta1.Role, error) {
// build the role defination we want to create
var role *v1beta1.Role
roleSpec := &v1beta1.Role{
ObjectMeta: v1.ObjectMeta{
Name: roleName,
Namespace: namespace,
Labels: map[string]string{
"app": "preflight",
},
},
Rules: []v1beta1.PolicyRule{},
}
// now create the role in kubernetes cluster using the clientset
if err := retryOnError(func() (err error) {
role, err = clientset.RbacV1beta1().Roles(namespace).Create(roleSpec)
return err
}); err != nil {
fmt.Println(err)
return nil, err
}
fmt.Printf("Created role: %s\n", role.Name)
return role, nil
}
func deleteRole(clientset *kubernetes.Clientset, namespace string, role *v1beta1.Role) {
rolesClient := clientset.RbacV1beta1().Roles(namespace)
deletePolicy := v1.DeletePropagationForeground
deleteOptions := v1.DeleteOptions{
PropagationPolicy: &deletePolicy,
}
err := rolesClient.Delete(role.GetName(), &deleteOptions)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Deleted role: %s\n\n", role.Name)
}
func createPfRoleBinding(clientset *kubernetes.Clientset, namespace, roleBindingName string) (*v1beta1.RoleBinding, error) {
var roleBinding *v1beta1.RoleBinding
// build the rolebinding defination we want to create
roleBindingSpec := &v1beta1.RoleBinding{
ObjectMeta: v1.ObjectMeta{
Name: roleBindingName,
Namespace: namespace,
Labels: map[string]string{
"app": "demo",
},
},
Subjects: []v1beta1.Subject{
{
Kind: "ServiceAccount",
APIGroup: "",
Name: "preflight-check-subject",
Namespace: namespace,
},
},
RoleRef: v1beta1.RoleRef{
APIGroup: "",
Kind: "Role",
Name: "preflight-check-roleref",
},
}
// now create the roleBinding in kubernetes cluster using the clientset
if err := retryOnError(func() (err error) {
roleBinding, err = clientset.RbacV1beta1().RoleBindings(namespace).Create(roleBindingSpec)
return err
}); err != nil {
fmt.Println(err)
return nil, err
}
fmt.Printf("Created RoleBinding: %s\n", roleBindingSpec.Name)
return roleBinding, nil
}
func deleteRoleBinding(clientset *kubernetes.Clientset, namespace string, roleBinding *v1beta1.RoleBinding) {
roleBindingClient := clientset.RbacV1beta1().RoleBindings(namespace)
deletePolicy := v1.DeletePropagationForeground
deleteOptions := v1.DeleteOptions{
PropagationPolicy: &deletePolicy,
}
err := roleBindingClient.Delete(roleBinding.GetName(), &deleteOptions)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Deleted RoleBinding: %s\n\n", roleBinding.Name)
}
func createPfServiceAccount(clientset *kubernetes.Clientset, namespace, serviceAccountName string) (*apiv1.ServiceAccount, error) {
var serviceAccount *apiv1.ServiceAccount
// build the serviceAccount defination we want to create
serviceAccountSpec := &apiv1.ServiceAccount{
ObjectMeta: v1.ObjectMeta{
Name: "preflight-check-test-serviceaccount",
Namespace: namespace,
Labels: map[string]string{
"app": "demo",
},
},
}
// now create the serviceAccount in kubernetes cluster using the clientset
if err := retryOnError(func() (err error) {
serviceAccount, err = clientset.CoreV1().ServiceAccounts(namespace).Create(serviceAccountSpec)
return err
}); err != nil {
fmt.Println(err)
return nil, err
}
fmt.Printf("Created Service Account: %s\n", serviceAccountSpec.Name)
return serviceAccount, nil
}
func deleteServiceAccount(clientset *kubernetes.Clientset, namespace string, serviceAccount *apiv1.ServiceAccount) {
serviceAccountClient := clientset.CoreV1().ServiceAccounts(namespace)
deletePolicy := v1.DeletePropagationForeground
deleteOptions := v1.DeleteOptions{
PropagationPolicy: &deletePolicy,
}
err := serviceAccountClient.Delete(serviceAccount.GetName(), &deleteOptions)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Deleted ServiceAccount: %s\n\n", serviceAccount.Name)
}

View File

@@ -1,12 +1,148 @@
package preflight
func (qp *QliksensePreflight) CreateRoleCheck(namespace string, kubeConfigContents []byte) error {
import (
"fmt"
"path"
"path/filepath"
// create service account
// create role
// create rolebinding
"github.com/mitchellh/go-homedir"
"github.com/qlik-oss/k-apis/pkg/cr"
"github.com/qlik-oss/sense-installer/pkg/api"
qapi "github.com/qlik-oss/sense-installer/pkg/api"
"github.com/qlik-oss/sense-installer/pkg/qliksense"
)
func (qp *QliksensePreflight) CheckCreateRole(namespace string) error {
// create a Role
fmt.Printf("Preflight role check: \n")
err := qp.checkCreateEntity(namespace, "Role")
if err != nil {
return err
}
fmt.Println("Completed preflight role check")
return nil
}
func (qp *QliksensePreflight) CheckCreateRoleBinding(namespace string) error {
// create a RoleBinding
fmt.Printf("Preflight rolebinding check: \n")
err := qp.checkCreateEntity(namespace, "RoleBinding")
if err != nil {
return err
}
fmt.Println("Completed preflight rolebinding check")
return nil
}
func (qp *QliksensePreflight) CheckCreateServiceAccount(namespace string) error {
// create a service account
fmt.Printf("Preflight serviceaccount check: \n")
err := qp.checkCreateEntity(namespace, "ServiceAccount")
if err != nil {
return err
}
fmt.Println("Completed preflight serviceaccount check")
return nil
}
func (qp *QliksensePreflight) checkCreateEntity(namespace, entityToTest string) error {
qConfig := qapi.NewQConfig(qp.Q.QliksenseHome)
var currentCR *qapi.QliksenseCR
mfroot := ""
kusDir := ""
var err error
currentCR, err = qConfig.GetCurrentCR()
if err != nil {
fmt.Printf("Unable to retrieve current CR: %v\n", err)
return err
}
if currentCR.IsRepoExist() {
mfroot = currentCR.Spec.GetManifestsRoot()
} else if tempDownloadedDir, err := qliksense.DownloadFromGitRepoToTmpDir(qliksense.QLIK_GIT_REPO, "master"); err != nil {
fmt.Printf("Unable to Download from git repo to tmp dir: %v\n", err)
return err
} else {
mfroot = tempDownloadedDir
}
if currentCR.Spec.Profile == "" {
kusDir = filepath.Join(mfroot, "manifests", "docker-desktop")
} else {
kusDir = filepath.Join(mfroot, "manifests", currentCR.Spec.Profile)
}
currentCR.SetName("random")
currentCR.Spec.RotateKeys = "None"
currentCR.Spec.ManifestsRoot = mfroot
userHomeDir, err := homedir.Dir()
if err != nil {
fmt.Printf(`error fetching user's home directory: %v\n`, err)
return err
}
cr.GeneratePatches(&currentCR.KApiCr, path.Join(userHomeDir, ".kube", "config"))
resultYamlString, err := qliksense.ExecuteKustomizeBuild(kusDir)
if err != nil {
fmt.Printf("Unable to retrieve manifests from executing kustomize: %v\n", err)
return err
}
sa := qliksense.GetYamlsFromMultiDoc(string(resultYamlString), entityToTest)
if sa != "" {
// sa = strings.ReplaceAll(sa, "namespace: default\n", fmt.Sprintf("namespace: %s\n", namespace))
} else {
err := fmt.Errorf("Unable to retrieve yamls to apply on cluster")
fmt.Println(err)
return err
}
namespace = "" // namespace is handled when generating the manifests
defer func() {
fmt.Println("Cleaning up resources")
api.KubectlDelete(sa, namespace)
if err != nil {
fmt.Println("Preflight cleanup failed!")
}
}()
err = api.KubectlApply(sa, namespace)
if err != nil {
err := fmt.Errorf("Failed to create entity on the cluster: %v", err)
fmt.Println(err)
return err
}
fmt.Printf("Preflight %s check: PASSED\n", entityToTest)
return nil
}
func (qp *QliksensePreflight) CheckCreateRB(namespace string, kubeConfigContents []byte) error {
// create a role
fmt.Printf("Preflight createRole check: \n")
err := qp.checkCreateEntity(namespace, "Role")
if err != nil {
fmt.Println("Preflight role check: FAILED")
}
fmt.Printf("Completed preflight role check\n\n")
// create a roleBinding
fmt.Printf("Preflight rolebinding check: \n")
err = qp.checkCreateEntity(namespace, "RoleBinding")
if err != nil {
fmt.Println("Preflight rolebinding check: FAILED")
}
fmt.Printf("Completed preflight rolebinding check\n\n")
// create a service account
fmt.Printf("Preflight serviceaccount check: \n")
err = qp.checkCreateEntity(namespace, "ServiceAccount")
if err != nil {
fmt.Println("Preflight serviceaccount check: FAILED")
}
fmt.Printf("Completed preflight serviceaccount check\n\n")
fmt.Println("Preflight RB check: PASSED")
fmt.Println("Completed preflight CreateRB check")
return nil
}

View File

@@ -19,12 +19,24 @@ func (q *Qliksense) ViewCrds(opts *CrdCommandOptions) error {
fmt.Println("cannot get the current-context cr", err)
return err
}
if engineCRD, err := getQliksenseInitCrd(qcr); err != nil {
engineCRD, err := getQliksenseInitCrd(qcr)
if err != nil {
return err
} else if opts.All {
fmt.Printf("%s\n%s", q.GetOperatorCRDString(), engineCRD)
} else {
fmt.Printf("%s", engineCRD)
}
customCrd, err := getCustomCrd(qcr)
if err != nil {
return nil
}
fmt.Println(engineCRD)
if customCrd != "" {
fmt.Println("---")
fmt.Println(customCrd)
}
if opts.All {
fmt.Println("---")
fmt.Printf("%s", q.GetOperatorCRDString())
}
return nil
}
@@ -43,6 +55,14 @@ func (q *Qliksense) InstallCrds(opts *CrdCommandOptions) error {
} else if err = qapi.KubectlApply(engineCRD, ""); err != nil {
return err
}
if customCrd, err := getCustomCrd(qcr); err != nil {
return err
} else if customCrd != "" {
if err = qapi.KubectlApply(customCrd, ""); err != nil {
return err
}
}
if opts.All { // install opeartor crd
if err := qapi.KubectlApply(q.GetOperatorCRDString(), ""); err != nil {
fmt.Println("cannot do kubectl apply on opeartor CRD", err)
@@ -72,3 +92,16 @@ func getQliksenseInitCrd(qcr *qapi.QliksenseCR) (string, error) {
}
return string(qInitByte), nil
}
func getCustomCrd(qcr *qapi.QliksenseCR) (string, error) {
crdPath := qcr.GetCustomCrdsPath()
if crdPath == "" {
return "", nil
}
qInitByte, err := ExecuteKustomizeBuild(crdPath)
if err != nil {
fmt.Println("cannot generate custom crds", err)
return "", err
}
return string(qInitByte), nil
}

View File

@@ -57,7 +57,7 @@ func GetYamlsFromMultiDoc(multiYaml string, kind string) string {
for _, doc := range yamlDocs {
scanner := bufio.NewScanner(strings.NewReader(doc))
for scanner.Scan() {
if strings.HasPrefix(scanner.Text(), "kind: "+kind) {
if scanner.Text() == "kind: "+kind {
resultDocs = resultDocs + "\n---\n" + doc
break
}