Compare commits

...

33 Commits

Author SHA1 Message Date
Foysal Iqbal
1a2de669ba FIx gke issue (#233) 2020-03-19 21:39:44 -04:00
Foysal Iqbal
86e8805bc7 Fix doc for gitops (#227) 2020-03-19 09:31:37 -04:00
Foysal Iqbal
c2430c3817 fix doc for gitips (#226) 2020-03-19 09:04:57 -04:00
Andriy Bulynko
2f039f2d2e get-versions command (#225) 2020-03-18 10:23:42 -04:00
Sanat Nayar
48ee673ddc refined auto-suggestion 2020-03-17 15:56:40 -04:00
Sanat Nayar
57a80a9533 refined auto-suggestion 2020-03-17 15:20:18 -04:00
Andriy Bulynko
4fe04d6142 Upgrading k-apis to v0.0.21 (#220) 2020-03-17 12:31:24 -04:00
Sanat Nayar
1fd3310e05 Merge pull request #219 from qlik-oss/support_config_set_gitops
changed k-api version
2020-03-17 11:33:54 -04:00
Sanat Nayar
b85269d908 changed k-api version 2020-03-17 11:29:39 -04:00
Sanat Nayar
cbdafadbaf changed k-api version 2020-03-17 11:24:27 -04:00
Sanat Nayar
c0e2128d5d Merge pull request #215 from qlik-oss/support_config_set_gitops
Support config set gitops
2020-03-17 08:59:21 -04:00
Ilir Bekteshi
df19cadcb6 Merge pull request #207 from qlik-oss/ibiqlik/upx
Move build from CircleCi to GitHub Actions; use UPX to compress binaries #88
2020-03-17 12:51:46 +01:00
Ilir Bekteshi
d9cbbf54cc Merge pull request #211 from qlik-oss/ibiqlik/tidydocs
Tidying up docs/readme
2020-03-17 10:39:16 +01:00
Sanat Nayar
c4f0ddcea3 added cron parser 2020-03-16 17:09:40 -04:00
Sanat Nayar
f57457029d added cron parser 2020-03-16 16:24:44 -04:00
Foysal Iqbal
69aca05a86 fix doubble print (#217)
Signed-off-by: Foysal Iqbal <mqb@qlik.com>
2020-03-16 16:08:07 -04:00
Sanat Nayar
aa737b0594 changed gitops arch 2020-03-16 14:58:17 -04:00
Ilir Bekteshi
e4d69f059a Archive uncompressed binaries, remove lzma in upx 2020-03-16 17:58:11 +01:00
Sanat Nayar
b7c0fd48b7 added basic test cases 2020-03-16 12:57:31 -04:00
Sanat Nayar
4530d1d9e2 fixed error 2020-03-16 12:50:40 -04:00
Sanat Nayar
ca20f8c992 go.sum 2020-03-13 17:44:11 -04:00
Sanat Nayar
b2c16a490b go.sum 2020-03-13 17:40:26 -04:00
Sanat Nayar
7f70cc661e go.sum 2020-03-13 17:06:30 -04:00
Sanat Nayar
2c054cd54e mod. go.sum 2020-03-13 17:04:02 -04:00
Andriy Bulynko
0b2fdae015 Scoping ejson keys and their rotations to the current context/CR (#214) 2020-03-13 16:28:06 -04:00
Ilir Bekteshi
cfc8fbb1f1 Tidying up docs/readme 2020-03-13 14:58:34 +01:00
Sanat Nayar
30f00461ec added GitOps to spec 2020-03-13 09:30:48 -04:00
Sanat Nayar
613b918dde init 2020-03-11 11:20:53 -04:00
Ilir Bekteshi
bdcadebeca Split workflow for PR and Release
Release workflow builds all variants and compresses them using UPX. All files under bin/ are uploaded to the release.
2020-03-11 11:46:37 +01:00
Ilir Bekteshi
626a2ebe68 Fetch git tags 2020-03-11 11:46:37 +01:00
Ilir Bekteshi
1f64641ab1 Use https instead of ssh for cloning git repo (ssh key issues) 2020-03-11 11:46:37 +01:00
Ilir Bekteshi
b764fd179d Add GOPATH workaround 2020-03-11 11:46:37 +01:00
Ilir Bekteshi
e8d1899a41 Use UPX to compress; mv build from circle to GH
The build process is moving to GitHub Actions from CircleCi
The tar archiving is removed as it does not serve a purpose when UPX compression is at the same file size
2020-03-11 11:46:37 +01:00
24 changed files with 400 additions and 310 deletions

View File

@@ -1,43 +0,0 @@
# Golang CircleCI 2.0 configuration file
#
# Check https://circleci.com/docs/2.0/language-go/ for more details
version: 2
jobs:
build:
docker:
- image: circleci/golang:stretch
working_directory: /go/src/github.com/qlik-oss/sense-installer
steps:
- checkout
- run: make test
- run: make build
build_release:
docker:
- image: circleci/golang:stretch
working_directory: /go/src/github.com/qlik-oss/sense-installer
steps:
- checkout
- run: make test
- run: make xbuild-all
- run:
name: "Publish Release on GitHub"
command: |
go get github.com/tcnksm/ghr
ghr -t ${GITHUB_TOKEN} -u ${CIRCLE_PROJECT_USERNAME} -r ${CIRCLE_PROJECT_REPONAME} -c ${CIRCLE_SHA1} -delete ${CIRCLE_TAG} /go/src/github.com/${CIRCLE_PROJECT_USERNAME}/${CIRCLE_PROJECT_REPONAME}/bin/${CIRCLE_TAG}/
workflows:
version: 2
commit:
jobs:
- build:
filters:
tags:
ignore: /^v.*/
build_release:
jobs:
- build_release:
filters:
tags:
only: /^v.*/
branches:
ignore: /.*/

27
.github/workflows/build.yml vendored Normal file
View File

@@ -0,0 +1,27 @@
name: Build Sense installer
on: [pull_request]
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- name: Set up Go 1.13
uses: actions/setup-go@v1
with:
go-version: 1.13
- uses: actions/checkout@v2
- run: git fetch --depth=1 origin +refs/tags/*:refs/tags/*
- name: Set GOPATH
# temporary fix
# see https://github.com/actions/setup-go/issues/14
run: |
echo "##[set-env name=GOPATH;]$(dirname $GITHUB_WORKSPACE)"
echo "##[add-path]$(dirname $GITHUB_WORKSPACE)/bin"
shell: bash
- run: make test
- run: make build

37
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,37 @@
name: Release Sense installer binaries
on:
push:
tags:
- 'v*.*.*'
jobs:
release:
name: Build
runs-on: ubuntu-latest
steps:
- name: Set up Go 1.13
uses: actions/setup-go@v1
with:
go-version: 1.13
- uses: actions/checkout@v2
- run: git fetch --depth=1 origin +refs/tags/*:refs/tags/* # Needed in makefile for versioning
- name: Set GOPATH
# temporary fix
# see https://github.com/actions/setup-go/issues/14
run: |
echo "##[set-env name=GOPATH;]$(dirname $GITHUB_WORKSPACE)"
echo "##[add-path]$(dirname $GITHUB_WORKSPACE)/bin"
shell: bash
- run: make test
- run: make xbuild-all
- name: Release
uses: softprops/action-gh-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
files: bin/**/*

1
.gitignore vendored
View File

@@ -6,3 +6,4 @@ pkg/qliksense/packrd
pkg/qliksense/qliksense-packr.go
pkg/qliksense/docker-registry
/pkg/qliksense/tests
.DS_Store

View File

@@ -57,17 +57,24 @@ endif
xbuild-all: clean generate
$(foreach OS, $(SUPPORTED_PLATFORMS), \
$(foreach ARCH, $(SUPPORTED_ARCHES), \
$(MAKE) $(MAKE_OPTS) CLIENT_PLATFORM=$(OS) CLIENT_ARCH=$(ARCH) MIXIN=$(MIXIN) xbuild; \
))
$(foreach ARCH, $(SUPPORTED_ARCHES), \
$(MAKE) $(MAKE_OPTS) CLIENT_PLATFORM=$(OS) CLIENT_ARCH=$(ARCH) MIXIN=$(MIXIN) xbuild; \
))
$(MAKE) clean
xbuild: $(BINDIR)/$(VERSION)/$(MIXIN)-$(CLIENT_PLATFORM)-$(CLIENT_ARCH)$(FILE_EXT)
$(BINDIR)/$(VERSION)/$(MIXIN)-$(CLIENT_PLATFORM)-$(CLIENT_ARCH)$(FILE_EXT):
mkdir -p $(dir $@)
GOOS=$(CLIENT_PLATFORM) GOARCH=$(CLIENT_ARCH) $(XBUILD) -o $@ ./cmd/$(MIXIN)
tar -czvf $(BINDIR)/$(VERSION)/$(MIXIN)-$(CLIENT_PLATFORM)-$(CLIENT_ARCH).tar.gz -C $(BINDIR)/$(VERSION)/ $(MIXIN)-$(CLIENT_PLATFORM)-$(CLIENT_ARCH)$(FILE_EXT)
#tar -C $(BINDIR)/$(VERSION)/ -cvf $(BINDIR)/$(VERSION)/$(MIXIN)-$(CLIENT_PLATFORM)-$(CLIENT_ARCH).tar.gz $(MIXIN)-$(CLIENT_PLATFORM)-$(CLIENT_ARCH)$(FILE_EXT)
ifeq ($(CLIENT_PLATFORM),windows)
zip $(BINDIR)/$(VERSION)/$(MIXIN)-$(CLIENT_PLATFORM)-$(CLIENT_ARCH).zip $(BINDIR)/$(VERSION)/ $(MIXIN)-$(CLIENT_PLATFORM)-$(CLIENT_ARCH)$(FILE_EXT)
else
tar -czvf $(BINDIR)/$(VERSION)/$(MIXIN)-$(CLIENT_PLATFORM)-$(CLIENT_ARCH).tar.gz -C $(BINDIR)/$(VERSION)/ $(MIXIN)-$(CLIENT_PLATFORM)-$(CLIENT_ARCH)$(FILE_EXT)
endif
upx $(BINDIR)/$(VERSION)/$(MIXIN)-$(CLIENT_PLATFORM)-$(CLIENT_ARCH)$(FILE_EXT)
generate: get-crds packr2
go generate ./...
@@ -85,7 +92,7 @@ clean-packr: packr2
get-crds:
$(eval TMP := $(shell mktemp -d))
git clone git@github.com:qlik-oss/qliksense-operator.git -b ms-3 $(TMP)/operator
git clone https://github.com/qlik-oss/qliksense-operator.git -b master $(TMP)/operator
mkdir -p pkg/qliksense/crds/cr
mkdir -p pkg/qliksense/crds/crd
mkdir -p pkg/qliksense/crds/crd-deploy

133
README.md
View File

@@ -1,17 +1,9 @@
# (WIP) Qlik Sense installation and operations CLI
- [Qlik Sense installation and operations CLI](#qlik-sense-installation-and-operations-cli)
- [About](#about)
- [Future Direction](#future-direction)
- [Getting Started](#getting-started)
- [Requirements](#requirements)
- [Download](#download)
- [TL;DR](#TL;DR)
- [How qliksense CLI works](#how-qliksense-cli-works)
- [Witout Git Repo](#Without-git-repo)
- [With Git Repo](#With-a-git-repo)
- [Air Gapped](#air-gaped)
## Documentation
To learn more about Qlik Sense installer go to https://qlik-oss.github.io/sense-installer/
## About
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:
@@ -31,120 +23,3 @@ For each version of a qliksense edge build there should be a corresponding relea
- backup/restore operations
- fully support airgap installation of QSEoK
- restore unwanted deletion of kubernetes resources
## 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`.
### TL;DR
- 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"
```
## 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
```
## Air gaped

View File

@@ -0,0 +1,29 @@
package main
import (
"github.com/qlik-oss/sense-installer/pkg/qliksense"
"github.com/spf13/cobra"
)
const defaultVersionsLimit = 10
func getInstallableVersionsCmd(q *qliksense.Qliksense) *cobra.Command {
opts := &qliksense.LsRemoteCmdOptions{
IncludeBranches: false,
Limit: defaultVersionsLimit,
}
c := &cobra.Command{
Use: "get-versions",
Short: "list remote/installable versions",
Long: `list remote/installable versions`,
Example: `qliksense get-versions`,
RunE: func(cmd *cobra.Command, args []string) error {
return q.GetInstallableVersions(opts)
},
}
f := c.Flags()
f.BoolVarP(&opts.IncludeBranches, "include-branches", "", opts.IncludeBranches, "Include branches")
f.IntVarP(&opts.Limit, "limit", "", opts.Limit, "Maximum versions to list (starting with the highest)")
return c
}

View File

@@ -42,18 +42,16 @@ func initAndExecute() error {
// create dirs and appropriate files for setting up contexts
api.LogDebugMessage("QliksenseHomeDir: %s", qlikSenseHome)
qliksenseClient, err := qliksense.New(qlikSenseHome)
if err != nil {
return err
}
qliksenseClient := qliksense.New(qlikSenseHome)
qliksenseClient.SetUpQliksenseDefaultContext()
cmd := rootCmd(qliksenseClient)
//levenstein checks
if levenstein(cmd) == false {
if err := cmd.Execute(); err != nil {
return err
}
if err := cmd.Execute(); err != nil {
//levenstein checks (auto-suggestions)
levenstein(cmd)
return err
}
return nil
}
@@ -107,6 +105,7 @@ func rootCmd(p *qliksense.Qliksense) *cobra.Command {
// For qliksense overrides/commands
cmd.AddCommand(getInstallableVersionsCmd(p))
cmd.AddCommand(pullQliksenseImages(p))
cmd.AddCommand(pushQliksenseImages(p))
cmd.AddCommand(about(p))
@@ -151,14 +150,12 @@ func rootCmd(p *qliksense.Qliksense) *cobra.Command {
// add the list config command as a sub-command to the app config sub-command
configCmd.AddCommand(listContextConfigCmd(p))
// add the delete-context config command as a sub-command to the app config command
configCmd.AddCommand(deleteContextConfigCmd(p))
// add set-image-registry command as a sub-command to the app config sub-command
configCmd.AddCommand(setImageRegistryCmd(p))
// add clean-config-repo-patches command as a sub-command to the app config sub-command
configCmd.AddCommand(cleanConfigRepoPatchesCmd(p))
@@ -231,18 +228,11 @@ func copy(src, dst string) (int64, error) {
return nBytes, err
}
func levenstein(cmd *cobra.Command) bool {
cmd.SuggestionsMinimumDistance = 4
func levenstein(cmd *cobra.Command) {
cmd.SuggestionsMinimumDistance = 2
if len(os.Args) > 1 {
args := os.Args[1]
for _, ctx := range cmd.Commands() {
val := *ctx
if args == val.Name() {
//found command
return false
}
}
suggest := cmd.SuggestionsFor(os.Args[1])
suggest := cmd.SuggestionsFor(args)
if len(suggest) > 0 {
arg := []string{}
for _, cm := range os.Args {
@@ -251,8 +241,6 @@ func levenstein(cmd *cobra.Command) bool {
arg[1] = suggest[0]
out := ansi.NewColorableStdout()
fmt.Fprintln(out, chalk.Green.Color("Did you mean: "), chalk.Bold.TextStyle(strings.Join(arg, " ")), "?")
return true
}
}
return false
}

View File

@@ -1,6 +1,6 @@
# How qliksense cli works
At the initialization `qliksense` cli create few files in the director `~/.qliksene` and it contains following files
At the initialization, `qliksense` cli creates few files in the director `~/.qliksene` and it contains following files:
```console
.qliksense
@@ -12,7 +12,7 @@ At the initialization `qliksense` cli create few files in the director `~/.qliks
└── keys
```
`qlik-default.yaml` is a default CR has been created with some default values like this
`qlik-default.yaml` is a default CR created with some default values like:
```yaml
apiVersion: qlik.com/v1
@@ -29,55 +29,68 @@ spec:
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.
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 later on.
New context and configuration can be created by the cli, get available commands using:
```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 config -h
```
---
`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
- 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`.
In this mode `qliksense` CLI downloads the specified version from [qliksense-k8s](https://github.com/qlik-oss/qliksense-k8s) and places it in `~/.qliksense/contexts/<context-name>/qlik-k8s` folder.
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.
The qliksense cli creates a CR for the QlikSense operator and all config operations are peformed to edit the CR.
`qliksense install` or `qliksense config apply` will generate patches in local file system (i.e `~/.qliksense/contexts/<context-name>/qlik-k8s`) and
- Install those manifests into the cluster
- Create a custom resoruce (CR) for the `qliksene operator`.
The operator makes the association to the installed resoruces so that when `qliksense uninstall` is performed the operator can delete all 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
Create a fork or clone of [qliksense-k8s](https://github.com/qlik-oss/qliksense-k8s) and push it to your git repo/server
- 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
To add your repo into CR, perform the following:
This is how repo info is provided into the CR
```console
```bash
qliksense config set git.repository="https://github.com/my-org/qliksense-k8s"
qliksense config set git.accessToken=blablalaala
qliksense config set git.accessToken="<mySecretToken>"
```
When you perform `qliksense install` or `qliksene config apply`, qliksense operator performs these tasks:
- Download corresponding version of manifests from the your git repo
- Generate kustomize patches
- Install kubernetes resources
- Push generated patches into a new branch in the provided git repo. _Gives you ability to merge patches into your master branch_
- Create a CronJob to monitor master branch. Any changes pushed to master branch will be applied into the cluster. _This is a light weight `git-ops` model_
## Enable GitOps
to enable gitops the following section should be in the CR
```yaml
....
spec:
git:
repository: https://github.com/ffoysal/qliksense-k8s
accessToken: git-token
userName: git-username
gitOps:
enabled: "yes"
schedule: "*/5 * * * *"
watchBranch: pr-branch-24868a33
image: qlik-docker-oss.bintray.io/qliksense-repo-watcher
....
```

View File

@@ -2,29 +2,52 @@
## 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)
- Kubernetes cluster (Docker Desktop with enabled Kubernetes)
- `kubectl` installed, configured and able to communicate with kubernetes cluster. _`qliksense` CLI uses `kubectl` under the hood to perform operations on cluster_
## Download
## Installing Sense installer
Download the executable for your platform from [releases page](https://github.com/qlik-oss/sense-installer/releases) and rename it to `qliksense`
??? tldr "Linux"
``` bash
curl -Lo qliksense https://github.com/qlik-oss/sense-installer/releases/download/v0.7.0/qliksense-linux-amd64
chmod +x qliksense
sudo mv qliksense /usr/local/bin
```
??? tldr "MacOS"
``` bash
curl -Lo qliksense https://github.com/qlik-oss/sense-installer/releases/download/v0.7.0/qliksense-darwin-amd64
chmod +x qliksense
sudo mv qliksense /usr/local/bin
```
??? tldr "Windows"
Download Windows executable and add it in your `PATH` as `qliksense.exe`
[https://github.com/qlik-oss/sense-installer/releases/download/v0.7.0/qliksense-windows-amd64.exe](https://github.com/qlik-oss/sense-installer/releases/download/v0.7.0/qliksense-windows-amd64.exe)
- 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
qliksense fetch v0.0.2
```
- To install CRDs for QSEoK and qliksense operator into the kubernetes cluster.
```shell
$qliksense crds install --all
qliksense crds install --all
```
- To install QSEoK into a namespace in the kubernetes cluster where `kubectl` is pointing to.
```shell
$qliksense install --acceptEULA="yes"
```
qliksense install --acceptEULA="yes"
```

View File

@@ -1,19 +1,22 @@
# 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:
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
- 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.
!!! info ""
This is a technology preview that uses Qlik modified [kustomize](https://github.com/qlik-oss/kustomize) for kubernetes manifests on [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)
!!! info ""
See QlikSense [edge releases on qliksense-k8s](https://github.com/qlik-oss/qliksense-k8s/releases) repository
## Future Direction
- More operations:
- Expand preflight checks
- backup/restore operations
- fully support airgap installation of QSEoK
- restore unwanted deletion of kubernetes resources
Operations:
- Expand preflight checks
- Backup/restore operations
- Fully support airgap installation of QSEoK
- Restore unwanted deletion of kubernetes resources

7
go.mod
View File

@@ -39,16 +39,17 @@ require (
github.com/mattn/go-colorable v0.1.4
github.com/mitchellh/go-homedir v1.1.0
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.22
github.com/robfig/cron/v3 v3.0.1
github.com/rogpeppe/go-internal v1.5.2 // indirect
github.com/spf13/cobra v0.0.6
github.com/spf13/viper v1.6.1
github.com/ttacon/chalk v0.0.0-20160626202418-22c06c80ed31
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073 // indirect
golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4 // indirect
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a // indirect
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 // indirect
golang.org/x/tools v0.0.0-20200309202150-20ab64c0d93f // indirect
golang.org/x/tools v0.0.0-20200312194400-c312e98713c2 // indirect
google.golang.org/genproto v0.0.0-20200128133413-58ce757ed39b // indirect
google.golang.org/grpc v1.27.0 // indirect
gopkg.in/yaml.v2 v2.2.8

16
go.sum
View File

@@ -843,14 +843,16 @@ 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/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
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.22 h1:tntQEeRqDYkBi2Ku5+xt7ABGMeFPck7+DOKrHUnpzwI=
github.com/qlik-oss/k-apis v0.0.22/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/go.mod h1:OCt7FTrRVHj4kmR2xLJJUIqu00BTr6GeF09hSmM17Kw=
github.com/quasilyte/go-consistent v0.0.0-20190521200055-c6f3937de18c/go.mod h1:5STLWrekHfjyYwxBRVRXNOSewLJ3PWfDJd1VyTS21fI=
github.com/rainycape/unidecode v0.0.0-20150907023854-cb7f23ec59be h1:ta7tUOvsPHVHGom5hKW5VXNc2xZIkfCKP8iaqOyYtUQ=
github.com/rainycape/unidecode v0.0.0-20150907023854-cb7f23ec59be/go.mod h1:MIDFMn7db1kT65GmV94GzpX9Qdi7N/pQlwb+AN8wh+Q=
github.com/remyoudompheng/bigfft v0.0.0-20170806203942-52369c62f446/go.mod h1:uYEyJGbgTkfkS4+E/PavXkNJcbFIpEtjt2B0KDQ5+9M=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
@@ -1040,10 +1042,8 @@ golang.org/x/crypto v0.0.0-20191112222119-e1110fd1c708/go.mod h1:LzIPMQfyMNhhGPh
golang.org/x/crypto v0.0.0-20191122220453-ac88ee75c92c/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d h1:9FCpayM9Egr1baVnV1SX0H87m+XB0B8S0hAMi99X/3U=
golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073 h1:xMPOj6Pz6UipU1wXLkrtqpHbR0AVFnyPEQq/wRWz9lM=
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073 h1:xMPOj6Pz6UipU1wXLkrtqpHbR0AVFnyPEQq/wRWz9lM=
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4 h1:QmwruyY+bKbDDL0BaglrbZABEali68eoMFhTZpCjYVA=
golang.org/x/crypto v0.0.0-20200311171314-f7b00557c8c4/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -1205,8 +1205,8 @@ golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapK
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200117161641-43d50277825c h1:2EA2K0k9bcvvEDlqD8xdlOhCOqq+O/p9Voqi4x9W1YU=
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200309202150-20ab64c0d93f h1:NbrfHxef+IfdI86qCgO/1Siq1BuMH2xG0NqgvCguRhQ=
golang.org/x/tools v0.0.0-20200309202150-20ab64c0d93f/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200312194400-c312e98713c2 h1:6TB4+MaZlkcSsJDu+BS5yxSEuZIYhjWz+jhbSLEZylI=
golang.org/x/tools v0.0.0-20200312194400-c312e98713c2/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

View File

@@ -10,6 +10,10 @@ markdown_extensions:
- toc:
permalink: true
- admonition
- codehilite
- pymdownx.inlinehilite
- pymdownx.superfences
- pymdownx.details
nav:
- Overview: index.md
- getting_started.md

BIN
pkg/.DS_Store vendored Normal file

Binary file not shown.

View File

@@ -22,6 +22,7 @@ const (
pullSecretFileName = "image-registry-pull-secret.yaml"
qliksenseContextsDirName = "contexts"
qliksenseSecretsDirName = "secrets"
qliksenseEjsonDirName = "ejson"
)
// NewQConfig create QliksenseConfig object from file ~/.qliksense/config.yaml
@@ -239,6 +240,18 @@ func (qc *QliksenseConfig) getCurrentContextEncryptionKeyPairLocation() (string,
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) {
secretKeyPairLocation, err := qc.getCurrentContextEncryptionKeyPairLocation()
if err != nil {

BIN
pkg/qliksense/.DS_Store vendored Normal file

Binary file not shown.

View File

@@ -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 {
if qcr.Spec.RotateKeys != "None" {
if err := os.Unsetenv("EJSON_KEY"); 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)
if err := q.configEjson(); err != nil {
return err
}
}
@@ -99,7 +106,6 @@ func (q *Qliksense) ConfigViewCR() error {
if err != nil {
return err
}
fmt.Println(r)
oth, err := q.getCurrentCrDependentResourceAsString()
if err != nil {
return err

View File

@@ -3,6 +3,7 @@ package qliksense
import (
"crypto/rsa"
"fmt"
"github.com/robfig/cron/v3"
"io/ioutil"
"log"
"os"
@@ -13,6 +14,7 @@ import (
"github.com/qlik-oss/k-apis/pkg/config"
b64 "encoding/base64"
ansi "github.com/mattn/go-colorable"
"github.com/qlik-oss/sense-installer/pkg/api"
"github.com/ttacon/chalk"
@@ -149,7 +151,6 @@ func (q *Qliksense) SetConfigs(args []string) error {
func retrieveCurrentContextInfo(q *Qliksense) (*api.QliksenseCR, string, error) {
var qliksenseConfig api.QliksenseConfig
qliksenseConfigFile := filepath.Join(q.QliksenseHome, QliksenseConfigFile)
if err := api.ReadFromFile(&qliksenseConfig, qliksenseConfigFile); err != nil {
log.Println(err)
return nil, "", err
@@ -225,8 +226,42 @@ func (q *Qliksense) SetOtherConfigs(args []string) error {
}
qliksenseCR.Spec.RotateKeys = rotateKeys
api.LogDebugMessage("Current rotateKeys after modification: %s ", qliksenseCR.Spec.RotateKeys)
case "gitops.enabled":
if qliksenseCR.Spec.GitOps == nil {
qliksenseCR.Spec.GitOps = &config.GitOps{}
}
if strings.EqualFold(argsString[1], "yes") || strings.EqualFold(argsString[1], "no") {
qliksenseCR.Spec.GitOps.Enabled = argsString[1]
api.LogDebugMessage("Current gitOps enabled status : %s ", qliksenseCR.Spec.GitOps.Enabled)
} else {
err := fmt.Errorf("Please use yes or no")
log.Println(err)
return err
}
case "gitops.schedule":
if qliksenseCR.Spec.GitOps == nil {
qliksenseCR.Spec.GitOps = &config.GitOps{}
}
if _, err := cron.ParseStandard(argsString[1]); err != nil {
err := fmt.Errorf("Please enter string with standard cron scheduling syntax ")
return err
}
qliksenseCR.Spec.GitOps.Schedule = argsString[1]
api.LogDebugMessage("Current gitOps schedule is : %s ", qliksenseCR.Spec.GitOps.Schedule)
case "gitops.watchbranch":
if qliksenseCR.Spec.GitOps == nil {
qliksenseCR.Spec.GitOps = &config.GitOps{}
}
qliksenseCR.Spec.GitOps.WatchBranch = argsString[1]
api.LogDebugMessage("Current gitOps watchbranch is : %s ", qliksenseCR.Spec.GitOps.WatchBranch)
case "gitops.image":
if qliksenseCR.Spec.GitOps == nil {
qliksenseCR.Spec.GitOps = &config.GitOps{}
}
qliksenseCR.Spec.GitOps.Image = argsString[1]
api.LogDebugMessage("Current gitOps image is : %s ", qliksenseCR.Spec.GitOps.Image)
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, git.repository or gitops arguments to configure the current context")
log.Println(err)
return err
}

View File

@@ -273,11 +273,7 @@ func TestSetUpQliksenseContext(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
q, err := New(tt.args.qlikSenseHome)
if err != nil {
t.Errorf("unable to create a qliksense instance")
return
}
q := New(tt.args.qlikSenseHome)
if err := q.SetUpQliksenseContext(tt.args.contextName, tt.args.isDefaultContext); (err != nil) != tt.wantErr {
t.Errorf("SetUpQliksenseContext() error = %v, wantErr %v", err, tt.wantErr)
}
@@ -306,11 +302,7 @@ func TestSetUpQliksenseDefaultContext(t *testing.T) {
defer tearDown()
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
q, err := New(tt.args.qlikSenseHome)
if err != nil {
t.Errorf("unable to create a qliksense instance")
return
}
q := New(tt.args.qlikSenseHome)
if err := q.SetUpQliksenseDefaultContext(); (err != nil) != tt.wantErr {
t.Errorf("SetUpQliksenseDefaultContext() error = %v, wantErr %v", err, tt.wantErr)
}
@@ -334,7 +326,7 @@ func TestSetOtherConfigs(t *testing.T) {
q: &Qliksense{
QliksenseHome: testDir,
},
args: []string{"profile=minikube", "rotateKeys=yes", "storageClassName=efs"},
args: []string{"profile=minikube", "rotateKeys=yes", "storageClassName=efs", "gitops.enabled=yes", "gitops.schedule=30 * * * *"},
},
wantErr: false,
},
@@ -344,7 +336,7 @@ func TestSetOtherConfigs(t *testing.T) {
q: &Qliksense{
QliksenseHome: testDir,
},
args: []string{"someconfig=somevalue"},
args: []string{"someconfig=somevalue, gitops.schedule=bar", "gitops.enabled=bar"},
},
wantErr: true,
},
@@ -836,7 +828,7 @@ spec:
log.Fatal(err)
}
contextYaml1 :=
`
`
apiVersion: qlik.com/v1
kind: Qliksense
metadata:
@@ -846,8 +838,8 @@ spec:
rotateKeys: "yes"
releaseName: qlik1`
contextYaml2 :=
`
contextYaml2 :=
`
apiVersion: qlik.com/v1
kind: Qliksense
metadata:
@@ -932,11 +924,7 @@ func TestDeleteContexts(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
q, err := New(tt.args.qlikSenseHome)
if err != nil {
t.Errorf("unable to create a qliksense instance")
return
}
q := New(tt.args.qlikSenseHome)
var arg []string
arg = append(arg, tt.args.contextName)
if err := q.DeleteContextConfig(arg); (err != nil) != tt.wantErr {

View File

@@ -0,0 +1,88 @@
package qliksense
import (
"errors"
"fmt"
"github.com/qlik-oss/k-apis/pkg/git"
qapi "github.com/qlik-oss/sense-installer/pkg/api"
)
type LsRemoteCmdOptions struct {
IncludeBranches bool
Limit int
}
func (q *Qliksense) GetInstallableVersions(opts *LsRemoteCmdOptions) error {
qConfig := qapi.NewQConfig(q.QliksenseHome)
qcr, err := qConfig.GetCurrentCR()
if err != nil {
return err
}
var repoPath string
if qcr.Spec.GetManifestsRoot() != "" {
repoPath = qcr.Spec.GetManifestsRoot()
} else {
repoPath, err = downloadFromGitRepoToTmpDir(defaultConfigRepoGitUrl, "master")
if err != nil {
return err
}
}
r, err := git.OpenRepository(repoPath)
if err != nil {
return err
}
remoteRefsList, err := git.GetRemoteRefs(r, nil,
&git.RemoteRefConstraints{
Include: true,
Sort: true,
SortOrder: git.RefSortOrderDescending,
},
&git.RemoteRefConstraints{
Include: opts.IncludeBranches,
Sort: true,
SortOrder: git.RefSortOrderAscending,
})
if err != nil {
return err
}
if len(remoteRefsList) < 1 {
return errors.New("cannot find git remote information in the config repository")
}
var originRemoteRefs *git.RemoteRefs
for _, remoteRefs := range remoteRefsList {
if remoteRefs.Name == "origin" {
originRemoteRefs = remoteRefs
break
}
}
if originRemoteRefs == nil {
return errors.New(`cannot find git remote called "origin" in the config repository`)
}
tags := originRemoteRefs.Tags
if len(tags) > opts.Limit {
tags = tags[:opts.Limit]
}
fmt.Print("Versions:\n")
for _, tag := range tags {
fmt.Printf(" %s\n", tag)
}
if opts.IncludeBranches {
branches := originRemoteRefs.Branches
if len(branches) > opts.Limit {
branches = branches[:opts.Limit]
}
fmt.Print("Branches:\n")
for _, branch := range branches {
fmt.Printf(" %s\n", branch)
}
}
return nil
}

View File

@@ -6,6 +6,7 @@ import (
"github.com/qlik-oss/sense-installer/pkg/api"
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp" // don't delete this line ref: https://github.com/kubernetes/client-go/issues/242
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/konfig"
"sigs.k8s.io/kustomize/api/krusty"

View File

@@ -2,29 +2,21 @@
package qliksense
import (
"os"
"path"
"github.com/gobuffalo/packr/v2"
)
// Qliksense is the logic behind the qliksense client
type Qliksense struct {
QliksenseHome string
QliksenseEjsonKeyDir string
CrdBox *packr.Box ``
QliksenseHome string
CrdBox *packr.Box ``
}
// New qliksense client, initialized with useful defaults.
func New(qliksenseHome string) (*Qliksense, error) {
func New(qliksenseHome string) *Qliksense {
qliksenseClient := &Qliksense{
QliksenseHome: qliksenseHome,
CrdBox: packr.New("crds", "./crds"),
}
qliksenseClient.QliksenseEjsonKeyDir = path.Join(qliksenseHome, "ejson", "keys")
if err := os.MkdirAll(qliksenseClient.QliksenseEjsonKeyDir, os.ModePerm); err != nil {
return nil, err
}
return qliksenseClient, nil
return qliksenseClient
}

View File

@@ -28,7 +28,9 @@ func (q *Qliksense) UpgradeQK8s(keepPatchFiles bool) error {
return err
}
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")
return err
}