Compare commits
21 Commits
config_uns
...
gitops_spe
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ffc0e5c062 | ||
|
|
9b2fec9987 | ||
|
|
bbecb56586 | ||
|
|
0b2fdae015 | ||
|
|
ef595b4b3f | ||
|
|
d38852398e | ||
|
|
e85636822d | ||
|
|
b9a80f588d | ||
|
|
b9074d9f3c | ||
|
|
f3a3e97618 | ||
|
|
5c56013a70 | ||
|
|
134dbd44ed | ||
|
|
9898d3b9ec | ||
|
|
32fa0a6570 | ||
|
|
0bf1f3ca3a | ||
|
|
8f56872842 | ||
|
|
c7478fb8c1 | ||
|
|
34df4b3a5c | ||
|
|
c7bac06533 | ||
|
|
89d5e261ab | ||
|
|
6cd70cb643 |
5
.gitattributes
vendored
Normal file
5
.gitattributes
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
# Ignore all files and folders that start with .; .circleci, .github, .git, etc.
|
||||||
|
# Warning! This will ignore files in subfolders as well.
|
||||||
|
# If you needs files starting with . then change condition below to be specific
|
||||||
|
# for each file and folder that needs to be ignored
|
||||||
|
.* export-ignore
|
||||||
21
.github/workflows/mkdocs.yml
vendored
Normal file
21
.github/workflows/mkdocs.yml
vendored
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
name: Publish docs via GitHub Pages
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
paths:
|
||||||
|
- docs/
|
||||||
|
- mkdocs.yml
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: Deploy docs
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout master
|
||||||
|
uses: actions/checkout@v1
|
||||||
|
|
||||||
|
- name: Deploy docs
|
||||||
|
uses: mhausenblas/mkdocs-deploy-gh-pages@1.11
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
23
MKDOCS.md
Normal file
23
MKDOCS.md
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# Qlik Sense installer documentation
|
||||||
|
|
||||||
|
## Local development of documentation
|
||||||
|
|
||||||
|
Documentation is built using [mkdocs](https://www.mkdocs.org/) and uses [Material for MKDocs theme](https://squidfunk.github.io/mkdocs-material/)
|
||||||
|
|
||||||
|
Requirements: Python and PIP or Docker
|
||||||
|
|
||||||
|
```console
|
||||||
|
pip install mkdocs
|
||||||
|
pip install mkdocs-material
|
||||||
|
```
|
||||||
|
|
||||||
|
View live changes locally at http://localhost:8000
|
||||||
|
```console
|
||||||
|
mkdocs serve
|
||||||
|
```
|
||||||
|
|
||||||
|
### Docker
|
||||||
|
|
||||||
|
```console
|
||||||
|
docker run --rm -it -p 8000:8000 -v ${PWD}:/docs squidfunk/mkdocs-material
|
||||||
|
```
|
||||||
@@ -64,25 +64,6 @@ qliksense config set <key>=<value>
|
|||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
func unsetOtherConfigsCmd(q *qliksense.Qliksense) *cobra.Command {
|
|
||||||
var (
|
|
||||||
cmd *cobra.Command
|
|
||||||
)
|
|
||||||
|
|
||||||
cmd = &cobra.Command{
|
|
||||||
Use: "un-set",
|
|
||||||
Short: "remove a key value pair in the current context",
|
|
||||||
Example: `
|
|
||||||
qliksense config unset <key>
|
|
||||||
- The above configuration will be removed in the CR
|
|
||||||
`,
|
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
|
||||||
return q.UnsetOtherConfigs(args)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
return cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
func setConfigsCmd(q *qliksense.Qliksense) *cobra.Command {
|
func setConfigsCmd(q *qliksense.Qliksense) *cobra.Command {
|
||||||
var (
|
var (
|
||||||
cmd *cobra.Command
|
cmd *cobra.Command
|
||||||
@@ -101,24 +82,6 @@ qliksense config set-configs <service_name>.<attribute>="<value>"
|
|||||||
}
|
}
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
func unsetConfigsCmd(q *qliksense.Qliksense) *cobra.Command {
|
|
||||||
var (
|
|
||||||
cmd *cobra.Command
|
|
||||||
)
|
|
||||||
|
|
||||||
cmd = &cobra.Command{
|
|
||||||
Use: "unset-configs",
|
|
||||||
Short: "unset configurations in the qliksense context as key-value pairs",
|
|
||||||
Example: `
|
|
||||||
qliksense config unset-configs <service_name>.<attribute>="<value>"
|
|
||||||
- The above configuration will be removed in the CR
|
|
||||||
`,
|
|
||||||
RunE: func(cmd *cobra.Command, args []string) error {
|
|
||||||
return q.UnsetConfigs(args)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
return cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
func setSecretsCmd(q *qliksense.Qliksense) *cobra.Command {
|
func setSecretsCmd(q *qliksense.Qliksense) *cobra.Command {
|
||||||
var (
|
var (
|
||||||
|
|||||||
@@ -42,10 +42,7 @@ func initAndExecute() error {
|
|||||||
// create dirs and appropriate files for setting up contexts
|
// create dirs and appropriate files for setting up contexts
|
||||||
api.LogDebugMessage("QliksenseHomeDir: %s", qlikSenseHome)
|
api.LogDebugMessage("QliksenseHomeDir: %s", qlikSenseHome)
|
||||||
|
|
||||||
qliksenseClient, err := qliksense.New(qlikSenseHome)
|
qliksenseClient := qliksense.New(qlikSenseHome)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
qliksenseClient.SetUpQliksenseDefaultContext()
|
qliksenseClient.SetUpQliksenseDefaultContext()
|
||||||
cmd := rootCmd(qliksenseClient)
|
cmd := rootCmd(qliksenseClient)
|
||||||
//levenstein checks
|
//levenstein checks
|
||||||
@@ -151,14 +148,12 @@ func rootCmd(p *qliksense.Qliksense) *cobra.Command {
|
|||||||
// add the list config command as a sub-command to the app config sub-command
|
// add the list config command as a sub-command to the app config sub-command
|
||||||
configCmd.AddCommand(listContextConfigCmd(p))
|
configCmd.AddCommand(listContextConfigCmd(p))
|
||||||
|
|
||||||
|
|
||||||
// add the delete-context config command as a sub-command to the app config command
|
// add the delete-context config command as a sub-command to the app config command
|
||||||
configCmd.AddCommand(deleteContextConfigCmd(p))
|
configCmd.AddCommand(deleteContextConfigCmd(p))
|
||||||
|
|
||||||
// add set-image-registry command as a sub-command to the app config sub-command
|
// add set-image-registry command as a sub-command to the app config sub-command
|
||||||
configCmd.AddCommand(setImageRegistryCmd(p))
|
configCmd.AddCommand(setImageRegistryCmd(p))
|
||||||
|
|
||||||
|
|
||||||
// add clean-config-repo-patches command as a sub-command to the app config sub-command
|
// add clean-config-repo-patches command as a sub-command to the app config sub-command
|
||||||
configCmd.AddCommand(cleanConfigRepoPatchesCmd(p))
|
configCmd.AddCommand(cleanConfigRepoPatchesCmd(p))
|
||||||
|
|
||||||
|
|||||||
0
docs/air_gap.md
Normal file
0
docs/air_gap.md
Normal file
83
docs/concepts.md
Normal file
83
docs/concepts.md
Normal file
@@ -0,0 +1,83 @@
|
|||||||
|
# How qliksense cli works
|
||||||
|
|
||||||
|
At the initialization `qliksense` cli create few files in the director `~/.qliksene` and it contains following files
|
||||||
|
|
||||||
|
```console
|
||||||
|
.qliksense
|
||||||
|
├── config.yaml
|
||||||
|
├── contexts
|
||||||
|
│ └── qlik-default
|
||||||
|
│ └── qlik-default.yaml
|
||||||
|
└── ejson
|
||||||
|
└── keys
|
||||||
|
```
|
||||||
|
|
||||||
|
`qlik-default.yaml` is a default CR has been created with some default values like this
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
apiVersion: qlik.com/v1
|
||||||
|
kind: Qliksense
|
||||||
|
metadata:
|
||||||
|
name: qlik-default
|
||||||
|
spec:
|
||||||
|
profile: docker-desktop
|
||||||
|
secrets:
|
||||||
|
qliksense:
|
||||||
|
- name: mongoDbUri
|
||||||
|
value: mongodb://qlik-default-mongodb:27017/qliksense?ssl=false
|
||||||
|
rotateKeys: "yes"
|
||||||
|
releaseName: qlik-default
|
||||||
|
```
|
||||||
|
|
||||||
|
The `qliksense` cli creates a default qliksense context (different from kubectl context) named `qlik-default` which will be the prefix for all kubernetes resources created by the cli under this context latter on. New context and configuration can be created by the cli.
|
||||||
|
|
||||||
|
```console
|
||||||
|
$ qliksense config -h
|
||||||
|
do operations on/around CR
|
||||||
|
|
||||||
|
Usage:
|
||||||
|
qliksense config [command]
|
||||||
|
|
||||||
|
Available Commands:
|
||||||
|
apply generate the patchs and apply manifests to k8s
|
||||||
|
list-contexts retrieves the contexts and lists them
|
||||||
|
set configure a key value pair into the current context
|
||||||
|
set-configs set configurations into the qliksense context as key-value pairs
|
||||||
|
set-context Sets the context in which the Kubernetes cluster and resources live in
|
||||||
|
set-secrets set secrets configurations into the qliksense context as key-value pairs
|
||||||
|
view view the qliksense operator CR
|
||||||
|
|
||||||
|
Flags:
|
||||||
|
-h, --help help for config
|
||||||
|
|
||||||
|
Use "qliksense config [command] --help" for more information about a command.
|
||||||
|
```
|
||||||
|
|
||||||
|
`qliksense` cli works in two modes
|
||||||
|
|
||||||
|
- with a git repo fork/clone of [qliksense-k8s](https://github.com/qlik-oss/qliksense-k8s)
|
||||||
|
- without git repo
|
||||||
|
|
||||||
|
## Without git repo
|
||||||
|
|
||||||
|
In this mode `qliksense` CLI download the specified version from [qliksense-k8s](https://github.com/qlik-oss/qliksense-k8s) and put it into folder `~/.qliksense/contexts/<context-name>/qlik-k8s`.
|
||||||
|
|
||||||
|
The qliksense cli create a CR for the qliksense operator and all the config operations are peformed to edit the CR. So when `qliksense install` or `qliksense config apply` both generate patches in local file system (i.e `~/.qliksense/contexts/<context-name>/qlik-k8s`) and install those manifests into the cluster and create a custom resoruce (CR) for the `qliksene operator` then the operator make association to the isntalled resoruces so that when `qliksenes uninstall` is performed the operator can delete all those kubernetes resources related to QSEoK for the current context.
|
||||||
|
|
||||||
|
## With a git repo
|
||||||
|
|
||||||
|
User has to create fork or clone of [qliksense-k8s](https://github.com/qlik-oss/qliksense-k8s) and push it to their own git server. When user perform `qliksense install` or `qliksene config apply` the qliksense operator do these tasks
|
||||||
|
|
||||||
|
- downloads the corresponding version of manifests from the user's git repo.
|
||||||
|
- generate kustomize patches
|
||||||
|
- install kubernetes resoruces
|
||||||
|
- push those generated patches into a new branch in the provided git repo. so that user user can merge those patches into their master branch.
|
||||||
|
- spinup a cornjob to monitor master branch. If user modifies anything in the master branch those changes will be applied into the cluster. This is a light weight `git-ops` model
|
||||||
|
|
||||||
|
This is how repo info is provided into the CR
|
||||||
|
|
||||||
|
```console
|
||||||
|
qliksense config set git.repository="https://github.com/my-org/qliksense-k8s"
|
||||||
|
|
||||||
|
qliksense config set git.accessToken=blablalaala
|
||||||
|
```
|
||||||
30
docs/getting_started.md
Normal file
30
docs/getting_started.md
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
# Getting started
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- `kubectl` need to be installed and configured properly so that `kubectl` can connect to the kubernetes cluser. The `qliksense` CLI uses `kubectl` under the hood to perform operations on cluster
|
||||||
|
- (Docker Desktop setup tested for these instructions)
|
||||||
|
|
||||||
|
## Download
|
||||||
|
|
||||||
|
- Download the appropriate executable for your platform from the [releases page](https://github.com/qlik-oss/sense-installer/releases) and rename it to `qliksense`. All the examplease down below uses `qliksense`.
|
||||||
|
|
||||||
|
## Quick start
|
||||||
|
|
||||||
|
- To download the version `v0.0.2` from qliksense-k8s [releases](https://github.com/qlik-oss/qliksense-k8s/releases).
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$qliksense fetch v0.0.2
|
||||||
|
```
|
||||||
|
|
||||||
|
- To install CRDs for QSEoK and qliksense operator into the kubernetes cluster.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$qliksense crds install --all
|
||||||
|
```
|
||||||
|
|
||||||
|
- To install QSEoK into a namespace in the kubernetes cluster where `kubectl` is pointing to.
|
||||||
|
|
||||||
|
```shell
|
||||||
|
$qliksense install --acceptEULA="yes"
|
||||||
|
```
|
||||||
19
docs/index.md
Normal file
19
docs/index.md
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
# Overview
|
||||||
|
|
||||||
|
The Qlik Sense installer CLI (qliksense) provides an imperative interface to many of the configurations that need to be applied against the declarative structure described in [qliksense-k8s](https://github.com/qlik-oss/qliksense-k8s). This cli facilitates:
|
||||||
|
|
||||||
|
- installation of QSEoK
|
||||||
|
- installation of qliksense operator to manage QSEoK
|
||||||
|
- air gapped installation of QSEoK
|
||||||
|
|
||||||
|
This is a technology preview that uses Qlik modified [kustomize](https://github.com/qlik-oss/kustomize) to kubernetes manifests of the versions of the [qliksense-k8s](https://github.com/qlik-oss/qliksense-k8s) repository.
|
||||||
|
|
||||||
|
For each version of a qliksense edge build there should be a corresponding release in [qliksense-k8s] repository under [releases](https://github.com/qlik-oss/qliksense-k8s/releases)
|
||||||
|
|
||||||
|
## Future Direction
|
||||||
|
|
||||||
|
- More operations:
|
||||||
|
- Expand preflight checks
|
||||||
|
- backup/restore operations
|
||||||
|
- fully support airgap installation of QSEoK
|
||||||
|
- restore unwanted deletion of kubernetes resources
|
||||||
2
go.mod
2
go.mod
@@ -39,7 +39,7 @@ require (
|
|||||||
github.com/mattn/go-colorable v0.1.4
|
github.com/mattn/go-colorable v0.1.4
|
||||||
github.com/mitchellh/go-homedir v1.1.0
|
github.com/mitchellh/go-homedir v1.1.0
|
||||||
github.com/morikuni/aec v1.0.0 // indirect
|
github.com/morikuni/aec v1.0.0 // indirect
|
||||||
github.com/qlik-oss/k-apis v0.0.17
|
github.com/qlik-oss/k-apis v0.0.19
|
||||||
github.com/rogpeppe/go-internal v1.5.2 // indirect
|
github.com/rogpeppe/go-internal v1.5.2 // indirect
|
||||||
github.com/spf13/cobra v0.0.6
|
github.com/spf13/cobra v0.0.6
|
||||||
github.com/spf13/viper v1.6.1
|
github.com/spf13/viper v1.6.1
|
||||||
|
|||||||
3
go.sum
3
go.sum
@@ -843,8 +843,11 @@ github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDa
|
|||||||
github.com/prometheus/procfs v0.0.5 h1:3+auTFlqw+ZaQYJARz6ArODtkaIwtvBTx3N2NehQlL8=
|
github.com/prometheus/procfs v0.0.5 h1:3+auTFlqw+ZaQYJARz6ArODtkaIwtvBTx3N2NehQlL8=
|
||||||
github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
||||||
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
|
||||||
|
github.com/qlik-oss/k-apis v0.0.16/go.mod h1:KOFzKVIdRqp47ytnHg3+9zb8fTlnrQjO6aKiwcrCJUE=
|
||||||
github.com/qlik-oss/k-apis v0.0.17 h1:tOdrEe9gfb9CXq0+uowFnXIsI781qz/zgeN8xqupXYw=
|
github.com/qlik-oss/k-apis v0.0.17 h1:tOdrEe9gfb9CXq0+uowFnXIsI781qz/zgeN8xqupXYw=
|
||||||
github.com/qlik-oss/k-apis v0.0.17/go.mod h1:KOFzKVIdRqp47ytnHg3+9zb8fTlnrQjO6aKiwcrCJUE=
|
github.com/qlik-oss/k-apis v0.0.17/go.mod h1:KOFzKVIdRqp47ytnHg3+9zb8fTlnrQjO6aKiwcrCJUE=
|
||||||
|
github.com/qlik-oss/k-apis v0.0.19 h1:yrMgALQ08vMDi5hN6fnvIfyNsEaXA5fZjB1YhyIdTfg=
|
||||||
|
github.com/qlik-oss/k-apis v0.0.19/go.mod h1:DNiWYqCqPIN216l7+1rccArNIYPb1Le7kYDcPSyNp+Q=
|
||||||
github.com/qlik-oss/kustomize/api v0.3.3-0.20200206224201-2e697eccbad9 h1:iqeqTS4zjp6rPEaxmFB7pemA2CMjOEN5dYSXZaQ82uw=
|
github.com/qlik-oss/kustomize/api v0.3.3-0.20200206224201-2e697eccbad9 h1:iqeqTS4zjp6rPEaxmFB7pemA2CMjOEN5dYSXZaQ82uw=
|
||||||
github.com/qlik-oss/kustomize/api v0.3.3-0.20200206224201-2e697eccbad9/go.mod h1:OCt7FTrRVHj4kmR2xLJJUIqu00BTr6GeF09hSmM17Kw=
|
github.com/qlik-oss/kustomize/api v0.3.3-0.20200206224201-2e697eccbad9/go.mod h1:OCt7FTrRVHj4kmR2xLJJUIqu00BTr6GeF09hSmM17Kw=
|
||||||
github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI=
|
github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI=
|
||||||
|
|||||||
18
mkdocs.yml
Normal file
18
mkdocs.yml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
site_name: Qlik Sense installer
|
||||||
|
repo_url: 'https://github.com/qlik-oss/sense-installer'
|
||||||
|
strict: true
|
||||||
|
theme:
|
||||||
|
name: "material"
|
||||||
|
palette:
|
||||||
|
primary: 'green'
|
||||||
|
accent: 'indigo'
|
||||||
|
markdown_extensions:
|
||||||
|
- toc:
|
||||||
|
permalink: true
|
||||||
|
- admonition
|
||||||
|
nav:
|
||||||
|
- Overview: index.md
|
||||||
|
- getting_started.md
|
||||||
|
- concepts.md
|
||||||
|
- air_gap.md
|
||||||
|
- Releases ⧉: https://github.com/qlik-oss/sense-installer/releases
|
||||||
@@ -22,6 +22,7 @@ const (
|
|||||||
pullSecretFileName = "image-registry-pull-secret.yaml"
|
pullSecretFileName = "image-registry-pull-secret.yaml"
|
||||||
qliksenseContextsDirName = "contexts"
|
qliksenseContextsDirName = "contexts"
|
||||||
qliksenseSecretsDirName = "secrets"
|
qliksenseSecretsDirName = "secrets"
|
||||||
|
qliksenseEjsonDirName = "ejson"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewQConfig create QliksenseConfig object from file ~/.qliksense/config.yaml
|
// NewQConfig create QliksenseConfig object from file ~/.qliksense/config.yaml
|
||||||
@@ -239,6 +240,18 @@ func (qc *QliksenseConfig) getCurrentContextEncryptionKeyPairLocation() (string,
|
|||||||
return secretKeyPairLocation, nil
|
return secretKeyPairLocation, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (qc *QliksenseConfig) GetCurrentContextEjsonKeyDir() (string, error) {
|
||||||
|
if qcr, err := qc.GetCurrentCR(); err != nil {
|
||||||
|
return "", err
|
||||||
|
} else {
|
||||||
|
ejsonKeyDir := filepath.Join(qc.QliksenseHomePath, qliksenseSecretsDirName, qliksenseContextsDirName, qcr.GetObjectMeta().GetName(), qliksenseEjsonDirName)
|
||||||
|
if err := os.MkdirAll(ejsonKeyDir, os.ModePerm); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return ejsonKeyDir, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (qc *QliksenseConfig) GetCurrentContextEncryptionKeyPair() (*rsa.PublicKey, *rsa.PrivateKey, error) {
|
func (qc *QliksenseConfig) GetCurrentContextEncryptionKeyPair() (*rsa.PublicKey, *rsa.PrivateKey, error) {
|
||||||
secretKeyPairLocation, err := qc.getCurrentContextEncryptionKeyPairLocation()
|
secretKeyPairLocation, err := qc.getCurrentContextEncryptionKeyPairLocation()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -80,31 +80,6 @@ func ProcessConfigArgs(args []string) ([]*ServiceKeyValue, error) {
|
|||||||
return resultSvcKV, nil
|
return resultSvcKV, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProcessUnsetConfigArgs processes args and returns an service, key, nil slice
|
|
||||||
func ProcessUnsetConfigArgs(args []string) ([]*ServiceKeyValue, error) {
|
|
||||||
if len(args) == 0 {
|
|
||||||
err := fmt.Errorf("No args were provided. Please provide args to configure the current context")
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
resultSvcKV := make([]*ServiceKeyValue, len(args))
|
|
||||||
re1 := regexp.MustCompile(`(\w{1,}).(\w{1,})`)
|
|
||||||
for i, arg := range args {
|
|
||||||
LogDebugMessage("Arg received: %s", arg)
|
|
||||||
result := re1.FindStringSubmatch(arg)
|
|
||||||
// check if result array's length is == 3 (index 0 - is the full match & indices 1,2,- are the fields we need)
|
|
||||||
if len(result) != 3 {
|
|
||||||
err := fmt.Errorf("Please provide valid args for this command")
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
resultSvcKV[i] = &ServiceKeyValue{
|
|
||||||
SvcName: result[1],
|
|
||||||
Key: result[2],
|
|
||||||
Value: "",
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return resultSvcKV, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func ExecuteTaskWithBlinkingStdoutFeedback(task func() (interface{}, error), feedback string) (result interface{}, err error) {
|
func ExecuteTaskWithBlinkingStdoutFeedback(task func() (interface{}, error), feedback string) (result interface{}, err error) {
|
||||||
taskDone := make(chan bool)
|
taskDone := make(chan bool)
|
||||||
go func() {
|
go func() {
|
||||||
|
|||||||
@@ -59,14 +59,21 @@ func (q *Qliksense) ConfigApplyQK8s() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (q *Qliksense) configEjson() error {
|
||||||
|
qConfig := qapi.NewQConfig(q.QliksenseHome)
|
||||||
|
if ejsonKeyDir, err := qConfig.GetCurrentContextEjsonKeyDir(); err != nil {
|
||||||
|
return err
|
||||||
|
} else if err := os.Unsetenv("EJSON_KEY"); err != nil {
|
||||||
|
return err
|
||||||
|
} else if err := os.Setenv("EJSON_KEYDIR", ejsonKeyDir); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (q *Qliksense) applyConfigToK8s(qcr *qapi.QliksenseCR) error {
|
func (q *Qliksense) applyConfigToK8s(qcr *qapi.QliksenseCR) error {
|
||||||
if qcr.Spec.RotateKeys != "None" {
|
if qcr.Spec.RotateKeys != "None" {
|
||||||
if err := os.Unsetenv("EJSON_KEY"); err != nil {
|
if err := q.configEjson(); err != nil {
|
||||||
fmt.Printf("error unsetting EJSON_KEY environment variable: %v\n", err)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := os.Setenv("EJSON_KEYDIR", q.QliksenseEjsonKeyDir); err != nil {
|
|
||||||
fmt.Printf("error setting EJSON_KEYDIR environment variable: %v\n", err)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import (
|
|||||||
"github.com/qlik-oss/k-apis/pkg/config"
|
"github.com/qlik-oss/k-apis/pkg/config"
|
||||||
|
|
||||||
b64 "encoding/base64"
|
b64 "encoding/base64"
|
||||||
|
|
||||||
ansi "github.com/mattn/go-colorable"
|
ansi "github.com/mattn/go-colorable"
|
||||||
"github.com/qlik-oss/sense-installer/pkg/api"
|
"github.com/qlik-oss/sense-installer/pkg/api"
|
||||||
"github.com/ttacon/chalk"
|
"github.com/ttacon/chalk"
|
||||||
@@ -147,27 +146,6 @@ func (q *Qliksense) SetConfigs(args []string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetConfigs - set-configs <key>=<value> commands
|
|
||||||
func (q *Qliksense) UnsetConfigs(args []string) error {
|
|
||||||
// retieve current context from config.yaml
|
|
||||||
qliksenseCR, qliksenseContextsFile, err := retrieveCurrentContextInfo(q)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
resultArgs, err := api.ProcessUnsetConfigArgs(args)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
for _, ra := range resultArgs {
|
|
||||||
qliksenseCR.Spec.AddToConfigs(ra.SvcName, ra.Key, ra.Value)
|
|
||||||
}
|
|
||||||
// write modified content into context.yaml
|
|
||||||
api.WriteToFile(&qliksenseCR, qliksenseContextsFile)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func retrieveCurrentContextInfo(q *Qliksense) (*api.QliksenseCR, string, error) {
|
func retrieveCurrentContextInfo(q *Qliksense) (*api.QliksenseCR, string, error) {
|
||||||
var qliksenseConfig api.QliksenseConfig
|
var qliksenseConfig api.QliksenseConfig
|
||||||
qliksenseConfigFile := filepath.Join(q.QliksenseHome, QliksenseConfigFile)
|
qliksenseConfigFile := filepath.Join(q.QliksenseHome, QliksenseConfigFile)
|
||||||
@@ -247,49 +225,38 @@ func (q *Qliksense) SetOtherConfigs(args []string) error {
|
|||||||
}
|
}
|
||||||
qliksenseCR.Spec.RotateKeys = rotateKeys
|
qliksenseCR.Spec.RotateKeys = rotateKeys
|
||||||
api.LogDebugMessage("Current rotateKeys after modification: %s ", qliksenseCR.Spec.RotateKeys)
|
api.LogDebugMessage("Current rotateKeys after modification: %s ", qliksenseCR.Spec.RotateKeys)
|
||||||
default:
|
case "gitops.enabled":
|
||||||
err := fmt.Errorf("Please enter one of: profile, storageClassName,rotateKeys, manifestRoot or git.repository arguments to configure the current context")
|
if qliksenseCR.Spec.GitOps == nil {
|
||||||
log.Println(err)
|
qliksenseCR.Spec.GitOps = &config.GitOps{}
|
||||||
return err
|
}
|
||||||
}
|
if strings.EqualFold(argsString[1], "false") {
|
||||||
}
|
qliksenseCR.Spec.GitOps.Enabled = false
|
||||||
// write modified content into context.yaml
|
} else if strings.EqualFold(argsString[1], "true") {
|
||||||
api.WriteToFile(&qliksenseCR, qliksenseContextsFile)
|
qliksenseCR.Spec.GitOps.Enabled = true
|
||||||
|
} else {
|
||||||
return nil
|
err := fmt.Errorf("Please use a boolean value")
|
||||||
}
|
log.Println(err)
|
||||||
|
return err
|
||||||
// SetOtherConfigs - set profile/storageclassname/git.repository/manifestRoot commands
|
}
|
||||||
func (q *Qliksense) UnsetOtherConfigs(args []string) error {
|
api.LogDebugMessage("Current gitOps enabled status : %s ", qliksenseCR.Spec.GitOps.Enabled)
|
||||||
// retieve current context from config.yaml
|
case "gitops.schedule":
|
||||||
qliksenseCR, qliksenseContextsFile, err := retrieveCurrentContextInfo(q)
|
if qliksenseCR.Spec.GitOps == nil {
|
||||||
if err != nil {
|
qliksenseCR.Spec.GitOps = &config.GitOps{}
|
||||||
return err
|
}
|
||||||
}
|
qliksenseCR.Spec.GitOps.Schedule = argsString[1]
|
||||||
|
api.LogDebugMessage("Current gitOps schedule is : %s ", qliksenseCR.Spec.GitOps.Schedule)
|
||||||
// modify appropriate fields
|
case "gitops.watchbranch":
|
||||||
if len(args) == 0 {
|
if qliksenseCR.Spec.GitOps == nil {
|
||||||
err := fmt.Errorf("No args were provided. Please provide args to configure the current context")
|
qliksenseCR.Spec.GitOps = &config.GitOps{}
|
||||||
log.Println(err)
|
}
|
||||||
return err
|
qliksenseCR.Spec.GitOps.WatchBranch = argsString[1]
|
||||||
}
|
api.LogDebugMessage("Current gitOps watchbranch is : %s ", qliksenseCR.Spec.GitOps.WatchBranch)
|
||||||
|
case "gitops.image":
|
||||||
for _, arg := range args {
|
if qliksenseCR.Spec.GitOps == nil {
|
||||||
switch arg {
|
qliksenseCR.Spec.GitOps = &config.GitOps{}
|
||||||
case "profile":
|
}
|
||||||
qliksenseCR.Spec.Profile = ""
|
qliksenseCR.Spec.GitOps.Image = argsString[1]
|
||||||
api.LogDebugMessage("Current profile after modification: %s ", qliksenseCR.Spec.Profile)
|
api.LogDebugMessage("Current gitOps watchbranch is : %s ", qliksenseCR.Spec.GitOps.Image)
|
||||||
case "git.repository":
|
|
||||||
qliksenseCR.Spec.Git.Repository = ""
|
|
||||||
api.LogDebugMessage("Current git repository after modification: %s ", qliksenseCR.Spec.Git.Repository)
|
|
||||||
case "storageClassName":
|
|
||||||
qliksenseCR.Spec.StorageClassName = ""
|
|
||||||
api.LogDebugMessage("Current StorageClassName after modification: %s ", qliksenseCR.Spec.StorageClassName)
|
|
||||||
case "manifestsRoot":
|
|
||||||
qliksenseCR.Spec.ManifestsRoot = ""
|
|
||||||
case "rotateKeys":
|
|
||||||
qliksenseCR.Spec.RotateKeys = ""
|
|
||||||
api.LogDebugMessage("Current rotateKeys after modification: %s ", qliksenseCR.Spec.RotateKeys)
|
|
||||||
default:
|
default:
|
||||||
err := fmt.Errorf("Please enter one of: profile, storageClassName,rotateKeys, manifestRoot or git.repository arguments to configure the current context")
|
err := fmt.Errorf("Please enter one of: profile, storageClassName,rotateKeys, manifestRoot or git.repository arguments to configure the current context")
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
@@ -349,10 +316,12 @@ func (q *Qliksense) DeleteContextConfig(args []string) error {
|
|||||||
out := ansi.NewColorableStdout()
|
out := ansi.NewColorableStdout()
|
||||||
switch args[0] {
|
switch args[0] {
|
||||||
case qliksenseConfig.Spec.CurrentContext:
|
case qliksenseConfig.Spec.CurrentContext:
|
||||||
fmt.Fprintln(out, chalk.Red.Color("Error: Cannot delete current context -"), chalk.Bold.TextStyle(qliksenseConfig.Spec.CurrentContext))
|
|
||||||
fmt.Fprintln(out, chalk.Yellow.Color("Please switch contexts to be able to delete this context."))
|
fmt.Fprintln(out, chalk.Yellow.Color("Please switch contexts to be able to delete this context."))
|
||||||
|
err := fmt.Errorf(chalk.Red.Color("Cannot delete current context - %s"), chalk.White.Color(chalk.Bold.TextStyle(qliksenseConfig.Spec.CurrentContext)))
|
||||||
|
return err
|
||||||
case DefaultQliksenseContext:
|
case DefaultQliksenseContext:
|
||||||
fmt.Fprintln(out, chalk.Red.Color("Error: Cannot delete default qliksense context"))
|
err := fmt.Errorf(chalk.Red.Color("Cannot delete default qliksense context"))
|
||||||
|
return err
|
||||||
default:
|
default:
|
||||||
qliksenseContextsDir1 := filepath.Join(q.QliksenseHome, QliksenseContextsDir)
|
qliksenseContextsDir1 := filepath.Join(q.QliksenseHome, QliksenseContextsDir)
|
||||||
qliksenseContextFile := filepath.Join(qliksenseContextsDir1, args[0])
|
qliksenseContextFile := filepath.Join(qliksenseContextsDir1, args[0])
|
||||||
@@ -385,7 +354,8 @@ func (q *Qliksense) DeleteContextConfig(args []string) error {
|
|||||||
fmt.Fprintln(out, chalk.Yellow.Color(chalk.Underline.TextStyle("Warning: Active resources may still be running in-cluster")))
|
fmt.Fprintln(out, chalk.Yellow.Color(chalk.Underline.TextStyle("Warning: Active resources may still be running in-cluster")))
|
||||||
fmt.Fprintln(out, chalk.Green.Color("Successfully deleted context: "), chalk.Bold.TextStyle(args[0]))
|
fmt.Fprintln(out, chalk.Green.Color("Successfully deleted context: "), chalk.Bold.TextStyle(args[0]))
|
||||||
} else {
|
} else {
|
||||||
fmt.Fprintln(out, chalk.Red.Color("Error: Context not found"))
|
err := fmt.Errorf(chalk.Red.Color("Context not found"))
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -273,11 +273,7 @@ func TestSetUpQliksenseContext(t *testing.T) {
|
|||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
q, err := New(tt.args.qlikSenseHome)
|
q := New(tt.args.qlikSenseHome)
|
||||||
if err != nil {
|
|
||||||
t.Errorf("unable to create a qliksense instance")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err := q.SetUpQliksenseContext(tt.args.contextName, tt.args.isDefaultContext); (err != nil) != tt.wantErr {
|
if err := q.SetUpQliksenseContext(tt.args.contextName, tt.args.isDefaultContext); (err != nil) != tt.wantErr {
|
||||||
t.Errorf("SetUpQliksenseContext() error = %v, wantErr %v", err, tt.wantErr)
|
t.Errorf("SetUpQliksenseContext() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
}
|
}
|
||||||
@@ -306,11 +302,7 @@ func TestSetUpQliksenseDefaultContext(t *testing.T) {
|
|||||||
defer tearDown()
|
defer tearDown()
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
q, err := New(tt.args.qlikSenseHome)
|
q := New(tt.args.qlikSenseHome)
|
||||||
if err != nil {
|
|
||||||
t.Errorf("unable to create a qliksense instance")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err := q.SetUpQliksenseDefaultContext(); (err != nil) != tt.wantErr {
|
if err := q.SetUpQliksenseDefaultContext(); (err != nil) != tt.wantErr {
|
||||||
t.Errorf("SetUpQliksenseDefaultContext() error = %v, wantErr %v", err, tt.wantErr)
|
t.Errorf("SetUpQliksenseDefaultContext() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
}
|
}
|
||||||
@@ -370,60 +362,6 @@ func TestSetOtherConfigs(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUnsetOtherConfigs(t *testing.T) {
|
|
||||||
type args struct {
|
|
||||||
q *Qliksense
|
|
||||||
args []string
|
|
||||||
}
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
args args
|
|
||||||
wantErr bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "valid case",
|
|
||||||
args: args{
|
|
||||||
q: &Qliksense{
|
|
||||||
QliksenseHome: testDir,
|
|
||||||
},
|
|
||||||
args: []string{"profile", "rotateKeys", "storageClassName"},
|
|
||||||
},
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "invalid configs",
|
|
||||||
args: args{
|
|
||||||
q: &Qliksense{
|
|
||||||
QliksenseHome: testDir,
|
|
||||||
},
|
|
||||||
args: []string{"someconfig"},
|
|
||||||
},
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "empty configs",
|
|
||||||
args: args{
|
|
||||||
q: &Qliksense{
|
|
||||||
QliksenseHome: testDir,
|
|
||||||
},
|
|
||||||
args: []string{},
|
|
||||||
},
|
|
||||||
wantErr: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
tearDown := setup()
|
|
||||||
defer tearDown()
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
//set arguments to be removed
|
|
||||||
_ = tt.args.q.SetOtherConfigs([]string{"profile=minikube", "rotateKeys=yes", "storageClassName=efs"})
|
|
||||||
if err := tt.args.q.UnsetOtherConfigs(tt.args.args); (err != nil) != tt.wantErr {
|
|
||||||
t.Errorf("SetOtherConfigs() error = %v, wantErr %v", err, tt.wantErr)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSetConfigs(t *testing.T) {
|
func TestSetConfigs(t *testing.T) {
|
||||||
type args struct {
|
type args struct {
|
||||||
q *Qliksense
|
q *Qliksense
|
||||||
@@ -456,40 +394,6 @@ func TestSetConfigs(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestUnsetConfigs(t *testing.T) {
|
|
||||||
type args struct {
|
|
||||||
q *Qliksense
|
|
||||||
args []string
|
|
||||||
}
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
args args
|
|
||||||
wantErr bool
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "valid case",
|
|
||||||
args: args{
|
|
||||||
q: &Qliksense{
|
|
||||||
QliksenseHome: testDir,
|
|
||||||
},
|
|
||||||
args: []string{"qliksense.acceptEULA", "qliksense.mongoDbUri"},
|
|
||||||
},
|
|
||||||
wantErr: false,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
tearDown := setup()
|
|
||||||
defer tearDown()
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
//set arguments to be removed
|
|
||||||
_ = tt.args.q.SetConfigs([]string{"qliksense.acceptEULA=\"yes\"", "qliksense.mongoDbUri=\"mongo://mongo:3307\""})
|
|
||||||
if err := tt.args.q.UnsetConfigs(tt.args.args); (err != nil) != tt.wantErr {
|
|
||||||
t.Errorf("SetConfigs() error = %v, wantErr %v", err, tt.wantErr)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSetImageRegistry(t *testing.T) {
|
func TestSetImageRegistry(t *testing.T) {
|
||||||
getQlikSense := func(tmpQlikSenseHome string) (*Qliksense, error) {
|
getQlikSense := func(tmpQlikSenseHome string) (*Qliksense, error) {
|
||||||
if err := ioutil.WriteFile(path.Join(tmpQlikSenseHome, "config.yaml"), []byte(fmt.Sprintf(`
|
if err := ioutil.WriteFile(path.Join(tmpQlikSenseHome, "config.yaml"), []byte(fmt.Sprintf(`
|
||||||
@@ -880,3 +784,153 @@ func getValueToBeDecodedForSetSecrets(item config.NameValue, qliksenseCR *api.Ql
|
|||||||
err := fmt.Errorf("Both Value and ValueFrom are empty")
|
err := fmt.Errorf("Both Value and ValueFrom are empty")
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func setupDeleteContext() func() {
|
||||||
|
if err := os.Mkdir(testDir, 0777); err != nil {
|
||||||
|
log.Printf("\nError occurred: %v", err)
|
||||||
|
}
|
||||||
|
config :=
|
||||||
|
`
|
||||||
|
apiVersion: config.qlik.com/v1
|
||||||
|
kind: QliksenseConfig
|
||||||
|
metadata:
|
||||||
|
name: qliksenseConfig
|
||||||
|
spec:
|
||||||
|
contexts:
|
||||||
|
- name: qlik-default
|
||||||
|
crFile: /root/.qliksense/contexts/qlik-default.yaml
|
||||||
|
- name: qlik1
|
||||||
|
crFile: /root/.qliksense/contexts/qlik1.yaml
|
||||||
|
- name: qlik2
|
||||||
|
crFile: /root/.qliksense/contexts/qlik2.yaml
|
||||||
|
currentContext: qlik1
|
||||||
|
`
|
||||||
|
configFile := filepath.Join(testDir, "config.yaml")
|
||||||
|
// tests/config.yaml exists
|
||||||
|
ioutil.WriteFile(configFile, []byte(config), 0777)
|
||||||
|
contextYaml :=
|
||||||
|
`
|
||||||
|
apiVersion: qlik.com/v1
|
||||||
|
kind: Qliksense
|
||||||
|
metadata:
|
||||||
|
name: qlik-default
|
||||||
|
spec:
|
||||||
|
profile: docker-desktop
|
||||||
|
rotateKeys: "yes"
|
||||||
|
releaseName: qlik-default
|
||||||
|
`
|
||||||
|
qlikDefaultContext := "qlik-default"
|
||||||
|
// create contexts/qlik-default/ under tests/
|
||||||
|
contexts := "contexts"
|
||||||
|
contextsDir1 := filepath.Join(testDir, contexts, qlikDefaultContext)
|
||||||
|
if err := os.MkdirAll(contextsDir1, 0777); err != nil {
|
||||||
|
err = fmt.Errorf("Not able to create directories")
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
contextYaml1 :=
|
||||||
|
`
|
||||||
|
apiVersion: qlik.com/v1
|
||||||
|
kind: Qliksense
|
||||||
|
metadata:
|
||||||
|
name: qlik1
|
||||||
|
spec:
|
||||||
|
profile: docker-desktop
|
||||||
|
rotateKeys: "yes"
|
||||||
|
releaseName: qlik1`
|
||||||
|
|
||||||
|
contextYaml2 :=
|
||||||
|
`
|
||||||
|
apiVersion: qlik.com/v1
|
||||||
|
kind: Qliksense
|
||||||
|
metadata:
|
||||||
|
name: qlik2
|
||||||
|
spec:
|
||||||
|
profile: docker-desktop
|
||||||
|
rotateKeys: "yes"
|
||||||
|
releaseName: qlik2`
|
||||||
|
|
||||||
|
contextsDir := filepath.Join(testDir, contexts, "qlik1")
|
||||||
|
if err := os.MkdirAll(contextsDir, 0777); err != nil {
|
||||||
|
err = fmt.Errorf("Not able to create directories")
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
contextsDir2 := filepath.Join(testDir, contexts, "qlik2")
|
||||||
|
if err := os.MkdirAll(contextsDir2, 0777); err != nil {
|
||||||
|
err = fmt.Errorf("Not able to create directories")
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
contextFile := filepath.Join(contextsDir, "qlik1.yaml")
|
||||||
|
ioutil.WriteFile(contextFile, []byte(contextYaml1), 0777)
|
||||||
|
|
||||||
|
contextFile2 := filepath.Join(contextsDir2, "qlik2.yaml")
|
||||||
|
ioutil.WriteFile(contextFile2, []byte(contextYaml2), 0777)
|
||||||
|
|
||||||
|
contextFile1 := filepath.Join(contextsDir1, "qlik-default.yaml")
|
||||||
|
ioutil.WriteFile(contextFile1, []byte(contextYaml), 0777)
|
||||||
|
|
||||||
|
tearDown := func() {
|
||||||
|
os.RemoveAll(testDir)
|
||||||
|
}
|
||||||
|
return tearDown
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDeleteContexts(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
qlikSenseHome string
|
||||||
|
contextName string
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "valid context",
|
||||||
|
args: args{
|
||||||
|
qlikSenseHome: testDir,
|
||||||
|
contextName: "qlik2",
|
||||||
|
},
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "default context",
|
||||||
|
args: args{
|
||||||
|
qlikSenseHome: testDir,
|
||||||
|
contextName: "qlik-default",
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "non-existent context",
|
||||||
|
args: args{
|
||||||
|
qlikSenseHome: testDir,
|
||||||
|
contextName: "qlik3",
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "current context",
|
||||||
|
args: args{
|
||||||
|
qlikSenseHome: testDir,
|
||||||
|
contextName: "qlik1",
|
||||||
|
},
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
tearDown := setupDeleteContext()
|
||||||
|
defer tearDown()
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
q := New(tt.args.qlikSenseHome)
|
||||||
|
var arg []string
|
||||||
|
arg = append(arg, tt.args.contextName)
|
||||||
|
if err := q.DeleteContextConfig(arg); (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("DeleteContext() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,29 +2,21 @@
|
|||||||
package qliksense
|
package qliksense
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
|
|
||||||
"github.com/gobuffalo/packr/v2"
|
"github.com/gobuffalo/packr/v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Qliksense is the logic behind the qliksense client
|
// Qliksense is the logic behind the qliksense client
|
||||||
type Qliksense struct {
|
type Qliksense struct {
|
||||||
QliksenseHome string
|
QliksenseHome string
|
||||||
QliksenseEjsonKeyDir string
|
CrdBox *packr.Box ``
|
||||||
CrdBox *packr.Box ``
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// New qliksense client, initialized with useful defaults.
|
// New qliksense client, initialized with useful defaults.
|
||||||
func New(qliksenseHome string) (*Qliksense, error) {
|
func New(qliksenseHome string) *Qliksense {
|
||||||
qliksenseClient := &Qliksense{
|
qliksenseClient := &Qliksense{
|
||||||
QliksenseHome: qliksenseHome,
|
QliksenseHome: qliksenseHome,
|
||||||
CrdBox: packr.New("crds", "./crds"),
|
CrdBox: packr.New("crds", "./crds"),
|
||||||
}
|
}
|
||||||
|
|
||||||
qliksenseClient.QliksenseEjsonKeyDir = path.Join(qliksenseHome, "ejson", "keys")
|
return qliksenseClient
|
||||||
if err := os.MkdirAll(qliksenseClient.QliksenseEjsonKeyDir, os.ModePerm); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return qliksenseClient, nil
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,9 @@ func (q *Qliksense) UpgradeQK8s(keepPatchFiles bool) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
qcr.Spec.RotateKeys = "no"
|
qcr.Spec.RotateKeys = "no"
|
||||||
if err := q.applyConfigToK8s(qcr); err != nil {
|
if dcr, err := qConfig.GetDecryptedCr(qcr); err != nil {
|
||||||
|
return err
|
||||||
|
} else if err := q.applyConfigToK8s(dcr); err != nil {
|
||||||
fmt.Println("cannot do kubectl apply on manifests")
|
fmt.Println("cannot do kubectl apply on manifests")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user