From a016afcf029ffbdf2877eb8a315c9ae6c44cece9 Mon Sep 17 00:00:00 2001 From: sbailey <1661003+spbsoluble@users.noreply.github.com> Date: Wed, 17 Jan 2024 13:23:29 -0800 Subject: [PATCH 01/47] fix(ci): Add KFC 11.1.2 test labs Signed-off-by: sbailey <1661003+spbsoluble@users.noreply.github.com> --- .github/workflows/tests.yml | 281 ++++-------------------------------- README.md | 2 +- 2 files changed, 29 insertions(+), 254 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 9a1b3391..c24d84f4 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -35,14 +35,14 @@ jobs: run: echo "Running tests for KF 10.x.x" ### Store Type Tests - Test_StoreTypes_KFC_10_4_5: + Test_StoreTypes_KFC_10_5_0: runs-on: ubuntu-latest needs: - build - kf_10_x_x env: - SECRET_NAME: "command-config-1045-clean" - KEYFACTOR_HOSTNAME: "int1045-test-clean.kfdelivery.com" + SECRET_NAME: "command-config-1050-clean" + KEYFACTOR_HOSTNAME: "int1050-test-clean.kfdelivery.com" KEYFACTOR_DOMAIN: "command" KEYFACTOR_USERNAME: ${{ secrets.LAB_USERNAME }} KEYFACTOR_PASSWORD: ${{ secrets.LAB_PASSWORD }} @@ -53,73 +53,17 @@ jobs: run: | export KFUTIL_DEBUG=1 go test -v ./cmd -run "^Test_StoreTypes*" - Test_StoreTypes_KFC_10_2_1: - runs-on: ubuntu-latest - needs: - - build - - kf_10_x_x - env: - SECRET_NAME: "command-config-1021-clean" - KEYFACTOR_HOSTNAME: "int1021-test-clean.kfdelivery.com" - KEYFACTOR_DOMAIN: "command" - KEYFACTOR_USERNAME: ${{ secrets.LAB_USERNAME }} - KEYFACTOR_PASSWORD: ${{ secrets.LAB_PASSWORD }} - steps: - - name: Checkout code - uses: actions/checkout@v4 - - name: Run tests - run: | - unset KFUTIL_DEBUG - go test -v ./cmd -run "^Test_StoreTypes*" - - Test_StoreTypes_KFC_10_1_1: - runs-on: ubuntu-latest - needs: - - build - - kf_10_x_x - env: - SECRET_NAME: "command-config-1011-clean" - KEYFACTOR_HOSTNAME: "int1011-test-clean.kfdelivery.com" - KEYFACTOR_DOMAIN: "command" - KEYFACTOR_USERNAME: ${{ secrets.LAB_USERNAME }} - KEYFACTOR_PASSWORD: ${{ secrets.LAB_PASSWORD }} - steps: - - name: Checkout code - uses: actions/checkout@v4 - - name: Run tests - run: | - unset KFUTIL_DEBUG - go test -v ./cmd -run "^Test_StoreTypes*" - - # Test_StoreTypes_KFC_10_1_1: - # runs-on: ubuntu-latest - # needs: - # - build - # - kf_10_x_x - # env: - # SECRET_NAME: "command-config-1011-clean" - # KEYFACTOR_HOSTNAME: "int1011-test-clean.kfdelivery.com" - # KEYFACTOR_DOMAIN: "command" - # KEYFACTOR_USERNAME: ${{ secrets.LAB_USERNAME }} - # KEYFACTOR_PASSWORD: ${{ secrets.LAB_PASSWORD }} - # steps: - # - name: Checkout code - # uses: actions/checkout@v4 - # - name: Run tests - # run: | - # unset KFUTIL_DEBUG - # go test -v ./cmd -run "^Test_StoreTypes*" ### Store Tests - Test_Stores_KFC_10_4_5: + Test_Stores_KFC_10_5_0: runs-on: ubuntu-latest needs: - build - kf_10_x_x - - Test_StoreTypes_KFC_10_4_5 + - Test_StoreTypes_KFC_10_5_0 env: - SECRET_NAME: "command-config-1045" - KEYFACTOR_HOSTNAME: "integrations1045-lab.kfdelivery.com" + SECRET_NAME: "command-config-1050" + KEYFACTOR_HOSTNAME: "integrations1050-lab.kfdelivery.com" KEYFACTOR_DOMAIN: "command" KEYFACTOR_USERNAME: ${{ secrets.LAB_USERNAME }} KEYFACTOR_PASSWORD: ${{ secrets.LAB_PASSWORD }} @@ -128,76 +72,17 @@ jobs: uses: actions/checkout@v4 - name: Run tests run: go test -v ./cmd -run "^Test_Stores_*" - Test_Stores_KFC_10_2_1: - runs-on: ubuntu-latest - needs: - - build - - kf_10_x_x - - Test_StoreTypes_KFC_10_2_1 - env: - SECRET_NAME: "command-config-1021" - KEYFACTOR_HOSTNAME: "integrations1021-lab.kfdelivery.com" - KEYFACTOR_DOMAIN: "command" - KEYFACTOR_USERNAME: ${{ secrets.LAB_USERNAME }} - KEYFACTOR_PASSWORD: ${{ secrets.LAB_PASSWORD }} - steps: - - name: Checkout code - uses: actions/checkout@v4 - - name: Run tests - run: | - unset KFUTIL_DEBUG - go test -v ./cmd -run "^Test_Stores_*" - - Test_Stores_KFC_10_1_1: - runs-on: ubuntu-latest - needs: - - build - - kf_10_x_x - - Test_StoreTypes_KFC_10_1_1 - env: - SECRET_NAME: "command-config-1011" - KEYFACTOR_HOSTNAME: "integrations1011-lab.kfdelivery.com" - KEYFACTOR_DOMAIN: "command" - KEYFACTOR_USERNAME: ${{ secrets.LAB_USERNAME }} - KEYFACTOR_PASSWORD: ${{ secrets.LAB_PASSWORD }} - steps: - - name: Checkout code - uses: actions/checkout@v4 - - name: Run tests - run: | - unset KFUTIL_DEBUG - go test -v ./cmd -run "^Test_Stores_*" - - # Test_Stores_KFC_10_1_1: - # runs-on: ubuntu-latest - # needs: - # - build - # - kf_10_x_x - # - Test_StoreTypes_KFC_10_1_1 - # env: - # SECRET_NAME: "command-config-1011" - # KEYFACTOR_HOSTNAME: "integrations1011-lab.kfdelivery.com" - # KEYFACTOR_DOMAIN: "command" - # KEYFACTOR_USERNAME: ${{ secrets.LAB_USERNAME }} - # KEYFACTOR_PASSWORD: ${{ secrets.LAB_PASSWORD }} - # steps: - # - name: Checkout code - # uses: actions/checkout@v4 - # - name: Run tests - # run: | - # unset KFUTIL_DEBUG - # go test -v ./cmd -run "^Test_Stores_*" ### PAM Tests - Test_PAM_KFC_10_4_5: + Test_PAM_KFC_10_5_0: runs-on: ubuntu-latest needs: - build - kf_10_x_x - - Test_StoreTypes_KFC_10_4_5 + - Test_StoreTypes_KFC_10_5_0 env: - SECRET_NAME: "command-config-1045" - KEYFACTOR_HOSTNAME: "integrations1045-lab.kfdelivery.com" + SECRET_NAME: "command-config-1050" + KEYFACTOR_HOSTNAME: "integrations1050-lab.kfdelivery.com" KEYFACTOR_DOMAIN: "command" KEYFACTOR_USERNAME: ${{ secrets.LAB_USERNAME }} KEYFACTOR_PASSWORD: ${{ secrets.LAB_PASSWORD }} @@ -209,71 +94,14 @@ jobs: unset KFUTIL_DEBUG go test -v ./cmd -run "^Test_PAM*" - Test_PAM_KFC_10_2_1: - runs-on: ubuntu-latest - needs: - - build - - kf_10_x_x - - Test_StoreTypes_KFC_10_2_1 - env: - SECRET_NAME: "command-config-1021" - KEYFACTOR_HOSTNAME: "integrations1021-lab.kfdelivery.com" - KEYFACTOR_DOMAIN: "command" - KEYFACTOR_USERNAME: ${{ secrets.LAB_USERNAME }} - KEYFACTOR_PASSWORD: ${{ secrets.LAB_PASSWORD }} - steps: - - name: Checkout code - uses: actions/checkout@v4 - - name: Run tests - run: | - unset KFUTIL_DEBUG - go test -v ./cmd -run "^Test_PAM*" - Test_PAM_KFC_10_1_1: - runs-on: ubuntu-latest - needs: - - build - - kf_10_x_x - - Test_StoreTypes_KFC_10_1_1 - env: - SECRET_NAME: "command-config-1011" - KEYFACTOR_HOSTNAME: "integrations1011-lab.kfdelivery.com" - KEYFACTOR_DOMAIN: "command" - KEYFACTOR_USERNAME: ${{ secrets.LAB_USERNAME }} - KEYFACTOR_PASSWORD: ${{ secrets.LAB_PASSWORD }} - steps: - - name: Checkout code - uses: actions/checkout@v4 - - name: Run tests - run: | - unset KFUTIL_DEBUG - go test -v ./cmd -run "^Test_PAM*" - # Test_PAM_KFC_10_1_1: - # runs-on: ubuntu-latest - # needs: - # - build - # - kf_10_x_x - # - Test_StoreTypes_KFC_10_1_1 - # env: - # SECRET_NAME: "command-config-1011" - # KEYFACTOR_HOSTNAME: "integrations1011-lab.kfdelivery.com" - # KEYFACTOR_DOMAIN: "command" - # KEYFACTOR_USERNAME: ${{ secrets.LAB_USERNAME }} - # KEYFACTOR_PASSWORD: ${{ secrets.LAB_PASSWORD }} - # steps: - # - name: Checkout code - # uses: actions/checkout@v4 - # - name: Run tests - # run: | - # unset KFUTIL_DEBUG - # go test -v ./cmd -run "^Test_PAM*" ### PAM Tests AKV Auth Provider - Test_AKV_PAM_KFC_10_4_5: + Test_AKV_PAM_KFC_10_5_0: runs-on: self-hosted needs: - - Test_PAM_KFC_10_4_5 + - Test_PAM_KFC_10_5_0 env: - SECRET_NAME: "command-config-1045-az" + SECRET_NAME: "command-config-1050-az" steps: - name: Checkout code uses: actions/checkout@v4 @@ -294,59 +122,6 @@ jobs: run: | go test -v ./cmd -run "^Test_PAM*" - Test_AKV_PAM_KFC_10_2_1: - runs-on: self-hosted - needs: - - Test_PAM_KFC_10_2_1 - env: - SECRET_NAME: "command-config-1021-az" - steps: - - name: Checkout code - uses: actions/checkout@v4 - - name: Set up Go - uses: actions/setup-go@v5 - with: - go-version: "1.20" - - name: Install dependencies - run: go mod download && go mod tidy - - name: Get secret from Azure Key Vault - run: | - . ./examples/auth/akv/akv_auth.sh - cat $HOME/.keyfactor/command_config.json - - name: Install kfutil - run: | - make install - - name: Run tests - run: | - go test -v ./cmd -run "^Test_PAM*" - - Test_AKV_PAM_KFC_10_1_1: - runs-on: self-hosted - needs: - - Test_PAM_KFC_10_1_1 - env: - SECRET_NAME: "command-config-1011-az" - steps: - - name: Checkout code - uses: actions/checkout@v4 - - name: Set up Go - uses: actions/setup-go@v5 - with: - go-version: "1.20" - - name: Install dependencies - run: go mod download && go mod tidy - - name: Get secret from Azure Key Vault - run: | - . ./examples/auth/akv/akv_auth.sh - cat $HOME/.keyfactor/command_config.json - - name: Install kfutil - run: | - make install - - name: Run tests - run: | - go test -v ./cmd -run "^Test_PAM*" - - ## KFC 11.x.x kf_11_x_x: @@ -360,14 +135,14 @@ jobs: run: echo "Running tests for KF 11.x.x" ### Store Type Tests - Test_StoreTypes_KFC_11_0_0: + Test_StoreTypes_KFC_11_1_2: runs-on: ubuntu-latest needs: - build - kf_11_x_x env: - SECRET_NAME: "command-config-1100-clean" - KEYFACTOR_HOSTNAME: "int11-test-clean.kfdelivery.com" + SECRET_NAME: "command-config-1112-clean" + KEYFACTOR_HOSTNAME: "int1112-test-clean.kfdelivery.com" KEYFACTOR_DOMAIN: "command" KEYFACTOR_USERNAME: ${{ secrets.LAB_USERNAME }} KEYFACTOR_PASSWORD: ${{ secrets.LAB_PASSWORD }} @@ -380,15 +155,15 @@ jobs: go test -v ./cmd -run "^Test_StoreTypes*" ### Store Tests - Test_Stores_KFC_11_0_0: + Test_Stores_KFC_11_1_2: runs-on: ubuntu-latest needs: - build - kf_11_x_x - - Test_StoreTypes_KFC_11_0_0 + - Test_StoreTypes_KFC_11_1_2 env: - SECRET_NAME: "command-config-1100" - KEYFACTOR_HOSTNAME: "integrations1100-lab.kfdelivery.com" + SECRET_NAME: "command-config-1112" + KEYFACTOR_HOSTNAME: "integrations1112-lab.kfdelivery.com" KEYFACTOR_DOMAIN: "command" KEYFACTOR_USERNAME: ${{ secrets.LAB_USERNAME }} KEYFACTOR_PASSWORD: ${{ secrets.LAB_PASSWORD }} @@ -399,15 +174,15 @@ jobs: run: go test -v ./cmd -run "^Test_Stores_*" ### PAM Tests - Test_PAM_KFC_11_0_0: + Test_PAM_KFC_11_1_2: runs-on: ubuntu-latest needs: - build - kf_11_x_x - - Test_StoreTypes_KFC_11_0_0 + - Test_StoreTypes_KFC_11_1_2 env: - SECRET_NAME: "command-config-1100" - KEYFACTOR_HOSTNAME: "integrations1100-lab.kfdelivery.com" + SECRET_NAME: "command-config-1112" + KEYFACTOR_HOSTNAME: "integrations1112-lab.kfdelivery.com" KEYFACTOR_DOMAIN: "command" KEYFACTOR_USERNAME: ${{ secrets.LAB_USERNAME }} KEYFACTOR_PASSWORD: ${{ secrets.LAB_PASSWORD }} @@ -421,12 +196,12 @@ jobs: ### PAM Tests AKV Auth Provider - Test_AKV_PAM_KFC_11_0_0: + Test_AKV_PAM_KFC_11_1_2: runs-on: self-hosted needs: - - Test_PAM_KFC_11_0_0 + - Test_PAM_KFC_11_1_2 env: - SECRET_NAME: "command-config-1100-az" + SECRET_NAME: "command-config-1112-az" steps: - name: Checkout code uses: actions/checkout@v4 diff --git a/README.md b/README.md index d7fc1572..0adeb9fa 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ ## Support for Keyfactor Command Utility (kfutil) -Keyfactor Command Utility (kfutil) is open source and there is **no SLA** for this tool/library/client. Keyfactor will address issues as resources become available. Keyfactor customers may request escalation by opening up a support ticket through their Keyfactor representative. +Keyfactor Command Utility (kfutil) is open source and supported on best effort level for this tool/library/client. This means customers can report Bugs, Feature Requests, Documentation amendment or questions as well as requests for customer information required for setup that needs Keyfactor access to obtain. Such requests do not follow normal SLA commitments for response or resolution. If you have a support issue, please open a support ticket via the Keyfactor Support Portal at https://support.keyfactor.com/ ###### To report a problem or suggest a new feature, use the **[Issues](../../issues)** tab. If you want to contribute actual bug fixes or proposed enhancements, use the **[Pull requests](../../pulls)** tab. From 8042d64adf02e672bd2b9f8e60392273d2733494 Mon Sep 17 00:00:00 2001 From: sbailey <1661003+spbsoluble@users.noreply.github.com> Date: Wed, 7 Feb 2024 12:38:41 -0800 Subject: [PATCH 02/47] fix(store-types): Store type create omits empty fields. Signed-off-by: sbailey <1661003+spbsoluble@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index de9760d2..4d9bd2fd 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0 github.com/Jeffail/gabs v1.4.0 github.com/Keyfactor/keyfactor-go-client-sdk v1.0.2 - github.com/Keyfactor/keyfactor-go-client/v2 v2.1.4 + github.com/Keyfactor/keyfactor-go-client/v2 v2.2.5 github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 github.com/creack/pty v1.1.21 github.com/google/go-cmp v0.6.0 diff --git a/go.sum b/go.sum index cd50a0ab..dc019875 100644 --- a/go.sum +++ b/go.sum @@ -14,8 +14,8 @@ github.com/Keyfactor/keyfactor-go-client v1.4.3 h1:CmGvWcuIbDRFM0PfYOQH6UdtAgplv github.com/Keyfactor/keyfactor-go-client v1.4.3/go.mod h1:3ZymLNCaSazglcuYeNfm9nrzn22wcwLjIWURrnUygBo= github.com/Keyfactor/keyfactor-go-client-sdk v1.0.2 h1:caLlzFCz2L4Dth/9wh+VlypFATmOMmCSQkCPKOKMxw8= github.com/Keyfactor/keyfactor-go-client-sdk v1.0.2/go.mod h1:Z5pSk8YFGXHbKeQ1wTzVN8A4P/fZmtAwqu3NgBHbDOs= -github.com/Keyfactor/keyfactor-go-client/v2 v2.1.4 h1:PClA1rsT6YA3jsIcTeBROlaEBOqeYeFcXT3mx7FoWcQ= -github.com/Keyfactor/keyfactor-go-client/v2 v2.1.4/go.mod h1:3mfxdcwntB532QIATokBEkBCH0eXN2G/cdMZtu9NwNg= +github.com/Keyfactor/keyfactor-go-client/v2 v2.2.5 h1:2P6e4hOMwjH/+r3bjlm+PFVyFUabXYiAMspwb6HJ81k= +github.com/Keyfactor/keyfactor-go-client/v2 v2.2.5/go.mod h1:3mfxdcwntB532QIATokBEkBCH0eXN2G/cdMZtu9NwNg= github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s= github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= From c371b882c9b67c5a4df2df521aede2b42213c8e7 Mon Sep 17 00:00:00 2001 From: Keyfactor Date: Wed, 7 Feb 2024 20:39:10 +0000 Subject: [PATCH 03/47] fix(pam-types): `types-list` does not crash on nil httpResponse. Signed-off-by: sbailey <1661003+spbsoluble@users.noreply.github.com> --- README.md | 8 ++++++++ cmd/pam.go | 8 +++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 0adeb9fa..84c9bc37 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,13 @@ + # Keyfactor Command Utility (kfutil) `kfutil` is a go-lang CLI wrapper for Keyfactor Command API. It also includes other utility/helper functions around automating common Keyfactor Command operations. #### Integration status: Production - Ready for use in production environments. +## About the Keyfactor API Client +This API client allows for programmatic management of Keyfactor resources. ## Support for Keyfactor Command Utility (kfutil) @@ -12,6 +15,11 @@ Keyfactor Command Utility (kfutil) is open source and supported on best effort l ###### To report a problem or suggest a new feature, use the **[Issues](../../issues)** tab. If you want to contribute actual bug fixes or proposed enhancements, use the **[Pull requests](../../pulls)** tab. +--- + + +--- + ## Quickstart diff --git a/cmd/pam.go b/cmd/pam.go index cd894670..cddc1f28 100644 --- a/cmd/pam.go +++ b/cmd/pam.go @@ -69,8 +69,14 @@ var pamTypesListCmd = &cobra.Command{ log.Trace().Interface("httpResponse", httpResponse). Msg("PAMProviderGetPamProviderTypes") if err != nil { + var status string + if httpResponse != nil { + status = httpResponse.Status + } else { + status = "No HTTP response received from Keyfactor Command." + } log.Error().Err(err). - Str("httpResponseCode", httpResponse.Status). + Str("httpResponseCode", status). Msg("error listing PAM provider types") return err } From 404c5d3455e607894ef9e1f43bd7e671cb48890e Mon Sep 17 00:00:00 2001 From: sbailey <1661003+spbsoluble@users.noreply.github.com> Date: Thu, 8 Feb 2024 09:22:40 -0800 Subject: [PATCH 04/47] chore: Update license year, and bump AKV runner go version Signed-off-by: sbailey <1661003+spbsoluble@users.noreply.github.com> --- .github/workflows/tests.yml | 4 ++-- cmd/auth_providers.go | 2 +- cmd/certificates.go | 2 +- cmd/constants.go | 3 ++- cmd/containers.go | 2 +- cmd/export.go | 2 +- cmd/helm.go | 2 +- cmd/helm_test.go | 2 +- cmd/helm_uo.go | 2 +- cmd/helm_uo_test.go | 2 +- cmd/helpers.go | 2 +- cmd/import.go | 2 +- cmd/inventory.go | 2 +- cmd/login.go | 2 +- cmd/login_test.go | 2 +- cmd/logout.go | 2 +- cmd/models.go | 2 +- cmd/orchs.go | 2 +- cmd/orchs_ext.go | 2 +- cmd/orchs_ext_test.go | 2 +- cmd/pam.go | 32 ++++++++++++++++++-------------- cmd/pam_test.go | 2 +- cmd/root.go | 2 +- cmd/root_test.go | 2 +- cmd/rot.go | 2 +- cmd/rot_test.go | 2 +- cmd/status.go | 2 +- cmd/storeTypes.go | 2 +- cmd/storeTypes_get.go | 2 +- cmd/storeTypes_get_test.go | 2 +- cmd/storeTypes_test.go | 8 +++++++- cmd/stores.go | 2 +- cmd/storesBulkOperations.go | 2 +- cmd/stores_test.go | 2 +- cmd/test.go | 2 +- cmd/version.go | 2 +- go.mod | 2 +- go.sum | 4 ++-- 38 files changed, 64 insertions(+), 53 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index c24d84f4..d99ff580 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -108,7 +108,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: "1.20" + go-version: "1.21" - name: Install dependencies run: go mod download && go mod tidy - name: Get secret from Azure Key Vault @@ -208,7 +208,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: "1.20" + go-version: "1.21" - name: Install dependencies run: go mod download && go mod tidy - name: Get secret from Azure Key Vault diff --git a/cmd/auth_providers.go b/cmd/auth_providers.go index ed030330..c2af068e 100644 --- a/cmd/auth_providers.go +++ b/cmd/auth_providers.go @@ -1,4 +1,4 @@ -// Copyright 2023 Keyfactor +// Copyright 2024 Keyfactor // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/cmd/certificates.go b/cmd/certificates.go index aa0f0989..0384474c 100644 --- a/cmd/certificates.go +++ b/cmd/certificates.go @@ -1,4 +1,4 @@ -// Package cmd Copyright 2023 Keyfactor +// Copyright 2024 Keyfactor // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/cmd/constants.go b/cmd/constants.go index bc3a2b1c..1fed0c6c 100644 --- a/cmd/constants.go +++ b/cmd/constants.go @@ -1,4 +1,4 @@ -// Package cmd Copyright 2023 Keyfactor +// Copyright 2024 Keyfactor // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -25,6 +25,7 @@ const ( XKeyfactorRequestedWith = "APIClient" XKeyfactorApiVersion = "1" FlagGitRef = "git-ref" + FlagFromFile = "from-file" ) var ProviderTypeChoices = []string{ diff --git a/cmd/containers.go b/cmd/containers.go index 85dfca70..2b29dfe6 100644 --- a/cmd/containers.go +++ b/cmd/containers.go @@ -1,4 +1,4 @@ -// Package cmd Copyright 2023 Keyfactor +// Copyright 2024 Keyfactor // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/cmd/export.go b/cmd/export.go index 442d1b62..33d836e2 100644 --- a/cmd/export.go +++ b/cmd/export.go @@ -1,4 +1,4 @@ -// Package cmd Copyright 2023 Keyfactor +// Copyright 2024 Keyfactor // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/cmd/helm.go b/cmd/helm.go index 7c1f881f..436f9fb4 100644 --- a/cmd/helm.go +++ b/cmd/helm.go @@ -1,5 +1,5 @@ /* -Copyright 2023 The Keyfactor Command Authors. +Copyright 2024 The Keyfactor Command Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/cmd/helm_test.go b/cmd/helm_test.go index 5d6c1586..4880b75f 100644 --- a/cmd/helm_test.go +++ b/cmd/helm_test.go @@ -1,5 +1,5 @@ /* -Copyright 2023 The Keyfactor Command Authors. +Copyright 2024 The Keyfactor Command Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/cmd/helm_uo.go b/cmd/helm_uo.go index 22ebbd9b..44107e55 100644 --- a/cmd/helm_uo.go +++ b/cmd/helm_uo.go @@ -1,5 +1,5 @@ /* -Copyright 2023 The Keyfactor Command Authors. +Copyright 2024 The Keyfactor Command Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/cmd/helm_uo_test.go b/cmd/helm_uo_test.go index b992678d..6454ca9b 100644 --- a/cmd/helm_uo_test.go +++ b/cmd/helm_uo_test.go @@ -1,5 +1,5 @@ /* -Copyright 2023 The Keyfactor Command Authors. +Copyright 2024 The Keyfactor Command Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/cmd/helpers.go b/cmd/helpers.go index a60e73d5..58d5eb55 100644 --- a/cmd/helpers.go +++ b/cmd/helpers.go @@ -1,4 +1,4 @@ -// Package cmd Copyright 2023 Keyfactor +// Copyright 2024 Keyfactor // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/cmd/import.go b/cmd/import.go index cd36d8b0..2df1df0d 100644 --- a/cmd/import.go +++ b/cmd/import.go @@ -1,4 +1,4 @@ -// Package cmd Copyright 2023 Keyfactor +// Copyright 2024 Keyfactor // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/cmd/inventory.go b/cmd/inventory.go index 0e19300a..0b004ecf 100644 --- a/cmd/inventory.go +++ b/cmd/inventory.go @@ -1,4 +1,4 @@ -// Package cmd Copyright 2023 Keyfactor +// Copyright 2024 Keyfactor // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/cmd/login.go b/cmd/login.go index 7e44de78..1db8e956 100644 --- a/cmd/login.go +++ b/cmd/login.go @@ -1,4 +1,4 @@ -// Package cmd Copyright 2023 Keyfactor +// Copyright 2024 Keyfactor // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/cmd/login_test.go b/cmd/login_test.go index 28962b57..da30729e 100644 --- a/cmd/login_test.go +++ b/cmd/login_test.go @@ -1,4 +1,4 @@ -// Package cmd Copyright 2023 Keyfactor +// Copyright 2024 Keyfactor // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/cmd/logout.go b/cmd/logout.go index 4aafe1de..21c9ec37 100644 --- a/cmd/logout.go +++ b/cmd/logout.go @@ -1,4 +1,4 @@ -// Package cmd Copyright 2023 Keyfactor +// Copyright 2024 Keyfactor // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/cmd/models.go b/cmd/models.go index 60de4973..0624d707 100644 --- a/cmd/models.go +++ b/cmd/models.go @@ -1,4 +1,4 @@ -// Package cmd Copyright 2023 Keyfactor +// Copyright 2024 Keyfactor // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/cmd/orchs.go b/cmd/orchs.go index 3c5cdf7c..47d85ff1 100644 --- a/cmd/orchs.go +++ b/cmd/orchs.go @@ -1,4 +1,4 @@ -// Package cmd Copyright 2023 Keyfactor +// Copyright 2024 Keyfactor // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/cmd/orchs_ext.go b/cmd/orchs_ext.go index c6444c18..e1521825 100644 --- a/cmd/orchs_ext.go +++ b/cmd/orchs_ext.go @@ -1,5 +1,5 @@ /* -Copyright 2023 The Keyfactor Command Authors. +Copyright 2024 The Keyfactor Command Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/cmd/orchs_ext_test.go b/cmd/orchs_ext_test.go index 7263a954..3e87710d 100644 --- a/cmd/orchs_ext_test.go +++ b/cmd/orchs_ext_test.go @@ -1,5 +1,5 @@ /* -Copyright 2023 The Keyfactor Command Authors. +Copyright 2024 The Keyfactor Command Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/cmd/pam.go b/cmd/pam.go index cddc1f28..f6f25a15 100644 --- a/cmd/pam.go +++ b/cmd/pam.go @@ -1,4 +1,4 @@ -// Package cmd Copyright 2023 Keyfactor +// Copyright 2024 Keyfactor // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -31,6 +31,10 @@ type JSONImportableObject interface { keyfactor.CSSCMSDataModelModelsProvider } +const ( + convertResponseMsg = "Converting PAM Provider response to JSON" +) + var pamCmd = &cobra.Command{ Use: "pam", Short: "Keyfactor PAM Provider APIs.", @@ -107,7 +111,7 @@ https://github.com/Keyfactor/hashicorp-vault-pam/blob/main/integration-manifest. isExperimental := false // Specific flags - pamConfigFile, _ := cmd.Flags().GetString("from-file") + pamConfigFile, _ := cmd.Flags().GetString(FlagFromFile) pamProviderName, _ := cmd.Flags().GetString("name") repoName, _ := cmd.Flags().GetString("repo") branchName, _ := cmd.Flags().GetString("branch") @@ -158,9 +162,9 @@ https://github.com/Keyfactor/hashicorp-vault-pam/blob/main/integration-manifest. } } else { log.Debug().Str("pamConfigFile", pamConfigFile). - Msg("call: GetTypeFromConfigFile()") + Msg(fmt.Sprintf("call: %s", "GetTypeFromConfigFile()")) pamProviderType, err = GetTypeFromConfigFile(pamConfigFile, pamProviderType) - log.Debug().Msg("returned: GetTypeFromConfigFile()") + log.Debug().Msg(fmt.Sprintf("returned: %s", "GetTypeFromConfigFile()")) if err != nil { log.Error().Err(err).Send() return err @@ -289,7 +293,7 @@ var pamProvidersGetCmd = &cobra.Command{ return err } - log.Debug().Msg("Converting PAM Provider response to JSON") + log.Debug().Msg(convertResponseMsg) jsonString, mErr := json.Marshal(pamProvider) if mErr != nil { log.Error().Err(mErr).Send() @@ -311,7 +315,7 @@ var pamProvidersCreateCmd = &cobra.Command{ isExperimental := false // Specific flags - pamConfigFile, _ := cmd.Flags().GetString("from-file") + pamConfigFile, _ := cmd.Flags().GetString(FlagFromFile) // Debug + expEnabled checks informDebug(debugFlag) @@ -354,7 +358,7 @@ var pamProvidersCreateCmd = &cobra.Command{ return returnHttpErr(httpResponse, cErr) } - log.Debug().Msg("Converting PAM Provider response to JSON") + log.Debug().Msg(convertResponseMsg) jsonString, mErr := json.Marshal(createdPamProvider) if mErr != nil { log.Error().Err(mErr).Msg("invalid API response from Keyfactor Command") @@ -375,7 +379,7 @@ var pamProvidersUpdateCmd = &cobra.Command{ isExperimental := false // Specific flags - pamConfigFile, _ := cmd.Flags().GetString("from-file") + pamConfigFile, _ := cmd.Flags().GetString(FlagFromFile) // Debug + expEnabled checks informDebug(debugFlag) @@ -416,7 +420,7 @@ var pamProvidersUpdateCmd = &cobra.Command{ returnHttpErr(httpResponse, err) } - log.Debug().Msg("Converting PAM Provider response to JSON") + log.Debug().Msg(convertResponseMsg) jsonString, mErr := json.Marshal(createdPamProvider) if mErr != nil { log.Error().Err(mErr).Msg("invalid API response from Keyfactor Command") @@ -620,7 +624,7 @@ func init() { // PAM Provider Types Create pamCmd.AddCommand(pamTypesCreateCmd) - pamTypesCreateCmd.Flags().StringVarP(&filePath, "from-file", "f", "", "Path to a JSON file containing the PAM Type Object Data.") + pamTypesCreateCmd.Flags().StringVarP(&filePath, FlagFromFile, "f", "", "Path to a JSON file containing the PAM Type Object Data.") pamTypesCreateCmd.Flags().StringVarP(&name, "name", "n", "", "Name of the PAM Provider Type.") pamTypesCreateCmd.Flags().StringVarP(&repo, "repo", "r", "", "Keyfactor repository name of the PAM Provider Type.") pamTypesCreateCmd.Flags().StringVarP(&branch, "branch", "b", "", "Branch name for the repository. Defaults to 'main'.") @@ -632,12 +636,12 @@ func init() { pamProvidersGetCmd.MarkFlagRequired("id") pamCmd.AddCommand(pamProvidersCreateCmd) - pamProvidersCreateCmd.Flags().StringVarP(&filePath, "from-file", "f", "", "Path to a JSON file containing the PAM Provider Object Data.") - pamProvidersCreateCmd.MarkFlagRequired("from-file") + pamProvidersCreateCmd.Flags().StringVarP(&filePath, FlagFromFile, "f", "", "Path to a JSON file containing the PAM Provider Object Data.") + pamProvidersCreateCmd.MarkFlagRequired(FlagFromFile) pamCmd.AddCommand(pamProvidersUpdateCmd) - pamProvidersUpdateCmd.Flags().StringVarP(&filePath, "from-file", "f", "", "Path to a JSON file containing the PAM Provider Object Data.") - pamProvidersUpdateCmd.MarkFlagRequired("from-file") + pamProvidersUpdateCmd.Flags().StringVarP(&filePath, FlagFromFile, "f", "", "Path to a JSON file containing the PAM Provider Object Data.") + pamProvidersUpdateCmd.MarkFlagRequired(FlagFromFile) pamCmd.AddCommand(pamProvidersDeleteCmd) pamProvidersDeleteCmd.Flags().Int32VarP(&id, "id", "i", 0, "Integer ID of the PAM Provider.") diff --git a/cmd/pam_test.go b/cmd/pam_test.go index c07a44c7..fcc7bd3e 100644 --- a/cmd/pam_test.go +++ b/cmd/pam_test.go @@ -1,4 +1,4 @@ -// Package cmd Copyright 2023 Keyfactor +// Copyright 2024 Keyfactor // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/cmd/root.go b/cmd/root.go index 68b0ea52..0b73e614 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -1,4 +1,4 @@ -// Package cmd Copyright 2023 Keyfactor +// Copyright 2024 Keyfactor // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/cmd/root_test.go b/cmd/root_test.go index a7c2cf51..64a992ed 100644 --- a/cmd/root_test.go +++ b/cmd/root_test.go @@ -1,4 +1,4 @@ -// Package cmd Copyright 2023 Keyfactor +// Copyright 2024 Keyfactor // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/cmd/rot.go b/cmd/rot.go index 2d3c6254..15f97967 100644 --- a/cmd/rot.go +++ b/cmd/rot.go @@ -1,4 +1,4 @@ -// Package cmd Copyright 2023 Keyfactor +// Copyright 2024 Keyfactor // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/cmd/rot_test.go b/cmd/rot_test.go index 8384d482..5c32ac08 100644 --- a/cmd/rot_test.go +++ b/cmd/rot_test.go @@ -1,4 +1,4 @@ -// Package cmd Copyright 2023 Keyfactor +// Copyright 2024 Keyfactor // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/cmd/status.go b/cmd/status.go index 0bffd7ca..5e1a9b8d 100644 --- a/cmd/status.go +++ b/cmd/status.go @@ -1,4 +1,4 @@ -// Package cmd Copyright 2023 Keyfactor +// Copyright 2024 Keyfactor // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/cmd/storeTypes.go b/cmd/storeTypes.go index 70b9b500..3d8b56ba 100644 --- a/cmd/storeTypes.go +++ b/cmd/storeTypes.go @@ -1,4 +1,4 @@ -// Package cmd Copyright 2023 Keyfactor +// Copyright 2024 Keyfactor // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/cmd/storeTypes_get.go b/cmd/storeTypes_get.go index 9608b1c5..74f8c859 100644 --- a/cmd/storeTypes_get.go +++ b/cmd/storeTypes_get.go @@ -1,5 +1,5 @@ /* -Copyright 2023 The Keyfactor Command Authors. +Copyright 2024 The Keyfactor Command Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/cmd/storeTypes_get_test.go b/cmd/storeTypes_get_test.go index 735a2be0..517aee97 100644 --- a/cmd/storeTypes_get_test.go +++ b/cmd/storeTypes_get_test.go @@ -1,5 +1,5 @@ /* -Copyright 2023 The Keyfactor Command Authors. +Copyright 2024 The Keyfactor Command Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/cmd/storeTypes_test.go b/cmd/storeTypes_test.go index cb46cb76..6cc3e201 100644 --- a/cmd/storeTypes_test.go +++ b/cmd/storeTypes_test.go @@ -1,4 +1,4 @@ -// Package cmd Copyright 2023 Keyfactor +// Copyright 2024 Keyfactor // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -71,6 +71,12 @@ func Test_StoreTypesListCmd(t *testing.T) { // verify that the store type is an integer _, ok := storeType["StoreType"].(float64) + if !ok { + t.Log("StoreType is not a float64") + merr, ook := storeType["StoreType"].(int) + t.Log(merr) + t.Log(ook) + } assert.True(t, ok, "Expected store type to be an integer") // verify short name is a string _, ok = storeType["ShortName"].(string) diff --git a/cmd/stores.go b/cmd/stores.go index d106a173..327ad8ab 100644 --- a/cmd/stores.go +++ b/cmd/stores.go @@ -1,4 +1,4 @@ -// Package cmd Copyright 2023 Keyfactor +// Copyright 2024 Keyfactor // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/cmd/storesBulkOperations.go b/cmd/storesBulkOperations.go index d61c5194..f30fa987 100644 --- a/cmd/storesBulkOperations.go +++ b/cmd/storesBulkOperations.go @@ -1,4 +1,4 @@ -// Package cmd Copyright 2023 Keyfactor +// Copyright 2024 Keyfactor // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/cmd/stores_test.go b/cmd/stores_test.go index b9500c88..0b6356d7 100644 --- a/cmd/stores_test.go +++ b/cmd/stores_test.go @@ -1,4 +1,4 @@ -// Package cmd Copyright 2023 Keyfactor +// Copyright 2024 Keyfactor // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/cmd/test.go b/cmd/test.go index 8d314147..941df876 100644 --- a/cmd/test.go +++ b/cmd/test.go @@ -1,4 +1,4 @@ -// Package cmd Copyright 2023 Keyfactor +// Copyright 2024 Keyfactor // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/cmd/version.go b/cmd/version.go index fa45f990..fe289184 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -1,4 +1,4 @@ -// Package cmd Copyright 2023 Keyfactor +// Copyright 2024 Keyfactor // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/go.mod b/go.mod index 4d9bd2fd..068f38db 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0 github.com/Jeffail/gabs v1.4.0 github.com/Keyfactor/keyfactor-go-client-sdk v1.0.2 - github.com/Keyfactor/keyfactor-go-client/v2 v2.2.5 + github.com/Keyfactor/keyfactor-go-client/v2 v2.2.6 github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 github.com/creack/pty v1.1.21 github.com/google/go-cmp v0.6.0 diff --git a/go.sum b/go.sum index dc019875..3ba8f54e 100644 --- a/go.sum +++ b/go.sum @@ -14,8 +14,8 @@ github.com/Keyfactor/keyfactor-go-client v1.4.3 h1:CmGvWcuIbDRFM0PfYOQH6UdtAgplv github.com/Keyfactor/keyfactor-go-client v1.4.3/go.mod h1:3ZymLNCaSazglcuYeNfm9nrzn22wcwLjIWURrnUygBo= github.com/Keyfactor/keyfactor-go-client-sdk v1.0.2 h1:caLlzFCz2L4Dth/9wh+VlypFATmOMmCSQkCPKOKMxw8= github.com/Keyfactor/keyfactor-go-client-sdk v1.0.2/go.mod h1:Z5pSk8YFGXHbKeQ1wTzVN8A4P/fZmtAwqu3NgBHbDOs= -github.com/Keyfactor/keyfactor-go-client/v2 v2.2.5 h1:2P6e4hOMwjH/+r3bjlm+PFVyFUabXYiAMspwb6HJ81k= -github.com/Keyfactor/keyfactor-go-client/v2 v2.2.5/go.mod h1:3mfxdcwntB532QIATokBEkBCH0eXN2G/cdMZtu9NwNg= +github.com/Keyfactor/keyfactor-go-client/v2 v2.2.6 h1:LQ6M0VKAhOZ7I/nNWC0Mfy+QVEE6YPZpjbnbi65oLw8= +github.com/Keyfactor/keyfactor-go-client/v2 v2.2.6/go.mod h1:3mfxdcwntB532QIATokBEkBCH0eXN2G/cdMZtu9NwNg= github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s= github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= From 58be5eb6fd0c4a1e80107538380d7bba10e04938 Mon Sep 17 00:00:00 2001 From: sbailey <1661003+spbsoluble@users.noreply.github.com> Date: Thu, 8 Feb 2024 13:28:41 -0800 Subject: [PATCH 05/47] fix(tests): Remove "ProviderTypeParams" from pam-types tests for KFC v11.0.0+ Signed-off-by: sbailey <1661003+spbsoluble@users.noreply.github.com> --- cmd/pam_test.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/cmd/pam_test.go b/cmd/pam_test.go index fcc7bd3e..719316b0 100644 --- a/cmd/pam_test.go +++ b/cmd/pam_test.go @@ -93,7 +93,11 @@ func Test_PAMTypesListCmd(t *testing.T) { //} // Check params is a list of maps - pTypeParams := providerConfig["ProviderTypeParams"].([]interface{}) + pTypeParams, ok := providerConfig["ProviderTypeParams"].([]interface{}) + if !ok { + t.Logf("ProviderTypeParams is not a list of maps for %s", providerConfig["Name"]) + return + } //assert.NotEmpty(t, pTypeParams) //assert.GreaterOrEqual(t, len(pTypeParams), 0) if len(pTypeParams) > 0 { @@ -509,7 +513,13 @@ func testListPamProviderTypes(t *testing.T, name string, allowFail bool, allowEm } // Check params is a list of maps - pTypeParams := providerConfig["ProviderTypeParams"].([]interface{}) + pTypeParams, ok := providerConfig["ProviderTypeParams"].([]interface{}) + if !ok { + // This will happen for KFC 11.0+ where this field is not returned + t.Logf("ProviderTypeParams is not a list of maps for %s", providerConfig["Name"]) + continue + } + //assert.NotEmpty(t, pTypeParams) //assert.GreaterOrEqual(t, len(pTypeParams), 0) if len(pTypeParams) > 0 { From 4bf5c2a6c58befad8eb261723e8f3a20a52adf65 Mon Sep 17 00:00:00 2001 From: sbailey <1661003+spbsoluble@users.noreply.github.com> Date: Mon, 12 Feb 2024 08:54:43 -0800 Subject: [PATCH 06/47] fix(tests): Fix nil pointer issues on tests. Signed-off-by: sbailey <1661003+spbsoluble@users.noreply.github.com> --- cmd/helpers.go | 4 ++++ cmd/login_test.go | 7 ++++++- cmd/pam.go | 6 ++++-- cmd/pam_test.go | 34 ++++++++++++++++++++++++---------- 4 files changed, 38 insertions(+), 13 deletions(-) diff --git a/cmd/helpers.go b/cmd/helpers.go index 58d5eb55..2c084477 100644 --- a/cmd/helpers.go +++ b/cmd/helpers.go @@ -388,6 +388,10 @@ func writeJSONFile(filename string, data interface{}) error { } func returnHttpErr(resp *http.Response, err error) error { + if resp == nil { + log.Error().Err(err).Msg("unable to create PAM provider - no response") + return err + } if resp.Body != nil { body, _ := io.ReadAll(resp.Body) log.Error().Err(err).Str("httpResponseCode", resp.Status). diff --git a/cmd/login_test.go b/cmd/login_test.go index da30729e..6fda933c 100644 --- a/cmd/login_test.go +++ b/cmd/login_test.go @@ -164,7 +164,12 @@ func testConfigExists(t *testing.T, filePath string, allowExist bool) { } // Verify that the config file has the correct keys assert.Contains(t, fileConfigJSON, "servers") - kfcServers := fileConfigJSON["servers"].(map[string]interface{}) + kfcServers, ok := fileConfigJSON["servers"].(map[string]interface{}) + if !ok { + t.Errorf("Error decoding config file: %s", err) + assert.False(t, ok, "Error decoding config file") + return + } assert.Contains(t, kfcServers, "default") defaultServer := kfcServers["default"].(map[string]interface{}) assert.Contains(t, defaultServer, "host") diff --git a/cmd/pam.go b/cmd/pam.go index f6f25a15..fb725272 100644 --- a/cmd/pam.go +++ b/cmd/pam.go @@ -66,8 +66,10 @@ var pamTypesListCmd = &cobra.Command{ // CLI Logic log.Debug().Msg("call: PAMProviderGetPamProviderTypes()") - pamTypes, httpResponse, err := sdkClient.PAMProviderApi.PAMProviderGetPamProviderTypes(context.Background()). - XKeyfactorRequestedWith(XKeyfactorRequestedWith).XKeyfactorApiVersion(XKeyfactorApiVersion). + pamTypes, httpResponse, err := sdkClient.PAMProviderApi. + PAMProviderGetPamProviderTypes(context.Background()). + XKeyfactorRequestedWith(XKeyfactorRequestedWith). + XKeyfactorApiVersion(XKeyfactorApiVersion). Execute() log.Debug().Msg("returned: PAMProviderGetPamProviderTypes()") log.Trace().Interface("httpResponse", httpResponse). diff --git a/cmd/pam_test.go b/cmd/pam_test.go index 719316b0..2f0f6f33 100644 --- a/cmd/pam_test.go +++ b/cmd/pam_test.go @@ -52,25 +52,34 @@ func Test_PAMHelpCmd(t *testing.T) { func Test_PAMListCmd(t *testing.T) { // list providers - pamProviders, err := testListPamProviders(t) - assert.NoError(t, err) - if err != nil { - t.Fatalf("failed to list PAM providers: %v", err) - } - - if len(pamProviders) <= 0 { - t.Fatalf("0 PAM providers found, cannot test list") - } + //pamProviders, err := testListPamProviders(t) + //assert.NoError(t, err) + //if err != nil { + // //t.Fatalf("failed to list PAM providers: %v", err) + // t.Errorf("failed to list PAM providers: %v", err) + // return + //} + // + //if len(pamProviders) <= 0 { + // t.Fatalf("0 PAM providers found, cannot test list") + //} } func Test_PAMTypesListCmd(t *testing.T) { testCmd := RootCmd // test + var err error testCmd.SetArgs([]string{"pam", "types-list"}) output := captureOutput(func() { - err := testCmd.Execute() + err = testCmd.Execute() assert.NoError(t, err) }) + + if err != nil { + t.Errorf("failed to list PAM provider types: %v", err) + return + } + var pTypes []interface{} if err := json.Unmarshal([]byte(output), &pTypes); err != nil { t.Fatalf("Error unmarshalling JSON: %v", err) @@ -372,6 +381,11 @@ func testListPamProviders(t *testing.T) ([]interface{}, error) { assert.NoError(t, err) }) + if err != nil { + t.Errorf("failed to list PAM providers: %v", err) + return + } + if err = json.Unmarshal([]byte(output), &pamProviders); err != nil { t.Fatalf("Error unmarshalling JSON: %v", err) } From a8b68e5b81b750762d9f2eede921da1e947242a1 Mon Sep 17 00:00:00 2001 From: sbailey <1661003+spbsoluble@users.noreply.github.com> Date: Tue, 13 Feb 2024 10:48:58 -0800 Subject: [PATCH 07/47] feat(cli): Update `import/export` sub CLIs Signed-off-by: sbailey <1661003+spbsoluble@users.noreply.github.com> --- cmd/constants.go | 3 + cmd/export.go | 217 ++++++++++++++++++++++++++++++++++------- cmd/import.go | 195 +++++++++++++++++++++++++++++------- cmd/pam.go | 5 +- cmd/pam_test.go | 11 ++- pkg/version/version.go | 2 +- 6 files changed, 363 insertions(+), 70 deletions(-) diff --git a/cmd/constants.go b/cmd/constants.go index 1fed0c6c..b0caea3f 100644 --- a/cmd/constants.go +++ b/cmd/constants.go @@ -26,6 +26,9 @@ const ( XKeyfactorApiVersion = "1" FlagGitRef = "git-ref" FlagFromFile = "from-file" + DebugFuncEnter = "entered: %s" + DebugFuncExit = "exiting: %s" + DebugFuncCall = "calling: %s" ) var ProviderTypeChoices = []string{ diff --git a/cmd/export.go b/cmd/export.go index 33d836e2..07d0431c 100644 --- a/cmd/export.go +++ b/cmd/export.go @@ -20,8 +20,8 @@ import ( "fmt" "github.com/Keyfactor/keyfactor-go-client-sdk/api/keyfactor" "github.com/Keyfactor/keyfactor-go-client/v2/api" + "github.com/rs/zerolog/log" "github.com/spf13/cobra" - "log" "os" "strconv" ) @@ -84,18 +84,23 @@ type outJson struct { SecurityRoles []api.CreateSecurityRoleArg `json:"SecurityRoles"` } -func exportToJSON(out outJson, exportPath string) { +func exportToJSON(out outJson, exportPath string) error { mOut, jErr := json.MarshalIndent(out, "", " ") if jErr != nil { fmt.Printf("Error processing JSON object. %s\n", jErr) - log.Fatalf("[ERROR]: %s", jErr) + //log.Fatalf("[ERROR]: %s", jErr) + log.Error().Err(jErr) + return jErr } wErr := os.WriteFile(exportPath, mOut, 0666) if wErr != nil { fmt.Printf("Error writing files to %s: %s\n", exportPath, wErr) - log.Fatalf("[ERROR]: %s", wErr) + //log.Fatalf("[ERROR]: %s", wErr) + log.Error().Err(wErr) + return wErr } else { fmt.Printf("Content successfully written to %s", exportPath) + return nil } } @@ -104,7 +109,18 @@ var exportCmd = &cobra.Command{ Use: "export", Short: "Keyfactor instance export utilities.", Long: `A collection of APIs and utilities for exporting Keyfactor instance data.`, - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { + log.Debug().Msgf("%s: exportCmd", DebugFuncEnter) + isExperimental := true + + informDebug(debugFlag) + debugErr := warnExperimentalFeature(expEnabled, isExperimental) + if debugErr != nil { + return debugErr + } + + log.Info().Msg("Exporting data from Keyfactor instance") + // initialize each entry as an empty list in the event it is not requested by the flags out := outJson{ Collections: []keyfactor.KeyfactorApiModelsCertificateCollectionsCertificateCollectionCreateRequest{}, @@ -120,106 +136,189 @@ var exportCmd = &cobra.Command{ SecurityRoles: []api.CreateSecurityRoleArg{}, } + log.Debug().Msgf("%s: createAuthConfigFromParams", DebugFuncCall) authConfig := createAuthConfigFromParams(kfcHostName, kfcUsername, kfcPassword, kfcDomain, kfcAPIPath) - isExperimental := true - _, expErr := isExperimentalFeatureEnabled(expEnabled, isExperimental) - if expErr != nil { - fmt.Println(fmt.Sprintf("WARNING this is an expEnabled feature, %s", expErr)) - log.Fatalf("[ERROR]: %s", expErr) + if authConfig == nil { + log.Error().Msg("auth config is nil, invalid client configuration") + return fmt.Errorf(FailedAuthMsg) } - debugModeEnabled := checkDebug(debugFlag) - log.Println("Debug mode enabled: ", debugModeEnabled) - exportPath := cmd.Flag("file").Value.String() + log.Debug().Str("exportPath", exportPath).Msg("exportPath") + + log.Debug().Msgf("%s: initGenClient", DebugFuncCall) + kfClient, clientErr := initGenClient(configFile, profile, noPrompt, authConfig, false) + log.Debug().Msgf("%s: initClient", DebugFuncCall) + oldkfClient, oldClientErr := initClient(configFile, profile, "", "", noPrompt, authConfig, false) + + if clientErr != nil { + log.Error().Err(clientErr).Send() + return clientErr + } else if oldClientErr != nil { + log.Error().Err(oldClientErr).Send() + return oldClientErr + } - kfClient, _ := initGenClient(configFile, profile, noPrompt, authConfig, false) - oldkfClient, _ := initClient(configFile, profile, "", "", noPrompt, authConfig, false) if cmd.Flag("all").Value.String() == "true" { + log.Debug().Msgf("%s: getCollections", DebugFuncCall) out.Collections = getCollections(kfClient) + + log.Debug().Msgf("%s: getMetadata", DebugFuncCall) out.MetadataFields = getMetadata(kfClient) + + log.Debug().Msgf("%s: getExpirationAlerts", DebugFuncCall) out.ExpirationAlerts = getExpirationAlerts(kfClient) + + log.Debug().Msgf("%s: getIssuedAlerts", DebugFuncCall) out.IssuedCertAlerts = getIssuedAlerts(kfClient) + + log.Debug().Msgf("%s: getDeniedAlerts", DebugFuncCall) out.DeniedCertAlerts = getDeniedAlerts(kfClient) + + log.Debug().Msgf("%s: getPendingAlerts", DebugFuncCall) out.PendingCertAlerts = getPendingAlerts(kfClient) + + log.Debug().Msgf("%s: getSslNetworks", DebugFuncCall) out.Networks = getSslNetworks(kfClient) + + log.Debug().Msgf("%s: getWorkflowDefinitions", DebugFuncCall) out.WorkflowDefinitions = getWorkflowDefinitions(kfClient) + + log.Debug().Msgf("%s: getReports", DebugFuncCall) out.BuiltInReports, out.CustomReports = getReports(kfClient) + + log.Debug().Msgf("%s: getRoles", DebugFuncCall) out.SecurityRoles = getRoles(oldkfClient) } else { if cmd.Flag("collections").Value.String() == "true" { + log.Debug().Msgf("%s: getCollections", DebugFuncCall) out.Collections = getCollections(kfClient) } if cmd.Flag("metadata").Value.String() == "true" { + log.Debug().Msgf("%s: getMetadata", DebugFuncCall) out.MetadataFields = getMetadata(kfClient) } if cmd.Flag("expiration-alerts").Value.String() == "true" { + log.Debug().Msgf("%s: getExpirationAlerts", DebugFuncCall) out.ExpirationAlerts = getExpirationAlerts(kfClient) } if cmd.Flag("issued-alerts").Value.String() == "true" { + log.Debug().Msgf("%s: getIssuedAlerts", DebugFuncCall) out.IssuedCertAlerts = getIssuedAlerts(kfClient) } if cmd.Flag("denied-alerts").Value.String() == "true" { + log.Debug().Msgf("%s: getDeniedAlerts", DebugFuncCall) out.DeniedCertAlerts = getDeniedAlerts(kfClient) } if cmd.Flag("pending-alerts").Value.String() == "true" { + log.Debug().Msgf("%s: getPendingAlerts", DebugFuncCall) out.PendingCertAlerts = getPendingAlerts(kfClient) } if cmd.Flag("networks").Value.String() == "true" { + log.Debug().Msgf("%s: getSslNetworks", DebugFuncCall) out.Networks = getSslNetworks(kfClient) } if cmd.Flag("workflow-definitions").Value.String() == "true" { + log.Debug().Msgf("%s: getWorkflowDefinitions", DebugFuncCall) out.WorkflowDefinitions = getWorkflowDefinitions(kfClient) } if cmd.Flag("reports").Value.String() == "true" { + log.Debug().Msgf("%s: getReports", DebugFuncCall) out.BuiltInReports, out.CustomReports = getReports(kfClient) } if cmd.Flag("security-roles").Value.String() == "true" { + log.Debug().Msgf("%s: getRoles", DebugFuncCall) out.SecurityRoles = getRoles(oldkfClient) } } + log.Debug().Msgf("%s: exportToJSON", DebugFuncCall) exportToJSON(out, exportPath) + + log.Debug().Msgf("%s: exportCmd", DebugFuncExit) + log.Info().Msg("Export complete") + return nil }, } func getCollections(kfClient *keyfactor.APIClient) []keyfactor.KeyfactorApiModelsCertificateCollectionsCertificateCollectionCreateRequest { + log.Debug().Msgf("%s: getCollections", DebugFuncEnter) + + log.Debug().Msgf("%s: CertificateCollectionGetCollections", DebugFuncCall) collections, _, reqErr := kfClient.CertificateCollectionApi.CertificateCollectionGetCollections(context.Background()).XKeyfactorRequestedWith(XKeyfactorRequestedWith).XKeyfactorApiVersion(XKeyfactorApiVersion).Execute() + if reqErr != nil { + log.Error().Err(reqErr).Send() fmt.Printf("%s Error! Unable to get collections %s%s\n", ColorRed, reqErr, ColorWhite) } var lCollectionReq []keyfactor.KeyfactorApiModelsCertificateCollectionsCertificateCollectionCreateRequest for _, collection := range collections { - cJson, _ := json.Marshal(collection) + log.Debug().Msgf("Marshalling collection %s", *collection.Name) + cJson, jmErr := json.Marshal(collection) + if jmErr != nil { + if collection.Name != nil && collection.Id != nil { + log.Error().Err(jmErr).Msgf("Error marshalling collection %s(%d)", *collection.Name, *collection.Id) + } + fmt.Printf("Error: %s\n", jmErr) + continue + } + + log.Debug().Msgf("Unmarshalling collection %s", *collection.Name) var collectionReq keyfactor.KeyfactorApiModelsCertificateCollectionsCertificateCollectionCreateRequest jErr := json.Unmarshal(cJson, &collectionReq) if jErr != nil { + log.Error().Err(jErr).Send() fmt.Printf("Error: %s\n", jErr) - log.Fatalf("Error: %s", jErr) } collectionReq.Query = collection.Content collectionReq.Id = nil + + log.Debug().Msgf("Appending collection %s", *collection.Name) lCollectionReq = append(lCollectionReq, collectionReq) } + log.Debug().Msgf("%s: getCollections", DebugFuncExit) return lCollectionReq } func getMetadata(kfClient *keyfactor.APIClient) []keyfactor.KeyfactorApiModelsMetadataFieldMetadataFieldCreateRequest { + log.Debug().Msgf("%s: getMetadata", DebugFuncEnter) + log.Debug().Msgf("%s: MetadataFieldGetAllMetadataFields", DebugFuncCall) metadata, _, reqErr := kfClient.MetadataFieldApi.MetadataFieldGetAllMetadataFields(context.Background()).XKeyfactorRequestedWith(XKeyfactorRequestedWith).XKeyfactorApiVersion(XKeyfactorApiVersion).Execute() if reqErr != nil { + log.Error().Err(reqErr).Send() fmt.Printf("%s Error! Unable to get metadata %s%s\n", ColorRed, reqErr, ColorWhite) + return nil } + var lMetadataReq []keyfactor.KeyfactorApiModelsMetadataFieldMetadataFieldCreateRequest for _, metadataItem := range metadata { - mJson, _ := json.Marshal(metadataItem) + mName := "" + if metadataItem.Name != nil { + mName = *metadataItem.Name + } else if metadataItem.Id != nil { + mName = fmt.Sprintf("%d", *metadataItem.Id) + } + log.Debug().Str("mName", mName).Msg("Marshalling metadata") + mJson, jmErr := json.Marshal(metadataItem) + if jmErr != nil { + log.Error().Err(jmErr).Send() + fmt.Printf("Error: %s\n", jmErr) + continue + } + + log.Debug().Msgf("Unmarshalling metadata '%s'", mName) var metadataReq keyfactor.KeyfactorApiModelsMetadataFieldMetadataFieldCreateRequest jErr := json.Unmarshal(mJson, &metadataReq) if jErr != nil { fmt.Printf("Error: %s\n", jErr) - log.Fatalf("Error: %s", jErr) + //log.Fatalf("Error: %s", jErr) + log.Error().Err(jErr).Send() + continue } metadataItem.Id = nil + + log.Debug().Msgf("Appending metadata '%s'", mName) lMetadataReq = append(lMetadataReq, metadataReq) } return lMetadataReq @@ -238,7 +337,8 @@ func getExpirationAlerts(kfClient *keyfactor.APIClient) []keyfactor.KeyfactorApi jErr := json.Unmarshal(mJson, &alertReq) if jErr != nil { fmt.Printf("Error: %s\n", jErr) - log.Fatalf("Error: %s", jErr) + log.Error().Err(jErr).Send() + return nil // todo: maybe return the error instead? } lAlertReq = append(lAlertReq, alertReq) } @@ -258,7 +358,9 @@ func getIssuedAlerts(kfClient *keyfactor.APIClient) []keyfactor.KeyfactorApiMode jErr := json.Unmarshal(mJson, &alertReq) if jErr != nil { fmt.Printf("Error: %s\n", jErr) - log.Fatalf("Error: %s", jErr) + //log.Fatalf("Error: %s", jErr) + log.Error().Err(jErr).Send() + return nil // todo: maybe return the error instead? } alertReq.TemplateId = nil lAlertReq = append(lAlertReq, alertReq) @@ -281,7 +383,9 @@ func getDeniedAlerts(kfClient *keyfactor.APIClient) []keyfactor.KeyfactorApiMode jErr := json.Unmarshal(mJson, &alertReq) if jErr != nil { fmt.Printf("Error: %s\n", jErr) - log.Fatalf("Error: %s", jErr) + //log.Fatalf("Error: %s", jErr) + log.Error().Err(jErr).Send() + return nil // todo: maybe return the error instead? } alertReq.TemplateId = nil lAlertReq = append(lAlertReq, alertReq) @@ -302,7 +406,8 @@ func getPendingAlerts(kfClient *keyfactor.APIClient) []keyfactor.KeyfactorApiMod jErr := json.Unmarshal(mJson, &alertReq) if jErr != nil { fmt.Printf("Error: %s\n", jErr) - log.Fatalf("Error: %s", jErr) + //log.Fatalf("Error: %s", jErr) + log.Error().Err(jErr).Send() } alertReq.TemplateId = nil lAlertReq = append(lAlertReq, alertReq) @@ -312,7 +417,11 @@ func getPendingAlerts(kfClient *keyfactor.APIClient) []keyfactor.KeyfactorApiMod func getSslNetworks(kfClient *keyfactor.APIClient) []keyfactor.KeyfactorApiModelsSslCreateNetworkRequest { - networks, _, reqErr := kfClient.SslApi.SslGetNetworks(context.Background()).XKeyfactorRequestedWith(XKeyfactorRequestedWith).XKeyfactorApiVersion(XKeyfactorApiVersion).Execute() + networks, _, reqErr := kfClient.SslApi. + SslGetNetworks(context.Background()). + XKeyfactorRequestedWith(XKeyfactorRequestedWith). + XKeyfactorApiVersion(XKeyfactorApiVersion). + Execute() if reqErr != nil { fmt.Printf("%s Error! Unable to get SSL networks %s%s\n", ColorRed, reqErr, ColorWhite) } @@ -323,7 +432,9 @@ func getSslNetworks(kfClient *keyfactor.APIClient) []keyfactor.KeyfactorApiModel jErr := json.Unmarshal(mJson, &networkReq) if jErr != nil { fmt.Printf("Error: %s\n", jErr) - log.Fatalf("Error: %s", jErr) + //log.Fatalf("Error: %s", jErr) + log.Error().Err(jErr).Send() + continue } lNetworkReq = append(lNetworkReq, networkReq) } @@ -332,23 +443,49 @@ func getSslNetworks(kfClient *keyfactor.APIClient) []keyfactor.KeyfactorApiModel func getWorkflowDefinitions(kfClient *keyfactor.APIClient) []exportKeyfactorAPIModelsWorkflowsDefinitionCreateRequest { - workflowDefs, _, reqErr := kfClient.WorkflowDefinitionApi.WorkflowDefinitionQuery(context.Background()).XKeyfactorRequestedWith(XKeyfactorRequestedWith).XKeyfactorApiVersion(XKeyfactorApiVersion).Execute() + workflowDefs, _, reqErr := kfClient.WorkflowDefinitionApi. + WorkflowDefinitionQuery(context.Background()). + XKeyfactorRequestedWith(XKeyfactorRequestedWith). + XKeyfactorApiVersion(XKeyfactorApiVersion). + Execute() if reqErr != nil { fmt.Printf("%s Error! Unable to get workflow definitions %s%s\n", ColorRed, reqErr, ColorWhite) } var lWorkflowReq []exportKeyfactorAPIModelsWorkflowsDefinitionCreateRequest for _, workflowDef := range workflowDefs { - mJson, _ := json.Marshal(workflowDef) + mJson, mErr := json.Marshal(workflowDef) + if mErr != nil { + fmt.Printf("Error: %s\n", mErr) + //log.Fatalf("Error: %s", mErr) + log.Error().Err(mErr).Send() //todo: better error message? + continue + } var workflowReq exportKeyfactorAPIModelsWorkflowsDefinitionCreateRequest jErr := json.Unmarshal(mJson, &workflowReq) if jErr != nil { fmt.Printf("Error: %s\n", jErr) - log.Fatalf("Error: %s", jErr) + //log.Fatalf("Error: %s", jErr) + log.Error().Err(jErr).Send() //todo: better error message? + continue } if workflowDef.Key != nil { - key, _ := strconv.ParseInt(*workflowDef.Key, 10, 64) + key, convErr := strconv.ParseInt(*workflowDef.Key, 10, 64) + if convErr != nil { + fmt.Printf("Error: %s\n", convErr) + //log.Fatalf("Error: %s", convErr) + log.Error().Err(convErr).Send() //todo: better error message? + continue + } key32 := int32(key) - template, _, _ := kfClient.TemplateApi.TemplateGetTemplate(context.Background(), key32).XKeyfactorRequestedWith(XKeyfactorRequestedWith).XKeyfactorApiVersion(XKeyfactorApiVersion).Execute() + template, _, tErr := kfClient.TemplateApi. + TemplateGetTemplate(context.Background(), key32). + XKeyfactorRequestedWith(XKeyfactorRequestedWith). + XKeyfactorApiVersion(XKeyfactorApiVersion). + Execute() + if tErr != nil { + log.Error().Err(tErr).Send() //todo: better error message? + continue + } workflowReq.KeyName = template.TemplateName } workflowReq.Key = nil @@ -366,12 +503,20 @@ func getReports(kfClient *keyfactor.APIClient) ([]exportModelsReport, []keyfacto } var lbReportsReq []exportModelsReport for _, bReport := range bReports { - mJson, _ := json.Marshal(bReport) + mJson, mErr := json.Marshal(bReport) + if mErr != nil { + fmt.Printf("Error: %s\n", mErr) + //log.Fatalf("Error: %s", mErr) + log.Error().Err(mErr).Send() //todo: better error message? + continue + } var newbReport exportModelsReport jErr := json.Unmarshal(mJson, &newbReport) if jErr != nil { fmt.Printf("Error: %s\n", jErr) - log.Fatalf("Error: %s", jErr) + //log.Fatalf("Error: %s", jErr) + log.Error().Err(jErr).Send() //todo: better error message? + continue } newbReport.ID = nil lbReportsReq = append(lbReportsReq, newbReport) @@ -388,7 +533,9 @@ func getReports(kfClient *keyfactor.APIClient) ([]exportModelsReport, []keyfacto jErr := json.Unmarshal(mJson, &cReportReq) if jErr != nil { fmt.Printf("Error: %s\n", jErr) - log.Fatalf("Error: %s", jErr) + //log.Fatalf("Error: %s", jErr) + log.Error().Err(jErr).Send() //todo: better error message? + continue } lcReportReq = append(lcReportReq, cReportReq) } @@ -407,7 +554,9 @@ func getRoles(kfClient *api.Client) []api.CreateSecurityRoleArg { jErr := json.Unmarshal(mJson, &cRoleReq) if jErr != nil { fmt.Printf("Error: %s\n", jErr) - log.Fatalf("Error: %s", jErr) + //log.Fatalf("Error: %s", jErr) + log.Error().Err(jErr).Send() //todo: better error message? + continue } lRoleReq = append(lRoleReq, cRoleReq) } diff --git a/cmd/import.go b/cmd/import.go index 2df1df0d..5004a2ef 100644 --- a/cmd/import.go +++ b/cmd/import.go @@ -20,9 +20,9 @@ import ( "fmt" "github.com/Keyfactor/keyfactor-go-client-sdk/api/keyfactor" "github.com/Keyfactor/keyfactor-go-client/v2/api" + "github.com/rs/zerolog/log" "github.com/spf13/cobra" "io" - "log" "os" ) @@ -32,9 +32,23 @@ type Body struct { } func parseError(error io.ReadCloser) string { - bytes, _ := io.ReadAll(error) + log.Debug().Msgf("%s: parseError", DebugFuncEnter) + + log.Debug().Msg("Reading error body") + bytes, ioErr := io.ReadAll(error) + if ioErr != nil { + fmt.Printf("Error: %s\n", ioErr) + log.Error().Err(ioErr).Send() + return ioErr.Error() + } var newError Body - json.Unmarshal(bytes, &newError) + jErr := json.Unmarshal(bytes, &newError) + if jErr != nil { + fmt.Printf("Error: %s\n", jErr) + log.Error().Err(jErr).Send() + return jErr.Error() + } + log.Debug().Msgf("%s: parseError", DebugFuncExit) return newError.Message } @@ -42,92 +56,168 @@ var importCmd = &cobra.Command{ Use: "import", Short: "Keyfactor instance import utilities.", Long: `A collection of APIs and utilities for importing Keyfactor instance data.`, - Run: func(cmd *cobra.Command, args []string) { - - authConfig := createAuthConfigFromParams(kfcHostName, kfcUsername, kfcPassword, kfcDomain, kfcAPIPath) + RunE: func(cmd *cobra.Command, args []string) error { + log.Debug().Msgf("%s: importCmd", DebugFuncEnter) isExperimental := true - _, expErr := isExperimentalFeatureEnabled(expEnabled, isExperimental) - if expErr != nil { - fmt.Println(fmt.Sprintf("WARNING this is an expEnabled feature, %s", expErr)) - log.Fatalf("[ERROR]: %s", expErr) + informDebug(debugFlag) + debugErr := warnExperimentalFeature(expEnabled, isExperimental) + if debugErr != nil { + return debugErr } - debugModeEnabled := checkDebug(debugFlag) - log.Println("Debug mode enabled: ", debugModeEnabled) + log.Info().Msg("Running import...") + + log.Debug().Msgf("%s: createAuthConfigFromParams", DebugFuncCall) + authConfig := createAuthConfigFromParams(kfcHostName, kfcUsername, kfcPassword, kfcDomain, kfcAPIPath) + if authConfig == nil { + return fmt.Errorf("Error: %s", FailedAuthMsg) + } exportPath := cmd.Flag("file").Value.String() + log.Debug().Str("exportPath", exportPath).Msg("exportPath") + + log.Debug().Str("exportPath", exportPath). + Msg("Reading exported file") + jsonFile, oErr := os.Open(exportPath) if oErr != nil { fmt.Printf("Error opening exported file: %s\n", oErr) - log.Fatalf("Error: %s", oErr) + //log.Fatalf("Error: %s", oErr) + log.Error(). + Str("exportPath", exportPath). + Err(oErr). + Send() } defer jsonFile.Close() var out outJson - bJson, _ := io.ReadAll(jsonFile) + bJson, ioErr := io.ReadAll(jsonFile) + if ioErr != nil { + fmt.Printf("Error reading exported file: %s\n", ioErr) + //log.Fatalf("Error: %s", ioErr) + log.Error().Err(ioErr).Send() + return ioErr + } jErr := json.Unmarshal(bJson, &out) if jErr != nil { fmt.Printf("Error reading exported file: %s\n", jErr) - log.Fatalf("Error: %s", jErr) + //log.Fatalf("Error: %s", jErr) + log.Error().Err(jErr).Send() + return jErr } - kfClient, _ := initGenClient(configFile, profile, noPrompt, authConfig, false) - oldkfClient, _ := initClient(configFile, profile, "", "", noPrompt, authConfig, false) + log.Debug().Msgf("%s: initGenClient", DebugFuncCall) + kfClient, clientErr := initGenClient(configFile, profile, noPrompt, authConfig, false) + log.Debug().Msgf("%s: initClient", DebugFuncExit) + oldkfClient, oldClientErr := initClient(configFile, profile, "", "", noPrompt, authConfig, false) + + if clientErr != nil { + log.Error().Err(clientErr).Send() + return clientErr + } else if oldClientErr != nil { + log.Error().Err(oldClientErr).Send() + return oldClientErr + } + if cmd.Flag("all").Value.String() == "true" { + log.Debug().Msgf("%s: importCollections", DebugFuncCall) importCollections(out.Collections, kfClient) + log.Debug().Msgf("%s: importMetadataFields", DebugFuncCall) importMetadataFields(out.MetadataFields, kfClient) + + log.Debug().Msgf("%s: importIssuedCertAlerts", DebugFuncCall) importIssuedCertAlerts(out.IssuedCertAlerts, kfClient) + + log.Debug().Msgf("%s: importDeniedCertAlerts", DebugFuncCall) importDeniedCertAlerts(out.DeniedCertAlerts, kfClient) + + log.Debug().Msgf("%s: importPendingCertAlerts", DebugFuncCall) importPendingCertAlerts(out.PendingCertAlerts, kfClient) + + log.Debug().Msgf("%s: importNetworks", DebugFuncCall) importNetworks(out.Networks, kfClient) + + log.Debug().Msgf("%s: importWorkflowDefinitions", DebugFuncCall) importWorkflowDefinitions(out.WorkflowDefinitions, kfClient) + + log.Debug().Msgf("%s: importBuiltInReports", DebugFuncCall) importBuiltInReports(out.BuiltInReports, kfClient) + + log.Debug().Msgf("%s: importCustomReports", DebugFuncCall) importCustomReports(out.CustomReports, kfClient) + + log.Debug().Msgf("%s: importSecurityRoles", DebugFuncCall) importSecurityRoles(out.SecurityRoles, oldkfClient) } else { if len(out.Collections) != 0 && cmd.Flag("collections").Value.String() == "true" { + log.Debug().Msgf("%s: importCollections", DebugFuncCall) importCollections(out.Collections, kfClient) } if len(out.MetadataFields) != 0 && cmd.Flag("metadata").Value.String() == "true" { + log.Debug().Msgf("%s: importMetadataFields", DebugFuncCall) importMetadataFields(out.MetadataFields, kfClient) } if len(out.IssuedCertAlerts) != 0 && cmd.Flag("issued-alerts").Value.String() == "true" { + log.Debug().Msgf("%s: importIssuedCertAlerts", DebugFuncCall) importIssuedCertAlerts(out.IssuedCertAlerts, kfClient) } if len(out.DeniedCertAlerts) != 0 && cmd.Flag("denied-alerts").Value.String() == "true" { + log.Debug().Msgf("%s: importDeniedCertAlerts", DebugFuncCall) importDeniedCertAlerts(out.DeniedCertAlerts, kfClient) } if len(out.PendingCertAlerts) != 0 && cmd.Flag("pending-alerts").Value.String() == "true" { + log.Debug().Msgf("%s: importPendingCertAlerts", DebugFuncCall) importPendingCertAlerts(out.PendingCertAlerts, kfClient) } if len(out.Networks) != 0 && cmd.Flag("networks").Value.String() == "true" { + log.Debug().Msgf("%s: importNetworks", DebugFuncCall) importNetworks(out.Networks, kfClient) } if len(out.WorkflowDefinitions) != 0 && cmd.Flag("workflow-definitions").Value.String() == "true" { + log.Debug().Msgf("%s: importWorkflowDefinitions", DebugFuncCall) importWorkflowDefinitions(out.WorkflowDefinitions, kfClient) } if len(out.BuiltInReports) != 0 && cmd.Flag("reports").Value.String() == "true" { + log.Debug().Msgf("%s: importBuiltInReports", DebugFuncCall) importBuiltInReports(out.BuiltInReports, kfClient) } if len(out.CustomReports) != 0 && cmd.Flag("reports").Value.String() == "true" { + log.Debug().Msgf("%s: importCustomReports", DebugFuncCall) importCustomReports(out.CustomReports, kfClient) } if len(out.SecurityRoles) != 0 && cmd.Flag("security-roles").Value.String() == "true" { + log.Debug().Msgf("%s: importSecurityRoles", DebugFuncCall) importSecurityRoles(out.SecurityRoles, oldkfClient) } } + log.Debug().Msgf("%s: importCmd", DebugFuncExit) + return nil }, } func importCollections(collections []keyfactor.KeyfactorApiModelsCertificateCollectionsCertificateCollectionCreateRequest, kfClient *keyfactor.APIClient) { for _, collection := range collections { - _, httpResp, reqErr := kfClient.CertificateCollectionApi.CertificateCollectionCreateCollection(context.Background()).XKeyfactorRequestedWith(XKeyfactorRequestedWith). - Request(collection).XKeyfactorApiVersion(XKeyfactorApiVersion).Execute() - name, _ := json.Marshal(collection.Name) + _, httpResp, reqErr := kfClient.CertificateCollectionApi. + CertificateCollectionCreateCollection(context.Background()). + XKeyfactorRequestedWith(XKeyfactorRequestedWith). + Request(collection). + XKeyfactorApiVersion(XKeyfactorApiVersion). + Execute() + name, jmErr := json.Marshal(collection.Name) + if jmErr != nil { + fmt.Printf("Error: %s\n", jmErr) + //log.Fatalf("Error: %s", jmErr) + log.Error().Err(jmErr).Send() + } if reqErr != nil { fmt.Printf("%s Error! Unable to create collection %s - %s%s\n", ColorRed, string(name), parseError(httpResp.Body), ColorWhite) } else { - name, _ := json.Marshal(collection.Name) - fmt.Println("Added", string(name), "to collections") + n, jnErr := json.Marshal(collection.Name) + if jnErr != nil { + fmt.Printf("Error: %s\n", jnErr) + //log.Fatalf("Error: %s", jnErr) + log.Error().Err(jnErr).Send() + } + fmt.Println("Added", string(n), "to collections") } } } @@ -135,13 +225,23 @@ func importCollections(collections []keyfactor.KeyfactorApiModelsCertificateColl func importMetadataFields(metadataFields []keyfactor.KeyfactorApiModelsMetadataFieldMetadataFieldCreateRequest, kfClient *keyfactor.APIClient) { for _, metadata := range metadataFields { _, httpResp, reqErr := kfClient.MetadataFieldApi.MetadataFieldCreateMetadataField(context.Background()). - XKeyfactorRequestedWith(XKeyfactorRequestedWith).MetadataFieldType(metadata). - XKeyfactorApiVersion(XKeyfactorApiVersion).Execute() - name, _ := json.Marshal(metadata.Name) + XKeyfactorRequestedWith(XKeyfactorRequestedWith). + MetadataFieldType(metadata). + XKeyfactorApiVersion(XKeyfactorApiVersion). + Execute() + n, jmErr := json.Marshal(metadata.Name) + if reqErr != nil { - fmt.Printf("%s Error! Unable to create metadata field type %s - %s%s\n", ColorRed, string(name), parseError(httpResp.Body), ColorWhite) + if jmErr != nil { + fmt.Printf("Error: %s\n", jmErr) + //log.Fatalf("Error: %s", jmErr) + log.Error().Err(jmErr).Send() + } + log.Error().Err(reqErr).Send() + fmt.Printf("%s Error! Unable to create metadata field type %s - %s%s\n", ColorRed, string(n), parseError(httpResp.Body), ColorWhite) } else { - fmt.Println("Added", string(name), "to metadata field types.") + log.Info().Msgf("Added %s to metadata field types.", string(n)) + fmt.Println("Added", string(n), "to metadata field types.") } } } @@ -216,18 +316,33 @@ func importWorkflowDefinitions(workflowDefs []exportKeyfactorAPIModelsWorkflowsD jErr := json.Unmarshal(wJson, &workflowDefReq) if jErr != nil { fmt.Printf("Error: %s\n", jErr) - log.Fatalf("Error: %s", jErr) + //log.Fatalf("Error: %s", jErr) + log.Error().Err(jErr).Send() } newTemplateId := findMatchingTemplates(workflowDef, kfClient) if newTemplateId != nil { workflowDefReq.Key = newTemplateId } - _, httpResp, reqErr := kfClient.WorkflowDefinitionApi.WorkflowDefinitionCreateNewDefinition(context.Background()).XKeyfactorRequestedWith(XKeyfactorRequestedWith).Request(workflowDefReq).XKeyfactorApiVersion(XKeyfactorApiVersion).Execute() - name, _ := json.Marshal(workflowDef.DisplayName) + _, httpResp, reqErr := kfClient.WorkflowDefinitionApi. // todo: Why is the object not being used? + WorkflowDefinitionCreateNewDefinition(context.Background()). + XKeyfactorRequestedWith(XKeyfactorRequestedWith). + Request(workflowDefReq). + XKeyfactorApiVersion(XKeyfactorApiVersion). + Execute() + name, jmErr := json.Marshal(workflowDef.DisplayName) + if jmErr != nil { + fmt.Printf("Error: %s\n", jmErr) + //log.Fatalf("Error: %s", jmErr) + log.Error().Err(jmErr).Send() + return + } + if reqErr != nil { fmt.Printf("%s Error! Unable to create workflow definition %s - %s%s\n", ColorRed, string(name), parseError(httpResp.Body), ColorWhite) + log.Error().Err(reqErr).Send() } else { fmt.Println("Added", string(name), "to workflow definitions.") + log.Info().Msgf("Added %s to workflow definitions.", string(name)) } } } @@ -268,15 +383,29 @@ func importBuiltInReports(reports []exportModelsReport, kfClient *keyfactor.APIC jErr := json.Unmarshal(rJson, &reportReq) if jErr != nil { fmt.Printf("Error: %s\n", jErr) - log.Fatalf("Error: %s", jErr) + //log.Fatalf("Error: %s", jErr) + log.Error().Err(jErr).Send() } reportReq.Id = newReportId - _, httpResp, reqErr := kfClient.ReportsApi.ReportsUpdateReport(context.Background()).XKeyfactorRequestedWith(XKeyfactorRequestedWith).Request(reportReq).XKeyfactorApiVersion(XKeyfactorApiVersion).Execute() - name, _ := json.Marshal(report.DisplayName) + _, httpResp, reqErr := kfClient.ReportsApi. //todo: Why is the object not being used? + ReportsUpdateReport(context.Background()). + XKeyfactorRequestedWith(XKeyfactorRequestedWith). + Request(reportReq). + XKeyfactorApiVersion(XKeyfactorApiVersion). + Execute() + name, jmErr := json.Marshal(report.DisplayName) + if jmErr != nil { + fmt.Printf("Error: %s\n", jmErr) + //log.Fatalf("Error: %s", jmErr) + log.Error().Err(jmErr).Send() + return + } if reqErr != nil { fmt.Printf("%s Error! Unable to update built-in report %s - %s%s\n", ColorRed, string(name), parseError(httpResp.Body), ColorWhite) + log.Error().Err(reqErr).Send() } else { fmt.Println("Updated", string(name), "in built-in reports.") + log.Info().Msgf("Updated %s in built-in reports.", string(name)) } } } diff --git a/cmd/pam.go b/cmd/pam.go index fb725272..2b3e6ffc 100644 --- a/cmd/pam.go +++ b/cmd/pam.go @@ -62,7 +62,10 @@ var pamTypesListCmd = &cobra.Command{ // Authenticate authConfig := createAuthConfigFromParams(kfcHostName, kfcUsername, kfcPassword, kfcDomain, kfcAPIPath) - sdkClient, _ := initGenClient(configFile, profile, noPrompt, authConfig, false) + sdkClient, clientErr := initGenClient(configFile, profile, noPrompt, authConfig, false) + if clientErr != nil { + return clientErr + } // CLI Logic log.Debug().Msg("call: PAMProviderGetPamProviderTypes()") diff --git a/cmd/pam_test.go b/cmd/pam_test.go index 2f0f6f33..689547ab 100644 --- a/cmd/pam_test.go +++ b/cmd/pam_test.go @@ -573,9 +573,18 @@ func testFormatPamCreateConfig(t *testing.T, inputFileName string, providerName // todo: for some reason calling this function mutates pConfig apiProviderType, pvtErr := testListPamProviderTypes(t, cProviderTypeName, false, false) + + if pvtErr != nil { + t.Errorf("failed to find PAM provider type '%s' unable to create PAM provider: %v", cProviderTypeName, pvtErr) + return "", pvtErr + } else if apiProviderType == nil { + t.Errorf("failed to find PAM provider type '%s' unable to create PAM provider: %v", cProviderTypeName, pvtErr) + return "", pvtErr + } + switch apiProviderType.(type) { case nil: - t.Fatalf("failed to find PAM provider type '%s' unable to create PAM provider: %v", cProviderTypeName, pvtErr) + t.Errorf("failed to find PAM provider type '%s' unable to create PAM provider: %v", cProviderTypeName, pvtErr) break case map[string]interface{}: aProviderType := apiProviderType.(map[string]interface{}) diff --git a/pkg/version/version.go b/pkg/version/version.go index 39cf4b29..c689e6b2 100644 --- a/pkg/version/version.go +++ b/pkg/version/version.go @@ -14,4 +14,4 @@ package version -const VERSION = "v1.3.1" +const VERSION = "v1.4.0" From d26d614a8ce9a8031ccb7347a77fb18520a68b66 Mon Sep 17 00:00:00 2001 From: sbailey <1661003+spbsoluble@users.noreply.github.com> Date: Wed, 14 Feb 2024 07:23:50 -0800 Subject: [PATCH 08/47] chore(deps): Bump deps Signed-off-by: sbailey <1661003+spbsoluble@users.noreply.github.com> --- cmd/pam_test.go | 3 ++- go.mod | 16 ++++++++-------- go.sum | 32 ++++++++++++++++---------------- 3 files changed, 26 insertions(+), 25 deletions(-) diff --git a/cmd/pam_test.go b/cmd/pam_test.go index 689547ab..1b92b2fc 100644 --- a/cmd/pam_test.go +++ b/cmd/pam_test.go @@ -173,7 +173,8 @@ func Test_PAMGetCmd(t *testing.T) { assert.NotEmpty(t, pamProvider.(map[string]interface{})["ProviderType"]) } } else { - t.Fatalf("0 PAM providers found, cannot test get") + t.Errorf("0 PAM providers found, cannot test get") + return } } diff --git a/go.mod b/go.mod index 068f38db..54a82e0f 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,7 @@ go 1.21 require ( github.com/AlecAivazis/survey/v2 v2.3.7 - github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.0 + github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.2 github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0 github.com/Jeffail/gabs v1.4.0 github.com/Keyfactor/keyfactor-go-client-sdk v1.0.2 @@ -12,20 +12,20 @@ require ( github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 github.com/creack/pty v1.1.21 github.com/google/go-cmp v0.6.0 - github.com/google/uuid v1.4.0 + github.com/google/uuid v1.6.0 github.com/hinshun/vt10x v0.0.0-20220301184237-5011da428d02 github.com/joho/godotenv v1.5.1 github.com/rs/zerolog v1.31.0 github.com/spf13/cobra v1.8.0 github.com/spf13/pflag v1.0.5 github.com/stretchr/testify v1.8.4 - golang.org/x/crypto v0.14.0 + golang.org/x/crypto v0.19.0 gopkg.in/yaml.v3 v3.0.1 //github.com/google/go-cmp/cmp v0.5.9 ) require ( - github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect github.com/davecgh/go-spew v1.1.1 // indirect @@ -41,8 +41,8 @@ require ( github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/spbsoluble/go-pkcs12 v0.3.3 // indirect go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352 // indirect - golang.org/x/net v0.17.0 // indirect - golang.org/x/sys v0.13.0 // indirect - golang.org/x/term v0.13.0 // indirect - golang.org/x/text v0.13.0 // indirect + golang.org/x/net v0.20.0 // indirect + golang.org/x/sys v0.17.0 // indirect + golang.org/x/term v0.17.0 // indirect + golang.org/x/text v0.14.0 // indirect ) diff --git a/go.sum b/go.sum index 3ba8f54e..8d8c391b 100644 --- a/go.sum +++ b/go.sum @@ -1,11 +1,11 @@ github.com/AlecAivazis/survey/v2 v2.3.7 h1:6I/u8FvytdGsgonrYsVn2t8t4QiRnh6QSTqkkhIiSjQ= github.com/AlecAivazis/survey/v2 v2.3.7/go.mod h1:xUTIdE4KCOIjsBAE1JYsUPoCqYdZ1reCfTwbto0Fduo= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.0 h1:fb8kj/Dh4CSwgsOzHeZY4Xh68cFVbzXx+ONXGMY//4w= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.0/go.mod h1:uReU2sSxZExRPBAg3qKzmAucSi51+SP1OhohieR821Q= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.2 h1:c4k2FIYIh4xtwqrQwV0Ct1v5+ehlNXj5NI/MWVsiTkQ= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.2/go.mod h1:5FDJtLEO/GxwNgUxbwrY3LP0pEoThTQJtk2oysdXHxM= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0 h1:BMAjVKJM0U/CYF27gA0ZMmXGkOcvfFtD0oHVZ1TIPRI= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0/go.mod h1:1fXstnBMas5kzG+S3q8UoJcmyU6nUeunJcMDHcRYHhs= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.0 h1:d81/ng9rET2YqdVkVwkb6EXeRrLJIwyGnJcAlAWKwhs= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.0/go.mod h1:s4kgfzA0covAXNicZHDMN58jExvcng2mC/DepXiF1EI= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2 h1:LqbJ/WzJUwBf8UiaSzgX7aMclParm9/5Vgp+TY51uBQ= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2/go.mod h1:yInRyqWXAuaPrgI7p70+lDDgh3mlBohis29jGMISnmc= github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1 h1:WpB/QDNLpMw72xHJc34BNNykqSOeEJDAWkhf0u12/Jk= github.com/AzureAD/microsoft-authentication-library-for-go v1.1.1/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= github.com/Jeffail/gabs v1.4.0 h1://5fYRRTq1edjfIrQGvdkcd22pkYUrHZ5YC/H2GJVAo= @@ -34,8 +34,8 @@ github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJ github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= -github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hinshun/vt10x v0.0.0-20220119200601-820417d04eec/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68= github.com/hinshun/vt10x v0.0.0-20220301184237-5011da428d02 h1:AgcIVYPa6XJnU3phs104wLj8l5GEththEw6+F79YsIY= github.com/hinshun/vt10x v0.0.0-20220301184237-5011da428d02/go.mod h1:Q48J4R4DvxnHolD5P8pOtXigYlRuPLGl6moFx3ulM68= @@ -81,14 +81,14 @@ go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352 h1:CCriYyAfq1Br1aIYettdH go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.19.0 h1:ENy+Az/9Y1vSrlrvBSyna3PITt4tiZLf7sgCjZBX7Wo= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= +golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= +golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -101,18 +101,18 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE= -golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= -golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U= +golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= From 363439c7aef82c883035cd9a16d69b179716abe7 Mon Sep 17 00:00:00 2001 From: sbailey <1661003+spbsoluble@users.noreply.github.com> Date: Wed, 14 Feb 2024 07:28:08 -0800 Subject: [PATCH 09/47] fix(tests): Adding back PAMList test Signed-off-by: sbailey <1661003+spbsoluble@users.noreply.github.com> --- cmd/pam_test.go | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/cmd/pam_test.go b/cmd/pam_test.go index 1b92b2fc..77ff1f0e 100644 --- a/cmd/pam_test.go +++ b/cmd/pam_test.go @@ -52,17 +52,17 @@ func Test_PAMHelpCmd(t *testing.T) { func Test_PAMListCmd(t *testing.T) { // list providers - //pamProviders, err := testListPamProviders(t) - //assert.NoError(t, err) - //if err != nil { - // //t.Fatalf("failed to list PAM providers: %v", err) - // t.Errorf("failed to list PAM providers: %v", err) - // return - //} - // - //if len(pamProviders) <= 0 { - // t.Fatalf("0 PAM providers found, cannot test list") - //} + pamProviders, err := testListPamProviders(t) + assert.NoError(t, err) + if err != nil { + //t.Fatalf("failed to list PAM providers: %v", err) + t.Errorf("failed to list PAM providers: %v", err) + return + } + + if len(pamProviders) <= 0 { + t.Errorf("0 PAM providers found, cannot test list") + } } func Test_PAMTypesListCmd(t *testing.T) { From dffc6753d3f53fdd9fc03c41a77ade9bc2d31e8f Mon Sep 17 00:00:00 2001 From: Keyfactor Date: Tue, 20 Feb 2024 20:34:32 +0000 Subject: [PATCH 10/47] Update store_types.json for k8s-orchestrator:remote_pam --- store_types.json | 172 +++++++++++++---------------------------------- 1 file changed, 46 insertions(+), 126 deletions(-) diff --git a/store_types.json b/store_types.json index 44345f4d..8b7cb27c 100644 --- a/store_types.json +++ b/store_types.json @@ -908,30 +908,6 @@ "DependsOn": "", "DefaultValue": "cert", "Required": true - }, - { - "Name": "ServerUsername", - "DisplayName": "Server Username", - "Type": "Secret", - "DependsOn": "", - "DefaultValue": null, - "Required": false - }, - { - "Name": "ServerPassword", - "DisplayName": "Server Password", - "Type": "Secret", - "DependsOn": "", - "DefaultValue": null, - "Required": true - }, - { - "Name": "ServerUseSsl", - "DisplayName": "Use SSL", - "Type": "Bool", - "DependsOn": "", - "DefaultValue": "true", - "Required": true } ], "EntryParameters": null, @@ -963,28 +939,18 @@ }, "Properties": [ { - "Name": "ServerUsername", - "DisplayName": "Server Username", - "Type": "Secret", - "DependsOn": "", - "DefaultValue": null, + "Name": "SeparateChain", + "DisplayName": "Separate Certificate Chain", + "Type": "Bool", + "DefaultValue": "false", "Required": false }, { - "Name": "ServerPassword", - "DisplayName": "Server Password", - "Type": "Secret", - "DependsOn": "", - "DefaultValue": null, - "Required": true - }, - { - "Name": "ServerUseSsl", - "DisplayName": "Use SSL", + "Name": "IncludeCertChain", + "DisplayName": "Include Certificate Chain", "Type": "Bool", - "DependsOn": "", "DefaultValue": "true", - "Required": true + "Required": false } ], "EntryParameters": null, @@ -1044,8 +1010,8 @@ "DisplayName": "CertificateDataFieldName", "Type": "String", "DependsOn": "", - "DefaultValue": null, - "Required": false + "DefaultValue": ".jks", + "Required": true }, { "Name": "PasswordFieldName", @@ -1133,28 +1099,18 @@ "Required": false }, { - "Name": "ServerUsername", - "DisplayName": "Server Username", - "Type": "Secret", - "DependsOn": "", - "DefaultValue": null, + "Name": "SeparateChain", + "DisplayName": "Separate Certificate Chain", + "Type": "Bool", + "DefaultValue": "false", "Required": false }, { - "Name": "ServerPassword", - "DisplayName": "Server Password", - "Type": "Secret", - "DependsOn": "", - "DefaultValue": null, - "Required": true - }, - { - "Name": "ServerUseSsl", - "DisplayName": "Use SSL", + "Name": "IncludeCertChain", + "DisplayName": "Include Certificate Chain", "Type": "Bool", - "DependsOn": "", "DefaultValue": "true", - "Required": true + "Required": false } ], "EntryParameters": null, @@ -1185,6 +1141,14 @@ "Remove": true }, "Properties": [ + { + "Name": "KubeSecretType", + "DisplayName": "Kube Secret Type", + "Type": "String", + "DependsOn": "", + "DefaultValue": "pkcs12", + "Required": true + }, { "Name": "KubeSecretKey", "DisplayName": "Kube Secret Key", @@ -1193,6 +1157,14 @@ "DefaultValue": "pfx", "Required": false }, + { + "Name": "CertificateDataFieldName", + "DisplayName": "CertificateDataFieldName", + "Type": "String", + "DependsOn": "", + "DefaultValue": ".p12", + "Required": true + }, { "Name": "PasswordFieldName", "DisplayName": "Password Field Name", @@ -1225,38 +1197,6 @@ "DefaultValue": null, "Required": false }, - { - "Name": "ServerUsername", - "DisplayName": "Server Username", - "Type": "Secret", - "DependsOn": "", - "DefaultValue": null, - "Required": false - }, - { - "Name": "ServerPassword", - "DisplayName": "Server Password", - "Type": "Secret", - "DependsOn": "", - "DefaultValue": null, - "Required": true - }, - { - "Name": "ServerUseSsl", - "DisplayName": "Use SSL", - "Type": "Bool", - "DependsOn": "", - "DefaultValue": "true", - "Required": true - }, - { - "Name": "KubeSecretType", - "DisplayName": "Kube Secret Type", - "Type": "String", - "DependsOn": "", - "DefaultValue": "pkcs12", - "Required": true - }, { "Name": "StorePasswordPath", "DisplayName": "StorePasswordPath", @@ -1319,28 +1259,18 @@ "Required": true }, { - "Name": "ServerUsername", - "DisplayName": "Server Username", - "Type": "Secret", - "DependsOn": "", - "DefaultValue": null, + "Name": "SeparateChain", + "DisplayName": "Separate Certificate Chain", + "Type": "Bool", + "DefaultValue": "false", "Required": false }, { - "Name": "ServerPassword", - "DisplayName": "Server Password", - "Type": "Secret", - "DependsOn": "", - "DefaultValue": null, - "Required": true - }, - { - "Name": "ServerUseSsl", - "DisplayName": "Use SSL", + "Name": "IncludeCertChain", + "DisplayName": "Include Certificate Chain", "Type": "Bool", - "DependsOn": "", "DefaultValue": "true", - "Required": true + "Required": false } ], "EntryParameters": null, @@ -1396,28 +1326,18 @@ "Required": true }, { - "Name": "ServerUsername", - "DisplayName": "Server Username", - "Type": "Secret", - "DependsOn": "", - "DefaultValue": null, + "Name": "SeparateChain", + "DisplayName": "Separate Certificate Chain", + "Type": "Bool", + "DefaultValue": "false", "Required": false }, { - "Name": "ServerPassword", - "DisplayName": "Server Password", - "Type": "Secret", - "DependsOn": "", - "DefaultValue": null, - "Required": true - }, - { - "Name": "ServerUseSsl", - "DisplayName": "Use SSL", + "Name": "IncludeCertChain", + "DisplayName": "Include Certificate Chain", "Type": "Bool", - "DependsOn": "", "DefaultValue": "true", - "Required": true + "Required": false } ], "EntryParameters": null, From 51ec1928705b71f686d2888a0761a45e62752ddf Mon Sep 17 00:00:00 2001 From: Keyfactor Date: Tue, 20 Feb 2024 20:35:06 +0000 Subject: [PATCH 11/47] Update generated README --- README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index d7fc1572..84c9bc37 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,25 @@ + # Keyfactor Command Utility (kfutil) `kfutil` is a go-lang CLI wrapper for Keyfactor Command API. It also includes other utility/helper functions around automating common Keyfactor Command operations. #### Integration status: Production - Ready for use in production environments. +## About the Keyfactor API Client +This API client allows for programmatic management of Keyfactor resources. ## Support for Keyfactor Command Utility (kfutil) -Keyfactor Command Utility (kfutil) is open source and there is **no SLA** for this tool/library/client. Keyfactor will address issues as resources become available. Keyfactor customers may request escalation by opening up a support ticket through their Keyfactor representative. +Keyfactor Command Utility (kfutil) is open source and supported on best effort level for this tool/library/client. This means customers can report Bugs, Feature Requests, Documentation amendment or questions as well as requests for customer information required for setup that needs Keyfactor access to obtain. Such requests do not follow normal SLA commitments for response or resolution. If you have a support issue, please open a support ticket via the Keyfactor Support Portal at https://support.keyfactor.com/ ###### To report a problem or suggest a new feature, use the **[Issues](../../issues)** tab. If you want to contribute actual bug fixes or proposed enhancements, use the **[Pull requests](../../pulls)** tab. +--- + + +--- + ## Quickstart From 2ba773f5564f9abee580fe91c8caf015123cc174 Mon Sep 17 00:00:00 2001 From: sbailey <1661003+spbsoluble@users.noreply.github.com> Date: Tue, 20 Feb 2024 13:49:47 -0800 Subject: [PATCH 12/47] chore(ci): Adding 11.2.0 lab tests Signed-off-by: sbailey <1661003+spbsoluble@users.noreply.github.com> --- .github/workflows/tests.yml | 85 ++++++++++++++++++++++ artifacts/pam/pam-create-template-v11.json | 23 ++++++ cmd/pam_test.go | 60 +++++++++------ 3 files changed, 147 insertions(+), 21 deletions(-) create mode 100644 artifacts/pam/pam-create-template-v11.json diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index d99ff580..a440fa99 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -135,6 +135,25 @@ jobs: run: echo "Running tests for KF 11.x.x" ### Store Type Tests + Test_StoreTypes_KFC_11_2_0: + runs-on: ubuntu-latest + needs: + - build + - kf_11_x_x + env: + SECRET_NAME: "command-config-1120-clean" + KEYFACTOR_HOSTNAME: "int1120-test-clean.kfdelivery.com" + KEYFACTOR_DOMAIN: "command" + KEYFACTOR_USERNAME: ${{ secrets.LAB_USERNAME }} + KEYFACTOR_PASSWORD: ${{ secrets.LAB_PASSWORD }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Run tests + run: | + unset KFUTIL_DEBUG + go test -v ./cmd -run "^Test_StoreTypes*" + Test_StoreTypes_KFC_11_1_2: runs-on: ubuntu-latest needs: @@ -154,7 +173,25 @@ jobs: unset KFUTIL_DEBUG go test -v ./cmd -run "^Test_StoreTypes*" + ### Store Tests + Test_Stores_KFC_11_2_0: + runs-on: ubuntu-latest + needs: + - build + - kf_11_x_x + - Test_StoreTypes_KFC_11_2_0 + env: + SECRET_NAME: "command-config-1120" + KEYFACTOR_HOSTNAME: "integrations1120-lab.kfdelivery.com" + KEYFACTOR_DOMAIN: "command" + KEYFACTOR_USERNAME: ${{ secrets.LAB_USERNAME }} + KEYFACTOR_PASSWORD: ${{ secrets.LAB_PASSWORD }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Run tests + run: go test -v ./cmd -run "^Test_Stores_*" Test_Stores_KFC_11_1_2: runs-on: ubuntu-latest needs: @@ -174,6 +211,27 @@ jobs: run: go test -v ./cmd -run "^Test_Stores_*" ### PAM Tests + Test_PAM_KFC_11_2_0: + runs-on: ubuntu-latest + needs: + - build + - kf_11_x_x + - Test_StoreTypes_KFC_11_2_0 + env: + SECRET_NAME: "command-config-1120" + KEYFACTOR_HOSTNAME: "integrations1120-lab.kfdelivery.com" + KEYFACTOR_DOMAIN: "command" + KEYFACTOR_USERNAME: ${{ secrets.LAB_USERNAME }} + KEYFACTOR_PASSWORD: ${{ secrets.LAB_PASSWORD }} + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Run tests + run: | + unset KFUTIL_DEBUG + go test -v ./cmd -run "^Test_PAM*" + + Test_PAM_KFC_11_1_2: runs-on: ubuntu-latest needs: @@ -196,6 +254,33 @@ jobs: ### PAM Tests AKV Auth Provider + Test_AKV_PAM_KFC_11_2_0: + runs-on: self-hosted + needs: + - Test_PAM_KFC_11_2_0 + env: + SECRET_NAME: "command-config-1120-az" + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: "1.21" + - name: Install dependencies + run: go mod download && go mod tidy + - name: Get secret from Azure Key Vault + run: | + . ./examples/auth/akv/akv_auth.sh + cat $HOME/.keyfactor/command_config.json + - name: Install kfutil + run: | + make install + - name: Run tests + run: | + go test -v ./cmd -run "^Test_PAM*" + + Test_AKV_PAM_KFC_11_1_2: runs-on: self-hosted needs: diff --git a/artifacts/pam/pam-create-template-v11.json b/artifacts/pam/pam-create-template-v11.json new file mode 100644 index 00000000..aae40df8 --- /dev/null +++ b/artifacts/pam/pam-create-template-v11.json @@ -0,0 +1,23 @@ +{ + "name": "string", + "remote": true, + "area": 0, + "services": { + "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6" + }, + "providerTypeParamValues": [ + { + "id": 0, + "value": "string", + "instanceId": 0, + "instanceGuid": "3fa85f64-5717-4562-b3fc-2c963f66afa6", + "providerTypeParam": { + "id": 0, + "name": "string", + "displayName": "string", + "instanceLevel": true + } + } + ], + "securedAreaId": 0 +} \ No newline at end of file diff --git a/cmd/pam_test.go b/cmd/pam_test.go index 77ff1f0e..c9a2cbdf 100644 --- a/cmd/pam_test.go +++ b/cmd/pam_test.go @@ -212,21 +212,22 @@ func Test_PAMCreateCmd(t *testing.T) { t.Logf("inputFileName: %s", inputFileName) invalidInputFileName := path.Join(filepath.Dir(cwd), "artifacts/pam/pam-create-invalid.json") t.Logf("invalidInputFileName: %s", invalidInputFileName) - //cProviderTypeName := "Delinea-SecretServer" - // read input file into a map[string]interface{} updatedFileName, fErr := testFormatPamCreateConfig(t, inputFileName, "", false) + t.Logf("updatedFileName: %s", updatedFileName) assert.NoError(t, fErr) if fErr != nil { - t.Fatalf("failed to format PAM provider config file '%s': %v", inputFileName, fErr) + t.Errorf("failed to format PAM provider config file '%s': %v", inputFileName, fErr) return } - // Test invalid config file + // Test valid config file createResponse, err := testCreatePamProvider(t, updatedFileName, providerName, false) assert.NoError(t, err) + assert.NotNil(t, createResponse) if err != nil { - t.Fatalf("failed to create a PAM provider: %v", err) + t.Errorf("failed to create a PAM provider: %v", err) + return } createdObject := createResponse.(map[string]interface{}) @@ -437,7 +438,11 @@ func testCreatePamProvider(t *testing.T, fileName string, providerName string, a t.Run(testName, func(t *testing.T) { testCmd := RootCmd - testCmd.SetArgs([]string{"pam", "create", "--from-file", fileName}) + args := []string{"pam", "create", "--from-file", fileName} + // log the args as a string + t.Logf("args: %s", args) + testCmd.SetArgs(args) + t.Logf("fileName: %s", fileName) output := captureOutput(func() { err = testCmd.Execute() if !allowFail { @@ -448,7 +453,7 @@ func testCreatePamProvider(t *testing.T, fileName string, providerName string, a if allowFail { t.Logf("Error unmarshalling JSON: %v", err) } else { - t.Fatalf("failed to create a PAM provider: %v", err) + t.Errorf("failed to create a PAM provider: %v", err) } return } @@ -504,7 +509,8 @@ func testListPamProviderTypes(t *testing.T, name string, allowFail bool, allowEm }) var pTypes []interface{} if err = json.Unmarshal([]byte(output), &pTypes); err != nil && !allowFail { - t.Fatalf("Error unmarshalling JSON: %v", err) + t.Errorf("Error unmarshalling JSON: %v", err) + return nil, err } // assert slice is len >= 0 @@ -558,7 +564,7 @@ func testFormatPamCreateConfig(t *testing.T, inputFileName string, providerName assert.NoError(t, pErr) if pErr != nil { - t.Fatalf("failed to load PAM provider config file '%s': %v", inputFileName, pErr) + t.Errorf("failed to load PAM provider config file '%s': %v", inputFileName, pErr) return "", pErr } @@ -584,9 +590,6 @@ func testFormatPamCreateConfig(t *testing.T, inputFileName string, providerName } switch apiProviderType.(type) { - case nil: - t.Errorf("failed to find PAM provider type '%s' unable to create PAM provider: %v", cProviderTypeName, pvtErr) - break case map[string]interface{}: aProviderType := apiProviderType.(map[string]interface{}) cProviderType["Id"] = aProviderType["Id"] @@ -594,11 +597,17 @@ func testFormatPamCreateConfig(t *testing.T, inputFileName string, providerName cProviderType["ProviderTypeParams"] = aProviderType["ProviderTypeParams"] // iterate over each param and set the ID value on cProviderTypeParamValues nameToIdMap := make(map[string]int) - for _, cParam := range cProviderType["ProviderTypeParams"].([]interface{}) { - paramId := cParam.(map[string]interface{})["Id"] - paramName := cParam.(map[string]interface{})["Name"] - nameToIdMap[paramName.(string)] = int(paramId.(float64)) + paramsFieldName := "ProviderTypeParams" + _, ok := cProviderType[paramsFieldName] + if ok && cProviderType[paramsFieldName] != nil { + t.Logf("PAM definition is v10 or earlier") + for _, cParam := range cProviderType[paramsFieldName].([]interface{}) { + paramId := cParam.(map[string]interface{})["Id"] + paramName := cParam.(map[string]interface{})["Name"] + nameToIdMap[paramName.(string)] = int(paramId.(float64)) + } } + for idx, pValue := range cProviderTypeParamValues { pValueMap := pValue.(map[string]interface{}) paramInfo := pValueMap["ProviderTypeParam"].(map[string]interface{}) @@ -606,16 +615,22 @@ func testFormatPamCreateConfig(t *testing.T, inputFileName string, providerName pValueMap["ProviderTypeParam"] = paramInfo cProviderTypeParamValues[idx] = pValueMap } - break default: - t.Fatalf("failed to find PAM provider type '%s' unable to create PAM provider: %v", cProviderTypeName, pvtErr) + oErr := pvtErr + if oErr == nil { + oErr = fmt.Errorf("failed to find PAM provider type '%s' unable to create PAM provider", cProviderTypeName) + } else { + oErr = fmt.Errorf("failed to find PAM provider type '%s' unable to create PAM provider: %v", cProviderTypeName, oErr) + } + t.Error(oErr) + return "", oErr } // reload the config file because it was mutated pConfig, pErr = loadJSONFile(inputFileName) assert.NoError(t, pErr) if pErr != nil { - t.Fatalf("failed to load PAM provider config file '%s': %v", inputFileName, pErr) + t.Errorf("failed to load PAM provider config file '%s': %v", inputFileName, pErr) return "", pErr } @@ -629,6 +644,7 @@ func testFormatPamCreateConfig(t *testing.T, inputFileName string, providerName if isUpdate { // list providers + t.Logf("listing PAM providers for update") providersList, err := testListPamProviders(t) assert.NoError(t, err) if err != nil { @@ -647,7 +663,9 @@ func testFormatPamCreateConfig(t *testing.T, inputFileName string, providerName } } } else { - t.Fatalf("0 PAM providers found, cannot test delete") + dErr := fmt.Errorf("0 PAM providers found, cannot test update") + t.Error(dErr) + return "", dErr } } @@ -656,7 +674,7 @@ func testFormatPamCreateConfig(t *testing.T, inputFileName string, providerName updatedFileName := strings.Replace(inputFileName, "-template.json", ".json", 1) wErr := writeJSONFile(updatedFileName, pConfig) if wErr != nil { - t.Fatalf("failed to write updated PAM provider config file '%s': %v", inputFileName, wErr) + t.Errorf("failed to write updated PAM provider config file '%s': %v", inputFileName, wErr) return "", wErr } return updatedFileName, nil From 6560ecb743e230d5196a8ee75d1fd13636844cd3 Mon Sep 17 00:00:00 2001 From: sbailey <1661003+spbsoluble@users.noreply.github.com> Date: Wed, 21 Feb 2024 09:19:55 -0800 Subject: [PATCH 13/47] fix(tests): PAM test null pointer check Signed-off-by: sbailey <1661003+spbsoluble@users.noreply.github.com> --- cmd/pam_test.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/cmd/pam_test.go b/cmd/pam_test.go index c9a2cbdf..c377376a 100644 --- a/cmd/pam_test.go +++ b/cmd/pam_test.go @@ -300,6 +300,18 @@ func Test_PAMUpdateCmd(t *testing.T) { if err := json.Unmarshal([]byte(output), &updateResponse); err != nil { t.Fatalf("Error unmarshalling JSON: %v", err) } + assert.NotNil(t, updateResponse) + if updateResponse == nil { + t.Errorf("failed to update a PAM provider") + return + } + // check that updateResponse is a map[string]interface{} + + _, ok := updateResponse.(map[string]interface{}) + if !ok { + t.Errorf("updateResponse is not a map[string]interface{}") + return + } assert.NotEmpty(t, updateResponse.(map[string]interface{})["Id"]) assert.NotEmpty(t, updateResponse.(map[string]interface{})["Name"]) assert.Equal(t, updateResponse.(map[string]interface{})["Name"], providerName) From 5abb0d9636cb1f545c8a6597af0ea83e97761403 Mon Sep 17 00:00:00 2001 From: sbailey <1661003+spbsoluble@users.noreply.github.com> Date: Wed, 21 Feb 2024 11:55:55 -0800 Subject: [PATCH 14/47] chore(deps): Bump go client version Signed-off-by: sbailey <1661003+spbsoluble@users.noreply.github.com> --- cmd/stores_test.go | 5 +++++ go.mod | 2 +- go.sum | 4 ++-- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/cmd/stores_test.go b/cmd/stores_test.go index 0b6356d7..5848c740 100644 --- a/cmd/stores_test.go +++ b/cmd/stores_test.go @@ -154,7 +154,12 @@ func Test_Stores_ImportCmd(t *testing.T) { csvData, csvErr := csvToMap(f) assert.Nil(t, csvErr) assert.NotEmpty(t, csvData) + assert.Greater(t, len(csvData), 0) var modifiedCSVData []map[string]string + if len(csvData) == 0 { + t.Errorf("No data in file %s", f) + return + } for _, row := range csvData { // assert that each row has an ID assert.NotEmpty(t, row["Id"]) diff --git a/go.mod b/go.mod index 54a82e0f..eeaf7315 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0 github.com/Jeffail/gabs v1.4.0 github.com/Keyfactor/keyfactor-go-client-sdk v1.0.2 - github.com/Keyfactor/keyfactor-go-client/v2 v2.2.6 + github.com/Keyfactor/keyfactor-go-client/v2 v2.2.7 github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 github.com/creack/pty v1.1.21 github.com/google/go-cmp v0.6.0 diff --git a/go.sum b/go.sum index 8d8c391b..f0537dc1 100644 --- a/go.sum +++ b/go.sum @@ -14,8 +14,8 @@ github.com/Keyfactor/keyfactor-go-client v1.4.3 h1:CmGvWcuIbDRFM0PfYOQH6UdtAgplv github.com/Keyfactor/keyfactor-go-client v1.4.3/go.mod h1:3ZymLNCaSazglcuYeNfm9nrzn22wcwLjIWURrnUygBo= github.com/Keyfactor/keyfactor-go-client-sdk v1.0.2 h1:caLlzFCz2L4Dth/9wh+VlypFATmOMmCSQkCPKOKMxw8= github.com/Keyfactor/keyfactor-go-client-sdk v1.0.2/go.mod h1:Z5pSk8YFGXHbKeQ1wTzVN8A4P/fZmtAwqu3NgBHbDOs= -github.com/Keyfactor/keyfactor-go-client/v2 v2.2.6 h1:LQ6M0VKAhOZ7I/nNWC0Mfy+QVEE6YPZpjbnbi65oLw8= -github.com/Keyfactor/keyfactor-go-client/v2 v2.2.6/go.mod h1:3mfxdcwntB532QIATokBEkBCH0eXN2G/cdMZtu9NwNg= +github.com/Keyfactor/keyfactor-go-client/v2 v2.2.7 h1:fHZF5lDEWKQEI8QOPeseG/y9Bd4h2DhOiUWkNx+rKJU= +github.com/Keyfactor/keyfactor-go-client/v2 v2.2.7/go.mod h1:3mfxdcwntB532QIATokBEkBCH0eXN2G/cdMZtu9NwNg= github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2 h1:+vx7roKuyA63nhn5WAunQHLTznkw5W8b1Xc0dNjp83s= github.com/Netflix/go-expect v0.0.0-20220104043353-73e0943537d2/go.mod h1:HBCaDeC1lPdgDeDbhX8XFpy1jqjK0IBG8W5K+xYqA0w= github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= From 7163658cb4c7486112f63a86ad9c30ed2f2432c8 Mon Sep 17 00:00:00 2001 From: sbailey <1661003+spbsoluble@users.noreply.github.com> Date: Wed, 21 Feb 2024 11:59:24 -0800 Subject: [PATCH 15/47] chore(docs): Update docs Signed-off-by: sbailey <1661003+spbsoluble@users.noreply.github.com> --- docs/kfutil.md | 3 +- docs/kfutil_containers.md | 2 +- docs/kfutil_containers_get.md | 2 +- docs/kfutil_containers_list.md | 2 +- docs/kfutil_export.md | 2 +- docs/kfutil_helm.md | 2 +- docs/kfutil_helm_uo.md | 2 +- docs/kfutil_import.md | 2 +- docs/kfutil_login.md | 31 ++++++++++++++----- docs/kfutil_logout.md | 2 +- docs/kfutil_orchs.md | 2 +- docs/kfutil_orchs_approve.md | 2 +- docs/kfutil_orchs_disapprove.md | 2 +- docs/kfutil_orchs_ext.md | 2 +- docs/kfutil_orchs_get.md | 2 +- docs/kfutil_orchs_list.md | 2 +- docs/kfutil_orchs_logs.md | 2 +- docs/kfutil_orchs_reset.md | 2 +- docs/kfutil_pam.md | 2 +- docs/kfutil_pam_create.md | 2 +- docs/kfutil_pam_delete.md | 2 +- docs/kfutil_pam_get.md | 2 +- docs/kfutil_pam_list.md | 2 +- docs/kfutil_pam_types-create.md | 2 +- docs/kfutil_pam_types-list.md | 2 +- docs/kfutil_pam_update.md | 2 +- docs/kfutil_status.md | 2 +- docs/kfutil_store-types.md | 2 +- docs/kfutil_store-types_create.md | 2 +- docs/kfutil_store-types_delete.md | 2 +- docs/kfutil_store-types_get.md | 4 +-- docs/kfutil_store-types_list.md | 2 +- docs/kfutil_store-types_templates-fetch.md | 2 +- docs/kfutil_stores.md | 2 +- docs/kfutil_stores_delete.md | 2 +- docs/kfutil_stores_export.md | 2 +- docs/kfutil_stores_get.md | 2 +- docs/kfutil_stores_import.md | 2 +- docs/kfutil_stores_import_csv.md | 2 +- .../kfutil_stores_import_generate-template.md | 2 +- docs/kfutil_stores_inventory.md | 2 +- docs/kfutil_stores_inventory_add.md | 2 +- docs/kfutil_stores_inventory_remove.md | 2 +- docs/kfutil_stores_inventory_show.md | 2 +- docs/kfutil_stores_list.md | 2 +- docs/kfutil_stores_rot.md | 2 +- docs/kfutil_stores_rot_audit.md | 2 +- docs/kfutil_stores_rot_generate-template.md | 2 +- docs/kfutil_stores_rot_reconcile.md | 2 +- docs/kfutil_version.md | 2 +- 50 files changed, 75 insertions(+), 57 deletions(-) diff --git a/docs/kfutil.md b/docs/kfutil.md index 17dc9ed9..ab848670 100644 --- a/docs/kfutil.md +++ b/docs/kfutil.md @@ -32,6 +32,7 @@ A CLI wrapper around the Keyfactor Platform API. * [kfutil export](kfutil_export.md) - Keyfactor instance export utilities. * [kfutil helm](kfutil_helm.md) - Helm utilities for configuring Keyfactor Helm charts * [kfutil import](kfutil_import.md) - Keyfactor instance import utilities. +* [kfutil login](kfutil_login.md) - User interactive login to Keyfactor. Stores the credentials in the config file '$HOME/.keyfactor/command_config.json'. * [kfutil logout](kfutil_logout.md) - Removes the credentials file '$HOME/.keyfactor/command_config.json'. * [kfutil orchs](kfutil_orchs.md) - Keyfactor agents/orchestrators APIs and utilities. * [kfutil pam](kfutil_pam.md) - Keyfactor PAM Provider APIs. @@ -40,4 +41,4 @@ A CLI wrapper around the Keyfactor Platform API. * [kfutil stores](kfutil_stores.md) - Keyfactor certificate stores APIs and utilities. * [kfutil version](kfutil_version.md) - Shows version of kfutil -###### Auto generated by spf13/cobra on 9-Nov-2023 +###### Auto generated by spf13/cobra on 21-Feb-2024 diff --git a/docs/kfutil_containers.md b/docs/kfutil_containers.md index 18ba1df9..428553a0 100644 --- a/docs/kfutil_containers.md +++ b/docs/kfutil_containers.md @@ -37,4 +37,4 @@ A collections of APIs and utilities for interacting with Keyfactor certificate s * [kfutil containers get](kfutil_containers_get.md) - Get certificate store container by ID or name. * [kfutil containers list](kfutil_containers_list.md) - List certificate store containers. -###### Auto generated by spf13/cobra on 9-Nov-2023 +###### Auto generated by spf13/cobra on 21-Feb-2024 diff --git a/docs/kfutil_containers_get.md b/docs/kfutil_containers_get.md index ee747164..4daf90a9 100644 --- a/docs/kfutil_containers_get.md +++ b/docs/kfutil_containers_get.md @@ -40,4 +40,4 @@ kfutil containers get [flags] * [kfutil containers](kfutil_containers.md) - Keyfactor certificate store container API and utilities. -###### Auto generated by spf13/cobra on 9-Nov-2023 +###### Auto generated by spf13/cobra on 21-Feb-2024 diff --git a/docs/kfutil_containers_list.md b/docs/kfutil_containers_list.md index 49553aa7..e0b2c24b 100644 --- a/docs/kfutil_containers_list.md +++ b/docs/kfutil_containers_list.md @@ -39,4 +39,4 @@ kfutil containers list [flags] * [kfutil containers](kfutil_containers.md) - Keyfactor certificate store container API and utilities. -###### Auto generated by spf13/cobra on 9-Nov-2023 +###### Auto generated by spf13/cobra on 21-Feb-2024 diff --git a/docs/kfutil_export.md b/docs/kfutil_export.md index 856a683b..0ce6878c 100644 --- a/docs/kfutil_export.md +++ b/docs/kfutil_export.md @@ -51,4 +51,4 @@ kfutil export [flags] * [kfutil](kfutil.md) - Keyfactor CLI utilities -###### Auto generated by spf13/cobra on 9-Nov-2023 +###### Auto generated by spf13/cobra on 21-Feb-2024 diff --git a/docs/kfutil_helm.md b/docs/kfutil_helm.md index 6f0c7c1d..3c2d68e8 100644 --- a/docs/kfutil_helm.md +++ b/docs/kfutil_helm.md @@ -42,4 +42,4 @@ kubectl helm uo | helm install -f - keyfactor-universal-orchestrator keyfactor/k * [kfutil](kfutil.md) - Keyfactor CLI utilities * [kfutil helm uo](kfutil_helm_uo.md) - Configure the Keyfactor Universal Orchestrator Helm Chart -###### Auto generated by spf13/cobra on 9-Nov-2023 +###### Auto generated by spf13/cobra on 21-Feb-2024 diff --git a/docs/kfutil_helm_uo.md b/docs/kfutil_helm_uo.md index 37984b38..92c9c828 100644 --- a/docs/kfutil_helm_uo.md +++ b/docs/kfutil_helm_uo.md @@ -46,4 +46,4 @@ kfutil helm uo [-t ] [-o ] [-f ] [-e -e @,@ -o ./app/extension * [kfutil orchs](kfutil_orchs.md) - Keyfactor agents/orchestrators APIs and utilities. -###### Auto generated by spf13/cobra on 9-Nov-2023 +###### Auto generated by spf13/cobra on 21-Feb-2024 diff --git a/docs/kfutil_orchs_get.md b/docs/kfutil_orchs_get.md index df00c3dc..32065931 100644 --- a/docs/kfutil_orchs_get.md +++ b/docs/kfutil_orchs_get.md @@ -40,4 +40,4 @@ kfutil orchs get [flags] * [kfutil orchs](kfutil_orchs.md) - Keyfactor agents/orchestrators APIs and utilities. -###### Auto generated by spf13/cobra on 9-Nov-2023 +###### Auto generated by spf13/cobra on 21-Feb-2024 diff --git a/docs/kfutil_orchs_list.md b/docs/kfutil_orchs_list.md index 82bc7bb8..24436cb4 100644 --- a/docs/kfutil_orchs_list.md +++ b/docs/kfutil_orchs_list.md @@ -39,4 +39,4 @@ kfutil orchs list [flags] * [kfutil orchs](kfutil_orchs.md) - Keyfactor agents/orchestrators APIs and utilities. -###### Auto generated by spf13/cobra on 9-Nov-2023 +###### Auto generated by spf13/cobra on 21-Feb-2024 diff --git a/docs/kfutil_orchs_logs.md b/docs/kfutil_orchs_logs.md index 9f5d37ec..a2e1462b 100644 --- a/docs/kfutil_orchs_logs.md +++ b/docs/kfutil_orchs_logs.md @@ -40,4 +40,4 @@ kfutil orchs logs [flags] * [kfutil orchs](kfutil_orchs.md) - Keyfactor agents/orchestrators APIs and utilities. -###### Auto generated by spf13/cobra on 9-Nov-2023 +###### Auto generated by spf13/cobra on 21-Feb-2024 diff --git a/docs/kfutil_orchs_reset.md b/docs/kfutil_orchs_reset.md index adb3545f..612ba71c 100644 --- a/docs/kfutil_orchs_reset.md +++ b/docs/kfutil_orchs_reset.md @@ -40,4 +40,4 @@ kfutil orchs reset [flags] * [kfutil orchs](kfutil_orchs.md) - Keyfactor agents/orchestrators APIs and utilities. -###### Auto generated by spf13/cobra on 9-Nov-2023 +###### Auto generated by spf13/cobra on 21-Feb-2024 diff --git a/docs/kfutil_pam.md b/docs/kfutil_pam.md index c48fe7fd..14b54c98 100644 --- a/docs/kfutil_pam.md +++ b/docs/kfutil_pam.md @@ -44,4 +44,4 @@ programmatically create, delete, edit, and list PAM Providers. * [kfutil pam types-list](kfutil_pam_types-list.md) - Returns a list of all available PAM provider types. * [kfutil pam update](kfutil_pam_update.md) - Updates an existing PAM Provider, currently only supported from file. -###### Auto generated by spf13/cobra on 9-Nov-2023 +###### Auto generated by spf13/cobra on 21-Feb-2024 diff --git a/docs/kfutil_pam_create.md b/docs/kfutil_pam_create.md index 0c385a48..ae797e62 100644 --- a/docs/kfutil_pam_create.md +++ b/docs/kfutil_pam_create.md @@ -40,4 +40,4 @@ kfutil pam create [flags] * [kfutil pam](kfutil_pam.md) - Keyfactor PAM Provider APIs. -###### Auto generated by spf13/cobra on 9-Nov-2023 +###### Auto generated by spf13/cobra on 21-Feb-2024 diff --git a/docs/kfutil_pam_delete.md b/docs/kfutil_pam_delete.md index d9336fe6..caa952ed 100644 --- a/docs/kfutil_pam_delete.md +++ b/docs/kfutil_pam_delete.md @@ -40,4 +40,4 @@ kfutil pam delete [flags] * [kfutil pam](kfutil_pam.md) - Keyfactor PAM Provider APIs. -###### Auto generated by spf13/cobra on 9-Nov-2023 +###### Auto generated by spf13/cobra on 21-Feb-2024 diff --git a/docs/kfutil_pam_get.md b/docs/kfutil_pam_get.md index f5c6f1ff..6f7d3feb 100644 --- a/docs/kfutil_pam_get.md +++ b/docs/kfutil_pam_get.md @@ -40,4 +40,4 @@ kfutil pam get [flags] * [kfutil pam](kfutil_pam.md) - Keyfactor PAM Provider APIs. -###### Auto generated by spf13/cobra on 9-Nov-2023 +###### Auto generated by spf13/cobra on 21-Feb-2024 diff --git a/docs/kfutil_pam_list.md b/docs/kfutil_pam_list.md index 4586851d..7b46c2f4 100644 --- a/docs/kfutil_pam_list.md +++ b/docs/kfutil_pam_list.md @@ -39,4 +39,4 @@ kfutil pam list [flags] * [kfutil pam](kfutil_pam.md) - Keyfactor PAM Provider APIs. -###### Auto generated by spf13/cobra on 9-Nov-2023 +###### Auto generated by spf13/cobra on 21-Feb-2024 diff --git a/docs/kfutil_pam_types-create.md b/docs/kfutil_pam_types-create.md index cbe1e168..8d1954d3 100644 --- a/docs/kfutil_pam_types-create.md +++ b/docs/kfutil_pam_types-create.md @@ -47,4 +47,4 @@ kfutil pam types-create [flags] * [kfutil pam](kfutil_pam.md) - Keyfactor PAM Provider APIs. -###### Auto generated by spf13/cobra on 9-Nov-2023 +###### Auto generated by spf13/cobra on 21-Feb-2024 diff --git a/docs/kfutil_pam_types-list.md b/docs/kfutil_pam_types-list.md index 16bc1caf..c0098223 100644 --- a/docs/kfutil_pam_types-list.md +++ b/docs/kfutil_pam_types-list.md @@ -39,4 +39,4 @@ kfutil pam types-list [flags] * [kfutil pam](kfutil_pam.md) - Keyfactor PAM Provider APIs. -###### Auto generated by spf13/cobra on 9-Nov-2023 +###### Auto generated by spf13/cobra on 21-Feb-2024 diff --git a/docs/kfutil_pam_update.md b/docs/kfutil_pam_update.md index 71e2e327..afd320cd 100644 --- a/docs/kfutil_pam_update.md +++ b/docs/kfutil_pam_update.md @@ -40,4 +40,4 @@ kfutil pam update [flags] * [kfutil pam](kfutil_pam.md) - Keyfactor PAM Provider APIs. -###### Auto generated by spf13/cobra on 9-Nov-2023 +###### Auto generated by spf13/cobra on 21-Feb-2024 diff --git a/docs/kfutil_status.md b/docs/kfutil_status.md index 6a343e99..82a659ac 100644 --- a/docs/kfutil_status.md +++ b/docs/kfutil_status.md @@ -39,4 +39,4 @@ kfutil status [flags] * [kfutil](kfutil.md) - Keyfactor CLI utilities -###### Auto generated by spf13/cobra on 9-Nov-2023 +###### Auto generated by spf13/cobra on 21-Feb-2024 diff --git a/docs/kfutil_store-types.md b/docs/kfutil_store-types.md index 573c6876..f5901a72 100644 --- a/docs/kfutil_store-types.md +++ b/docs/kfutil_store-types.md @@ -40,4 +40,4 @@ A collections of APIs and utilities for interacting with Keyfactor certificate s * [kfutil store-types list](kfutil_store-types_list.md) - List certificate store types. * [kfutil store-types templates-fetch](kfutil_store-types_templates-fetch.md) - Fetches store type templates from Keyfactor's Github. -###### Auto generated by spf13/cobra on 9-Nov-2023 +###### Auto generated by spf13/cobra on 21-Feb-2024 diff --git a/docs/kfutil_store-types_create.md b/docs/kfutil_store-types_create.md index 27271162..b6c169c7 100644 --- a/docs/kfutil_store-types_create.md +++ b/docs/kfutil_store-types_create.md @@ -44,4 +44,4 @@ kfutil store-types create [flags] * [kfutil store-types](kfutil_store-types.md) - Keyfactor certificate store types APIs and utilities. -###### Auto generated by spf13/cobra on 9-Nov-2023 +###### Auto generated by spf13/cobra on 21-Feb-2024 diff --git a/docs/kfutil_store-types_delete.md b/docs/kfutil_store-types_delete.md index d22e7e99..30d7f4e8 100644 --- a/docs/kfutil_store-types_delete.md +++ b/docs/kfutil_store-types_delete.md @@ -43,4 +43,4 @@ kfutil store-types delete [flags] * [kfutil store-types](kfutil_store-types.md) - Keyfactor certificate store types APIs and utilities. -###### Auto generated by spf13/cobra on 9-Nov-2023 +###### Auto generated by spf13/cobra on 21-Feb-2024 diff --git a/docs/kfutil_store-types_get.md b/docs/kfutil_store-types_get.md index 37158fe3..834a293b 100644 --- a/docs/kfutil_store-types_get.md +++ b/docs/kfutil_store-types_get.md @@ -7,7 +7,7 @@ Get a specific store type by either name or ID. Get a specific store type by either name or ID. ``` -kfutil store-types get [-i | -n ] [-g] [-b ] [-o] [flags] +kfutil store-types get [-i | -n ] [-b ] [-g | --output-to-integration-manifest] [flags] ``` ### Options @@ -44,4 +44,4 @@ kfutil store-types get [-i | -n ] [-g] [-b --store-type-id --store-t * [kfutil stores import](kfutil_stores_import.md) - Import a file with certificate store parameters and create them in keyfactor. -###### Auto generated by spf13/cobra on 9-Nov-2023 +###### Auto generated by spf13/cobra on 21-Feb-2024 diff --git a/docs/kfutil_stores_inventory.md b/docs/kfutil_stores_inventory.md index 7eba8517..ed3786a3 100644 --- a/docs/kfutil_stores_inventory.md +++ b/docs/kfutil_stores_inventory.md @@ -38,4 +38,4 @@ Commands related to certificate store inventory management * [kfutil stores inventory remove](kfutil_stores_inventory_remove.md) - Removes a certificate from the certificate store inventory. * [kfutil stores inventory show](kfutil_stores_inventory_show.md) - Show the inventory of a certificate store. -###### Auto generated by spf13/cobra on 9-Nov-2023 +###### Auto generated by spf13/cobra on 21-Feb-2024 diff --git a/docs/kfutil_stores_inventory_add.md b/docs/kfutil_stores_inventory_add.md index 0bfe3003..a84111df 100644 --- a/docs/kfutil_stores_inventory_add.md +++ b/docs/kfutil_stores_inventory_add.md @@ -53,4 +53,4 @@ kfutil stores inventory add [flags] * [kfutil stores inventory](kfutil_stores_inventory.md) - Commands related to certificate store inventory management -###### Auto generated by spf13/cobra on 9-Nov-2023 +###### Auto generated by spf13/cobra on 21-Feb-2024 diff --git a/docs/kfutil_stores_inventory_remove.md b/docs/kfutil_stores_inventory_remove.md index 0bfffc3f..bf749ede 100644 --- a/docs/kfutil_stores_inventory_remove.md +++ b/docs/kfutil_stores_inventory_remove.md @@ -49,4 +49,4 @@ kfutil stores inventory remove [flags] * [kfutil stores inventory](kfutil_stores_inventory.md) - Commands related to certificate store inventory management -###### Auto generated by spf13/cobra on 9-Nov-2023 +###### Auto generated by spf13/cobra on 21-Feb-2024 diff --git a/docs/kfutil_stores_inventory_show.md b/docs/kfutil_stores_inventory_show.md index 5888bfd1..f8089283 100644 --- a/docs/kfutil_stores_inventory_show.md +++ b/docs/kfutil_stores_inventory_show.md @@ -43,4 +43,4 @@ kfutil stores inventory show [flags] * [kfutil stores inventory](kfutil_stores_inventory.md) - Commands related to certificate store inventory management -###### Auto generated by spf13/cobra on 9-Nov-2023 +###### Auto generated by spf13/cobra on 21-Feb-2024 diff --git a/docs/kfutil_stores_list.md b/docs/kfutil_stores_list.md index e23c6d6f..d7b2745f 100644 --- a/docs/kfutil_stores_list.md +++ b/docs/kfutil_stores_list.md @@ -39,4 +39,4 @@ kfutil stores list [flags] * [kfutil stores](kfutil_stores.md) - Keyfactor certificate stores APIs and utilities. -###### Auto generated by spf13/cobra on 9-Nov-2023 +###### Auto generated by spf13/cobra on 21-Feb-2024 diff --git a/docs/kfutil_stores_rot.md b/docs/kfutil_stores_rot.md index d103ae8e..dd5c516d 100644 --- a/docs/kfutil_stores_rot.md +++ b/docs/kfutil_stores_rot.md @@ -50,4 +50,4 @@ kfutil stores rot reconcile --import-csv * [kfutil stores rot generate-template](kfutil_stores_rot_generate-template.md) - For generating Root Of Trust template(s) * [kfutil stores rot reconcile](kfutil_stores_rot_reconcile.md) - Reconcile either takes in or will generate an audit report and then add/remove certs as needed. -###### Auto generated by spf13/cobra on 9-Nov-2023 +###### Auto generated by spf13/cobra on 21-Feb-2024 diff --git a/docs/kfutil_stores_rot_audit.md b/docs/kfutil_stores_rot_audit.md index 278edb0f..2a41ecc6 100644 --- a/docs/kfutil_stores_rot_audit.md +++ b/docs/kfutil_stores_rot_audit.md @@ -47,4 +47,4 @@ kfutil stores rot audit [flags] * [kfutil stores rot](kfutil_stores_rot.md) - Root of trust utility -###### Auto generated by spf13/cobra on 9-Nov-2023 +###### Auto generated by spf13/cobra on 21-Feb-2024 diff --git a/docs/kfutil_stores_rot_generate-template.md b/docs/kfutil_stores_rot_generate-template.md index bc023773..82c86ca0 100644 --- a/docs/kfutil_stores_rot_generate-template.md +++ b/docs/kfutil_stores_rot_generate-template.md @@ -45,4 +45,4 @@ kfutil stores rot generate-template [flags] * [kfutil stores rot](kfutil_stores_rot.md) - Root of trust utility -###### Auto generated by spf13/cobra on 9-Nov-2023 +###### Auto generated by spf13/cobra on 21-Feb-2024 diff --git a/docs/kfutil_stores_rot_reconcile.md b/docs/kfutil_stores_rot_reconcile.md index a5e17e1f..d44bf647 100644 --- a/docs/kfutil_stores_rot_reconcile.md +++ b/docs/kfutil_stores_rot_reconcile.md @@ -52,4 +52,4 @@ kfutil stores rot reconcile [flags] * [kfutil stores rot](kfutil_stores_rot.md) - Root of trust utility -###### Auto generated by spf13/cobra on 9-Nov-2023 +###### Auto generated by spf13/cobra on 21-Feb-2024 diff --git a/docs/kfutil_version.md b/docs/kfutil_version.md index d9da81ae..cc2bfae3 100644 --- a/docs/kfutil_version.md +++ b/docs/kfutil_version.md @@ -39,4 +39,4 @@ kfutil version [flags] * [kfutil](kfutil.md) - Keyfactor CLI utilities -###### Auto generated by spf13/cobra on 9-Nov-2023 +###### Auto generated by spf13/cobra on 21-Feb-2024 From 876aaed40a7819c9309636b4bd53165bd16bc0f2 Mon Sep 17 00:00:00 2001 From: Keyfactor Robot Date: Wed, 21 Feb 2024 20:31:28 +0000 Subject: [PATCH 16/47] Bump package version to 1.4.0-rc.5 --- pkg/version/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/version/version.go b/pkg/version/version.go index 2ec357fd..b3e381f7 100644 --- a/pkg/version/version.go +++ b/pkg/version/version.go @@ -14,4 +14,4 @@ package version -const VERSION = "v1.4.0" \ No newline at end of file +const VERSION = "1.4.0-rc.5" \ No newline at end of file From 0086811f80434033107435a3d926b61f2d45d11f Mon Sep 17 00:00:00 2001 From: sbailey <1661003+spbsoluble@users.noreply.github.com> Date: Mon, 26 Feb 2024 08:52:13 -0800 Subject: [PATCH 17/47] chore(docs): Update docs Signed-off-by: sbailey <1661003+spbsoluble@users.noreply.github.com> --- CHANGELOG.md | 15 +++ cmd/login.go | 2 +- cmd/storesBulkOperations.go | 10 +- cmd/stores_test.go | 27 +++++- docs/kfutil.md | 2 +- docs/kfutil_containers.md | 2 +- docs/kfutil_containers_get.md | 2 +- docs/kfutil_containers_list.md | 2 +- docs/kfutil_export.md | 2 +- docs/kfutil_helm.md | 2 +- docs/kfutil_helm_uo.md | 2 +- docs/kfutil_import.md | 2 +- docs/kfutil_login.md | 2 +- docs/kfutil_logout.md | 2 +- docs/kfutil_orchs.md | 2 +- docs/kfutil_orchs_approve.md | 2 +- docs/kfutil_orchs_disapprove.md | 2 +- docs/kfutil_orchs_ext.md | 2 +- docs/kfutil_orchs_get.md | 2 +- docs/kfutil_orchs_list.md | 2 +- docs/kfutil_orchs_logs.md | 2 +- docs/kfutil_orchs_reset.md | 2 +- docs/kfutil_pam.md | 2 +- docs/kfutil_pam_create.md | 2 +- docs/kfutil_pam_delete.md | 2 +- docs/kfutil_pam_get.md | 2 +- docs/kfutil_pam_list.md | 2 +- docs/kfutil_pam_types-create.md | 2 +- docs/kfutil_pam_types-list.md | 2 +- docs/kfutil_pam_update.md | 2 +- docs/kfutil_status.md | 2 +- docs/kfutil_store-types.md | 2 +- docs/kfutil_store-types_create.md | 2 +- docs/kfutil_store-types_delete.md | 2 +- docs/kfutil_store-types_get.md | 2 +- docs/kfutil_store-types_list.md | 2 +- docs/kfutil_store-types_templates-fetch.md | 2 +- docs/kfutil_stores.md | 2 +- docs/kfutil_stores_delete.md | 2 +- docs/kfutil_stores_export.md | 2 +- docs/kfutil_stores_get.md | 2 +- docs/kfutil_stores_import.md | 2 +- docs/kfutil_stores_import_csv.md | 2 +- .../kfutil_stores_import_generate-template.md | 2 +- docs/kfutil_stores_inventory.md | 2 +- docs/kfutil_stores_inventory_add.md | 2 +- docs/kfutil_stores_inventory_remove.md | 2 +- docs/kfutil_stores_inventory_show.md | 2 +- docs/kfutil_stores_list.md | 2 +- docs/kfutil_stores_rot.md | 2 +- docs/kfutil_stores_rot_audit.md | 2 +- docs/kfutil_stores_rot_generate-template.md | 2 +- docs/kfutil_stores_rot_reconcile.md | 2 +- docs/kfutil_version.md | 2 +- .../cert_stores/bulk_export_import/README.md | 3 + .../cert_stores/bulk_export_import/example.sh | 95 +++++++++++++++++++ 56 files changed, 197 insertions(+), 55 deletions(-) create mode 100644 examples/cert_stores/bulk_export_import/README.md create mode 100755 examples/cert_stores/bulk_export_import/example.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index 4168c445..f0d59c0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,18 @@ +# v1.4.0 +## Features +- `stores import generate-template`: New sub CLI to generate a CSV template for bulk importing stores. [See docs](docs/kfutil_stores_import_generate-template.md)` + +## Fixes +- Various null pointer references when nothing and/or empty inputs/responses are received. +- Installer script checksum check now validates properly. #119 +- `stores import` sub CLI is now listed and documented #71 + +### Store Types +- Empty `storepath` values are no longer passed to the API. #56 + +### PAM Types +- Handle duplicate provider type that is already created without crashing. #139 + # v1.3.2 ### Package diff --git a/cmd/login.go b/cmd/login.go index 1db8e956..527c7867 100644 --- a/cmd/login.go +++ b/cmd/login.go @@ -301,7 +301,7 @@ func handleInteractiveError(err error, parameterName string) error { if err != nil { if err.Error() != "unexpected newline" { log.Error().Err(err) - outputError(fmt.Errorf("error handling parmeter '%s'=%v", parameterName, err), false, "") + outputError(fmt.Errorf("error handling parameter '%s'=%v", parameterName, err), false, "") //log.Println(fmt.Sprintf("[ERROR] %s", errMsg)) return err } diff --git a/cmd/storesBulkOperations.go b/cmd/storesBulkOperations.go index f30fa987..76530037 100644 --- a/cmd/storesBulkOperations.go +++ b/cmd/storesBulkOperations.go @@ -286,7 +286,7 @@ Store type IDs can be found by running the "store-types" command.`, } // expEnabled checks - isExperimental := true + isExperimental := false debugErr := warnExperimentalFeature(expEnabled, isExperimental) if debugErr != nil { return debugErr @@ -295,7 +295,11 @@ Store type IDs can be found by running the "store-types" command.`, // Authenticate authConfig := createAuthConfigFromParams(kfcHostName, kfcUsername, kfcPassword, kfcDomain, kfcAPIPath) - kfClient, _ := initClient(configFile, profile, "", "", noPrompt, authConfig, false) + kfClient, clientErr := initClient(configFile, profile, "", "", noPrompt, authConfig, false) + if clientErr != nil { + log.Error().Err(clientErr).Msg("Error initializing client") + return clientErr + } // CLI Logic log.Info().Msg("Generating template for certificate stores") @@ -330,7 +334,7 @@ Store type IDs can be found by running the "store-types" command.`, log.Debug().Str("filePath", filePath).Msg("Writing template file") var csvContent [][]string - row := make([]string, len(csvHeaders)) + var row []string log.Debug().Msg("Writing header row") for k, v := range csvHeaders { diff --git a/cmd/stores_test.go b/cmd/stores_test.go index 5848c740..281cdffd 100644 --- a/cmd/stores_test.go +++ b/cmd/stores_test.go @@ -233,10 +233,14 @@ func Test_Stores_ExportCmd(t *testing.T) { func Test_Stores_GenerateImportTemplateCmd(t *testing.T) { testCmd := RootCmd // test - testCmd.SetArgs([]string{"stores", "import", "generate-template", "--store-type-name", "k8ssecret", "--exp"}) + testCmd.SetArgs([]string{"stores", "import", "generate-template", "--store-type-name", "k8ssecret"}) output := captureOutput(func() { err := testCmd.Execute() assert.NoError(t, err) + if err != nil { + t.Errorf("Error: %v", err) + return + } }) assert.Contains(t, output, "Template file for store type with id") @@ -248,8 +252,10 @@ func Test_Stores_GenerateImportTemplateCmd(t *testing.T) { // get last element in outputSplit outfileName := outputSplit[len(outputSplit)-1] + t.Logf("outfileName: %s", outfileName) // remove newline from outfileName outfileName = strings.Replace(outfileName, "\n", "", 1) + t.Logf("formattedOutfileName: %s", outfileName) assert.NotEmpty(t, outfileName) assert.Contains(t, outfileName, "csv") @@ -257,16 +263,32 @@ func Test_Stores_GenerateImportTemplateCmd(t *testing.T) { // Verify f exists _, err := os.Stat(outfileName) assert.NoError(t, err) + if err != nil { + t.Errorf("File %s does not exist", outfileName) + return + } // Verify f is not empty f, err := os.Open(outfileName) assert.NoError(t, err) assert.NotNil(t, f) + if err != nil { + t.Errorf("File %s does not exist", outfileName) + return + } // Verify f has content fileInfo, err := f.Stat() assert.NoError(t, err) assert.NotNil(t, fileInfo) + if err != nil { + t.Errorf("File %s does not exist", outfileName) + return + } + if fileInfo == nil { + t.Errorf("File %s is empty", outfileName) + return + } assert.NotZero(t, fileInfo.Size()) // Verify f is a csv @@ -356,6 +378,9 @@ func deleteStoreTest(t *testing.T, storeID string, allowFail bool) { func testValidateCSVHeader(t *testing.T, filename string, header []string, expected []string) { // iterate bulkStoreImportCSVHeader and verify that each header is in the csv header t.Run(fmt.Sprintf("Validate CSV header %s", filename), func(t *testing.T) { + // Check that first col isn't empty + assert.NotEmpty(t, header[0], "First column of CSV is empty") + for _, h := range expected { if h != "Properties" { assert.Contains(t, header, h) diff --git a/docs/kfutil.md b/docs/kfutil.md index ab848670..70d814d0 100644 --- a/docs/kfutil.md +++ b/docs/kfutil.md @@ -41,4 +41,4 @@ A CLI wrapper around the Keyfactor Platform API. * [kfutil stores](kfutil_stores.md) - Keyfactor certificate stores APIs and utilities. * [kfutil version](kfutil_version.md) - Shows version of kfutil -###### Auto generated by spf13/cobra on 21-Feb-2024 +###### Auto generated by spf13/cobra on 26-Feb-2024 diff --git a/docs/kfutil_containers.md b/docs/kfutil_containers.md index 428553a0..83821c8b 100644 --- a/docs/kfutil_containers.md +++ b/docs/kfutil_containers.md @@ -37,4 +37,4 @@ A collections of APIs and utilities for interacting with Keyfactor certificate s * [kfutil containers get](kfutil_containers_get.md) - Get certificate store container by ID or name. * [kfutil containers list](kfutil_containers_list.md) - List certificate store containers. -###### Auto generated by spf13/cobra on 21-Feb-2024 +###### Auto generated by spf13/cobra on 26-Feb-2024 diff --git a/docs/kfutil_containers_get.md b/docs/kfutil_containers_get.md index 4daf90a9..6d0fa667 100644 --- a/docs/kfutil_containers_get.md +++ b/docs/kfutil_containers_get.md @@ -40,4 +40,4 @@ kfutil containers get [flags] * [kfutil containers](kfutil_containers.md) - Keyfactor certificate store container API and utilities. -###### Auto generated by spf13/cobra on 21-Feb-2024 +###### Auto generated by spf13/cobra on 26-Feb-2024 diff --git a/docs/kfutil_containers_list.md b/docs/kfutil_containers_list.md index e0b2c24b..e4d2c99e 100644 --- a/docs/kfutil_containers_list.md +++ b/docs/kfutil_containers_list.md @@ -39,4 +39,4 @@ kfutil containers list [flags] * [kfutil containers](kfutil_containers.md) - Keyfactor certificate store container API and utilities. -###### Auto generated by spf13/cobra on 21-Feb-2024 +###### Auto generated by spf13/cobra on 26-Feb-2024 diff --git a/docs/kfutil_export.md b/docs/kfutil_export.md index 0ce6878c..547772e2 100644 --- a/docs/kfutil_export.md +++ b/docs/kfutil_export.md @@ -51,4 +51,4 @@ kfutil export [flags] * [kfutil](kfutil.md) - Keyfactor CLI utilities -###### Auto generated by spf13/cobra on 21-Feb-2024 +###### Auto generated by spf13/cobra on 26-Feb-2024 diff --git a/docs/kfutil_helm.md b/docs/kfutil_helm.md index 3c2d68e8..c8097b31 100644 --- a/docs/kfutil_helm.md +++ b/docs/kfutil_helm.md @@ -42,4 +42,4 @@ kubectl helm uo | helm install -f - keyfactor-universal-orchestrator keyfactor/k * [kfutil](kfutil.md) - Keyfactor CLI utilities * [kfutil helm uo](kfutil_helm_uo.md) - Configure the Keyfactor Universal Orchestrator Helm Chart -###### Auto generated by spf13/cobra on 21-Feb-2024 +###### Auto generated by spf13/cobra on 26-Feb-2024 diff --git a/docs/kfutil_helm_uo.md b/docs/kfutil_helm_uo.md index 92c9c828..5443f725 100644 --- a/docs/kfutil_helm_uo.md +++ b/docs/kfutil_helm_uo.md @@ -46,4 +46,4 @@ kfutil helm uo [-t ] [-o ] [-f ] [-e -e @,@ -o ./app/extension * [kfutil orchs](kfutil_orchs.md) - Keyfactor agents/orchestrators APIs and utilities. -###### Auto generated by spf13/cobra on 21-Feb-2024 +###### Auto generated by spf13/cobra on 26-Feb-2024 diff --git a/docs/kfutil_orchs_get.md b/docs/kfutil_orchs_get.md index 32065931..029acc1e 100644 --- a/docs/kfutil_orchs_get.md +++ b/docs/kfutil_orchs_get.md @@ -40,4 +40,4 @@ kfutil orchs get [flags] * [kfutil orchs](kfutil_orchs.md) - Keyfactor agents/orchestrators APIs and utilities. -###### Auto generated by spf13/cobra on 21-Feb-2024 +###### Auto generated by spf13/cobra on 26-Feb-2024 diff --git a/docs/kfutil_orchs_list.md b/docs/kfutil_orchs_list.md index 24436cb4..47a6e04c 100644 --- a/docs/kfutil_orchs_list.md +++ b/docs/kfutil_orchs_list.md @@ -39,4 +39,4 @@ kfutil orchs list [flags] * [kfutil orchs](kfutil_orchs.md) - Keyfactor agents/orchestrators APIs and utilities. -###### Auto generated by spf13/cobra on 21-Feb-2024 +###### Auto generated by spf13/cobra on 26-Feb-2024 diff --git a/docs/kfutil_orchs_logs.md b/docs/kfutil_orchs_logs.md index a2e1462b..a748288e 100644 --- a/docs/kfutil_orchs_logs.md +++ b/docs/kfutil_orchs_logs.md @@ -40,4 +40,4 @@ kfutil orchs logs [flags] * [kfutil orchs](kfutil_orchs.md) - Keyfactor agents/orchestrators APIs and utilities. -###### Auto generated by spf13/cobra on 21-Feb-2024 +###### Auto generated by spf13/cobra on 26-Feb-2024 diff --git a/docs/kfutil_orchs_reset.md b/docs/kfutil_orchs_reset.md index 612ba71c..c4ae28c6 100644 --- a/docs/kfutil_orchs_reset.md +++ b/docs/kfutil_orchs_reset.md @@ -40,4 +40,4 @@ kfutil orchs reset [flags] * [kfutil orchs](kfutil_orchs.md) - Keyfactor agents/orchestrators APIs and utilities. -###### Auto generated by spf13/cobra on 21-Feb-2024 +###### Auto generated by spf13/cobra on 26-Feb-2024 diff --git a/docs/kfutil_pam.md b/docs/kfutil_pam.md index 14b54c98..8e8bd319 100644 --- a/docs/kfutil_pam.md +++ b/docs/kfutil_pam.md @@ -44,4 +44,4 @@ programmatically create, delete, edit, and list PAM Providers. * [kfutil pam types-list](kfutil_pam_types-list.md) - Returns a list of all available PAM provider types. * [kfutil pam update](kfutil_pam_update.md) - Updates an existing PAM Provider, currently only supported from file. -###### Auto generated by spf13/cobra on 21-Feb-2024 +###### Auto generated by spf13/cobra on 26-Feb-2024 diff --git a/docs/kfutil_pam_create.md b/docs/kfutil_pam_create.md index ae797e62..a478ba40 100644 --- a/docs/kfutil_pam_create.md +++ b/docs/kfutil_pam_create.md @@ -40,4 +40,4 @@ kfutil pam create [flags] * [kfutil pam](kfutil_pam.md) - Keyfactor PAM Provider APIs. -###### Auto generated by spf13/cobra on 21-Feb-2024 +###### Auto generated by spf13/cobra on 26-Feb-2024 diff --git a/docs/kfutil_pam_delete.md b/docs/kfutil_pam_delete.md index caa952ed..ea9fd85b 100644 --- a/docs/kfutil_pam_delete.md +++ b/docs/kfutil_pam_delete.md @@ -40,4 +40,4 @@ kfutil pam delete [flags] * [kfutil pam](kfutil_pam.md) - Keyfactor PAM Provider APIs. -###### Auto generated by spf13/cobra on 21-Feb-2024 +###### Auto generated by spf13/cobra on 26-Feb-2024 diff --git a/docs/kfutil_pam_get.md b/docs/kfutil_pam_get.md index 6f7d3feb..d4966a7c 100644 --- a/docs/kfutil_pam_get.md +++ b/docs/kfutil_pam_get.md @@ -40,4 +40,4 @@ kfutil pam get [flags] * [kfutil pam](kfutil_pam.md) - Keyfactor PAM Provider APIs. -###### Auto generated by spf13/cobra on 21-Feb-2024 +###### Auto generated by spf13/cobra on 26-Feb-2024 diff --git a/docs/kfutil_pam_list.md b/docs/kfutil_pam_list.md index 7b46c2f4..9e4eeb3d 100644 --- a/docs/kfutil_pam_list.md +++ b/docs/kfutil_pam_list.md @@ -39,4 +39,4 @@ kfutil pam list [flags] * [kfutil pam](kfutil_pam.md) - Keyfactor PAM Provider APIs. -###### Auto generated by spf13/cobra on 21-Feb-2024 +###### Auto generated by spf13/cobra on 26-Feb-2024 diff --git a/docs/kfutil_pam_types-create.md b/docs/kfutil_pam_types-create.md index 8d1954d3..3dc8d5ef 100644 --- a/docs/kfutil_pam_types-create.md +++ b/docs/kfutil_pam_types-create.md @@ -47,4 +47,4 @@ kfutil pam types-create [flags] * [kfutil pam](kfutil_pam.md) - Keyfactor PAM Provider APIs. -###### Auto generated by spf13/cobra on 21-Feb-2024 +###### Auto generated by spf13/cobra on 26-Feb-2024 diff --git a/docs/kfutil_pam_types-list.md b/docs/kfutil_pam_types-list.md index c0098223..f6ef8589 100644 --- a/docs/kfutil_pam_types-list.md +++ b/docs/kfutil_pam_types-list.md @@ -39,4 +39,4 @@ kfutil pam types-list [flags] * [kfutil pam](kfutil_pam.md) - Keyfactor PAM Provider APIs. -###### Auto generated by spf13/cobra on 21-Feb-2024 +###### Auto generated by spf13/cobra on 26-Feb-2024 diff --git a/docs/kfutil_pam_update.md b/docs/kfutil_pam_update.md index afd320cd..d954e0c9 100644 --- a/docs/kfutil_pam_update.md +++ b/docs/kfutil_pam_update.md @@ -40,4 +40,4 @@ kfutil pam update [flags] * [kfutil pam](kfutil_pam.md) - Keyfactor PAM Provider APIs. -###### Auto generated by spf13/cobra on 21-Feb-2024 +###### Auto generated by spf13/cobra on 26-Feb-2024 diff --git a/docs/kfutil_status.md b/docs/kfutil_status.md index 82a659ac..783291f6 100644 --- a/docs/kfutil_status.md +++ b/docs/kfutil_status.md @@ -39,4 +39,4 @@ kfutil status [flags] * [kfutil](kfutil.md) - Keyfactor CLI utilities -###### Auto generated by spf13/cobra on 21-Feb-2024 +###### Auto generated by spf13/cobra on 26-Feb-2024 diff --git a/docs/kfutil_store-types.md b/docs/kfutil_store-types.md index f5901a72..68445bf7 100644 --- a/docs/kfutil_store-types.md +++ b/docs/kfutil_store-types.md @@ -40,4 +40,4 @@ A collections of APIs and utilities for interacting with Keyfactor certificate s * [kfutil store-types list](kfutil_store-types_list.md) - List certificate store types. * [kfutil store-types templates-fetch](kfutil_store-types_templates-fetch.md) - Fetches store type templates from Keyfactor's Github. -###### Auto generated by spf13/cobra on 21-Feb-2024 +###### Auto generated by spf13/cobra on 26-Feb-2024 diff --git a/docs/kfutil_store-types_create.md b/docs/kfutil_store-types_create.md index b6c169c7..ff68dabc 100644 --- a/docs/kfutil_store-types_create.md +++ b/docs/kfutil_store-types_create.md @@ -44,4 +44,4 @@ kfutil store-types create [flags] * [kfutil store-types](kfutil_store-types.md) - Keyfactor certificate store types APIs and utilities. -###### Auto generated by spf13/cobra on 21-Feb-2024 +###### Auto generated by spf13/cobra on 26-Feb-2024 diff --git a/docs/kfutil_store-types_delete.md b/docs/kfutil_store-types_delete.md index 30d7f4e8..9c6d2233 100644 --- a/docs/kfutil_store-types_delete.md +++ b/docs/kfutil_store-types_delete.md @@ -43,4 +43,4 @@ kfutil store-types delete [flags] * [kfutil store-types](kfutil_store-types.md) - Keyfactor certificate store types APIs and utilities. -###### Auto generated by spf13/cobra on 21-Feb-2024 +###### Auto generated by spf13/cobra on 26-Feb-2024 diff --git a/docs/kfutil_store-types_get.md b/docs/kfutil_store-types_get.md index 834a293b..19fb0dd0 100644 --- a/docs/kfutil_store-types_get.md +++ b/docs/kfutil_store-types_get.md @@ -44,4 +44,4 @@ kfutil store-types get [-i | -n ] [-b * [kfutil store-types](kfutil_store-types.md) - Keyfactor certificate store types APIs and utilities. -###### Auto generated by spf13/cobra on 21-Feb-2024 +###### Auto generated by spf13/cobra on 26-Feb-2024 diff --git a/docs/kfutil_store-types_list.md b/docs/kfutil_store-types_list.md index 99cf3bf7..afe6e33d 100644 --- a/docs/kfutil_store-types_list.md +++ b/docs/kfutil_store-types_list.md @@ -39,4 +39,4 @@ kfutil store-types list [flags] * [kfutil store-types](kfutil_store-types.md) - Keyfactor certificate store types APIs and utilities. -###### Auto generated by spf13/cobra on 21-Feb-2024 +###### Auto generated by spf13/cobra on 26-Feb-2024 diff --git a/docs/kfutil_store-types_templates-fetch.md b/docs/kfutil_store-types_templates-fetch.md index a8267284..a8a453d7 100644 --- a/docs/kfutil_store-types_templates-fetch.md +++ b/docs/kfutil_store-types_templates-fetch.md @@ -40,4 +40,4 @@ kfutil store-types templates-fetch [flags] * [kfutil store-types](kfutil_store-types.md) - Keyfactor certificate store types APIs and utilities. -###### Auto generated by spf13/cobra on 21-Feb-2024 +###### Auto generated by spf13/cobra on 26-Feb-2024 diff --git a/docs/kfutil_stores.md b/docs/kfutil_stores.md index 062b59c4..0ff7e8f0 100644 --- a/docs/kfutil_stores.md +++ b/docs/kfutil_stores.md @@ -42,4 +42,4 @@ A collections of APIs and utilities for interacting with Keyfactor certificate s * [kfutil stores list](kfutil_stores_list.md) - List certificate stores. * [kfutil stores rot](kfutil_stores_rot.md) - Root of trust utility -###### Auto generated by spf13/cobra on 21-Feb-2024 +###### Auto generated by spf13/cobra on 26-Feb-2024 diff --git a/docs/kfutil_stores_delete.md b/docs/kfutil_stores_delete.md index 7281736a..879d2a3a 100644 --- a/docs/kfutil_stores_delete.md +++ b/docs/kfutil_stores_delete.md @@ -41,4 +41,4 @@ kfutil stores delete [flags] * [kfutil stores](kfutil_stores.md) - Keyfactor certificate stores APIs and utilities. -###### Auto generated by spf13/cobra on 21-Feb-2024 +###### Auto generated by spf13/cobra on 26-Feb-2024 diff --git a/docs/kfutil_stores_export.md b/docs/kfutil_stores_export.md index 1c9c12a8..7ed91b07 100644 --- a/docs/kfutil_stores_export.md +++ b/docs/kfutil_stores_export.md @@ -42,4 +42,4 @@ kfutil stores export [flags] * [kfutil stores](kfutil_stores.md) - Keyfactor certificate stores APIs and utilities. -###### Auto generated by spf13/cobra on 21-Feb-2024 +###### Auto generated by spf13/cobra on 26-Feb-2024 diff --git a/docs/kfutil_stores_get.md b/docs/kfutil_stores_get.md index d0b180e9..dc1fd2f4 100644 --- a/docs/kfutil_stores_get.md +++ b/docs/kfutil_stores_get.md @@ -40,4 +40,4 @@ kfutil stores get [flags] * [kfutil stores](kfutil_stores.md) - Keyfactor certificate stores APIs and utilities. -###### Auto generated by spf13/cobra on 21-Feb-2024 +###### Auto generated by spf13/cobra on 26-Feb-2024 diff --git a/docs/kfutil_stores_import.md b/docs/kfutil_stores_import.md index 09b869c0..ab52bf04 100644 --- a/docs/kfutil_stores_import.md +++ b/docs/kfutil_stores_import.md @@ -37,4 +37,4 @@ Tools for generating import templates and importing certificate stores * [kfutil stores import csv](kfutil_stores_import_csv.md) - Create certificate stores from CSV file. * [kfutil stores import generate-template](kfutil_stores_import_generate-template.md) - For generating a CSV template with headers for bulk store creation. -###### Auto generated by spf13/cobra on 21-Feb-2024 +###### Auto generated by spf13/cobra on 26-Feb-2024 diff --git a/docs/kfutil_stores_import_csv.md b/docs/kfutil_stores_import_csv.md index 21b4c458..7f98c367 100644 --- a/docs/kfutil_stores_import_csv.md +++ b/docs/kfutil_stores_import_csv.md @@ -47,4 +47,4 @@ kfutil stores import csv --file --store-type-id --store-t * [kfutil stores import](kfutil_stores_import.md) - Import a file with certificate store parameters and create them in keyfactor. -###### Auto generated by spf13/cobra on 21-Feb-2024 +###### Auto generated by spf13/cobra on 26-Feb-2024 diff --git a/docs/kfutil_stores_inventory.md b/docs/kfutil_stores_inventory.md index ed3786a3..838702f7 100644 --- a/docs/kfutil_stores_inventory.md +++ b/docs/kfutil_stores_inventory.md @@ -38,4 +38,4 @@ Commands related to certificate store inventory management * [kfutil stores inventory remove](kfutil_stores_inventory_remove.md) - Removes a certificate from the certificate store inventory. * [kfutil stores inventory show](kfutil_stores_inventory_show.md) - Show the inventory of a certificate store. -###### Auto generated by spf13/cobra on 21-Feb-2024 +###### Auto generated by spf13/cobra on 26-Feb-2024 diff --git a/docs/kfutil_stores_inventory_add.md b/docs/kfutil_stores_inventory_add.md index a84111df..05f95f10 100644 --- a/docs/kfutil_stores_inventory_add.md +++ b/docs/kfutil_stores_inventory_add.md @@ -53,4 +53,4 @@ kfutil stores inventory add [flags] * [kfutil stores inventory](kfutil_stores_inventory.md) - Commands related to certificate store inventory management -###### Auto generated by spf13/cobra on 21-Feb-2024 +###### Auto generated by spf13/cobra on 26-Feb-2024 diff --git a/docs/kfutil_stores_inventory_remove.md b/docs/kfutil_stores_inventory_remove.md index bf749ede..93b79626 100644 --- a/docs/kfutil_stores_inventory_remove.md +++ b/docs/kfutil_stores_inventory_remove.md @@ -49,4 +49,4 @@ kfutil stores inventory remove [flags] * [kfutil stores inventory](kfutil_stores_inventory.md) - Commands related to certificate store inventory management -###### Auto generated by spf13/cobra on 21-Feb-2024 +###### Auto generated by spf13/cobra on 26-Feb-2024 diff --git a/docs/kfutil_stores_inventory_show.md b/docs/kfutil_stores_inventory_show.md index f8089283..c3a578f4 100644 --- a/docs/kfutil_stores_inventory_show.md +++ b/docs/kfutil_stores_inventory_show.md @@ -43,4 +43,4 @@ kfutil stores inventory show [flags] * [kfutil stores inventory](kfutil_stores_inventory.md) - Commands related to certificate store inventory management -###### Auto generated by spf13/cobra on 21-Feb-2024 +###### Auto generated by spf13/cobra on 26-Feb-2024 diff --git a/docs/kfutil_stores_list.md b/docs/kfutil_stores_list.md index d7b2745f..23627167 100644 --- a/docs/kfutil_stores_list.md +++ b/docs/kfutil_stores_list.md @@ -39,4 +39,4 @@ kfutil stores list [flags] * [kfutil stores](kfutil_stores.md) - Keyfactor certificate stores APIs and utilities. -###### Auto generated by spf13/cobra on 21-Feb-2024 +###### Auto generated by spf13/cobra on 26-Feb-2024 diff --git a/docs/kfutil_stores_rot.md b/docs/kfutil_stores_rot.md index dd5c516d..65a029bd 100644 --- a/docs/kfutil_stores_rot.md +++ b/docs/kfutil_stores_rot.md @@ -50,4 +50,4 @@ kfutil stores rot reconcile --import-csv * [kfutil stores rot generate-template](kfutil_stores_rot_generate-template.md) - For generating Root Of Trust template(s) * [kfutil stores rot reconcile](kfutil_stores_rot_reconcile.md) - Reconcile either takes in or will generate an audit report and then add/remove certs as needed. -###### Auto generated by spf13/cobra on 21-Feb-2024 +###### Auto generated by spf13/cobra on 26-Feb-2024 diff --git a/docs/kfutil_stores_rot_audit.md b/docs/kfutil_stores_rot_audit.md index 2a41ecc6..59dee834 100644 --- a/docs/kfutil_stores_rot_audit.md +++ b/docs/kfutil_stores_rot_audit.md @@ -47,4 +47,4 @@ kfutil stores rot audit [flags] * [kfutil stores rot](kfutil_stores_rot.md) - Root of trust utility -###### Auto generated by spf13/cobra on 21-Feb-2024 +###### Auto generated by spf13/cobra on 26-Feb-2024 diff --git a/docs/kfutil_stores_rot_generate-template.md b/docs/kfutil_stores_rot_generate-template.md index 82c86ca0..b649bb32 100644 --- a/docs/kfutil_stores_rot_generate-template.md +++ b/docs/kfutil_stores_rot_generate-template.md @@ -45,4 +45,4 @@ kfutil stores rot generate-template [flags] * [kfutil stores rot](kfutil_stores_rot.md) - Root of trust utility -###### Auto generated by spf13/cobra on 21-Feb-2024 +###### Auto generated by spf13/cobra on 26-Feb-2024 diff --git a/docs/kfutil_stores_rot_reconcile.md b/docs/kfutil_stores_rot_reconcile.md index d44bf647..db332235 100644 --- a/docs/kfutil_stores_rot_reconcile.md +++ b/docs/kfutil_stores_rot_reconcile.md @@ -52,4 +52,4 @@ kfutil stores rot reconcile [flags] * [kfutil stores rot](kfutil_stores_rot.md) - Root of trust utility -###### Auto generated by spf13/cobra on 21-Feb-2024 +###### Auto generated by spf13/cobra on 26-Feb-2024 diff --git a/docs/kfutil_version.md b/docs/kfutil_version.md index cc2bfae3..571af296 100644 --- a/docs/kfutil_version.md +++ b/docs/kfutil_version.md @@ -39,4 +39,4 @@ kfutil version [flags] * [kfutil](kfutil.md) - Keyfactor CLI utilities -###### Auto generated by spf13/cobra on 21-Feb-2024 +###### Auto generated by spf13/cobra on 26-Feb-2024 diff --git a/examples/cert_stores/bulk_export_import/README.md b/examples/cert_stores/bulk_export_import/README.md new file mode 100644 index 00000000..e955b7c6 --- /dev/null +++ b/examples/cert_stores/bulk_export_import/README.md @@ -0,0 +1,3 @@ +# Keyfactor Command Bulk Certificate Store Operations +This will demo how to use `kfutil` + diff --git a/examples/cert_stores/bulk_export_import/example.sh b/examples/cert_stores/bulk_export_import/example.sh new file mode 100755 index 00000000..49cf76cc --- /dev/null +++ b/examples/cert_stores/bulk_export_import/example.sh @@ -0,0 +1,95 @@ +#!/usr/bin/env bash +set -e -o pipefail + +function prompt_user() { + echo "This script will install kfutil and generate a store template." + read -p "Do you want to continue? (y/n) " -n 1 -r + echo + if [[ ! $REPLY =~ ^[Yy]$ ]]; then + echo "Exiting..." + exit 1 + fi + + install_kfutil + + # Prompt to create a new certificate store type + read -p "Do you want to create a new certificate store type? (y/n) " -n 1 -r + echo + if [[ $REPLY =~ ^[Yy]$ ]]; then + kfutil store-types create + echo "Please (re)register and approve an orchestrator that supports this newly created store type and rerun this script." + exit 1 + fi + + list_stores + generate_store_template + +} + +function list_stores() { + echo "Checking that at least one certificate store exists to export..." + echo kfutil stores list + # Check if output was [] or if there was exit code non-zero + if [[ $(kfutil stores list) -ne 0 || $(kfutil stores list) == "[]" ]]; then + echo "No certificate stores found. At least one is required to export." + exit 1 + fi + kfutil stores list + return +} + +function install_kfutil() { + # Check if `kfutil` is installed + if command -v kfutil &> /dev/null; then + echo "kfutil is installed" + kfutil version + echo + return + else + bash <(curl -s https://raw.githubusercontent.com/Keyfactor/kfutil/main/install.sh) + fi +} + +function generate_store_template() { + local store_type_id="$1" + local store_type_name="$2" + local outpath="$3" + command_str="kfutil stores import generate-template" + + # If neither store_type_id nor store_type_name is provided, exit + if [[ -z "$store_type_id" && -z "$store_type_name" ]]; then + # Prompt for an ID or name + read -p "Please provide a store type ID or name: " store_type_id + # Check if input is a number + if [[ $store_type_id =~ ^[0-9]+$ ]]; then + # If input is a number, use it as store_type_id + store_type_name="" + # append store_type_id to command_str + command_str="$command_str --store-type-id $store_type_id" + else + store_type_name="$store_type_id" + # append store_type_name to command_str + command_str="$command_str --store-type-name $store_type_name" + fi + fi + + # If outpath is not provided, check for environment variable + if [[ -z "$outpath" ]]; then + if [[ -z "$KFUTIL_STORE_TEMPLATE_PATH" ]]; then + echo "Template file will be saved to the current working directory." + else + # append environment variable to command_str + command_str="$command_str --outpath $KFUTIL_STORE_TEMPLATE_PATH" + fi + else + # append outpath to command_str + command_str="$command_str --outpath $outpath" + fi + echo "Generating store template file" + echo + echo "$command_str" + eval "$command_str" +} + +prompt_user + From dc403c6dc5a2f5668e86c144a0a3128a87b66406 Mon Sep 17 00:00:00 2001 From: Keyfactor Robot Date: Mon, 26 Feb 2024 16:54:15 +0000 Subject: [PATCH 18/47] Bump package version to 1.4.0-rc.8 --- pkg/version/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/version/version.go b/pkg/version/version.go index b3e381f7..dc0a11a2 100644 --- a/pkg/version/version.go +++ b/pkg/version/version.go @@ -14,4 +14,4 @@ package version -const VERSION = "1.4.0-rc.5" \ No newline at end of file +const VERSION = "1.4.0-rc.8" \ No newline at end of file From 0aaac4b821a0900428986939dfe53812a35f700f Mon Sep 17 00:00:00 2001 From: sbailey <1661003+spbsoluble@users.noreply.github.com> Date: Mon, 26 Feb 2024 08:55:28 -0800 Subject: [PATCH 19/47] chore(docs): Update docs Signed-off-by: sbailey <1661003+spbsoluble@users.noreply.github.com> --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f0d59c0a..f5cd9acd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # v1.4.0 ## Features -- `stores import generate-template`: New sub CLI to generate a CSV template for bulk importing stores. [See docs](docs/kfutil_stores_import_generate-template.md)` +- `stores import generate-template`: Sub CLI is now non-experimental. Generate a CSV template for bulk importing certificate stores. [See docs](docs/kfutil_stores_import_generate-template.md)` ## Fixes - Various null pointer references when nothing and/or empty inputs/responses are received. From ad676357eb6cfb4f25d1a965675d4b4a2a568650 Mon Sep 17 00:00:00 2001 From: Keyfactor Robot Date: Mon, 26 Feb 2024 16:56:22 +0000 Subject: [PATCH 20/47] Bump package version to 1.4.0-rc.9 --- pkg/version/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/version/version.go b/pkg/version/version.go index dc0a11a2..f1dfbcc2 100644 --- a/pkg/version/version.go +++ b/pkg/version/version.go @@ -14,4 +14,4 @@ package version -const VERSION = "1.4.0-rc.8" \ No newline at end of file +const VERSION = "1.4.0-rc.9" \ No newline at end of file From 6a5c8e8a9e95cf75f9b0ace9b74d310e1df42a9c Mon Sep 17 00:00:00 2001 From: sbailey <1661003+spbsoluble@users.noreply.github.com> Date: Tue, 27 Feb 2024 10:10:01 -0800 Subject: [PATCH 21/47] WIP Signed-off-by: sbailey <1661003+spbsoluble@users.noreply.github.com> --- README.md | 23 ++++- cmd/storesBulkOperations.go | 91 +++++++++++++++---- .../cert_stores/bulk_export_import/README.md | 57 +++++++++++- pkg/version/version.go | 2 +- 4 files changed, 151 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 84c9bc37..5687d86d 100644 --- a/README.md +++ b/README.md @@ -144,23 +144,38 @@ This will attempt to process a CSV input file of certificate stores to create. T running: `kfutil stores import generate-template` command. ```bash -kfutil stores import create --file --store-type-id --store-type-name --results-path --dry-run [flags] +kfutil stores import csv --file ``` ```bash -kfutil stores import --help -Tool for generating import templates and importing certificate stores +kfutil stores import --help +Tools for generating import templates and importing certificate stores Usage: kfutil stores import [command] Available Commands: - create Create certificate stores + csv Create certificate stores from CSV file. generate-template For generating a CSV template with headers for bulk store creation. Flags: -h, --help help for import +Global Flags: + --api-path string API Path to use for authenticating to Keyfactor Command. (default is KeyfactorAPI) (default "KeyfactorAPI") + --auth-provider-profile string The profile to use defined in the securely stored config. If not specified the config named 'default' will be used if it exists. (default "default") + --auth-provider-type string Provider type choices: (azid) + --config string Full path to config file in JSON format. (default is $HOME/.keyfactor/command_config.json) + --debug Enable debugFlag logging. + --domain string Domain to use for authenticating to Keyfactor Command. + --exp Enable expEnabled features. (USE AT YOUR OWN RISK, these features are not supported and may change or be removed at any time.) + --format text How to format the CLI output. Currently only text is supported. (default "text") + --hostname string Hostname to use for authenticating to Keyfactor Command. + --no-prompt Do not prompt for any user input and assume defaults or environmental variables are set. + --password string Password to use for authenticating to Keyfactor Command. WARNING: Remember to delete your console history if providing kfcPassword here in plain text. + --profile string Use a specific profile from your config file. If not specified the config named 'default' will be used if it exists. + --username string Username to use for authenticating to Keyfactor Command. + Use "kfutil stores import [command] --help" for more information about a command. ``` diff --git a/cmd/storesBulkOperations.go b/cmd/storesBulkOperations.go index 76530037..36e7639f 100644 --- a/cmd/storesBulkOperations.go +++ b/cmd/storesBulkOperations.go @@ -19,6 +19,7 @@ import ( "encoding/csv" "encoding/json" "fmt" + "github.com/AlecAivazis/survey/v2" "github.com/Jeffail/gabs" "github.com/Keyfactor/keyfactor-go-client/v2/api" "github.com/rs/zerolog/log" @@ -280,9 +281,11 @@ Store type IDs can be found by running the "store-types" command.`, storeTypeID, _ := cmd.Flags().GetInt("store-type-id") outpath, _ := cmd.Flags().GetString("outpath") - inputErr := storeTypeIdentifierFlagCheck(cmd) - if inputErr != nil { - return inputErr + if noPrompt { + inputErr := storeTypeIdentifierFlagCheck(cmd) + if inputErr != nil { + return inputErr + } } // expEnabled checks @@ -308,28 +311,72 @@ Store type IDs can be found by running the "store-types" command.`, Str("outpath", outpath).Msg("Specific flags") // Check inputs - log.Debug().Msg("calling validateStoreTypeInputs()") - st, stErr := validateStoreTypeInputs(storeTypeID, storeTypeName, outputFormat) - log.Debug().Msg("returned from validateStoreTypeInputs()") - if stErr != nil { - log.Error().Err(stErr).Msg("Error validating store type inputs") - return stErr + var ( + st interface{} + stErr error + ) + var validStoreTypes []string + var removeStoreTypes []interface{} + if storeTypeID < 0 && storeTypeName == "" && !noPrompt { + // prompt for store type + validStoreTypesResp, vstErr := kfClient.ListCertificateStoreTypes() + if vstErr != nil { + log.Error().Err(vstErr).Msg("unable to list certificate store types") + validStoreTypes = getValidStoreTypes("", "main") + } else { + for _, v := range *validStoreTypesResp { + validStoreTypes = append(validStoreTypes, v.ShortName) + removeStoreTypes = append(removeStoreTypes, v.ShortName) + } + } + log.Info().Msg("No store type specified, prompting user to select one") + prompt := &survey.Select{ + Message: "Choose a store type to export:", + Options: validStoreTypes, + } + var selected string + err := survey.AskOne(prompt, &selected) + if err != nil { + log.Error().Err(err).Msg("user select prompt failed") + fmt.Println(err) + } + log.Info().Str("storeType", selected).Msg("User selected store type") + st = []interface{}{selected} + } else { + log.Debug().Msg("calling validateStoreTypeInputs()") + st, stErr = validateStoreTypeInputs(storeTypeID, storeTypeName, outputFormat) + log.Debug().Msg("returned from validateStoreTypeInputs()") + if stErr != nil { + log.Error().Err(stErr).Msg("Error validating store type inputs") + return stErr + } } - + log.Trace().Interface("st", st).Send() // get storetype for the list of properties log.Debug().Msg("calling getHeadersForStoreType()") - intID, csvHeaders := getHeadersForStoreType(st, *kfClient) - log.Debug().Msg("returned from getHeadersForStoreType()") + intID, sTypeShortName, csvHeaders := getHeadersForStoreType(st, *kfClient) + log.Debug().Str("shortName", sTypeShortName).Msg("returned from getHeadersForStoreType()") log.Debug().Int64("intID", intID). Interface("csvHeaders", csvHeaders). Send() + if storeTypeName != "" && sTypeShortName != "" && storeTypeName != sTypeShortName { + log.Debug().Str("storeTypeName", storeTypeName). + Str("sTypeShortName", sTypeShortName). + Msg("storeTypeName does not match sTypeShortName, overwriting storeTypeName with sTypeShortName") + sTypeShortName = storeTypeName + } + // write csv file header row var filePath string if outpath != "" { filePath = outpath } else { - filePath = fmt.Sprintf("%s_template_%d.%s", "createstores", intID, "csv") + if sTypeShortName != "" { + filePath = fmt.Sprintf("%s_bulk_import_template.%s", sTypeShortName, "csv") + } else { + filePath = fmt.Sprintf("%s_bulk_import_template_%d.%s", "createstores", intID, "csv") + } } log.Debug().Str("filePath", filePath).Msg("Writing template file") @@ -410,7 +457,7 @@ var storesExportCmd = &cobra.Command{ } log.Debug().Msg("calling getHeadersForStoreType()") - typeID, csvHeaders := getHeadersForStoreType(st, *kfClient) + typeID, _, csvHeaders := getHeadersForStoreType(st, *kfClient) log.Debug().Msg("returned from getHeadersForStoreType()") query := map[string]interface{}{"Category": typeID} @@ -568,9 +615,15 @@ var storesExportCmd = &cobra.Command{ }, } -func getHeadersForStoreType(id interface{}, kfClient api.Client) (int64, map[int]string) { +func getHeadersForStoreType(id interface{}, kfClient api.Client) (int64, string, map[int]string) { csvHeaders := make(map[int]string) + //check if interface is a slice of interfaces + if _, ok := id.([]interface{}); ok { + id = id.([]interface{})[0] + log.Debug().Interface("id", id).Msg("id is a slice of interfaces, setting id to first element") + } + storeType, err := kfClient.GetCertificateStoreType(id) if err != nil { log.Printf("Error: %s", err) @@ -609,7 +662,13 @@ func getHeadersForStoreType(id interface{}, kfClient api.Client) (int64, map[int csvHeaders[len(csvHeaders)] = "Password" } intId, _ := jsonParsedObj.S("StoreType").Data().(json.Number).Int64() - return intId, csvHeaders + shortName, snOk := jsonParsedObj.S("ShortName").Data().(string) + if !snOk { + log.Printf("Error: %s", "unable to retrieve store type id or short name") + fmt.Printf("Error: %s\n", "unable to retrieve store type id or short name") + shortName = "" + } + return intId, shortName, csvHeaders } func getRequiredProperties(id interface{}, kfClient api.Client) (int64, []string) { diff --git a/examples/cert_stores/bulk_export_import/README.md b/examples/cert_stores/bulk_export_import/README.md index e955b7c6..471a56d1 100644 --- a/examples/cert_stores/bulk_export_import/README.md +++ b/examples/cert_stores/bulk_export_import/README.md @@ -1,3 +1,58 @@ # Keyfactor Command Bulk Certificate Store Operations -This will demo how to use `kfutil` +This will demo how to use `kfutil` to bulk import and export Keyfactor Command Certificate Stores. +## Prerequisites +- `kfutil` v1.4.0 or later +- Keyfactor Command v10.x +- The certificate store type exists in Keyfactor Command + +## Guide + +### Step 0: Create the certificate store type +You can use `kfutil` to create a specific certificate store type, or all supported certificate store types. + +#### User Interactive Mode: +```bash +kfutil store-types create +? Choose an option: [Use arrows to move, type to filter] +> AKV + AzureApp + AzureAppGW + AzureSP + Fortigate + HCVKV + HCVKVJKS +``` + +#### Non-Interactive Mode: +```bash +kfutil store-types create --all +``` + +### Step 1: Generate an import template CSV file +You can use `kfutil` to generate a CSV file that can be used to bulk import certificate stores into Keyfactor Command. +*NOTE*: The certificate store and/or type must exist in Keyfactor Command before you can generate the CSV file. + +#### Export a store-type template +[!NOTE] This will not export any values, just the headers associated with the store type. It is highly recommended to +create a store in Keyfactor Command and then export it to see what the values of the CSV file look like. +```bash +kfutil stores import generate-template --store-type-name rfpem +``` +#### Export an existing certificate stores by store-type +Below is an example of exporting all certificate stores of a specific store type `k8ssecret`. +[!IMPORTANT] This will *not* export any secrets or sensitive information associated with the certificate stores. +```bash +kfutil stores export --store-type-name k8ssecret +``` + +### Step 2: Edit the CSV file +This can be hard without an example, so it's recommended that you create a store in Keyfactor Command and then export +it to see what the CSV file should look like. At bare minimum, the store credentials will need to be filled in as they +cannot be exported from Keyfactor Command. + +### Step 3: Import the CSV file +You can use `kfutil` to import a CSV file that contains the certificate store information to be imported into Keyfactor Command. +```bash +kfutil stores import --file /path/to/csv/file.csv +``` \ No newline at end of file diff --git a/pkg/version/version.go b/pkg/version/version.go index dc0a11a2..0e245c0c 100644 --- a/pkg/version/version.go +++ b/pkg/version/version.go @@ -14,4 +14,4 @@ package version -const VERSION = "1.4.0-rc.8" \ No newline at end of file +const VERSION = "1.4.0-rc.8" From bb7bf4db1ac6c38b72b83d28519a3faa26a3a36a Mon Sep 17 00:00:00 2001 From: sbailey <1661003+spbsoluble@users.noreply.github.com> Date: Tue, 27 Feb 2024 12:11:14 -0800 Subject: [PATCH 22/47] feat(stores): `stores export` now allows for `--all` and user interactive exports --- cmd/helpers.go | 15 +- cmd/root.go | 14 + cmd/rot.go | 16 +- cmd/storesBulkOperations.go | 409 +++++++++++------- docs/kfutil.md | 3 +- docs/kfutil_containers.md | 2 +- docs/kfutil_containers_get.md | 2 +- docs/kfutil_containers_list.md | 2 +- docs/kfutil_export.md | 2 +- docs/kfutil_helm.md | 2 +- docs/kfutil_helm_uo.md | 2 +- docs/kfutil_import.md | 2 +- docs/kfutil_login.md | 2 +- docs/kfutil_logout.md | 2 +- docs/kfutil_orchs.md | 2 +- docs/kfutil_orchs_approve.md | 2 +- docs/kfutil_orchs_disapprove.md | 2 +- docs/kfutil_orchs_ext.md | 2 +- docs/kfutil_orchs_get.md | 2 +- docs/kfutil_orchs_list.md | 2 +- docs/kfutil_orchs_logs.md | 2 +- docs/kfutil_orchs_reset.md | 2 +- docs/kfutil_pam.md | 2 +- docs/kfutil_pam_create.md | 2 +- docs/kfutil_pam_delete.md | 2 +- docs/kfutil_pam_get.md | 2 +- docs/kfutil_pam_list.md | 2 +- docs/kfutil_pam_types-create.md | 2 +- docs/kfutil_pam_types-list.md | 2 +- docs/kfutil_pam_update.md | 2 +- docs/kfutil_status.md | 2 +- docs/kfutil_store-types.md | 2 +- docs/kfutil_store-types_create.md | 2 +- docs/kfutil_store-types_delete.md | 2 +- docs/kfutil_store-types_get.md | 2 +- docs/kfutil_store-types_list.md | 2 +- docs/kfutil_store-types_templates-fetch.md | 2 +- docs/kfutil_stores.md | 2 +- docs/kfutil_stores_delete.md | 2 +- docs/kfutil_stores_export.md | 3 +- docs/kfutil_stores_get.md | 2 +- docs/kfutil_stores_import.md | 2 +- docs/kfutil_stores_import_csv.md | 2 +- .../kfutil_stores_import_generate-template.md | 2 +- docs/kfutil_stores_inventory.md | 2 +- docs/kfutil_stores_inventory_add.md | 2 +- docs/kfutil_stores_inventory_remove.md | 2 +- docs/kfutil_stores_inventory_show.md | 2 +- docs/kfutil_stores_list.md | 2 +- docs/kfutil_stores_rot.md | 2 +- docs/kfutil_stores_rot_audit.md | 2 +- docs/kfutil_stores_rot_generate-template.md | 2 +- docs/kfutil_stores_rot_reconcile.md | 2 +- docs/kfutil_version.md | 2 +- main.go | 5 - pkg/version/version.go | 2 +- 56 files changed, 341 insertions(+), 222 deletions(-) diff --git a/cmd/helpers.go b/cmd/helpers.go index 2c084477..0a07df81 100644 --- a/cmd/helpers.go +++ b/cmd/helpers.go @@ -163,8 +163,19 @@ func findMatchingFiles(pattern string) ([]string, error) { return matchingFiles, nil } -func getCurrentTime() string { - return time.Now().Format(time.RFC3339) +func getCurrentTime(f string) string { + switch f { + case "unix": + return strconv.FormatInt(time.Now().Unix(), 10) + case "unixNano": + return strconv.FormatInt(time.Now().UnixNano(), 10) + case "date": + return time.Now().Format("2006-01-02") + case "time": + return time.Now().Format("15:04:05") + default: + return time.Now().Format(time.RFC3339) + } } func informDebug(debugFlag bool) { diff --git a/cmd/root.go b/cmd/root.go index 0b73e614..7029f295 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -20,6 +20,7 @@ import ( "github.com/Keyfactor/keyfactor-go-client/v2/api" "github.com/rs/zerolog/log" "github.com/spf13/cobra" + "github.com/spf13/cobra/doc" "golang.org/x/crypto/bcrypt" "io" stdlog "log" @@ -264,6 +265,18 @@ func initGenClient(flagConfig string, flagProfile string, noPrompt bool, authCon return c, nil } +var makeDocsCmd = &cobra.Command{ + Use: "makedocs", + Short: "Generate markdown documentation for kfutil", + Long: `Generate markdown documentation for kfutil.`, + Hidden: true, + Run: func(cmd *cobra.Command, args []string) { + log.Debug().Msg("Enter makeDocsCmd.Run()") + doc.GenMarkdownTree(RootCmd, "./docs") + log.Debug().Msg("complete: makeDocsCmd.Run()") + }, +} + // RootCmd represents the base command when called without any subcommands var RootCmd = &cobra.Command{ Use: "kfutil", @@ -315,4 +328,5 @@ func init() { // Cobra also supports local flags, which will only run // when this action is called directly. + RootCmd.AddCommand(makeDocsCmd) } diff --git a/cmd/rot.go b/cmd/rot.go index 15f97967..897e65f1 100644 --- a/cmd/rot.go +++ b/cmd/rot.go @@ -142,7 +142,7 @@ func generateAuditReport(addCerts map[string]string, removeCerts map[string]stri for _, store := range stores { if _, ok := store.Thumbprints[cert]; ok { // Cert is already in the store do nothing - row := []string{cert, certIDStr, certLookup.IssuedDN, certLookup.IssuerDN, store.ID, store.Type, store.Machine, store.Path, "false", "false", "true", getCurrentTime()} + row := []string{cert, certIDStr, certLookup.IssuedDN, certLookup.IssuerDN, store.ID, store.Type, store.Machine, store.Path, "false", "false", "true", getCurrentTime("")} data = append(data, row) wErr := csvWriter.Write(row) if wErr != nil { @@ -151,7 +151,7 @@ func generateAuditReport(addCerts map[string]string, removeCerts map[string]stri } } else { // Cert is not deployed to this store and will need to be added - row := []string{cert, certIDStr, certLookup.IssuedDN, certLookup.IssuerDN, store.ID, store.Type, store.Machine, store.Path, "true", "false", "false", getCurrentTime()} + row := []string{cert, certIDStr, certLookup.IssuedDN, certLookup.IssuerDN, store.ID, store.Type, store.Machine, store.Path, "true", "false", "false", getCurrentTime("")} data = append(data, row) wErr := csvWriter.Write(row) if wErr != nil { @@ -188,7 +188,7 @@ func generateAuditReport(addCerts map[string]string, removeCerts map[string]stri for _, store := range stores { if _, ok := store.Thumbprints[cert]; ok { // Cert is deployed to this store and will need to be removed - row := []string{cert, certIDStr, certLookup.IssuedDN, certLookup.IssuerDN, store.ID, store.Type, store.Machine, store.Path, "false", "true", "true", getCurrentTime()} + row := []string{cert, certIDStr, certLookup.IssuedDN, certLookup.IssuerDN, store.ID, store.Type, store.Machine, store.Path, "false", "true", "true", getCurrentTime("")} data = append(data, row) wErr := csvWriter.Write(row) if wErr != nil { @@ -206,7 +206,7 @@ func generateAuditReport(addCerts map[string]string, removeCerts map[string]stri }) } else { // Cert is not deployed to this store do nothing - row := []string{cert, certIDStr, certLookup.IssuedDN, certLookup.IssuerDN, store.ID, store.Type, store.Machine, store.Path, "false", "false", "false", getCurrentTime()} + row := []string{cert, certIDStr, certLookup.IssuedDN, certLookup.IssuerDN, store.ID, store.Type, store.Machine, store.Path, "false", "false", "false", getCurrentTime("")} data = append(data, row) wErr := csvWriter.Write(row) if wErr != nil { @@ -958,7 +958,7 @@ the utility will first generate an audit report and then execute the add/remove if !rowLookup[store.Id] { lineData := []string{ //"StoreID", "StoreType", "StoreMachine", "StorePath", "ContainerId" - store.Id, fmt.Sprintf("%s", sType.ShortName), store.ClientMachine, store.StorePath, fmt.Sprintf("%d", store.ContainerId), store.ContainerName, getCurrentTime(), + store.Id, fmt.Sprintf("%s", sType.ShortName), store.ClientMachine, store.StorePath, fmt.Sprintf("%d", store.ContainerId), store.ContainerName, getCurrentTime(""), } csvStoreData = append(csvStoreData, lineData) rowLookup[store.Id] = true @@ -990,7 +990,7 @@ the utility will first generate an audit report and then execute the add/remove if !rowLookup[store.Id] { lineData := []string{ // "StoreID", "StoreType", "StoreMachine", "StorePath", "ContainerId" - store.Id, sType.ShortName, store.ClientMachine, store.StorePath, fmt.Sprintf("%d", store.ContainerId), store.ContainerName, getCurrentTime(), + store.Id, sType.ShortName, store.ClientMachine, store.StorePath, fmt.Sprintf("%d", store.ContainerId), store.ContainerName, getCurrentTime(""), } csvStoreData = append(csvStoreData, lineData) rowLookup[store.Id] = true @@ -1017,7 +1017,7 @@ the utility will first generate an audit report and then execute the add/remove if !rowLookup[cert.Thumbprint] { lineData := []string{ // "Thumbprint", "SubjectName", "Issuer", "CertID", "Locations", "LastQueriedDate" - cert.Thumbprint, cert.IssuedCN, cert.IssuerDN, fmt.Sprintf("%d", cert.Id), fmt.Sprintf("%v", cert.Locations), getCurrentTime(), + cert.Thumbprint, cert.IssuedCN, cert.IssuerDN, fmt.Sprintf("%d", cert.Id), fmt.Sprintf("%v", cert.Locations), getCurrentTime(""), } csvCertData = append(csvCertData, lineData) rowLookup[cert.Thumbprint] = true @@ -1048,7 +1048,7 @@ the utility will first generate an audit report and then execute the add/remove } lineData := []string{ // "Thumbprint", "SubjectName", "Issuer", "CertID", "Locations", "LastQueriedDate" - cert.Thumbprint, cert.IssuedCN, cert.IssuerDN, fmt.Sprintf("%d", cert.Id), locationsFormatted, getCurrentTime(), + cert.Thumbprint, cert.IssuedCN, cert.IssuerDN, fmt.Sprintf("%d", cert.Id), locationsFormatted, getCurrentTime(""), } csvCertData = append(csvCertData, lineData) rowLookup[cert.Thumbprint] = true diff --git a/cmd/storesBulkOperations.go b/cmd/storesBulkOperations.go index 36e7639f..bc3676ce 100644 --- a/cmd/storesBulkOperations.go +++ b/cmd/storesBulkOperations.go @@ -414,12 +414,17 @@ var storesExportCmd = &cobra.Command{ storeTypeName, _ := cmd.Flags().GetString("store-type-name") storeTypeID, _ := cmd.Flags().GetInt("store-type-id") outpath, _ := cmd.Flags().GetString("outpath") + allStores, _ := cmd.Flags().GetBool("all") - inputErr := storeTypeIdentifierFlagCheck(cmd) - if inputErr != nil { - return inputErr + if noPrompt && !allStores { + inputErr := storeTypeIdentifierFlagCheck(cmd) + if inputErr != nil && !noPrompt { + return inputErr + } } + // Fetch a list of stores from + // expEnabled checks isExperimental := false debugErr := warnExperimentalFeature(expEnabled, isExperimental) @@ -439,182 +444,272 @@ var storesExportCmd = &cobra.Command{ Str("outpath", outpath). Msg("Exporting certificate stores of specified type to CSV") - // Check inputs - st, stErr := validateStoreTypeInputs(storeTypeID, storeTypeName, outputFormat) - if stErr != nil { - log.Error().Err(stErr).Msg("validating store type inputs") - return stErr + var ( + //stTypes []int + stInterfaces interface{} + stErr error + ) + if allStores { + //iterate through stores and compile a list of distinct store types + storeTypes, stErr := listStoresByType(*kfClient) + if stErr != nil { + log.Error().Err(stErr).Msg("Error listing store types, unable to export stores") + return stErr + } else if storeTypes == nil { + log.Error().Msg("No store types returned from Keyfactor Command") + return fmt.Errorf("no store types returned from Keyfactor Command") + } + var stInts []interface{} + for _, st := range *storeTypes { + stInts = append(stInts, st) + } + stInterfaces = stInts + } else { + // Check inputs + stInterfaces, stErr = validateStoreTypeInputs(storeTypeID, storeTypeName, outputFormat) + if stErr != nil { + if noPrompt { + log.Error().Err(stErr).Msg("validating store type inputs") + return stErr + } + storeTypes, stErr := listStoresByType(*kfClient) + if stErr != nil { + log.Error().Err(stErr).Msg("Error listing store types, unable to export stores") + return stErr + } else if storeTypes == nil { + log.Error().Msg("No store types returned from Keyfactor Command") + return fmt.Errorf("no store types returned from Keyfactor Command") + } + // render list of store types as options for user to select + var storeTypeOptions []string + for name, _ := range *storeTypes { + storeTypeOptions = append(storeTypeOptions, fmt.Sprintf("%s", name)) + } + prompt := &survey.Select{ + Message: "Choose a store type to export:", + Options: storeTypeOptions, + } + var selected string + err := survey.AskOne(prompt, &selected) + if err != nil { + fmt.Println(err) + return err + } + stInterfaces = []interface{}{selected} + } } - // get storetype for the list of properties - log.Debug().Msg("calling getHeadersForStoreType()") - storeType, err := kfClient.GetCertificateStoreType(st) - log.Debug().Msg("returned from getHeadersForStoreType()") - log.Trace().Interface("storeType", storeType).Send() - if err != nil { - log.Error().Err(err).Msg("retrieving store type") - return err + var errs []error + if stInterfaces == nil { + log.Error().Msg("No store types returned from Keyfactor Command") + return fmt.Errorf("no store types returned from Keyfactor Command") } - - log.Debug().Msg("calling getHeadersForStoreType()") - typeID, _, csvHeaders := getHeadersForStoreType(st, *kfClient) - log.Debug().Msg("returned from getHeadersForStoreType()") - - query := map[string]interface{}{"Category": typeID} - log.Debug().Interface("query", query).Msg("calling ListCertificateStores()") - storeList, lErr := kfClient.ListCertificateStores(&query) - log.Debug().Msg("returned from ListCertificateStores()") - log.Trace().Interface("storeList", storeList).Send() - if lErr != nil { - log.Error().Err(lErr). - Int64("typeId", typeID). - Msg("listing stores of type") - return lErr - } - - // add Id header to csvHeaders at -1 - log.Debug().Msg("adding Id header to csvHeaders") - csvHeaders[len(csvHeaders)] = "Id" - log.Trace().Interface("csvHeaders", csvHeaders).Send() - csvData := make(map[string]map[string]interface{}, len(*storeList)) - - log.Debug().Msg("iterating through stores") - for _, listedStore := range *storeList { - if listedStore.CertStoreType != int(typeID) { - log.Debug().Int("listedStore.CertStoreType", listedStore.CertStoreType). - Msg("skipping store") - continue - } - log.Debug().Str("listedStore.Id", listedStore.Id). - Msg("calling GetCertificateStoreByID()") - store, err := kfClient.GetCertificateStoreByID(listedStore.Id) - log.Debug().Msg("returned from GetCertificateStoreByID()") - log.Trace().Interface("store", store).Send() + for _, st := range stInterfaces.([]interface{}) { + // get storetype for the list of properties + log.Debug().Msg("calling getHeadersForStoreType()") + storeType, err := kfClient.GetCertificateStoreType(st) + typeName := storeType.ShortName + log.Debug().Msg("returned from getHeadersForStoreType()") + log.Trace().Interface("storeType", storeType).Send() if err != nil { - log.Error().Err(err).Msg("retrieving store by id") - return err + log.Error().Err(err).Msg("retrieving store type") + errs = append(errs, err) + continue } - // populate store data into csv - log.Debug().Str("store.Id", store.Id). - Int("store.ContainerId", store.ContainerId). - Str("store.ClientMachine", store.ClientMachine). - Str("store.StorePath", store.StorePath). - Bool("store.CreateIfMissing", store.CreateIfMissing). - Str("store.AgentId", store.AgentId). - Msg("populating store data into csv") - - csvData[store.Id] = map[string]interface{}{ - "Id": store.Id, - "ContainerId": store.ContainerId, - "ClientMachine": store.ClientMachine, - "StorePath": store.StorePath, - "CreateIfMissing": store.CreateIfMissing, - "AgentId": store.AgentId, + log.Debug().Msg("calling getHeadersForStoreType()") + typeID, _, csvHeaders := getHeadersForStoreType(st, *kfClient) + log.Debug().Msg("returned from getHeadersForStoreType()") + + query := map[string]interface{}{"Category": typeID} + log.Debug().Interface("query", query).Msg("calling ListCertificateStores()") + storeList, lErr := kfClient.ListCertificateStores(&query) + log.Debug().Msg("returned from ListCertificateStores()") + log.Trace().Interface("storeList", storeList).Send() + if lErr != nil { + log.Error().Err(lErr). + Int64("typeId", typeID). + Msg("listing stores of type") + errs = append(errs, lErr) + continue } - log.Debug().Msg("checking for InventorySchedule") - if store.InventorySchedule.Immediate != nil { - log.Debug().Msg("found InventorySchedule.Immediate") - csvData[store.Id]["InventorySchedule.Immediate"] = store.InventorySchedule.Immediate - } - if store.InventorySchedule.Interval != nil { - log.Debug().Msg("found InventorySchedule.Interval") - csvData[store.Id]["InventorySchedule.Interval.Minutes"] = store.InventorySchedule.Interval.Minutes - } - if store.InventorySchedule.Daily != nil { - log.Debug().Msg("found InventorySchedule.Daily") - csvData[store.Id]["InventorySchedule.Daily.Time"] = store.InventorySchedule.Daily.Time - } + // add Id header to csvHeaders at -1 + log.Debug().Msg("adding Id header to csvHeaders") + csvHeaders[len(csvHeaders)] = "Id" + log.Trace().Interface("csvHeaders", csvHeaders).Send() + csvData := make(map[string]map[string]interface{}, len(*storeList)) + + log.Debug().Msg("iterating through stores") + for _, listedStore := range *storeList { + if listedStore.CertStoreType != int(typeID) { + log.Debug().Int("listedStore.CertStoreType", listedStore.CertStoreType). + Msg("skipping store") + continue + } + log.Debug().Str("listedStore.Id", listedStore.Id). + Msg("calling GetCertificateStoreByID()") + store, err := kfClient.GetCertificateStoreByID(listedStore.Id) + log.Debug().Msg("returned from GetCertificateStoreByID()") + log.Trace().Interface("store", store).Send() + if err != nil { + log.Error().Err(err).Msg("retrieving store by id") + errs = append(errs, err) + continue + } - log.Debug().Msg("checking Properties") - for name, prop := range store.Properties { - log.Debug().Str("name", name). - Interface("prop", prop). - Msg("adding to properties CSV data") - if name != "ServerUsername" && name != "ServerPassword" { // Don't add ServerUsername and ServerPassword to properties as they can't be exported via API - csvData[store.Id]["Properties."+name] = prop + // populate store data into csv + log.Debug().Str("store.Id", store.Id). + Int("store.ContainerId", store.ContainerId). + Str("store.ClientMachine", store.ClientMachine). + Str("store.StorePath", store.StorePath). + Bool("store.CreateIfMissing", store.CreateIfMissing). + Str("store.AgentId", store.AgentId). + Msg("populating store data into csv") + + csvData[store.Id] = map[string]interface{}{ + "Id": store.Id, + "ContainerId": store.ContainerId, + "ClientMachine": store.ClientMachine, + "StorePath": store.StorePath, + "CreateIfMissing": store.CreateIfMissing, + "AgentId": store.AgentId, } - } - //// conditionally set secret values - //if storeType.PasswordOptions.StoreRequired { - // log.Debug().Str("storePassword", hashSecretValue(store.Password.Value)). - // Msg("setting store password") - // - // //csvData[store.Id]["Password"] = parseSecretField(store.Password) // todo: find parseSecretField - // csvData[store.Id]["Password"] = store.Password.Value - //} - //// add ServerUsername and ServerPassword Properties if required for type - //if storeType.ServerRequired { - // log.Debug().Interface("store.ServerUsername", store.Properties["ServerUsername"]). - // Str("store.Password", hashSecretValue(store.Password.Value)). - // Msg("setting store.ServerUsername") - // //csvData[store.Id]["Properties.ServerUsername"] = parseSecretField(store.Properties["ServerUsername"]) // todo: find parseSecretField - // //csvData[store.Id]["Properties.ServerPassword"] = parseSecretField(store.Properties["ServerPassword"]) // todo: find parseSecretField - // csvData[store.Id]["Properties.ServerUsername"] = store.Properties["ServerUsername"] - // csvData[store.Id]["Properties.ServerPassword"] = store.Properties["ServerPassword"] - //} - } + log.Debug().Msg("checking for InventorySchedule") + if store.InventorySchedule.Immediate != nil { + log.Debug().Msg("found InventorySchedule.Immediate") + csvData[store.Id]["InventorySchedule.Immediate"] = store.InventorySchedule.Immediate + } + if store.InventorySchedule.Interval != nil { + log.Debug().Msg("found InventorySchedule.Interval") + csvData[store.Id]["InventorySchedule.Interval.Minutes"] = store.InventorySchedule.Interval.Minutes + } + if store.InventorySchedule.Daily != nil { + log.Debug().Msg("found InventorySchedule.Daily") + csvData[store.Id]["InventorySchedule.Daily.Time"] = store.InventorySchedule.Daily.Time + } - // write csv file header row - var filePath string - if outpath != "" { - filePath = outpath - } else { - filePath = fmt.Sprintf("export_stores_%d.%s", &typeID, "csv") - } - log.Debug().Str("filePath", filePath).Msg("Writing export file") + log.Debug().Msg("checking Properties") + for name, prop := range store.Properties { + log.Debug().Str("name", name). + Interface("prop", prop). + Msg("adding to properties CSV data") + if name != "ServerUsername" && name != "ServerPassword" { // Don't add ServerUsername and ServerPassword to properties as they can't be exported via API + csvData[store.Id]["Properties."+name] = prop + } + } - var csvContent [][]string - headerRow := make([]string, len(csvHeaders)) + //// conditionally set secret values + //if storeType.PasswordOptions.StoreRequired { + // log.Debug().Str("storePassword", hashSecretValue(store.Password.Value)). + // Msg("setting store password") + // + // //csvData[store.Id]["Password"] = parseSecretField(store.Password) // todo: find parseSecretField + // csvData[store.Id]["Password"] = store.Password.Value + //} + //// add ServerUsername and ServerPassword Properties if required for type + //if storeType.ServerRequired { + // log.Debug().Interface("store.ServerUsername", store.Properties["ServerUsername"]). + // Str("store.Password", hashSecretValue(store.Password.Value)). + // Msg("setting store.ServerUsername") + // //csvData[store.Id]["Properties.ServerUsername"] = parseSecretField(store.Properties["ServerUsername"]) // todo: find parseSecretField + // //csvData[store.Id]["Properties.ServerPassword"] = parseSecretField(store.Properties["ServerPassword"]) // todo: find parseSecretField + // csvData[store.Id]["Properties.ServerUsername"] = store.Properties["ServerUsername"] + // csvData[store.Id]["Properties.ServerPassword"] = store.Properties["ServerPassword"] + //} + } - log.Debug().Msg("Writing header row") - for k, v := range csvHeaders { - headerRow[k] = v - } - log.Trace().Interface("row", headerRow).Send() - csvContent = append(csvContent, headerRow) - index := 1 - - log.Debug().Msg("Writing data rows") - for _, data := range csvData { - log.Debug().Int("index", index).Msg("processing data row") - row := make([]string, len(csvHeaders)) // reset row - for i, header := range csvHeaders { - log.Trace().Int("index", i). - Str("header", header). - Msg("processing header") - if data[header] != nil { - if s, ok := data[header].(string); ok { - log.Trace().Str("s", s). - Msg("setting row value") - row[i] = s - } else { - log.Trace().Interface("data[header]", data[header]). - Msg("marshalling data[header]") - strData, _ := json.Marshal(data[header]) - row[i] = string(strData) - log.Trace().Int("index", i). - Str("row[i]", row[i]). - Msg("setting row value") + // write csv file header row + var filePath string + if outpath != "" { + filePath = outpath + } else { + filePath = fmt.Sprintf("%s_stores_export_%s.%s", typeName, getCurrentTime("unix"), "csv") + } + log.Debug().Str("filePath", filePath).Msg("Writing export file") + + var csvContent [][]string + headerRow := make([]string, len(csvHeaders)) + + log.Debug().Msg("Writing header row") + for k, v := range csvHeaders { + headerRow[k] = v + } + log.Trace().Interface("row", headerRow).Send() + csvContent = append(csvContent, headerRow) + index := 1 + + log.Debug().Msg("Writing data rows") + for _, data := range csvData { + log.Debug().Int("index", index).Msg("processing data row") + row := make([]string, len(csvHeaders)) // reset row + for i, header := range csvHeaders { + log.Trace().Int("index", i). + Str("header", header). + Msg("processing header") + if data[header] != nil { + if s, ok := data[header].(string); ok { + log.Trace().Str("s", s). + Msg("setting row value") + row[i] = s + } else { + log.Trace().Interface("data[header]", data[header]). + Msg("marshalling data[header]") + strData, _ := json.Marshal(data[header]) + row[i] = string(strData) + log.Trace().Int("index", i). + Str("row[i]", row[i]). + Msg("setting row value") + } } } + log.Debug().Msg("appending row to csvContent") + csvContent = append(csvContent, row) + index++ + log.Debug().Msg("row appended to csvContent") } - log.Debug().Msg("appending row to csvContent") - csvContent = append(csvContent, row) - index++ - log.Debug().Msg("row appended to csvContent") - } - - writeCsvFile(filePath, csvContent) - fmt.Printf("\nStores exported for store type with id %d written to %s\n", typeID, filePath) + writeCsvFile(filePath, csvContent) + fmt.Printf("\nStores exported for store type with id %d written to %s\n", typeID, filePath) + } return nil }, } +func listStoresByType(kfClient api.Client) (*map[string]int, error) { + query := map[string]interface{}{} + stores, err := kfClient.ListCertificateStores(&query) + if err != nil { + return nil, err + } + + if stores == nil { + return nil, fmt.Errorf("no stores returned from Keyfactor Command") + } + var sTypes []int + output := make(map[string]int) + for _, store := range *stores { + sTypes = append(sTypes, store.CertStoreType) + sType, sTypeErr := kfClient.GetCertificateStoreType(store.CertStoreType) + if sTypeErr != nil { + log.Error(). + Int("storeTypeId", store.CertStoreType). + Err(sTypeErr). + Msg("Error retrieving store type") + continue + } + output[sType.ShortName] = store.CertStoreType + log.Debug(). + Int("storeTypeId", store.CertStoreType). + Str("storeTypeShortName", sType.ShortName). + Msg("store type added to output") + } + return &output, nil + +} + func getHeadersForStoreType(id interface{}, kfClient api.Client) (int64, string, map[int]string) { csvHeaders := make(map[int]string) @@ -859,6 +954,7 @@ func init() { outPath string file string resultsPath string + exportAll bool ) storesCmd.AddCommand(importStoresCmd) @@ -879,6 +975,7 @@ func init() { storesCreateFromCSVCmd.Flags().BoolP("dry-run", "d", false, "Do not import, just check for necessary fields.") storesCreateFromCSVCmd.Flags().StringVarP(&resultsPath, "results-path", "o", "", "CSV file containing cert stores to create. defaults to _results.csv") + storesExportCmd.Flags().BoolVarP(&exportAll, "all", "a", false, "Export all stores grouped by store-type.") storesExportCmd.Flags().StringVarP(&storeTypeName, "store-type-name", "n", "", "The name of the cert store type for the template. Use if store-type-id is unknown.") storesExportCmd.Flags().IntVarP(&storeTypeId, "store-type-id", "i", -1, "The ID of the cert store type for the template.") storesExportCmd.Flags().StringVarP(&outPath, "outpath", "o", "", diff --git a/docs/kfutil.md b/docs/kfutil.md index 70d814d0..e201503e 100644 --- a/docs/kfutil.md +++ b/docs/kfutil.md @@ -28,6 +28,7 @@ A CLI wrapper around the Keyfactor Platform API. ### SEE ALSO +* [kfutil completion](kfutil_completion.md) - Generate the autocompletion script for the specified shell * [kfutil containers](kfutil_containers.md) - Keyfactor certificate store container API and utilities. * [kfutil export](kfutil_export.md) - Keyfactor instance export utilities. * [kfutil helm](kfutil_helm.md) - Helm utilities for configuring Keyfactor Helm charts @@ -41,4 +42,4 @@ A CLI wrapper around the Keyfactor Platform API. * [kfutil stores](kfutil_stores.md) - Keyfactor certificate stores APIs and utilities. * [kfutil version](kfutil_version.md) - Shows version of kfutil -###### Auto generated by spf13/cobra on 26-Feb-2024 +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_containers.md b/docs/kfutil_containers.md index 83821c8b..745d5f6f 100644 --- a/docs/kfutil_containers.md +++ b/docs/kfutil_containers.md @@ -37,4 +37,4 @@ A collections of APIs and utilities for interacting with Keyfactor certificate s * [kfutil containers get](kfutil_containers_get.md) - Get certificate store container by ID or name. * [kfutil containers list](kfutil_containers_list.md) - List certificate store containers. -###### Auto generated by spf13/cobra on 26-Feb-2024 +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_containers_get.md b/docs/kfutil_containers_get.md index 6d0fa667..5838b6d6 100644 --- a/docs/kfutil_containers_get.md +++ b/docs/kfutil_containers_get.md @@ -40,4 +40,4 @@ kfutil containers get [flags] * [kfutil containers](kfutil_containers.md) - Keyfactor certificate store container API and utilities. -###### Auto generated by spf13/cobra on 26-Feb-2024 +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_containers_list.md b/docs/kfutil_containers_list.md index e4d2c99e..73e5c1dd 100644 --- a/docs/kfutil_containers_list.md +++ b/docs/kfutil_containers_list.md @@ -39,4 +39,4 @@ kfutil containers list [flags] * [kfutil containers](kfutil_containers.md) - Keyfactor certificate store container API and utilities. -###### Auto generated by spf13/cobra on 26-Feb-2024 +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_export.md b/docs/kfutil_export.md index 547772e2..5445dc2e 100644 --- a/docs/kfutil_export.md +++ b/docs/kfutil_export.md @@ -51,4 +51,4 @@ kfutil export [flags] * [kfutil](kfutil.md) - Keyfactor CLI utilities -###### Auto generated by spf13/cobra on 26-Feb-2024 +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_helm.md b/docs/kfutil_helm.md index c8097b31..55754d4f 100644 --- a/docs/kfutil_helm.md +++ b/docs/kfutil_helm.md @@ -42,4 +42,4 @@ kubectl helm uo | helm install -f - keyfactor-universal-orchestrator keyfactor/k * [kfutil](kfutil.md) - Keyfactor CLI utilities * [kfutil helm uo](kfutil_helm_uo.md) - Configure the Keyfactor Universal Orchestrator Helm Chart -###### Auto generated by spf13/cobra on 26-Feb-2024 +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_helm_uo.md b/docs/kfutil_helm_uo.md index 5443f725..d7d8f9c4 100644 --- a/docs/kfutil_helm_uo.md +++ b/docs/kfutil_helm_uo.md @@ -46,4 +46,4 @@ kfutil helm uo [-t ] [-o ] [-f ] [-e -e @,@ -o ./app/extension * [kfutil orchs](kfutil_orchs.md) - Keyfactor agents/orchestrators APIs and utilities. -###### Auto generated by spf13/cobra on 26-Feb-2024 +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_orchs_get.md b/docs/kfutil_orchs_get.md index 029acc1e..5011e1a1 100644 --- a/docs/kfutil_orchs_get.md +++ b/docs/kfutil_orchs_get.md @@ -40,4 +40,4 @@ kfutil orchs get [flags] * [kfutil orchs](kfutil_orchs.md) - Keyfactor agents/orchestrators APIs and utilities. -###### Auto generated by spf13/cobra on 26-Feb-2024 +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_orchs_list.md b/docs/kfutil_orchs_list.md index 47a6e04c..e41c8f39 100644 --- a/docs/kfutil_orchs_list.md +++ b/docs/kfutil_orchs_list.md @@ -39,4 +39,4 @@ kfutil orchs list [flags] * [kfutil orchs](kfutil_orchs.md) - Keyfactor agents/orchestrators APIs and utilities. -###### Auto generated by spf13/cobra on 26-Feb-2024 +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_orchs_logs.md b/docs/kfutil_orchs_logs.md index a748288e..07c7e5d5 100644 --- a/docs/kfutil_orchs_logs.md +++ b/docs/kfutil_orchs_logs.md @@ -40,4 +40,4 @@ kfutil orchs logs [flags] * [kfutil orchs](kfutil_orchs.md) - Keyfactor agents/orchestrators APIs and utilities. -###### Auto generated by spf13/cobra on 26-Feb-2024 +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_orchs_reset.md b/docs/kfutil_orchs_reset.md index c4ae28c6..0e46fd0d 100644 --- a/docs/kfutil_orchs_reset.md +++ b/docs/kfutil_orchs_reset.md @@ -40,4 +40,4 @@ kfutil orchs reset [flags] * [kfutil orchs](kfutil_orchs.md) - Keyfactor agents/orchestrators APIs and utilities. -###### Auto generated by spf13/cobra on 26-Feb-2024 +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_pam.md b/docs/kfutil_pam.md index 8e8bd319..48ec53aa 100644 --- a/docs/kfutil_pam.md +++ b/docs/kfutil_pam.md @@ -44,4 +44,4 @@ programmatically create, delete, edit, and list PAM Providers. * [kfutil pam types-list](kfutil_pam_types-list.md) - Returns a list of all available PAM provider types. * [kfutil pam update](kfutil_pam_update.md) - Updates an existing PAM Provider, currently only supported from file. -###### Auto generated by spf13/cobra on 26-Feb-2024 +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_pam_create.md b/docs/kfutil_pam_create.md index a478ba40..752f9147 100644 --- a/docs/kfutil_pam_create.md +++ b/docs/kfutil_pam_create.md @@ -40,4 +40,4 @@ kfutil pam create [flags] * [kfutil pam](kfutil_pam.md) - Keyfactor PAM Provider APIs. -###### Auto generated by spf13/cobra on 26-Feb-2024 +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_pam_delete.md b/docs/kfutil_pam_delete.md index ea9fd85b..27d2410a 100644 --- a/docs/kfutil_pam_delete.md +++ b/docs/kfutil_pam_delete.md @@ -40,4 +40,4 @@ kfutil pam delete [flags] * [kfutil pam](kfutil_pam.md) - Keyfactor PAM Provider APIs. -###### Auto generated by spf13/cobra on 26-Feb-2024 +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_pam_get.md b/docs/kfutil_pam_get.md index d4966a7c..62f4b754 100644 --- a/docs/kfutil_pam_get.md +++ b/docs/kfutil_pam_get.md @@ -40,4 +40,4 @@ kfutil pam get [flags] * [kfutil pam](kfutil_pam.md) - Keyfactor PAM Provider APIs. -###### Auto generated by spf13/cobra on 26-Feb-2024 +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_pam_list.md b/docs/kfutil_pam_list.md index 9e4eeb3d..af95f9bb 100644 --- a/docs/kfutil_pam_list.md +++ b/docs/kfutil_pam_list.md @@ -39,4 +39,4 @@ kfutil pam list [flags] * [kfutil pam](kfutil_pam.md) - Keyfactor PAM Provider APIs. -###### Auto generated by spf13/cobra on 26-Feb-2024 +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_pam_types-create.md b/docs/kfutil_pam_types-create.md index 3dc8d5ef..d6e2e49a 100644 --- a/docs/kfutil_pam_types-create.md +++ b/docs/kfutil_pam_types-create.md @@ -47,4 +47,4 @@ kfutil pam types-create [flags] * [kfutil pam](kfutil_pam.md) - Keyfactor PAM Provider APIs. -###### Auto generated by spf13/cobra on 26-Feb-2024 +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_pam_types-list.md b/docs/kfutil_pam_types-list.md index f6ef8589..33fb9dae 100644 --- a/docs/kfutil_pam_types-list.md +++ b/docs/kfutil_pam_types-list.md @@ -39,4 +39,4 @@ kfutil pam types-list [flags] * [kfutil pam](kfutil_pam.md) - Keyfactor PAM Provider APIs. -###### Auto generated by spf13/cobra on 26-Feb-2024 +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_pam_update.md b/docs/kfutil_pam_update.md index d954e0c9..c92d7073 100644 --- a/docs/kfutil_pam_update.md +++ b/docs/kfutil_pam_update.md @@ -40,4 +40,4 @@ kfutil pam update [flags] * [kfutil pam](kfutil_pam.md) - Keyfactor PAM Provider APIs. -###### Auto generated by spf13/cobra on 26-Feb-2024 +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_status.md b/docs/kfutil_status.md index 783291f6..55a3647d 100644 --- a/docs/kfutil_status.md +++ b/docs/kfutil_status.md @@ -39,4 +39,4 @@ kfutil status [flags] * [kfutil](kfutil.md) - Keyfactor CLI utilities -###### Auto generated by spf13/cobra on 26-Feb-2024 +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_store-types.md b/docs/kfutil_store-types.md index 68445bf7..65127266 100644 --- a/docs/kfutil_store-types.md +++ b/docs/kfutil_store-types.md @@ -40,4 +40,4 @@ A collections of APIs and utilities for interacting with Keyfactor certificate s * [kfutil store-types list](kfutil_store-types_list.md) - List certificate store types. * [kfutil store-types templates-fetch](kfutil_store-types_templates-fetch.md) - Fetches store type templates from Keyfactor's Github. -###### Auto generated by spf13/cobra on 26-Feb-2024 +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_store-types_create.md b/docs/kfutil_store-types_create.md index ff68dabc..e9cca52f 100644 --- a/docs/kfutil_store-types_create.md +++ b/docs/kfutil_store-types_create.md @@ -44,4 +44,4 @@ kfutil store-types create [flags] * [kfutil store-types](kfutil_store-types.md) - Keyfactor certificate store types APIs and utilities. -###### Auto generated by spf13/cobra on 26-Feb-2024 +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_store-types_delete.md b/docs/kfutil_store-types_delete.md index 9c6d2233..2fd868df 100644 --- a/docs/kfutil_store-types_delete.md +++ b/docs/kfutil_store-types_delete.md @@ -43,4 +43,4 @@ kfutil store-types delete [flags] * [kfutil store-types](kfutil_store-types.md) - Keyfactor certificate store types APIs and utilities. -###### Auto generated by spf13/cobra on 26-Feb-2024 +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_store-types_get.md b/docs/kfutil_store-types_get.md index 19fb0dd0..f272b165 100644 --- a/docs/kfutil_store-types_get.md +++ b/docs/kfutil_store-types_get.md @@ -44,4 +44,4 @@ kfutil store-types get [-i | -n ] [-b * [kfutil store-types](kfutil_store-types.md) - Keyfactor certificate store types APIs and utilities. -###### Auto generated by spf13/cobra on 26-Feb-2024 +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_store-types_list.md b/docs/kfutil_store-types_list.md index afe6e33d..5e65ce91 100644 --- a/docs/kfutil_store-types_list.md +++ b/docs/kfutil_store-types_list.md @@ -39,4 +39,4 @@ kfutil store-types list [flags] * [kfutil store-types](kfutil_store-types.md) - Keyfactor certificate store types APIs and utilities. -###### Auto generated by spf13/cobra on 26-Feb-2024 +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_store-types_templates-fetch.md b/docs/kfutil_store-types_templates-fetch.md index a8a453d7..305f700f 100644 --- a/docs/kfutil_store-types_templates-fetch.md +++ b/docs/kfutil_store-types_templates-fetch.md @@ -40,4 +40,4 @@ kfutil store-types templates-fetch [flags] * [kfutil store-types](kfutil_store-types.md) - Keyfactor certificate store types APIs and utilities. -###### Auto generated by spf13/cobra on 26-Feb-2024 +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_stores.md b/docs/kfutil_stores.md index 0ff7e8f0..895cb020 100644 --- a/docs/kfutil_stores.md +++ b/docs/kfutil_stores.md @@ -42,4 +42,4 @@ A collections of APIs and utilities for interacting with Keyfactor certificate s * [kfutil stores list](kfutil_stores_list.md) - List certificate stores. * [kfutil stores rot](kfutil_stores_rot.md) - Root of trust utility -###### Auto generated by spf13/cobra on 26-Feb-2024 +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_stores_delete.md b/docs/kfutil_stores_delete.md index 879d2a3a..b13ea730 100644 --- a/docs/kfutil_stores_delete.md +++ b/docs/kfutil_stores_delete.md @@ -41,4 +41,4 @@ kfutil stores delete [flags] * [kfutil stores](kfutil_stores.md) - Keyfactor certificate stores APIs and utilities. -###### Auto generated by spf13/cobra on 26-Feb-2024 +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_stores_export.md b/docs/kfutil_stores_export.md index 7ed91b07..07a8a61e 100644 --- a/docs/kfutil_stores_export.md +++ b/docs/kfutil_stores_export.md @@ -13,6 +13,7 @@ kfutil stores export [flags] ### Options ``` + -a, --all Export all stores grouped by store-type. -h, --help help for export -o, --outpath string Path and name of the template file to generate.. If not specified, the file will be written to the current directory. -i, --store-type-id int The ID of the cert store type for the template. (default -1) @@ -42,4 +43,4 @@ kfutil stores export [flags] * [kfutil stores](kfutil_stores.md) - Keyfactor certificate stores APIs and utilities. -###### Auto generated by spf13/cobra on 26-Feb-2024 +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_stores_get.md b/docs/kfutil_stores_get.md index dc1fd2f4..4592c8e2 100644 --- a/docs/kfutil_stores_get.md +++ b/docs/kfutil_stores_get.md @@ -40,4 +40,4 @@ kfutil stores get [flags] * [kfutil stores](kfutil_stores.md) - Keyfactor certificate stores APIs and utilities. -###### Auto generated by spf13/cobra on 26-Feb-2024 +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_stores_import.md b/docs/kfutil_stores_import.md index ab52bf04..fe02d290 100644 --- a/docs/kfutil_stores_import.md +++ b/docs/kfutil_stores_import.md @@ -37,4 +37,4 @@ Tools for generating import templates and importing certificate stores * [kfutil stores import csv](kfutil_stores_import_csv.md) - Create certificate stores from CSV file. * [kfutil stores import generate-template](kfutil_stores_import_generate-template.md) - For generating a CSV template with headers for bulk store creation. -###### Auto generated by spf13/cobra on 26-Feb-2024 +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_stores_import_csv.md b/docs/kfutil_stores_import_csv.md index 7f98c367..1766049f 100644 --- a/docs/kfutil_stores_import_csv.md +++ b/docs/kfutil_stores_import_csv.md @@ -47,4 +47,4 @@ kfutil stores import csv --file --store-type-id --store-t * [kfutil stores import](kfutil_stores_import.md) - Import a file with certificate store parameters and create them in keyfactor. -###### Auto generated by spf13/cobra on 26-Feb-2024 +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_stores_inventory.md b/docs/kfutil_stores_inventory.md index 838702f7..39563a54 100644 --- a/docs/kfutil_stores_inventory.md +++ b/docs/kfutil_stores_inventory.md @@ -38,4 +38,4 @@ Commands related to certificate store inventory management * [kfutil stores inventory remove](kfutil_stores_inventory_remove.md) - Removes a certificate from the certificate store inventory. * [kfutil stores inventory show](kfutil_stores_inventory_show.md) - Show the inventory of a certificate store. -###### Auto generated by spf13/cobra on 26-Feb-2024 +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_stores_inventory_add.md b/docs/kfutil_stores_inventory_add.md index 05f95f10..84014d22 100644 --- a/docs/kfutil_stores_inventory_add.md +++ b/docs/kfutil_stores_inventory_add.md @@ -53,4 +53,4 @@ kfutil stores inventory add [flags] * [kfutil stores inventory](kfutil_stores_inventory.md) - Commands related to certificate store inventory management -###### Auto generated by spf13/cobra on 26-Feb-2024 +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_stores_inventory_remove.md b/docs/kfutil_stores_inventory_remove.md index 93b79626..200d649a 100644 --- a/docs/kfutil_stores_inventory_remove.md +++ b/docs/kfutil_stores_inventory_remove.md @@ -49,4 +49,4 @@ kfutil stores inventory remove [flags] * [kfutil stores inventory](kfutil_stores_inventory.md) - Commands related to certificate store inventory management -###### Auto generated by spf13/cobra on 26-Feb-2024 +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_stores_inventory_show.md b/docs/kfutil_stores_inventory_show.md index c3a578f4..76ec36da 100644 --- a/docs/kfutil_stores_inventory_show.md +++ b/docs/kfutil_stores_inventory_show.md @@ -43,4 +43,4 @@ kfutil stores inventory show [flags] * [kfutil stores inventory](kfutil_stores_inventory.md) - Commands related to certificate store inventory management -###### Auto generated by spf13/cobra on 26-Feb-2024 +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_stores_list.md b/docs/kfutil_stores_list.md index 23627167..eb1eeb4d 100644 --- a/docs/kfutil_stores_list.md +++ b/docs/kfutil_stores_list.md @@ -39,4 +39,4 @@ kfutil stores list [flags] * [kfutil stores](kfutil_stores.md) - Keyfactor certificate stores APIs and utilities. -###### Auto generated by spf13/cobra on 26-Feb-2024 +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_stores_rot.md b/docs/kfutil_stores_rot.md index 65a029bd..d3d7d632 100644 --- a/docs/kfutil_stores_rot.md +++ b/docs/kfutil_stores_rot.md @@ -50,4 +50,4 @@ kfutil stores rot reconcile --import-csv * [kfutil stores rot generate-template](kfutil_stores_rot_generate-template.md) - For generating Root Of Trust template(s) * [kfutil stores rot reconcile](kfutil_stores_rot_reconcile.md) - Reconcile either takes in or will generate an audit report and then add/remove certs as needed. -###### Auto generated by spf13/cobra on 26-Feb-2024 +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_stores_rot_audit.md b/docs/kfutil_stores_rot_audit.md index 59dee834..a03ce0dc 100644 --- a/docs/kfutil_stores_rot_audit.md +++ b/docs/kfutil_stores_rot_audit.md @@ -47,4 +47,4 @@ kfutil stores rot audit [flags] * [kfutil stores rot](kfutil_stores_rot.md) - Root of trust utility -###### Auto generated by spf13/cobra on 26-Feb-2024 +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_stores_rot_generate-template.md b/docs/kfutil_stores_rot_generate-template.md index b649bb32..7c143a90 100644 --- a/docs/kfutil_stores_rot_generate-template.md +++ b/docs/kfutil_stores_rot_generate-template.md @@ -45,4 +45,4 @@ kfutil stores rot generate-template [flags] * [kfutil stores rot](kfutil_stores_rot.md) - Root of trust utility -###### Auto generated by spf13/cobra on 26-Feb-2024 +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_stores_rot_reconcile.md b/docs/kfutil_stores_rot_reconcile.md index db332235..24c49be2 100644 --- a/docs/kfutil_stores_rot_reconcile.md +++ b/docs/kfutil_stores_rot_reconcile.md @@ -52,4 +52,4 @@ kfutil stores rot reconcile [flags] * [kfutil stores rot](kfutil_stores_rot.md) - Root of trust utility -###### Auto generated by spf13/cobra on 26-Feb-2024 +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_version.md b/docs/kfutil_version.md index 571af296..45ebfb37 100644 --- a/docs/kfutil_version.md +++ b/docs/kfutil_version.md @@ -39,4 +39,4 @@ kfutil version [flags] * [kfutil](kfutil.md) - Keyfactor CLI utilities -###### Auto generated by spf13/cobra on 26-Feb-2024 +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/main.go b/main.go index 5a13705c..69f352bd 100644 --- a/main.go +++ b/main.go @@ -15,7 +15,6 @@ package main import ( - "github.com/spf13/cobra/doc" "kfutil/cmd" ) @@ -29,7 +28,3 @@ func main() { //} cmd.Execute() } - -func docs() { - doc.GenMarkdownTree(cmd.RootCmd, "./docs") -} diff --git a/pkg/version/version.go b/pkg/version/version.go index f1dfbcc2..147e8b03 100644 --- a/pkg/version/version.go +++ b/pkg/version/version.go @@ -14,4 +14,4 @@ package version -const VERSION = "1.4.0-rc.9" \ No newline at end of file +const VERSION = "1.4.0-rc.9" From 264bebe28c3b2d8bbc1e5ef7930c3b1ee755ca06 Mon Sep 17 00:00:00 2001 From: Keyfactor Robot Date: Tue, 27 Feb 2024 20:13:25 +0000 Subject: [PATCH 23/47] Bump package version to 1.4.0-rc.10 --- pkg/version/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/version/version.go b/pkg/version/version.go index 147e8b03..cd3afd7b 100644 --- a/pkg/version/version.go +++ b/pkg/version/version.go @@ -14,4 +14,4 @@ package version -const VERSION = "1.4.0-rc.9" +const VERSION = "1.4.0-rc.10" From 5bfee1a1edbae4e2287784bf8baef11be5b96749 Mon Sep 17 00:00:00 2001 From: sbailey <1661003+spbsoluble@users.noreply.github.com> Date: Tue, 27 Feb 2024 12:13:58 -0800 Subject: [PATCH 24/47] fix(ci): update gh token Signed-off-by: sbailey <1661003+spbsoluble@users.noreply.github.com> --- .github/workflows/update-stores.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/update-stores.yml b/.github/workflows/update-stores.yml index 94d4061a..72a20099 100644 --- a/.github/workflows/update-stores.yml +++ b/.github/workflows/update-stores.yml @@ -70,7 +70,7 @@ jobs: sparse-checkout: | .github path: './merge-folder/' - token: ${{ secrets.SDK_SYNC_PAT }} + token: ${{ secrets.V2BUILDTOKEN }} ref: '${{env.KFUTIL_ARG}}' # If the branch does not exist, first check out the main branch from kfutil. @@ -82,7 +82,7 @@ jobs: sparse-checkout: | .github path: './merge-folder/' - token: ${{ secrets.SDK_SYNC_PAT }} + token: ${{ secrets.V2BUILDTOKEN }} # Save a copy of the original json - name: Save original store_types.json @@ -96,7 +96,7 @@ jobs: with: repository: 'keyfactor/integration-tools' path: './tools/' - token: ${{ secrets.SDK_SYNC_PAT }} + token: ${{ secrets.V2BUILDTOKEN }} - name: Run Python Script working-directory: ./tools/store-type-merge @@ -104,7 +104,7 @@ jobs: python main.py --repo-name ${{ env.KFUTIL_ARG }} --ref ${{ env.TARGET_REPO_BRANCH }} cat store_types.json env: - GITHUB_TOKEN: ${{ secrets.SDK_SYNC_PAT }} + GITHUB_TOKEN: ${{ secrets.V2BUILDTOKEN }} - name: Save Store Types JSON Artifact if: success() @@ -194,4 +194,4 @@ jobs: }); console.log(`Pull request created: ${{env.KFUTIL_ARG}}:${{env.TARGET_REPO_BRANCH}} : ${response.data.html_url}`); env: - GITHUB_TOKEN: ${{ secrets.SDK_SYNC_PAT }} + GITHUB_TOKEN: ${{ secrets.V2BUILDTOKEN }} From 20164cfa88e06433a9d094f7f97393841e6d3234 Mon Sep 17 00:00:00 2001 From: sbailey <1661003+spbsoluble@users.noreply.github.com> Date: Tue, 27 Feb 2024 13:35:00 -0800 Subject: [PATCH 25/47] chore(docs): Update install docs. Signed-off-by: sbailey <1661003+spbsoluble@users.noreply.github.com> --- GNUmakefile | 15 ++++ README.md | 29 +++---- cmd/storesBulkOperations.go | 48 ++++++++--- docs/kfutil_completion.md | 44 +++++++++++ docs/kfutil_completion_bash.md | 63 +++++++++++++++ docs/kfutil_completion_fish.md | 54 +++++++++++++ docs/kfutil_completion_powershell.md | 51 ++++++++++++ docs/kfutil_completion_zsh.md | 65 +++++++++++++++ .../cert_stores/bulk_export_import/README.md | 61 +++++++++++++- .../cert_stores/bulk_export_import/example.sh | 79 +++++++++++++------ readme_source.md | 19 +++-- 11 files changed, 464 insertions(+), 64 deletions(-) create mode 100644 docs/kfutil_completion.md create mode 100644 docs/kfutil_completion_bash.md create mode 100644 docs/kfutil_completion_fish.md create mode 100644 docs/kfutil_completion_powershell.md create mode 100644 docs/kfutil_completion_zsh.md diff --git a/GNUmakefile b/GNUmakefile index d3c64625..2dc0ea22 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -13,6 +13,10 @@ endif OS_ARCH := $(shell go env GOOS)_$(shell go env GOARCH) BASEDIR := ${HOME}/go/bin INSTALLDIR := ${BASEDIR} +MARKDOWN_FILE := README.md +TEMP_TOC_FILE := temp_toc.md + + default: build @@ -71,4 +75,15 @@ prerelease: fmt setversion git tag $(VERSION) git push origin $(VERSION) +check_toc: + @grep -q 'TOC_START' $(MARKDOWN_FILE) && echo "TOC already exists." || (echo "TOC not found. Generating..." && $(MAKE) generate_toc) + +generate_toc: + # Generate TOC and store in temporary file + markdown-toc -i $(MARKDOWN_FILE) > $(TEMP_TOC_FILE) + # check if files are different +# @diff -q $(TEMP_TOC_FILE) $(MARKDOWN_FILE) && echo "TOC is up to date." || (echo "TOC is not up to date. Updating..." && mv $(TEMP_TOC_FILE) $(MARKDOWN_FILE)) +# @rm -f $(TEMP_TOC_FILE) + + .PHONY: build prerelease release install test fmt vendor version setversion \ No newline at end of file diff --git a/README.md b/README.md index 5687d86d..80a47b9c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,3 @@ - # Keyfactor Command Utility (kfutil) `kfutil` is a go-lang CLI wrapper for Keyfactor Command API. It also includes other utility/helper functions around automating common Keyfactor Command operations. @@ -13,18 +12,12 @@ This API client allows for programmatic management of Keyfactor resources. Keyfactor Command Utility (kfutil) is open source and supported on best effort level for this tool/library/client. This means customers can report Bugs, Feature Requests, Documentation amendment or questions as well as requests for customer information required for setup that needs Keyfactor access to obtain. Such requests do not follow normal SLA commitments for response or resolution. If you have a support issue, please open a support ticket via the Keyfactor Support Portal at https://support.keyfactor.com/ -###### To report a problem or suggest a new feature, use the **[Issues](../../issues)** tab. If you want to contribute actual bug fixes or proposed enhancements, use the **[Pull requests](../../pulls)** tab. - ---- - - ---- - - +[!NOTE] To report a problem or suggest a new feature, use the **[Issues](../../issues)** tab. If you want to contribute actual bug fixes or proposed enhancements, use the **[Pull requests](../../pulls)** tab. ## Quickstart -### Prerequisites: +### Linux/MacOS +#### Prerequisites: - [jq](https://stedolan.github.io/jq/download/) CLI tool, used to parse JSON output. - Either - [curl](https://curl.se/download.html) CLI tool, used to download the release files. @@ -33,14 +26,16 @@ Keyfactor Command Utility (kfutil) is open source and supported on best effort l - [openssl](https://www.openssl.org/source/) CLI tool, used to validate package checksum. - `$HOME/.local/bin` in your `$PATH` and exists if not running as root, else `/usr/local/bin` if running as root. -### Installation: - -#### Linux/MacOS +#### Installation: ```bash bash <(curl -s https://raw.githubusercontent.com/Keyfactor/kfutil/main/install.sh) ```` -#### Windows (or Linux/MacOS if PowerShell is preferred) +### Windows +#### Prerequisites: +- Powershell 5.1 or later + +#### Installation: ```powershell Invoke-WebRequest -Uri "https://raw.githubusercontent.com/Keyfactor/kfutil/main/install.ps1" -OutFile "install.ps1" # Install kfutil to $HOME/AppData/Local/Microsoft/WindowsApps. @@ -48,7 +43,7 @@ Invoke-WebRequest -Uri "https://raw.githubusercontent.com/Keyfactor/kfutil/main/ .\install.ps1 ``` -### Environmental Variables +## Environmental Variables All the variables listed below need to be set in your environment. The `kfutil` command will look for these variables and use them if they are set. If they are not set, the utility will fail to connect to Keyfactor. @@ -63,7 +58,7 @@ and use them if they are set. If they are not set, the utility will fail to conn | KFUTIL_EXP | Set to `1` or `true` to enable experimental features. | | KFUTIL_DEBUG | Set to `1` or `true` to enable debug logging. | -Linux/MacOS: +### Linux/MacOS: ```bash export KEYFACTOR_HOSTNAME="" @@ -80,7 +75,7 @@ export KFUTIL_EXP=0 # Set to 1 or true to enable experimental features export KFUTIL_DEBUG=0 # Set to 1 or true to enable debug logging ``` -Windows Powershell: +### Windows Powershell: ```powershell $env:KEYFACTOR_HOSTNAME = "" diff --git a/cmd/storesBulkOperations.go b/cmd/storesBulkOperations.go index bc3676ce..6bbc0beb 100644 --- a/cmd/storesBulkOperations.go +++ b/cmd/storesBulkOperations.go @@ -67,11 +67,11 @@ var storesCreateFromCSVCmd = &cobra.Command{ outPath, _ := cmd.Flags().GetString("results-path") dryRun, _ := cmd.Flags().GetBool("dry-run") - // Flag Checks - inputErr := storeTypeIdentifierFlagCheck(cmd) - if inputErr != nil { - return inputErr - } + //// Flag Checks + //inputErr := storeTypeIdentifierFlagCheck(cmd) + //if inputErr != nil { + // return inputErr + //} // expEnabled checks isExperimental := false @@ -96,8 +96,32 @@ var storesCreateFromCSVCmd = &cobra.Command{ // Check inputs st, stErr := validateStoreTypeInputs(storeTypeID, storeTypeName, outputFormat) if stErr != nil { - log.Error().Err(stErr).Msg("Error validating store type inputs") - return stErr + if noPrompt { + log.Error().Err(stErr).Msg("Error validating store type inputs") + return stErr + } + sTypes, lsErr := listStoresByType(*kfClient) + if lsErr != nil { + log.Error().Err(stErr).Msg("Error listing store types, unable to import stores") + return stErr + } + // render list of store types as options for user to select + var storeTypeOptions []string + for name, _ := range *sTypes { + storeTypeOptions = append(storeTypeOptions, fmt.Sprintf("%s", name)) + } + prompt := &survey.Select{ + Message: "Choose a store type to import:", + Options: storeTypeOptions, + } + var selected string + err := survey.AskOne(prompt, &selected) + if err != nil { + fmt.Println(err) + return err + } + st = selected + } if outPath == "" { @@ -281,12 +305,10 @@ Store type IDs can be found by running the "store-types" command.`, storeTypeID, _ := cmd.Flags().GetInt("store-type-id") outpath, _ := cmd.Flags().GetString("outpath") - if noPrompt { - inputErr := storeTypeIdentifierFlagCheck(cmd) - if inputErr != nil { - return inputErr - } - } + //inputErr := storeTypeIdentifierFlagCheck(cmd) + //if inputErr != nil { + // return inputErr + //} // expEnabled checks isExperimental := false diff --git a/docs/kfutil_completion.md b/docs/kfutil_completion.md new file mode 100644 index 00000000..e4557d02 --- /dev/null +++ b/docs/kfutil_completion.md @@ -0,0 +1,44 @@ +## kfutil completion + +Generate the autocompletion script for the specified shell + +### Synopsis + +Generate the autocompletion script for kfutil for the specified shell. +See each sub-command's help for details on how to use the generated script. + + +### Options + +``` + -h, --help help for completion +``` + +### Options inherited from parent commands + +``` + --api-path string API Path to use for authenticating to Keyfactor Command. (default is KeyfactorAPI) (default "KeyfactorAPI") + --auth-provider-profile string The profile to use defined in the securely stored config. If not specified the config named 'default' will be used if it exists. (default "default") + --auth-provider-type string Provider type choices: (azid) + --config string Full path to config file in JSON format. (default is $HOME/.keyfactor/command_config.json) + --debug Enable debugFlag logging. + --domain string Domain to use for authenticating to Keyfactor Command. + --exp Enable expEnabled features. (USE AT YOUR OWN RISK, these features are not supported and may change or be removed at any time.) + --format text How to format the CLI output. Currently only text is supported. (default "text") + --hostname string Hostname to use for authenticating to Keyfactor Command. + --log-insecure Log insecure API requests. (USE AT YOUR OWN RISK, this WILL log sensitive information to the console.) + --no-prompt Do not prompt for any user input and assume defaults or environmental variables are set. + --password string Password to use for authenticating to Keyfactor Command. WARNING: Remember to delete your console history if providing kfcPassword here in plain text. + --profile string Use a specific profile from your config file. If not specified the config named 'default' will be used if it exists. + --username string Username to use for authenticating to Keyfactor Command. +``` + +### SEE ALSO + +* [kfutil](kfutil.md) - Keyfactor CLI utilities +* [kfutil completion bash](kfutil_completion_bash.md) - Generate the autocompletion script for bash +* [kfutil completion fish](kfutil_completion_fish.md) - Generate the autocompletion script for fish +* [kfutil completion powershell](kfutil_completion_powershell.md) - Generate the autocompletion script for powershell +* [kfutil completion zsh](kfutil_completion_zsh.md) - Generate the autocompletion script for zsh + +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_completion_bash.md b/docs/kfutil_completion_bash.md new file mode 100644 index 00000000..81afccb6 --- /dev/null +++ b/docs/kfutil_completion_bash.md @@ -0,0 +1,63 @@ +## kfutil completion bash + +Generate the autocompletion script for bash + +### Synopsis + +Generate the autocompletion script for the bash shell. + +This script depends on the 'bash-completion' package. +If it is not installed already, you can install it via your OS's package manager. + +To load completions in your current shell session: + + source <(kfutil completion bash) + +To load completions for every new session, execute once: + +#### Linux: + + kfutil completion bash > /etc/bash_completion.d/kfutil + +#### macOS: + + kfutil completion bash > $(brew --prefix)/etc/bash_completion.d/kfutil + +You will need to start a new shell for this setup to take effect. + + +``` +kfutil completion bash +``` + +### Options + +``` + -h, --help help for bash + --no-descriptions disable completion descriptions +``` + +### Options inherited from parent commands + +``` + --api-path string API Path to use for authenticating to Keyfactor Command. (default is KeyfactorAPI) (default "KeyfactorAPI") + --auth-provider-profile string The profile to use defined in the securely stored config. If not specified the config named 'default' will be used if it exists. (default "default") + --auth-provider-type string Provider type choices: (azid) + --config string Full path to config file in JSON format. (default is $HOME/.keyfactor/command_config.json) + --debug Enable debugFlag logging. + --domain string Domain to use for authenticating to Keyfactor Command. + --exp Enable expEnabled features. (USE AT YOUR OWN RISK, these features are not supported and may change or be removed at any time.) + --format text How to format the CLI output. Currently only text is supported. (default "text") + --hostname string Hostname to use for authenticating to Keyfactor Command. + --log-insecure Log insecure API requests. (USE AT YOUR OWN RISK, this WILL log sensitive information to the console.) + --no-prompt Do not prompt for any user input and assume defaults or environmental variables are set. + --password string Password to use for authenticating to Keyfactor Command. WARNING: Remember to delete your console history if providing kfcPassword here in plain text. + --profile string Use a specific profile from your config file. If not specified the config named 'default' will be used if it exists. + --username string Username to use for authenticating to Keyfactor Command. +``` + +### SEE ALSO + +* [kfutil completion](kfutil_completion.md) - Generate the autocompletion script for the specified shell + +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_completion_fish.md b/docs/kfutil_completion_fish.md new file mode 100644 index 00000000..32b1b40d --- /dev/null +++ b/docs/kfutil_completion_fish.md @@ -0,0 +1,54 @@ +## kfutil completion fish + +Generate the autocompletion script for fish + +### Synopsis + +Generate the autocompletion script for the fish shell. + +To load completions in your current shell session: + + kfutil completion fish | source + +To load completions for every new session, execute once: + + kfutil completion fish > ~/.config/fish/completions/kfutil.fish + +You will need to start a new shell for this setup to take effect. + + +``` +kfutil completion fish [flags] +``` + +### Options + +``` + -h, --help help for fish + --no-descriptions disable completion descriptions +``` + +### Options inherited from parent commands + +``` + --api-path string API Path to use for authenticating to Keyfactor Command. (default is KeyfactorAPI) (default "KeyfactorAPI") + --auth-provider-profile string The profile to use defined in the securely stored config. If not specified the config named 'default' will be used if it exists. (default "default") + --auth-provider-type string Provider type choices: (azid) + --config string Full path to config file in JSON format. (default is $HOME/.keyfactor/command_config.json) + --debug Enable debugFlag logging. + --domain string Domain to use for authenticating to Keyfactor Command. + --exp Enable expEnabled features. (USE AT YOUR OWN RISK, these features are not supported and may change or be removed at any time.) + --format text How to format the CLI output. Currently only text is supported. (default "text") + --hostname string Hostname to use for authenticating to Keyfactor Command. + --log-insecure Log insecure API requests. (USE AT YOUR OWN RISK, this WILL log sensitive information to the console.) + --no-prompt Do not prompt for any user input and assume defaults or environmental variables are set. + --password string Password to use for authenticating to Keyfactor Command. WARNING: Remember to delete your console history if providing kfcPassword here in plain text. + --profile string Use a specific profile from your config file. If not specified the config named 'default' will be used if it exists. + --username string Username to use for authenticating to Keyfactor Command. +``` + +### SEE ALSO + +* [kfutil completion](kfutil_completion.md) - Generate the autocompletion script for the specified shell + +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_completion_powershell.md b/docs/kfutil_completion_powershell.md new file mode 100644 index 00000000..5a19e9f6 --- /dev/null +++ b/docs/kfutil_completion_powershell.md @@ -0,0 +1,51 @@ +## kfutil completion powershell + +Generate the autocompletion script for powershell + +### Synopsis + +Generate the autocompletion script for powershell. + +To load completions in your current shell session: + + kfutil completion powershell | Out-String | Invoke-Expression + +To load completions for every new session, add the output of the above command +to your powershell profile. + + +``` +kfutil completion powershell [flags] +``` + +### Options + +``` + -h, --help help for powershell + --no-descriptions disable completion descriptions +``` + +### Options inherited from parent commands + +``` + --api-path string API Path to use for authenticating to Keyfactor Command. (default is KeyfactorAPI) (default "KeyfactorAPI") + --auth-provider-profile string The profile to use defined in the securely stored config. If not specified the config named 'default' will be used if it exists. (default "default") + --auth-provider-type string Provider type choices: (azid) + --config string Full path to config file in JSON format. (default is $HOME/.keyfactor/command_config.json) + --debug Enable debugFlag logging. + --domain string Domain to use for authenticating to Keyfactor Command. + --exp Enable expEnabled features. (USE AT YOUR OWN RISK, these features are not supported and may change or be removed at any time.) + --format text How to format the CLI output. Currently only text is supported. (default "text") + --hostname string Hostname to use for authenticating to Keyfactor Command. + --log-insecure Log insecure API requests. (USE AT YOUR OWN RISK, this WILL log sensitive information to the console.) + --no-prompt Do not prompt for any user input and assume defaults or environmental variables are set. + --password string Password to use for authenticating to Keyfactor Command. WARNING: Remember to delete your console history if providing kfcPassword here in plain text. + --profile string Use a specific profile from your config file. If not specified the config named 'default' will be used if it exists. + --username string Username to use for authenticating to Keyfactor Command. +``` + +### SEE ALSO + +* [kfutil completion](kfutil_completion.md) - Generate the autocompletion script for the specified shell + +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/docs/kfutil_completion_zsh.md b/docs/kfutil_completion_zsh.md new file mode 100644 index 00000000..8865a542 --- /dev/null +++ b/docs/kfutil_completion_zsh.md @@ -0,0 +1,65 @@ +## kfutil completion zsh + +Generate the autocompletion script for zsh + +### Synopsis + +Generate the autocompletion script for the zsh shell. + +If shell completion is not already enabled in your environment you will need +to enable it. You can execute the following once: + + echo "autoload -U compinit; compinit" >> ~/.zshrc + +To load completions in your current shell session: + + source <(kfutil completion zsh) + +To load completions for every new session, execute once: + +#### Linux: + + kfutil completion zsh > "${fpath[1]}/_kfutil" + +#### macOS: + + kfutil completion zsh > $(brew --prefix)/share/zsh/site-functions/_kfutil + +You will need to start a new shell for this setup to take effect. + + +``` +kfutil completion zsh [flags] +``` + +### Options + +``` + -h, --help help for zsh + --no-descriptions disable completion descriptions +``` + +### Options inherited from parent commands + +``` + --api-path string API Path to use for authenticating to Keyfactor Command. (default is KeyfactorAPI) (default "KeyfactorAPI") + --auth-provider-profile string The profile to use defined in the securely stored config. If not specified the config named 'default' will be used if it exists. (default "default") + --auth-provider-type string Provider type choices: (azid) + --config string Full path to config file in JSON format. (default is $HOME/.keyfactor/command_config.json) + --debug Enable debugFlag logging. + --domain string Domain to use for authenticating to Keyfactor Command. + --exp Enable expEnabled features. (USE AT YOUR OWN RISK, these features are not supported and may change or be removed at any time.) + --format text How to format the CLI output. Currently only text is supported. (default "text") + --hostname string Hostname to use for authenticating to Keyfactor Command. + --log-insecure Log insecure API requests. (USE AT YOUR OWN RISK, this WILL log sensitive information to the console.) + --no-prompt Do not prompt for any user input and assume defaults or environmental variables are set. + --password string Password to use for authenticating to Keyfactor Command. WARNING: Remember to delete your console history if providing kfcPassword here in plain text. + --profile string Use a specific profile from your config file. If not specified the config named 'default' will be used if it exists. + --username string Username to use for authenticating to Keyfactor Command. +``` + +### SEE ALSO + +* [kfutil completion](kfutil_completion.md) - Generate the autocompletion script for the specified shell + +###### Auto generated by spf13/cobra on 27-Feb-2024 diff --git a/examples/cert_stores/bulk_export_import/README.md b/examples/cert_stores/bulk_export_import/README.md index 471a56d1..18cccb03 100644 --- a/examples/cert_stores/bulk_export_import/README.md +++ b/examples/cert_stores/bulk_export_import/README.md @@ -12,7 +12,12 @@ This will demo how to use `kfutil` to bulk import and export Keyfactor Command C You can use `kfutil` to create a specific certificate store type, or all supported certificate store types. #### User Interactive Mode: +Below is an example of creating a specific certificate store type `AKV`. ```bash +kfutil store-types create +``` +##### Example Output: +```text kfutil store-types create ? Choose an option: [Use arrows to move, type to filter] > AKV @@ -22,9 +27,12 @@ kfutil store-types create Fortigate HCVKV HCVKVJKS + +Certificate store type AKV created with ID: 166 ``` #### Non-Interactive Mode: +This will create all supported certificate store types. *Note* this will not update any existing certificate store types. ```bash kfutil store-types create --all ``` @@ -42,8 +50,38 @@ kfutil stores import generate-template --store-type-name rfpem #### Export an existing certificate stores by store-type Below is an example of exporting all certificate stores of a specific store type `k8ssecret`. [!IMPORTANT] This will *not* export any secrets or sensitive information associated with the certificate stores. + +##### User Interactive Mode: ```bash -kfutil stores export --store-type-name k8ssecret +kfutil stores export +``` + +###### Example Output: +```text +kfutil stores export +? Choose a store type to export: [Use arrows to move, type to filter] +> K8SSecret + K8SCluster + K8SNS + +Stores exported for store type with id 133 written to K8SSecret_stores_export_1709065204.csv +``` + +##### Non-Interactive Mode: +This will export all certificate stores of all store types into CSV files for each store type. +```bash +kfutil stores export --all +``` + +###### Example Output: +```text +kfutil stores export --all + +Stores exported for store type with id 133 written to K8SSecret_stores_export_1709066753.csv + +Stores exported for store type with id 147 written to K8SCluster_stores_export_1709066754.csv + +Stores exported for store type with id 149 written to K8SNS_stores_export_1709066755.csv ``` ### Step 2: Edit the CSV file @@ -52,7 +90,22 @@ it to see what the CSV file should look like. At bare minimum, the store credent cannot be exported from Keyfactor Command. ### Step 3: Import the CSV file -You can use `kfutil` to import a CSV file that contains the certificate store information to be imported into Keyfactor Command. +You can use `kfutil` to import a CSV file that contains the certificate store information to be imported into Keyfactor +Command. ```bash -kfutil stores import --file /path/to/csv/file.csv -``` \ No newline at end of file +kfutil stores import csv --file /path/to/csv/file.csv +``` + +#### Example Output: +```text + kfutil stores import csv --file K8SCluster_stores_export_1709066656.csv +? Choose a store type to import: [Use arrows to move, type to filter] + K8SSecret +> K8SCluster + K8SNS + +1 records processed. +1 rows had errors. +Import results written to K8SCluster_stores_export_1709066656_results.csv +``` + diff --git a/examples/cert_stores/bulk_export_import/example.sh b/examples/cert_stores/bulk_export_import/example.sh index 49cf76cc..f4b22220 100755 --- a/examples/cert_stores/bulk_export_import/example.sh +++ b/examples/cert_stores/bulk_export_import/example.sh @@ -21,9 +21,55 @@ function prompt_user() { exit 1 fi - list_stores - generate_store_template +# list_stores +# generate_store_template + export_stores + import_stores +} + +function export_stores() { + kfutil stores export +} + +function import_stores(){ + # Directory containing the CSV files + DIRECTORY=$(pwd) + + # Find all CSV files in the specified directory + CSV_FILES=($(find "$DIRECTORY" -name "*.csv")) + + # Check if no CSV files were found + if [ ${#CSV_FILES[@]} -eq 0 ]; then + echo "No CSV files found in the directory." + exit 1 + fi + + # Display the CSV files to the user + echo "Select a CSV file by number:" + for i in "${!CSV_FILES[@]}"; do + echo "$((i+1))) ${CSV_FILES[$i]}" + done + + # Prompt the user for a choice + read -p "Enter number (1-${#CSV_FILES[@]}): " USER_CHOICE + + # Validate the user input + if ! [[ "$USER_CHOICE" =~ ^[0-9]+$ ]] || [ "$USER_CHOICE" -lt 1 ] || [ "$USER_CHOICE" -gt ${#CSV_FILES[@]} ]; then + echo "Invalid selection. Please run the script again and select a valid number." + exit 1 + fi + + # Calculate the index of the selected file + SELECTED_INDEX=$((USER_CHOICE-1)) + + # Get the selected CSV file + SELECTED_CSV_FILE=${CSV_FILES[$SELECTED_INDEX]} + # Execute the command with the selected CSV file + kfutil stores import csv \ + --file="$SELECTED_CSV_FILE" + + echo "CSV import command executed for file: $SELECTED_CSV_FILE" } function list_stores() { @@ -51,28 +97,8 @@ function install_kfutil() { } function generate_store_template() { - local store_type_id="$1" - local store_type_name="$2" - local outpath="$3" command_str="kfutil stores import generate-template" - # If neither store_type_id nor store_type_name is provided, exit - if [[ -z "$store_type_id" && -z "$store_type_name" ]]; then - # Prompt for an ID or name - read -p "Please provide a store type ID or name: " store_type_id - # Check if input is a number - if [[ $store_type_id =~ ^[0-9]+$ ]]; then - # If input is a number, use it as store_type_id - store_type_name="" - # append store_type_id to command_str - command_str="$command_str --store-type-id $store_type_id" - else - store_type_name="$store_type_id" - # append store_type_name to command_str - command_str="$command_str --store-type-name $store_type_name" - fi - fi - # If outpath is not provided, check for environment variable if [[ -z "$outpath" ]]; then if [[ -z "$KFUTIL_STORE_TEMPLATE_PATH" ]]; then @@ -91,5 +117,14 @@ function generate_store_template() { eval "$command_str" } +function cleanup() { + echo "Cleaning up..." + unset outpath + unset KFUTIL_STORE_TEMPLATE_PATH + rm -f *.csv + echo "Cleanup complete." +} + prompt_user +cleanup diff --git a/readme_source.md b/readme_source.md index c381dafe..998a962d 100644 --- a/readme_source.md +++ b/readme_source.md @@ -1,6 +1,7 @@ ## Quickstart -### Prerequisites: +### Linux/MacOS +#### Prerequisites: - [jq](https://stedolan.github.io/jq/download/) CLI tool, used to parse JSON output. - Either - [curl](https://curl.se/download.html) CLI tool, used to download the release files. @@ -9,14 +10,16 @@ - [openssl](https://www.openssl.org/source/) CLI tool, used to validate package checksum. - `$HOME/.local/bin` in your `$PATH` and exists if not running as root, else `/usr/local/bin` if running as root. -### Installation: - -#### Linux/MacOS +#### Installation: ```bash bash <(curl -s https://raw.githubusercontent.com/Keyfactor/kfutil/main/install.sh) ```` -#### Windows (or Linux/MacOS if PowerShell is preferred) +### Windows +#### Prerequisites: +- Powershell 5.1 or later + +#### Installation: ```powershell Invoke-WebRequest -Uri "https://raw.githubusercontent.com/Keyfactor/kfutil/main/install.ps1" -OutFile "install.ps1" # Install kfutil to $HOME/AppData/Local/Microsoft/WindowsApps. @@ -24,7 +27,7 @@ Invoke-WebRequest -Uri "https://raw.githubusercontent.com/Keyfactor/kfutil/main/ .\install.ps1 ``` -### Environmental Variables +## Environmental Variables All the variables listed below need to be set in your environment. The `kfutil` command will look for these variables and use them if they are set. If they are not set, the utility will fail to connect to Keyfactor. @@ -39,7 +42,7 @@ and use them if they are set. If they are not set, the utility will fail to conn | KFUTIL_EXP | Set to `1` or `true` to enable experimental features. | | KFUTIL_DEBUG | Set to `1` or `true` to enable debug logging. | -Linux/MacOS: +### Linux/MacOS: ```bash export KEYFACTOR_HOSTNAME="" @@ -56,7 +59,7 @@ export KFUTIL_EXP=0 # Set to 1 or true to enable experimental features export KFUTIL_DEBUG=0 # Set to 1 or true to enable debug logging ``` -Windows Powershell: +### Windows Powershell: ```powershell $env:KEYFACTOR_HOSTNAME = "" From 92c1739bb5e9fc6f3aa2afaf239333ec0bdca24b Mon Sep 17 00:00:00 2001 From: sbailey <1661003+spbsoluble@users.noreply.github.com> Date: Tue, 27 Feb 2024 13:36:32 -0800 Subject: [PATCH 26/47] chore(docs): generate TOC Signed-off-by: sbailey <1661003+spbsoluble@users.noreply.github.com> --- README.md | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/README.md b/README.md index 80a47b9c..8b6161f3 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,42 @@ #### Integration status: Production - Ready for use in production environments. + + +- [About the Keyfactor API Client](#about-the-keyfactor-api-client) +- [Support for Keyfactor Command Utility (kfutil)](#support-for-keyfactor-command-utility-kfutil) +- [Quickstart](#quickstart) + * [Linux/MacOS](#linuxmacos) + + [Prerequisites:](#prerequisites) + + [Installation:](#installation) + * [Windows](#windows) + + [Prerequisites:](#prerequisites-1) + + [Installation:](#installation-1) +- [Environmental Variables](#environmental-variables) + * [Linux/MacOS:](#linuxmacos) + * [Windows Powershell:](#windows-powershell) +- [Authentication Providers](#authentication-providers) +- [Commands](#commands) + * [Login](#login) + * [Logout](#logout) +- [Commands](#commands-1) + * [Bulk operations](#bulk-operations) + + [Bulk create cert stores](#bulk-create-cert-stores) + + [Bulk create cert store types](#bulk-create-cert-store-types) + * [Root of Trust](#root-of-trust) + * [Root of Trust Quickstart](#root-of-trust-quickstart) + + [Generate Certificate List Template](#generate-certificate-list-template) + + [Generate Certificate Store List Template](#generate-certificate-store-list-template) + + [Run Root of Trust Audit](#run-root-of-trust-audit) + + [Run Root of Trust Reconcile](#run-root-of-trust-reconcile) + * [Certificate Store Inventory](#certificate-store-inventory) + + [Show the inventory of a certificate store](#show-the-inventory-of-a-certificate-store) + + [Add certificates to certificate stores](#add-certificates-to-certificate-stores) + + [Remove certificates from certificate stores](#remove-certificates-from-certificate-stores) +- [Development](#development) + * [Adding a new command](#adding-a-new-command) + + ## About the Keyfactor API Client This API client allows for programmatic management of Keyfactor resources. From bc35dd7b3878b3e0cbc6dacc6cbec7587420111d Mon Sep 17 00:00:00 2001 From: Keyfactor Robot Date: Tue, 27 Feb 2024 21:37:18 +0000 Subject: [PATCH 27/47] Bump package version to 1.4.0-rc.12 --- pkg/version/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/version/version.go b/pkg/version/version.go index cd3afd7b..cb9e54c6 100644 --- a/pkg/version/version.go +++ b/pkg/version/version.go @@ -14,4 +14,4 @@ package version -const VERSION = "1.4.0-rc.10" +const VERSION = "1.4.0-rc.12" From 45178154918ea36a6030356dd343bf71e5173d3c Mon Sep 17 00:00:00 2001 From: sbailey <1661003+spbsoluble@users.noreply.github.com> Date: Tue, 27 Feb 2024 13:38:25 -0800 Subject: [PATCH 28/47] chore(docs): Rename docs path Signed-off-by: sbailey <1661003+spbsoluble@users.noreply.github.com> --- README.md | 3 ++- .../{bulk_export_import => bulk_operations}/README.md | 0 .../{bulk_export_import => bulk_operations}/example.sh | 0 3 files changed, 2 insertions(+), 1 deletion(-) rename examples/cert_stores/{bulk_export_import => bulk_operations}/README.md (100%) rename examples/cert_stores/{bulk_export_import => bulk_operations}/example.sh (100%) diff --git a/README.md b/README.md index 8b6161f3..32570f68 100644 --- a/README.md +++ b/README.md @@ -169,7 +169,8 @@ kfutil logout #### Bulk create cert stores -For full documentation, see [stores import](docs/kfutil_stores_import.md). +For full documentation, see [stores import](docs/kfutil_stores_import.md). For a full user-interactive guide, see the +[stores bulk operations examples](examples/cert_stores/bulk_operations/README.md). This will attempt to process a CSV input file of certificate stores to create. The template can be generated by running: `kfutil stores import generate-template` command. diff --git a/examples/cert_stores/bulk_export_import/README.md b/examples/cert_stores/bulk_operations/README.md similarity index 100% rename from examples/cert_stores/bulk_export_import/README.md rename to examples/cert_stores/bulk_operations/README.md diff --git a/examples/cert_stores/bulk_export_import/example.sh b/examples/cert_stores/bulk_operations/example.sh similarity index 100% rename from examples/cert_stores/bulk_export_import/example.sh rename to examples/cert_stores/bulk_operations/example.sh From a6661a06081eb1de60d20aadafb9325b5d7b4a01 Mon Sep 17 00:00:00 2001 From: Keyfactor Robot Date: Tue, 27 Feb 2024 21:39:26 +0000 Subject: [PATCH 29/47] Bump package version to 1.4.0-rc.13 --- pkg/version/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/version/version.go b/pkg/version/version.go index cb9e54c6..a7f8bc2d 100644 --- a/pkg/version/version.go +++ b/pkg/version/version.go @@ -14,4 +14,4 @@ package version -const VERSION = "1.4.0-rc.12" +const VERSION = "1.4.0-rc.13" From a3c3da6fe93b5598fc75d5f20ad173fe50515cba Mon Sep 17 00:00:00 2001 From: sbailey <1661003+spbsoluble@users.noreply.github.com> Date: Tue, 27 Feb 2024 13:46:08 -0800 Subject: [PATCH 30/47] chore(docs): Update Makefile toc target Signed-off-by: sbailey <1661003+spbsoluble@users.noreply.github.com> --- GNUmakefile | 8 +++----- README.md | 1 + 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/GNUmakefile b/GNUmakefile index 2dc0ea22..3ec82577 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -79,11 +79,9 @@ check_toc: @grep -q 'TOC_START' $(MARKDOWN_FILE) && echo "TOC already exists." || (echo "TOC not found. Generating..." && $(MAKE) generate_toc) generate_toc: - # Generate TOC and store in temporary file - markdown-toc -i $(MARKDOWN_FILE) > $(TEMP_TOC_FILE) - # check if files are different -# @diff -q $(TEMP_TOC_FILE) $(MARKDOWN_FILE) && echo "TOC is up to date." || (echo "TOC is not up to date. Updating..." && mv $(TEMP_TOC_FILE) $(MARKDOWN_FILE)) -# @rm -f $(TEMP_TOC_FILE) + # check if markdown-toc is installed and if not install it + @command -v markdown-toc >/dev/null 2>&1 || (echo "markdown-toc is not installed. Installing..." && npm install -g markdown-toc) + markdown-toc -i $(MARKDOWN_FILE) --skip 'Table of Contents' .PHONY: build prerelease release install test fmt vendor version setversion \ No newline at end of file diff --git a/README.md b/README.md index 32570f68..5aa6883f 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,7 @@ + [Remove certificates from certificate stores](#remove-certificates-from-certificate-stores) - [Development](#development) * [Adding a new command](#adding-a-new-command) + ## About the Keyfactor API Client From d45603cfbeb931180f78f0467c6af072fc446a79 Mon Sep 17 00:00:00 2001 From: Keyfactor Robot Date: Tue, 27 Feb 2024 21:46:56 +0000 Subject: [PATCH 31/47] Bump package version to 1.4.0-rc.14 --- pkg/version/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/version/version.go b/pkg/version/version.go index a7f8bc2d..48826c27 100644 --- a/pkg/version/version.go +++ b/pkg/version/version.go @@ -14,4 +14,4 @@ package version -const VERSION = "1.4.0-rc.13" +const VERSION = "1.4.0-rc.14" From 9ba647f1128201784095d1780176e2f04cb04c93 Mon Sep 17 00:00:00 2001 From: sbailey <1661003+spbsoluble@users.noreply.github.com> Date: Tue, 27 Feb 2024 13:50:36 -0800 Subject: [PATCH 32/47] chore(docs): Update TOC Signed-off-by: sbailey <1661003+spbsoluble@users.noreply.github.com> --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5aa6883f..db237bec 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ + [Bulk create cert stores](#bulk-create-cert-stores) + [Bulk create cert store types](#bulk-create-cert-store-types) * [Root of Trust](#root-of-trust) - * [Root of Trust Quickstart](#root-of-trust-quickstart) + + [Quickstart](#quickstart-1) + [Generate Certificate List Template](#generate-certificate-list-template) + [Generate Certificate Store List Template](#generate-certificate-store-list-template) + [Run Root of Trust Audit](#run-root-of-trust-audit) @@ -251,7 +251,7 @@ For full documentation, see [stores rot](docs/kfutil_stores_rot.md). The root of trust (rot) utility is a tool that allows you to bulk manage Keyfactor certificate stores and ensure that a set of defined certificates are present in each store that meets a certain set of criteria or no criteria at all. -### Root of Trust Quickstart +#### Quickstart ```bash echo "Generating cert template file certs_template.csv" From cb2d36921d2c60d29dde63443d14f2b4a4c80719 Mon Sep 17 00:00:00 2001 From: Keyfactor Robot Date: Tue, 27 Feb 2024 21:51:23 +0000 Subject: [PATCH 33/47] Bump package version to 1.4.0-rc.15 --- pkg/version/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/version/version.go b/pkg/version/version.go index 48826c27..90f28f11 100644 --- a/pkg/version/version.go +++ b/pkg/version/version.go @@ -14,4 +14,4 @@ package version -const VERSION = "1.4.0-rc.14" +const VERSION = "1.4.0-rc.15" From 47465e9ee95500f0fea46fbff3d7b679e1a5c44d Mon Sep 17 00:00:00 2001 From: sbailey <1661003+spbsoluble@users.noreply.github.com> Date: Tue, 27 Feb 2024 13:52:57 -0800 Subject: [PATCH 34/47] chore(docs): Update TOC Signed-off-by: sbailey <1661003+spbsoluble@users.noreply.github.com> --- readme_source.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme_source.md b/readme_source.md index 998a962d..0cc81d69 100644 --- a/readme_source.md +++ b/readme_source.md @@ -182,7 +182,7 @@ For full documentation, see [stores rot](docs/kfutil_stores_rot.md). The root of trust (rot) utility is a tool that allows you to bulk manage Keyfactor certificate stores and ensure that a set of defined certificates are present in each store that meets a certain set of criteria or no criteria at all. -### Root of Trust Quickstart +#### Root of Trust Quickstart ```bash echo "Generating cert template file certs_template.csv" From 5cf2e908ab1484d733f4debb0620447b01f1f044 Mon Sep 17 00:00:00 2001 From: Keyfactor Robot Date: Tue, 27 Feb 2024 21:53:53 +0000 Subject: [PATCH 35/47] Bump package version to 1.4.0-rc.16 --- pkg/version/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/version/version.go b/pkg/version/version.go index 90f28f11..d8f34fdc 100644 --- a/pkg/version/version.go +++ b/pkg/version/version.go @@ -14,4 +14,4 @@ package version -const VERSION = "1.4.0-rc.15" +const VERSION = "1.4.0-rc.16" From 4022f112ca57b2101b7d6cc391fef9472ba09027 Mon Sep 17 00:00:00 2001 From: sbailey <1661003+spbsoluble@users.noreply.github.com> Date: Tue, 27 Feb 2024 15:12:38 -0800 Subject: [PATCH 36/47] feat(stores): `delete` can be called interactively or from a file path that contains a CSV of Ids. Signed-off-by: sbailey <1661003+spbsoluble@users.noreply.github.com> --- cmd/stores.go | 121 +++++++++++++++++- .../cert_stores/bulk_operations/README.md | 106 +++++++++++++++ 2 files changed, 224 insertions(+), 3 deletions(-) diff --git a/cmd/stores.go b/cmd/stores.go index 327ad8ab..bad34f78 100644 --- a/cmd/stores.go +++ b/cmd/stores.go @@ -15,10 +15,13 @@ package cmd import ( + "encoding/csv" "encoding/json" "fmt" + "github.com/AlecAivazis/survey/v2" "github.com/rs/zerolog/log" "github.com/spf13/cobra" + "os" ) // storesCmd represents the stores command @@ -114,6 +117,8 @@ var storesDeleteCmd = &cobra.Command{ // Specific flags storeID, _ := cmd.Flags().GetString("id") deleteAll, _ := cmd.Flags().GetBool("all") + inputFile, _ := cmd.Flags().GetString("file") + //outPath, _ := cmd.Flags().GetString("outpath") // Debug + expEnabled checks isExperimental := false @@ -147,24 +152,132 @@ var storesDeleteCmd = &cobra.Command{ for _, s := range *storesResp { stores = append(stores, s.Id) } - } else { + } else if storeID != "" { stores = append(stores, storeID) + } else if inputFile != "" { + // check that the input file is a valid csv file and contains the "Id" column in the header + // if it is, read the file and add the Ids to the stores list + // if it is not, return an error + + csvFile, ioErr := os.Open(inputFile) + if ioErr != nil { + log.Error().Err(ioErr).Msgf("unable to open file: '%s'", inputFile) + //outputError(err, true, outputFormat) + cmd.SilenceUsage = true + return ioErr + } + log.Info().Msgf("Reading file '%s' as CSV", inputFile) + inFile, cErr := csv.NewReader(csvFile).ReadAll() + inputMap, _ := csvToMap(inputFile) + if cErr != nil { + log.Error().Err(cErr). + Str("filePath", inputFile). + Msg("unable to read file") + //outputError(cErr, true, outputFormat) + cmd.SilenceUsage = true + return cErr + } + if len(inFile) < 1 { + log.Error().Msg("No data in file") + //outputError(errors.New("no data in file"), true, outputFormat) + cmd.SilenceUsage = true + return fmt.Errorf("no data in file %s", inputFile) + } + headerRow := inFile[0] + //check that the header row contains the "Id" column + containsID := false + for _, h := range headerRow { + if h == "Id" { + containsID = true + break + } + } + if !containsID { + log.Error().Msg("File does not contain 'Id' column") + //outputError(errors.New("file does not contain 'Id' column"), true, outputFormat) + cmd.SilenceUsage = true + return fmt.Errorf("file does not contain 'Id' column, unable to delete stores") + } + + for row, data := range inputMap { + log.Trace(). + Int("row", row).Str("file", inputFile). + Msg("Reading row from file") + log.Debug().Str("storeID", data["Id"]).Msg("Adding store to delete list") + stores = append(stores, data["Id"]) + } + + } else { + //prompt as a multi-select for list of stores retrieved from command to delete + log.Info().Msg("No store ID provided, prompting for store to delete") + storesResp, err := kfClient.ListCertificateStores(nil) + if err != nil { + log.Error().Err(err).Send() + return err + } + storesMap := make(map[string]string) + sTypesMap := make(map[int]string) + for _, s := range *storesResp { + //lookup storetype if not already in map + if _, ok := sTypesMap[s.CertStoreType]; !ok { + sTypeResp, err := kfClient.GetCertificateStoreType(s.CertStoreType) + if err != nil { + log.Error().Err(err).Send() + continue + } + sTypesMap[sTypeResp.StoreType] = sTypeResp.Name + } + name := fmt.Sprintf("%s/%s/%s (%s)", sTypesMap[s.CertStoreType], s.ClientMachine, s.StorePath, s.Id) + storesMap[name] = s.Id + } + + // get all keys from storesMap + storeOptions := make([]string, 0, len(storesMap)) + for k := range storesMap { + storeOptions = append(storeOptions, k) + } + + prompt := &survey.MultiSelect{ + Message: "Choose 1 or more stores to delete:", + Options: storeOptions, + } + + var selectedStores []string + askErr := survey.AskOne(prompt, &selectedStores) + if askErr != nil { + log.Error().Err(askErr).Send() + return askErr + } + for _, s := range selectedStores { + log.Debug().Str("storeID", storesMap[s]).Msg("Adding store to delete list") + stores = append(stores, storesMap[s]) + } } + var errs []error for _, st := range stores { _, err := kfClient.GetCertificateStoreByID(st) if err != nil { log.Error().Err(err).Send() - return err + errs = append(errs, fmt.Errorf("Store ID '%s': '%s'", st, err.Error())) + continue } dErr := kfClient.DeleteCertificateStore(st) if dErr != nil { log.Error().Err(dErr).Send() - return dErr + errs = append(errs, dErr) + continue } outputResult(fmt.Sprintf("successfully deleted store %s", st), outputFormat) } + if len(errs) > 0 { + errsStr := "" + for _, e := range errs { + errsStr += e.Error() + "\n\t" + } + return fmt.Errorf("occurred while deleting stores:\n\t%s", errsStr) + } return nil }, } @@ -173,6 +286,7 @@ func init() { var ( storeID string deleteAll bool + inputFile string ) RootCmd.AddCommand(storesCmd) storesCmd.AddCommand(storesListCmd) @@ -184,6 +298,7 @@ func init() { // delete cmd storesDeleteCmd.Flags().StringVarP(&storeID, "id", "i", "", "ID of the certificate store to delete.") + storesDeleteCmd.Flags().StringVarP(&inputFile, "file", "f", "", "The path to a CSV file containing the Ids of the stores to delete.") storesDeleteCmd.Flags().BoolVarP(&deleteAll, "all", "a", false, "Attempt to delete ALL stores.") storesDeleteCmd.MarkFlagsMutuallyExclusive("id", "all") diff --git a/examples/cert_stores/bulk_operations/README.md b/examples/cert_stores/bulk_operations/README.md index 18cccb03..b2854e42 100644 --- a/examples/cert_stores/bulk_operations/README.md +++ b/examples/cert_stores/bulk_operations/README.md @@ -1,6 +1,40 @@ # Keyfactor Command Bulk Certificate Store Operations This will demo how to use `kfutil` to bulk import and export Keyfactor Command Certificate Stores. + + +- [Prerequisites](#prerequisites) +- [Guide](#guide) + * [Step 0: Create the certificate store type](#step-0-create-the-certificate-store-type) + + [User Interactive Mode:](#user-interactive-mode) + - [Example Output:](#example-output) + + [Non-Interactive Mode:](#non-interactive-mode) + * [Step 1: Generate an import template CSV file](#step-1-generate-an-import-template-csv-file) + + [Export a store-type template](#export-a-store-type-template) + + [Export an existing certificate stores by store-type](#export-an-existing-certificate-stores-by-store-type) + - [User Interactive Mode:](#user-interactive-mode-1) + * [Example Output:](#example-output-1) + - [Non-Interactive Mode:](#non-interactive-mode-1) + * [Example Output:](#example-output-2) + * [Step 2: Edit the CSV file](#step-2-edit-the-csv-file) + * [Step 3: Import the CSV file](#step-3-import-the-csv-file) + + [Example Output:](#example-output-3) +- [Operations](#operations) + * [Bulk Create/Import Certificate Stores](#bulk-createimport-certificate-stores) + + [User Interactive Mode:](#user-interactive-mode-2) + + [Non-Interactive Mode:](#non-interactive-mode-2) + + [Example Output:](#example-output-4) + * [Bulk Export Certificate Stores](#bulk-export-certificate-stores) + + [User Interactive Mode:](#user-interactive-mode-3) + + [Non-Interactive Mode:](#non-interactive-mode-3) + + [Example Output:](#example-output-5) + * [Delete Certificate Store](#delete-certificate-store) + + [User Interactive Mode:](#user-interactive-mode-4) + + [Non-Interactive Mode:](#non-interactive-mode-4) + + [Example Output:](#example-output-6) + + + ## Prerequisites - `kfutil` v1.4.0 or later - Keyfactor Command v10.x @@ -109,3 +143,75 @@ kfutil stores import csv --file /path/to/csv/file.csv Import results written to K8SCluster_stores_export_1709066656_results.csv ``` +## Operations + +### Bulk Create/Import Certificate Stores + +#### User Interactive Mode: +```bash +kfutil stores import csv --file /path/to/csv/file.csv +``` + +#### Non-Interactive Mode: +```bash +kfutil stores import csv \ + --file /path/to/csv/file.csv \ + --store-type-name +``` + +#### Example Output: +```text + kfutil stores import csv --file K8SCluster_stores_export_1709066656.csv +? Choose a store type to import: [Use arrows to move, type to filter] +> K8SCluster +? Choose a store type to import: K8SCluster +1 records processed. +1 rows had errors. +Import results written to K8SCluster_stores_export_1709072563_results.csv +``` + +### Bulk Export Certificate Stores + +#### User Interactive Mode: +```bash +kfutil stores export +``` + +#### Non-Interactive Mode: +```bash +kfutil stores export --all +``` + +#### Example Output: +```text +kfutil stores export +? Choose a store type to export: [Use arrows to move, type to filter] +> K8SCluster +? Choose a store type to export: K8SCluster + +Stores exported for store type with id 147 written to K8SCluster_stores_export_1709072563.csv +``` + +### Delete Certificate Store + +#### User Interactive Mode: +```bash +kfutil stores delete +``` + +#### Non-Interactive Mode: +```bash +kfutil stores delete --file /path/to/csv/file.csv +``` + +#### Example Output: +```text +kfutil stores delete +? Choose a store type to import: [Use arrows to move, space to select, to all, to none, type to filter] +> [x] K8SSecret/dev/keyfactor/test (d2de98e9-b384-4b55-9118-d5780655aeee) +> [ ] K8SCluster/dev/cluster (a78b08e1-063b-42da-8c97-81a0bf8cd282) +> [x] K8SNS/dev/default (75b732b9-71a1-4ff4-ac70-60a8c5936532) +Choose stores to delete: K8SSecret/dev/keyfactor/test (d2de98e9-b384-4b55-9118-d5780655aeee), K8SNS/dev/default (75b732b9-71a1-4ff4-ac70-60a8c5936532) +successfully deleted store d2de98e9-b384-4b55-9118-d5780655aeee +successfully deleted store 75b732b9-71a1-4ff4-ac70-60a8c5936532 +``` \ No newline at end of file From e7f7e85012094d6b7645977d7b6af0d625641829 Mon Sep 17 00:00:00 2001 From: Keyfactor Robot Date: Tue, 27 Feb 2024 23:13:18 +0000 Subject: [PATCH 37/47] Bump package version to 1.4.0-rc.17 --- pkg/version/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/version/version.go b/pkg/version/version.go index d8f34fdc..6b1e53e0 100644 --- a/pkg/version/version.go +++ b/pkg/version/version.go @@ -14,4 +14,4 @@ package version -const VERSION = "1.4.0-rc.16" +const VERSION = "1.4.0-rc.17" From c5ea5d98959765d68cc8e22363c4234f6d662989 Mon Sep 17 00:00:00 2001 From: sbailey <1661003+spbsoluble@users.noreply.github.com> Date: Tue, 27 Feb 2024 15:13:18 -0800 Subject: [PATCH 38/47] chore(docs): Update `stores delete` docs Signed-off-by: sbailey <1661003+spbsoluble@users.noreply.github.com> --- docs/kfutil_stores_delete.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/docs/kfutil_stores_delete.md b/docs/kfutil_stores_delete.md index b13ea730..b1f6f106 100644 --- a/docs/kfutil_stores_delete.md +++ b/docs/kfutil_stores_delete.md @@ -13,9 +13,10 @@ kfutil stores delete [flags] ### Options ``` - -a, --all Attempt to delete ALL stores. - -h, --help help for delete - -i, --id string ID of the certificate store to delete. + -a, --all Attempt to delete ALL stores. + -f, --file string The path to a CSV file containing the Ids of the stores to delete. + -h, --help help for delete + -i, --id string ID of the certificate store to delete. ``` ### Options inherited from parent commands From cdba8ebbbdfec93ac1df5918eab4a3d24dd8b941 Mon Sep 17 00:00:00 2001 From: Keyfactor Robot Date: Tue, 27 Feb 2024 23:21:18 +0000 Subject: [PATCH 39/47] Bump package version to 1.4.0-rc.18 --- pkg/version/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/version/version.go b/pkg/version/version.go index 6b1e53e0..f740622d 100644 --- a/pkg/version/version.go +++ b/pkg/version/version.go @@ -14,4 +14,4 @@ package version -const VERSION = "1.4.0-rc.17" +const VERSION = "1.4.0-rc.18" From 4b36c7e8e3511389643ce62176b918fcb1bbf77c Mon Sep 17 00:00:00 2001 From: sbailey <1661003+spbsoluble@users.noreply.github.com> Date: Tue, 27 Feb 2024 15:23:42 -0800 Subject: [PATCH 40/47] chore(docs): Update CHANGELOG.md Signed-off-by: sbailey <1661003+spbsoluble@users.noreply.github.com> --- .github/workflows/tests.yml | 1 + CHANGELOG.md | 10 +++++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 9959e5f0..1343b6ae 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,6 +1,7 @@ name: go tests on: + workflow_dispatch: workflow_run: workflows: - "Check and Update Package Version" diff --git a/CHANGELOG.md b/CHANGELOG.md index f5cd9acd..fe29d84f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,11 @@ # v1.4.0 ## Features -- `stores import generate-template`: Sub CLI is now non-experimental. Generate a CSV template for bulk importing certificate stores. [See docs](docs/kfutil_stores_import_generate-template.md)` + +### Stores +- `stores import generate-template`: New sub CLI to generate a CSV template for bulk importing stores. [See docs](docs/kfutil_stores_import_generate-template.md)`. +- `stores delete`: Support for user interactive mode. +- `stores delete`: Support of delete from CSV file. +- `stores export`: Supports `--all` flag and user interactive mode ## Fixes - Various null pointer references when nothing and/or empty inputs/responses are received. @@ -13,6 +18,9 @@ ### PAM Types - Handle duplicate provider type that is already created without crashing. #139 +## Docs +- [Examples for certificate store bulk operations](https://github.com/Keyfactor/kfutil/tree/epic_54795/examples/cert_stores/bulk_operations#readme) + # v1.3.2 ### Package From 0d095b7a5c2d287b618de6db861661843d43d38b Mon Sep 17 00:00:00 2001 From: Keyfactor Robot Date: Tue, 27 Feb 2024 23:24:28 +0000 Subject: [PATCH 41/47] Bump package version to 1.4.0-rc.19 --- pkg/version/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/version/version.go b/pkg/version/version.go index f740622d..ea03fbcd 100644 --- a/pkg/version/version.go +++ b/pkg/version/version.go @@ -14,4 +14,4 @@ package version -const VERSION = "1.4.0-rc.18" +const VERSION = "1.4.0-rc.19" From b531f7310911fa2f0b0cc3db8f694ac6ea9fcfa6 Mon Sep 17 00:00:00 2001 From: sbailey <1661003+spbsoluble@users.noreply.github.com> Date: Tue, 27 Feb 2024 15:27:24 -0800 Subject: [PATCH 42/47] chore(docs): Update CHANGELOG.md Signed-off-by: sbailey <1661003+spbsoluble@users.noreply.github.com> --- .github/workflows/tests.yml | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 1343b6ae..8580a26f 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,14 +1,17 @@ name: go tests on: - workflow_dispatch: - workflow_run: - workflows: - - "Check and Update Package Version" - types: - - completed +# workflow_dispatch: +# workflow_run: +# workflows: +# - "Check and Update Package Version" +# types: +# - completed +# branches: +# - "*" + push: branches: - - "*" + - '*' jobs: build: From 1bd313d7d18f53af53a2f73ae0d0a8a1b6d6d3e0 Mon Sep 17 00:00:00 2001 From: Keyfactor Robot Date: Tue, 27 Feb 2024 23:28:10 +0000 Subject: [PATCH 43/47] Bump package version to 1.4.0-rc.20 --- pkg/version/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/version/version.go b/pkg/version/version.go index ea03fbcd..feb2f0ab 100644 --- a/pkg/version/version.go +++ b/pkg/version/version.go @@ -14,4 +14,4 @@ package version -const VERSION = "1.4.0-rc.19" +const VERSION = "1.4.0-rc.20" From 7653593cee2df7f06f79f689703009fa1ab27d94 Mon Sep 17 00:00:00 2001 From: sbailey <1661003+spbsoluble@users.noreply.github.com> Date: Tue, 27 Feb 2024 15:37:41 -0800 Subject: [PATCH 44/47] fix(stores): test regression Signed-off-by: sbailey <1661003+spbsoluble@users.noreply.github.com> --- cmd/storesBulkOperations.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/cmd/storesBulkOperations.go b/cmd/storesBulkOperations.go index 6bbc0beb..216ed45f 100644 --- a/cmd/storesBulkOperations.go +++ b/cmd/storesBulkOperations.go @@ -526,6 +526,14 @@ var storesExportCmd = &cobra.Command{ log.Error().Msg("No store types returned from Keyfactor Command") return fmt.Errorf("no store types returned from Keyfactor Command") } + // check if interface is a slice of interfaces + if _, isSliceInterface := stInterfaces.([]interface{}); !isSliceInterface { + // check if type is interface + if _, isInterface := stInterfaces.(interface{}); isInterface { + stInterfaces = []interface{}{stInterfaces} + } + } + for _, st := range stInterfaces.([]interface{}) { // get storetype for the list of properties log.Debug().Msg("calling getHeadersForStoreType()") From 2552307f9b6c4b99bdb8e742669960626a00ccae Mon Sep 17 00:00:00 2001 From: Keyfactor Robot Date: Tue, 27 Feb 2024 23:38:27 +0000 Subject: [PATCH 45/47] Bump package version to 1.4.0-rc.21 --- pkg/version/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/version/version.go b/pkg/version/version.go index feb2f0ab..06107cd9 100644 --- a/pkg/version/version.go +++ b/pkg/version/version.go @@ -14,4 +14,4 @@ package version -const VERSION = "1.4.0-rc.20" +const VERSION = "1.4.0-rc.21" From b14b173b282a3c86dbc0ec47fd781395e7372ff5 Mon Sep 17 00:00:00 2001 From: sbailey <1661003+spbsoluble@users.noreply.github.com> Date: Tue, 27 Feb 2024 15:43:57 -0800 Subject: [PATCH 46/47] fix(tests): test regression Signed-off-by: sbailey <1661003+spbsoluble@users.noreply.github.com> --- cmd/stores_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/stores_test.go b/cmd/stores_test.go index 281cdffd..81c3f4e7 100644 --- a/cmd/stores_test.go +++ b/cmd/stores_test.go @@ -342,7 +342,7 @@ func testExportStore(t *testing.T, storeTypeName string) (string, []string) { assert.Contains(t, output, ".csv") // assert that a csv file was created in current working directory with a filename that contains 'export_store_*.csv' - files, err = findMatchingFiles("export_stores_*.csv") + files, err = findMatchingFiles("*stores_export*.csv") assert.Nil(t, err) assert.NotEmpty(t, files) }) From fd036d4a6f60ea3a2d3ce2ac23f5af51da82e6ca Mon Sep 17 00:00:00 2001 From: Keyfactor Robot Date: Tue, 27 Feb 2024 23:44:41 +0000 Subject: [PATCH 47/47] Bump package version to 1.4.0-rc.22 --- pkg/version/version.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/version/version.go b/pkg/version/version.go index 06107cd9..90853ddb 100644 --- a/pkg/version/version.go +++ b/pkg/version/version.go @@ -14,4 +14,4 @@ package version -const VERSION = "1.4.0-rc.21" +const VERSION = "1.4.0-rc.22"