From b3a8abf24ac5ab59b44a2112d2c483b0a12eade6 Mon Sep 17 00:00:00 2001 From: Tae Park Date: Thu, 24 Jul 2025 19:40:19 +0000 Subject: [PATCH] Adding openbao-monitor code Adding the openbao-monitor code pulled from the openbao-manager-go repo found here: https://github.com/michel-thebeau-WR/openbao-manager-go git related files have been trimmed off. Partial-bug: 2117422 Change-Id: I1a27ab4a4d0b68810d97c86e2930dd482a11d0cb Signed-off-by: Tae Park --- security/openbao-monitor/source/LICENSE | 201 ++++++++++++ security/openbao-monitor/source/README.md | 16 + .../openbao-monitor/source/build/Dockerfile | 44 +++ .../source/build/lintConfig.yaml | 15 + .../source/commands/dumpConfig.go | 102 ++++++ .../openbao-monitor/source/commands/go.mod | 77 +++++ .../openbao-monitor/source/commands/go.sum | 234 ++++++++++++++ .../openbao-monitor/source/commands/health.go | 56 ++++ .../openbao-monitor/source/commands/init.go | 117 +++++++ .../openbao-monitor/source/commands/root.go | 161 ++++++++++ .../openbao-monitor/source/commands/run.go | 94 ++++++ .../openbao-monitor/source/commands/unseal.go | 94 ++++++ .../openbao-monitor/source/config/config.go | 299 ++++++++++++++++++ security/openbao-monitor/source/config/go.mod | 73 +++++ security/openbao-monitor/source/config/go.sum | 228 +++++++++++++ security/openbao-monitor/source/config/k8s.go | 178 +++++++++++ .../openbao-monitor/source/config/validate.go | 94 ++++++ security/openbao-monitor/source/go.mod | 80 +++++ security/openbao-monitor/source/go.sum | 234 ++++++++++++++ security/openbao-monitor/source/main.go | 15 + .../openbao-monitor/source/test/Dockerfile | 63 ++++ .../test_examples/exampleAuthToken1.yaml | 13 + .../test_examples/exampleAuthToken2.yaml | 10 + .../test_examples/exampleAuthToken3.yaml | 10 + .../test_examples/exampleAuthToken4.yaml | 10 + .../config/test_examples/exampleServer1.yaml | 16 + .../config/test_examples/exampleServer2.yaml | 7 + .../config/test_examples/exampleServer3.yaml | 10 + .../test_examples/exampleUnsealShards1.yaml | 39 +++ .../test_examples/exampleUnsealShards2.yaml | 39 +++ .../test_examples/exampleUnsealShards3.yaml | 39 +++ .../source/test/inPodConfig.yaml | 6 + .../openbao-monitor/source/test/newRole.yaml | 21 ++ .../source/test/scripts/gen_certs.sh | 110 +++++++ .../source/test/testConfig.yaml | 16 + .../source/test/testInitConfig.json | 4 + .../source/test/testOpenbaoConfig.hcl | 29 ++ 37 files changed, 2854 insertions(+) create mode 100644 security/openbao-monitor/source/LICENSE create mode 100644 security/openbao-monitor/source/README.md create mode 100644 security/openbao-monitor/source/build/Dockerfile create mode 100644 security/openbao-monitor/source/build/lintConfig.yaml create mode 100644 security/openbao-monitor/source/commands/dumpConfig.go create mode 100644 security/openbao-monitor/source/commands/go.mod create mode 100644 security/openbao-monitor/source/commands/go.sum create mode 100644 security/openbao-monitor/source/commands/health.go create mode 100644 security/openbao-monitor/source/commands/init.go create mode 100644 security/openbao-monitor/source/commands/root.go create mode 100644 security/openbao-monitor/source/commands/run.go create mode 100644 security/openbao-monitor/source/commands/unseal.go create mode 100644 security/openbao-monitor/source/config/config.go create mode 100644 security/openbao-monitor/source/config/go.mod create mode 100644 security/openbao-monitor/source/config/go.sum create mode 100644 security/openbao-monitor/source/config/k8s.go create mode 100644 security/openbao-monitor/source/config/validate.go create mode 100644 security/openbao-monitor/source/go.mod create mode 100644 security/openbao-monitor/source/go.sum create mode 100644 security/openbao-monitor/source/main.go create mode 100644 security/openbao-monitor/source/test/Dockerfile create mode 100644 security/openbao-monitor/source/test/config/test_examples/exampleAuthToken1.yaml create mode 100644 security/openbao-monitor/source/test/config/test_examples/exampleAuthToken2.yaml create mode 100644 security/openbao-monitor/source/test/config/test_examples/exampleAuthToken3.yaml create mode 100644 security/openbao-monitor/source/test/config/test_examples/exampleAuthToken4.yaml create mode 100644 security/openbao-monitor/source/test/config/test_examples/exampleServer1.yaml create mode 100644 security/openbao-monitor/source/test/config/test_examples/exampleServer2.yaml create mode 100644 security/openbao-monitor/source/test/config/test_examples/exampleServer3.yaml create mode 100644 security/openbao-monitor/source/test/config/test_examples/exampleUnsealShards1.yaml create mode 100644 security/openbao-monitor/source/test/config/test_examples/exampleUnsealShards2.yaml create mode 100644 security/openbao-monitor/source/test/config/test_examples/exampleUnsealShards3.yaml create mode 100644 security/openbao-monitor/source/test/inPodConfig.yaml create mode 100644 security/openbao-monitor/source/test/newRole.yaml create mode 100755 security/openbao-monitor/source/test/scripts/gen_certs.sh create mode 100644 security/openbao-monitor/source/test/testConfig.yaml create mode 100644 security/openbao-monitor/source/test/testInitConfig.json create mode 100644 security/openbao-monitor/source/test/testOpenbaoConfig.hcl diff --git a/security/openbao-monitor/source/LICENSE b/security/openbao-monitor/source/LICENSE new file mode 100644 index 00000000..261eeb9e --- /dev/null +++ b/security/openbao-monitor/source/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/security/openbao-monitor/source/README.md b/security/openbao-monitor/source/README.md new file mode 100644 index 00000000..6503e24f --- /dev/null +++ b/security/openbao-monitor/source/README.md @@ -0,0 +1,16 @@ +# openbao-manager-go +Golang code for the OpenBao Manager + +Manager is a Kubernetes pod or host service that performs the following actions: +* Discover OpenBao servers +* Initialize the OpenBao cluster, raft backend +* Store and retrieve token and shards +* Add/remove OpenBao servers from the raft +* Unseal OpenBao servers + +[OpenBao](https://openbao.org/) is an open source, community-driven fork of Vault managed by the Linux Foundation. OpenBao Manager is a [StarlingX](https://www.starlingx.io/) project. + +## Project Status +_Concept and early development_ + +The openbao-manager-go repo is a pre-alpha status project. diff --git a/security/openbao-monitor/source/build/Dockerfile b/security/openbao-monitor/source/build/Dockerfile new file mode 100644 index 00000000..3f3f3735 --- /dev/null +++ b/security/openbao-monitor/source/build/Dockerfile @@ -0,0 +1,44 @@ +# +# Copyright (c) 2025 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +# Simple environment image to build the go openbao monitor +# The build result should be in the output folder +# Example: docker build --target bin --output bin/ -f ./build/Dockerfile . + +ARG WITH_LINTERS=0 + +FROM golang:1.24.3-bullseye AS build + +WORKDIR /src + +# copy source code +COPY . ./ + +RUN go mod download + +RUN go mod tidy + +# run linting + +ADD ./build/lintConfig.yaml /src/.golangci.yaml + +RUN if [ "$WITH_LINTERS" ]; then \ + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/HEAD/install.sh | sh -s v2.1.6 \ + && ./bin/golangci-lint migrate -c /src/.golangci.yaml \ + && ./bin/golangci-lint run; fi + +RUN go build -o /out/baomon . + +# save the module sources +RUN mkdir /src/mod; GOPATH=/src/mod go get; \ + tar zcf /out/mod.src.tar.gz /src/mod + +# create auto-completion file +RUN /out/baomon completion bash > /out/baomon.completion + +FROM scratch AS bin + +COPY --from=build /out/* / diff --git a/security/openbao-monitor/source/build/lintConfig.yaml b/security/openbao-monitor/source/build/lintConfig.yaml new file mode 100644 index 00000000..88d5f15b --- /dev/null +++ b/security/openbao-monitor/source/build/lintConfig.yaml @@ -0,0 +1,15 @@ +linters-settings: + gocyclo: + min-complexity: 7 + goconst: + min-occurrences: 2 + gomoddirectives: + replace-local: true + +linters: + enable-all: true + disable: + - interfacer + - dupl + - depguard + - prealloc \ No newline at end of file diff --git a/security/openbao-monitor/source/commands/dumpConfig.go b/security/openbao-monitor/source/commands/dumpConfig.go new file mode 100644 index 00000000..48012d5f --- /dev/null +++ b/security/openbao-monitor/source/commands/dumpConfig.go @@ -0,0 +1,102 @@ +// +// Copyright (c) 2025 Wind River Systems, Inc. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package baoCommands + +import ( + "fmt" + "os" + + baoConfig "github.com/michel-thebeau-WR/openbao-manager-go/baomon/config" + "github.com/spf13/cobra" + yaml "sigs.k8s.io/yaml/goyaml.v3" +) + +var dumpConfigReadCmd = &cobra.Command{ + Use: "read readFile", + Short: "Read config from a YAML file", + Long: "Read baomon configuration from a specified YAML file, and prints to stdout", + Args: cobra.ExactArgs(1), + RunE: func(cmd *cobra.Command, args []string) error { + var S baoConfig.MonitorConfig + openedFile, err := os.Open(args[0]) + if err != nil { + return err + } + defer openedFile.Close() + + err = S.ReadYAMLMonitorConfig(openedFile) + if err != nil { + return err + } + fmt.Printf("Result: \n%#v\n", S) + + return nil + }, +} + +var dumpConfigWriteCmd = &cobra.Command{ + Use: "write readFile readWrite", + Short: "Write config to another YAML file", + Long: "Copy a config file from the first file to the second file, using baoConfig's write method", + Args: cobra.ExactArgs(2), + RunE: func(cmd *cobra.Command, args []string) error { + var S baoConfig.MonitorConfig + openedFile, err := os.Open(args[0]) + if err != nil { + return err + } + defer openedFile.Close() + + err = S.ReadYAMLMonitorConfig(openedFile) + if err != nil { + return err + } + + writeFile, err := os.Create(args[1]) + if err != nil { + return err + } + defer writeFile.Close() + + err = S.WriteYAMLMonitorConfig(writeFile) + if err != nil { + return err + } + + fmt.Print("Write Complete\n") + return nil + }, +} + +var dumpConfigPrintGlobal = &cobra.Command{ + Use: "global", + Short: "Dev command that prints current global config", + Long: "Dev command that prints current global config. For testing setup & clean", + PersistentPreRunE: setupCmd, + PersistentPostRunE: cleanCmd, + RunE: func(cmd *cobra.Command, args []string) error { + configBytes, err := yaml.Marshal(globalConfig) + if err != nil { + return err + } + fmt.Println(string(configBytes)) + return nil + }, +} + +var dumpConfigCmd = &cobra.Command{ + Use: "dumpConfig", + Short: "Dev command for read/write YAML config files", + Long: `A dev command for interacting with the baoConfig package using a YAML file.`, +} + +func init() { + dumpConfigCmd.AddCommand(dumpConfigReadCmd) + dumpConfigCmd.AddCommand(dumpConfigWriteCmd) + dumpConfigCmd.AddCommand(dumpConfigPrintGlobal) + RootCmd.AddCommand(dumpConfigCmd) +} diff --git a/security/openbao-monitor/source/commands/go.mod b/security/openbao-monitor/source/commands/go.mod new file mode 100644 index 00000000..c40a5176 --- /dev/null +++ b/security/openbao-monitor/source/commands/go.mod @@ -0,0 +1,77 @@ +// +// Copyright (c) 2025 Wind River Systems, Inc. +// +// SPDX-License-Identifier: Apache-2.0 +// + +module github.com/michel-thebeau-WR/openbao-manager-go/baomon/commands + +go 1.24.0 + +toolchain go1.24.2 + +replace github.com/michel-thebeau-WR/openbao-manager-go/baomon/config => ../config + +require ( + github.com/michel-thebeau-WR/openbao-manager-go/baomon/config v0.0.0-00010101000000-000000000000 + github.com/openbao/openbao/api/v2 v2.2.0 + github.com/spf13/cobra v1.9.1 + k8s.io/client-go v0.33.0 + sigs.k8s.io/yaml v1.4.0 +) + +require ( + github.com/cenkalti/backoff/v4 v4.3.0 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/emicklei/go-restful/v3 v3.11.0 // indirect + github.com/fxamacker/cbor/v2 v2.7.0 // indirect + github.com/go-jose/go-jose/v3 v3.0.3 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect + github.com/go-openapi/jsonreference v0.20.2 // indirect + github.com/go-openapi/swag v0.23.0 // indirect + github.com/go-yaml/yaml v2.1.0+incompatible // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/google/gnostic-models v0.6.9 // indirect + github.com/google/go-cmp v0.7.0 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-cleanhttp v0.5.2 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/go-retryablehttp v0.7.7 // indirect + github.com/hashicorp/go-secure-stdlib/parseutil v0.1.9 // indirect + github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect + github.com/hashicorp/go-sockaddr v1.0.6 // indirect + github.com/hashicorp/hcl v1.0.1-vault-5 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/ryanuber/go-glob v1.0.0 // indirect + github.com/spf13/pflag v1.0.6 // indirect + github.com/x448/float16 v0.8.4 // indirect + golang.org/x/crypto v0.36.0 // indirect + golang.org/x/net v0.38.0 // indirect + golang.org/x/oauth2 v0.27.0 // indirect + golang.org/x/sys v0.31.0 // indirect + golang.org/x/term v0.30.0 // indirect + golang.org/x/text v0.23.0 // indirect + golang.org/x/time v0.9.0 // indirect + google.golang.org/protobuf v1.36.5 // indirect + gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/api v0.33.0 // indirect + k8s.io/apimachinery v0.33.0 // indirect + k8s.io/klog/v2 v2.130.1 // indirect + k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect + k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect + sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect + sigs.k8s.io/randfill v1.0.0 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect +) diff --git a/security/openbao-monitor/source/commands/go.sum b/security/openbao-monitor/source/commands/go.sum new file mode 100644 index 00000000..77da2c88 --- /dev/null +++ b/security/openbao-monitor/source/commands/go.sum @@ -0,0 +1,234 @@ +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= +github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= +github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= +github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= +github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= +github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7G7k= +github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= +github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= +github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg= +github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= +github.com/go-yaml/yaml v2.1.0+incompatible h1:RYi2hDdss1u4YE7GwixGzWwVo47T8UQwnTLB6vQiq+o= +github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw= +github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo= +github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= +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/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= +github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU= +github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= +github.com/hashicorp/go-secure-stdlib/parseutil v0.1.9 h1:FW0YttEnUNDJ2WL9XcrrfteS1xW8u+sh4ggM8pN5isQ= +github.com/hashicorp/go-secure-stdlib/parseutil v0.1.9/go.mod h1:Ll013mhdmsVDuoIXVfBtvgGJsXDYkTw1kooNcoCXuE0= +github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts= +github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4= +github.com/hashicorp/go-sockaddr v1.0.6 h1:RSG8rKU28VTUTvEKghe5gIhIQpv8evvNpnDEyqO4u9I= +github.com/hashicorp/go-sockaddr v1.0.6/go.mod h1:uoUUmtwU7n9Dv3O4SNLeFvg0SxQ3lyjsj6+CCykpaxI= +github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= +github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM= +github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= +github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4= +github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= +github.com/openbao/openbao/api/v2 v2.2.0 h1:RPHdUtC/A6ZZSb1uR8dxA1X5Eu71ojH+UiRHz90Pm8g= +github.com/openbao/openbao/api/v2 v2.2.0/go.mod h1:9EkGGfWrjhh/1cqBXGPA15PawB0TOXohYmHPe0Djku8= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= +github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= +github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= +github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= +github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= +github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= +github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= +golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +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.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= +golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M= +golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +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.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y= +golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g= +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.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= +golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= +golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +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.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= +golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= +google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= +gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +k8s.io/api v0.33.0 h1:yTgZVn1XEe6opVpP1FylmNrIFWuDqe2H0V8CT5gxfIU= +k8s.io/api v0.33.0/go.mod h1:CTO61ECK/KU7haa3qq8sarQ0biLq2ju405IZAd9zsiM= +k8s.io/apimachinery v0.33.0 h1:1a6kHrJxb2hs4t8EE5wuR/WxKDwGN1FKH3JvDtA0CIQ= +k8s.io/apimachinery v0.33.0/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM= +k8s.io/client-go v0.33.0 h1:UASR0sAYVUzs2kYuKn/ZakZlcs2bEHaizrrHUZg0G98= +k8s.io/client-go v0.33.0/go.mod h1:kGkd+l/gNGg8GYWAPr0xF1rRKvVWvzh9vmZAMXtaKOg= +k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= +k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff h1:/usPimJzUKKu+m+TE36gUyGcf03XZEP0ZIKgKj35LS4= +k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8= +k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro= +k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8= +sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo= +sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= +sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= +sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= +sigs.k8s.io/structured-merge-diff/v4 v4.6.0 h1:IUA9nvMmnKWcj5jl84xn+T5MnlZKThmUW1TdblaLVAc= +sigs.k8s.io/structured-merge-diff/v4 v4.6.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps= +sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= +sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/security/openbao-monitor/source/commands/health.go b/security/openbao-monitor/source/commands/health.go new file mode 100644 index 00000000..91594892 --- /dev/null +++ b/security/openbao-monitor/source/commands/health.go @@ -0,0 +1,56 @@ +package baoCommands + +import ( + "encoding/json" + "fmt" + "log/slog" + + openbao "github.com/openbao/openbao/api/v2" + "github.com/spf13/cobra" +) + +func checkHealth(dnshost string, client *openbao.Client) (*openbao.HealthResponse, error) { + slog.Debug(fmt.Sprintf("Attempting to check openbao health on host %v", dnshost)) + healthResult, err := client.Sys().Health() + if err != nil { + return nil, fmt.Errorf("error during call to openbao check health: %v", err) + } + + slog.Debug("health check complete") + return healthResult, nil +} + +var healthCmd = &cobra.Command{ + Use: "health DNSHost", + Short: "Check openbao health", + Long: "Check the health status of the openbao server on the specified host", + Args: cobra.ExactArgs(1), + PersistentPreRunE: setupCmd, + PersistentPostRunE: cleanCmd, + RunE: func(cmd *cobra.Command, args []string) error { + slog.Debug(fmt.Sprintf("Action: Health %v", args[0])) + + cmd.SilenceUsage = true + newClient, err := globalConfig.SetupClient(args[0]) + if err != nil { + return fmt.Errorf("openbao health failed with error: %v", err) + } + healthResult, err := checkHealth(args[0], newClient) + if err != nil { + return fmt.Errorf("openbao health failed with error: %v", err) + } + healthPrint, err := json.MarshalIndent(healthResult, "", " ") + if err != nil { + return fmt.Errorf("unable to marshal health check result: %v", err) + } + slog.Info(fmt.Sprintf("Health check command successful for host %v", args[0])) + fmt.Print("Health check successful. Result:\n") + fmt.Print(string(healthPrint)) + + return nil + }, +} + +func init() { + RootCmd.AddCommand(healthCmd) +} diff --git a/security/openbao-monitor/source/commands/init.go b/security/openbao-monitor/source/commands/init.go new file mode 100644 index 00000000..31e1fee3 --- /dev/null +++ b/security/openbao-monitor/source/commands/init.go @@ -0,0 +1,117 @@ +// +// Copyright (c) 2025 Wind River Systems, Inc. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package baoCommands + +import ( + "encoding/json" + "fmt" + "log/slog" + "os" + + openbao "github.com/openbao/openbao/api/v2" + "github.com/spf13/cobra" +) + +var optFileStr string +var secretShares int +var secretThreshold int + +func initializeOpenbao(dnshost string, opts *openbao.InitRequest) error { + slog.Debug(fmt.Sprintf("Attempting the initialize openbao on host %v", dnshost)) + newClient, err := globalConfig.SetupClient(dnshost) + if err != nil { + return err + } + + slog.Debug("Checking current openbao status") + healthResult, err := checkHealth(dnshost, newClient) + if err != nil { + return err + } + if healthResult.Initialized { + return fmt.Errorf("openbao server on host %v is already initialized", dnshost) + } + + slog.Debug("Running /sys/init") + response, err := newClient.Sys().Init(opts) + if err != nil { + return fmt.Errorf("error during call to openbao init: %v", err) + } + + slog.Debug("/sys/init complete") + err = globalConfig.ParseInitResponse(dnshost, response) + if err != nil { + return fmt.Errorf("error during parsing init response: %v", err) + } + + return nil +} + +var initCmd = &cobra.Command{ + Use: "init DNSHost", + Short: "Initialize openbao", + Long: `Initialize openbao server using the monitor configurations. +The key shards returned from the initResponse will be stored in the monitor +configurations.`, + Args: cobra.ExactArgs(1), + PersistentPreRunE: setupCmd, + RunE: func(cmd *cobra.Command, args []string) error { + slog.Debug(fmt.Sprintf("Action: init %v", args[0])) + fileGiven := cmd.Flags().Lookup("file").Changed + secretSharesFlag := cmd.Flags().Lookup("secret-shares").Changed + secretThresholdFlag := cmd.Flags().Lookup("secret-threshold").Changed + + if (fileGiven && (secretSharesFlag || secretThresholdFlag)) || + (!fileGiven && !(secretSharesFlag && secretThresholdFlag)) { + fmt.Fprintf(os.Stderr, "The options for openbao init must be set by one of:\n") + fmt.Fprintf(os.Stderr, "utilizing an option file using --file, or\n") + fmt.Fprintf(os.Stderr, "--secret-shares and -- secret-threshold\n") + return fmt.Errorf("failed due to invalid or missing options") + } + + var opts openbao.InitRequest + if fileGiven { + optFileReader, err := os.ReadFile(optFileStr) + if err != nil { + return fmt.Errorf("unable to open init option file %v: %v", optFileStr, err) + } + err = json.Unmarshal(optFileReader, &opts) + if err != nil { + return fmt.Errorf("unable to parse JSON file %v: %v", optFileStr, err) + } + } else { + if secretShares == 0 { + return fmt.Errorf("the field secret-shares cannot be 0") + } + if secretThreshold == 0 { + return fmt.Errorf("the field secret-threshold cannot be 0") + } + if secretShares < secretThreshold { + return fmt.Errorf("the field secret-threshold cannot be greater than secret-shares") + } + opts.SecretShares = secretShares + opts.SecretThreshold = secretThreshold + } + slog.Debug(fmt.Sprintf("Parsing init option successful. Attempting to run openbao init on host %v", args[0])) + cmd.SilenceUsage = true + err := initializeOpenbao(args[0], &opts) + if err != nil { + return fmt.Errorf("openbao init failed with error: %v", err) + } + slog.Info(fmt.Sprintf("Openbao init successful for host %v", args[0])) + fmt.Print("Openbao init complete\n") + return nil + }, + PersistentPostRunE: cleanCmd, +} + +func init() { + initCmd.Flags().StringVarP(&optFileStr, "file", "f", "", "A JSON file containing the options for openbao init") + initCmd.Flags().IntVar(&secretShares, "secret-shares", 0, "The number of shares to split the root key into.") + initCmd.Flags().IntVar(&secretThreshold, "secret-threshold", 0, "The number of shares required to reconstruct the root key.") + RootCmd.AddCommand(initCmd) +} diff --git a/security/openbao-monitor/source/commands/root.go b/security/openbao-monitor/source/commands/root.go new file mode 100644 index 00000000..6668ac2b --- /dev/null +++ b/security/openbao-monitor/source/commands/root.go @@ -0,0 +1,161 @@ +// +// Copyright (c) 2025 Wind River Systems, Inc. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package baoCommands + +import ( + "fmt" + "log/slog" + "os" + + baoConfig "github.com/michel-thebeau-WR/openbao-manager-go/baomon/config" + "github.com/spf13/cobra" + "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" +) + +var configFile string +var globalConfig baoConfig.MonitorConfig +var logWriter *os.File +var baoLogger *slog.Logger = nil +var useK8sConfig bool +var useInClusterConfig bool +var kubeConfigPath string + +func getK8sConfig() (*rest.Config, error) { + var config *rest.Config + var err error = nil + slog.Debug("Setting up kubernetes config...") + if useInClusterConfig { + slog.Debug("Baomon is running inside the kubernetes cluster. Using in-cluster configs.") + config, err = rest.InClusterConfig() + if err != nil { + return nil, err + } + } else { + slog.Debug(fmt.Sprintf("Baomon is running outside the kubernetes cluster. Using configs from %v", kubeConfigPath)) + config, err = clientcmd.BuildConfigFromFlags("", kubeConfigPath) + if err != nil { + return nil, err + } + } + slog.Debug("Setting up kubernetes config successful.") + return config, nil +} + +func setupCmd(cmd *cobra.Command, args []string) error { + // Open config from file + configReader, err := os.Open(configFile) + if err != nil { + return fmt.Errorf("error in opening config file: %v, message: %v", configFile, err) + } + defer configReader.Close() + err = globalConfig.ReadYAMLMonitorConfig(configReader) + if err != nil { + return fmt.Errorf("error in parsing config file: %v, message: %v", configFile, err) + } + + // Set default configuration for logs if no custum configs are given + logFile := globalConfig.LogPath + logLevel := globalConfig.LogLevel + if logLevel == "" { + // Default log level if no log level was set + logLevel = "INFO" + } + + // Set default to stdout if no log file was specified. + logWriter = os.Stdout + if logFile != "" { + // Setup Logs + logWriter, err = os.OpenFile(logFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) + if err != nil { + return fmt.Errorf("error in opening the log file to write: %v", err) + } + } + + var LogLevel slog.Level + LogLevel.UnmarshalText([]byte(logLevel)) + baoLogger = slog.New(slog.NewTextHandler(logWriter, &slog.HandlerOptions{ + Level: LogLevel, + })) + slog.SetDefault(baoLogger) + slog.Debug(fmt.Sprintf("Set log level: %v", logLevel)) + + // If useK8sConfig is set to true, then it will override the following configs: + // OpenbaoAddresses, Tokens, UnsealKeyShards + if useK8sConfig { + // create client config + config, err := getK8sConfig() + if err != nil { + return err + } + + // Get the necessary configs from kubernetes + err = globalConfig.MigrateK8sConfig(config) + if err != nil { + return err + } + } + + return nil +} + +func cleanCmd(cmd *cobra.Command, args []string) error { + slog.Debug("Running cleanup...") + // Write back to configs from file only + if !useK8sConfig { + configWriter, err := os.OpenFile(configFile, os.O_WRONLY|os.O_TRUNC, 0644) + if err != nil { + return fmt.Errorf("error with opening config file to write in the changed configs: %v", err) + } + err = globalConfig.WriteYAMLMonitorConfig(configWriter) + if err != nil { + return fmt.Errorf("error with writing the changed configs: %v", err) + } + err = configWriter.Close() + if err != nil { + return fmt.Errorf("error with closing the changed config file: %v", err) + } + } + + // Close the log file + if logWriter != os.Stdout { + err := logWriter.Close() + if err != nil { + return fmt.Errorf("error with closing the log file: %v", err) + } + } + + return nil +} + +var RootCmd = &cobra.Command{ + Use: "baomon", + Short: "A monitor service for managing Openbao in StarlingX", + Long: `A monitor service for managing Openbao servers in StarlingX systems.`, +} + +func Execute() { + if err := RootCmd.Execute(); err != nil { + slog.Error(fmt.Sprintf("Baomon failed with error: %v", err)) + if baoLogger != nil && logWriter != os.Stdout { + // If logging was setup on a file, print error separately to stderr as well. + fmt.Fprintln(os.Stderr, err) + } + os.Exit(1) + } +} + +func init() { + // Declarations for global flags + RootCmd.PersistentFlags().StringVar(&configFile, "config", + "/workdir/testConfig.yaml", "file path to the monitor config file") + RootCmd.PersistentFlags().BoolVar(&useK8sConfig, "k8s", false, "use openbao configs from kubernetes instead") + RootCmd.PersistentFlags().BoolVar(&useInClusterConfig, "in-cluster", true, + "Set this to true if baomon is run in a kubernetes pod") + RootCmd.PersistentFlags().StringVar(&kubeConfigPath, "kubeconfig", "/etc/kubernetes/admin.conf", + "The path for kubernetes config file (KUBECONFIG)") +} diff --git a/security/openbao-monitor/source/commands/run.go b/security/openbao-monitor/source/commands/run.go new file mode 100644 index 00000000..1d19fbd9 --- /dev/null +++ b/security/openbao-monitor/source/commands/run.go @@ -0,0 +1,94 @@ +package baoCommands + +import ( + "encoding/json" + "fmt" + "log/slog" + "maps" + "time" + + openbao "github.com/openbao/openbao/api/v2" + "github.com/spf13/cobra" + "k8s.io/client-go/rest" +) + +var waitInterval int + +var runCmd = &cobra.Command{ + Use: "run", + Short: "keep unsealing openbao", + Long: `Run a loop which detects if the openbao server is sealed, then if it is +attempt to unseal.`, + PersistentPreRunE: setupCmd, + PersistentPostRunE: cleanCmd, + RunE: func(cmd *cobra.Command, args []string) error { + slog.Debug("Action: run") + if globalConfig.WaitInterval != 0 { + waitInterval = globalConfig.WaitInterval + } + + var k8sconfig *rest.Config = nil + var err error = nil + + if useK8sConfig { + k8sconfig, err = getK8sConfig() + if err != nil { + return err + } + } + + for { + // If config was pulled from k8s, repull each time to reset the list of adresses, + // in case any of them changed + if useK8sConfig { + err := globalConfig.MigratePodConfig(k8sconfig) + if err != nil { + return err + } + } + + slog.Debug("Creating api clients for each openbao addresses..") + clientMap := make(map[string]*openbao.Client, len(globalConfig.OpenbaoAddresses)) + for host := range maps.Keys(globalConfig.OpenbaoAddresses) { + slog.Debug(fmt.Sprintf("Creating client for host %v", host)) + newClient, err := globalConfig.SetupClient(host) + if err != nil { + return fmt.Errorf("error occured during creating client for host %v: %v", host, err) + } + clientMap[host] = newClient + } + + for host, client := range clientMap { + slog.Debug(fmt.Sprintf("Checking current health status for host %v", host)) + healthStatus, err := checkHealth(host, client) + if err != nil { + slog.Error(fmt.Sprintf("error occured during check health for host %v: %v", host, err)) + // skip to next host if an error occured + continue + } + healthPrint, err := json.Marshal(healthStatus) + if err != nil { + slog.Error(fmt.Sprintf("error occured parsing check health result for host %v: %v", host, err)) + continue + } + slog.Debug(fmt.Sprintf("health check result: %v", string(healthPrint))) + if healthStatus.Sealed { + slog.Info(fmt.Sprintf("Openbao is sealed on host %v. Attempting to unseal.", host)) + _, err := runUnseal(host, client) + if err != nil { + slog.Error(fmt.Sprintf("error occured during unseal on host %v: %v", host, err)) + continue + } + } + slog.Debug(fmt.Sprintf("Openbao on host %v is unsealed", host)) + } + slog.Debug(fmt.Sprintf("Unseal check complete. Waiting %v seconds until the next check...", waitInterval)) + time.Sleep(time.Duration(waitInterval) * time.Second) + } + }, +} + +func init() { + runCmd.Flags().IntVar(&waitInterval, "waitInterval", 5, "wait time between each check") + RootCmd.AddCommand(runCmd) +} diff --git a/security/openbao-monitor/source/commands/unseal.go b/security/openbao-monitor/source/commands/unseal.go new file mode 100644 index 00000000..2812a835 --- /dev/null +++ b/security/openbao-monitor/source/commands/unseal.go @@ -0,0 +1,94 @@ +package baoCommands + +import ( + "encoding/json" + "fmt" + "log/slog" + "strings" + + baoConfig "github.com/michel-thebeau-WR/openbao-manager-go/baomon/config" + openbao "github.com/openbao/openbao/api/v2" + "github.com/spf13/cobra" +) + +// A single instance of unseal. +func tryUnseal(keyShard baoConfig.KeyShards, client *openbao.Client) (*openbao.SealStatusResponse, error) { + slog.Debug("Attempting unseal...") + key := keyShard.Key + UnsealResult, err := client.Sys().Unseal(key) + if err != nil { + return nil, fmt.Errorf("error with unseal call: %v", err) + } + slog.Debug("Unseal attempt successful") + return UnsealResult, nil +} + +// run unseal on all keys associated with dnshost until unsealed. +func runUnseal(dnshost string, client *openbao.Client) (*openbao.SealStatusResponse, error) { + slog.Debug(fmt.Sprintf("Attempting to run unseal on host %v", dnshost)) + + slog.Debug("Checking if openbao is already unsealed") + healthResult, err := checkHealth(dnshost, client) + if err != nil { + return nil, err + } + if !healthResult.Sealed { + return nil, fmt.Errorf("openbao server on host %v is already unsealed", dnshost) + } + + tryCount := 1 + for keyName, keyShard := range globalConfig.UnsealKeyShards { + // Don't use recovery keys + if !strings.Contains(keyName, "recovery") { + slog.Debug(fmt.Sprintf("Unseal attempt %v", tryCount)) + UnsealResult, err := tryUnseal(keyShard, client) + if err != nil { + return nil, err + } + if !UnsealResult.Sealed { + slog.Debug("Unseal complete.") + return UnsealResult, nil + } + slog.Debug(fmt.Sprintf("Openbao still sealed: threshold %v, progress %v", UnsealResult.T, UnsealResult.Progress)) + tryCount++ + } + } + + return nil, fmt.Errorf("exhausted all non-recovery keys associated with %v", dnshost) +} + +var unsealCmd = &cobra.Command{ + Use: "unseal DNSHost", + Short: "Unseal openbao", + Long: `Unseal openbao server hosted on DNSHost. It will use all +non-recovery keys with its name on it to unseal.`, + Args: cobra.ExactArgs(1), + PersistentPreRunE: setupCmd, + PersistentPostRunE: cleanCmd, + RunE: func(cmd *cobra.Command, args []string) error { + slog.Debug(fmt.Sprintf("Action: unseal %v", args[0])) + + cmd.SilenceUsage = true + newClient, err := globalConfig.SetupClient(args[0]) + if err != nil { + return fmt.Errorf("openbao unseal failed with error: %v", err) + } + UnsealResult, err := runUnseal(args[0], newClient) + if err != nil { + return fmt.Errorf("openbao unseal failed with error: %v", err) + } + + UnsealPrint, err := json.MarshalIndent(UnsealResult, "", " ") + if err != nil { + return fmt.Errorf("unable to marshal unseal result: %v", err) + } + slog.Debug(fmt.Sprintf("Unseal successful. Result: %v", string(UnsealPrint))) + slog.Info(fmt.Sprintf("Unseal successful for host %v", args[0])) + + return nil + }, +} + +func init() { + RootCmd.AddCommand(unsealCmd) +} diff --git a/security/openbao-monitor/source/config/config.go b/security/openbao-monitor/source/config/config.go new file mode 100644 index 00000000..619268ea --- /dev/null +++ b/security/openbao-monitor/source/config/config.go @@ -0,0 +1,299 @@ +// +// Copyright (c) 2025 Wind River Systems, Inc. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package baoConfig + +import ( + "fmt" + "io" + "log/slog" + "strconv" + "strings" + "time" + + "github.com/go-yaml/yaml" + openbao "github.com/openbao/openbao/api/v2" +) + +type OpenbaoAddress struct { + Host string `yaml:"host"` + Port int `yaml:"port"` +} + +type Token struct { + Duration int `yaml:"duration"` + Key string `yaml:"key"` +} + +type KeyShards struct { + Key string `yaml:"key"` + KeyBase64 string `yaml:"key_base64"` +} + +type MonitorConfig struct { + // A map value listing all DNS names + // Key: Domain name + // Value: OpenbaoAddress. consisting of host address and port number + OpenbaoAddresses map[string]OpenbaoAddress `yaml:"OpenbaoAddresses"` + + // A map value listing all authentication tokens + // Key: release id + // Value: Token. consisting of lease duration and the token key + Tokens map[string]Token `yaml:"Tokens"` + + // A map value listing all key shards for unseal + // Key: shard name + // Value: The shard key and the base64 encoded version of that key + UnsealKeyShards map[string]KeyShards `yaml:"UnsealKeyShards"` + + // A string of path to the PEM-encoded CA cert file to use to verify + // Openbao's server SSL certificate + // Leave this empty if using the default CA cert file location + CACert string `yaml:"CACert"` + + // ClientCert is the path to the certificate for Vault communication + ClientCert string `yaml:"ClientCert"` + + // ClientKey is the path to the private key for Vault communication + ClientKey string `yaml:"ClientKey"` + + // The path of the log file + LogPath string `yaml:"logPath"` + + // The default log level + // Available log levels: DEBUG, INFO, WARN and ERROR + LogLevel string `yaml:"logLevel"` + + // The time in seconds waited between each unseal check in the run command. + // If this is unset or set to 0, the command option can be used to supply the time. + // If neither is supplied, then default time of 5 seconds will be used. + WaitInterval int `yaml:"WaitInterval"` + + // Time, in seconds, the openbao client will wait for each request before + // returning timeout exceeded error. + // Set this value in negative to use the default value of 60 seconds. + Timeout int `yaml:"Timeout"` + + // Namespace used for openbao. + // Default is "openbao" + Namespace string `yaml:"Namespace"` + + // Default port for all addresses. + // If the port number was not specified in the config file, it will use this port number. + // This port number will also be used for all generated addresses from Kubernetes pods + // Default value is always 8200 + DefaultPort int `yaml:"DefaultPort"` + + // Prefix string used to find all openbao server pods + // Default is "stx-openbao" + PodPrefix string `yaml:"PodPrefix"` + + // Suffix string for all generated pod addresses + // Default is "pod.cluster.local" + PodAddressSuffix string `yaml:"PodAddressSuffix"` + + // Prefix string used to find root token and unseal key shards + // Default is "cluster-key" + SecretPrefix string `yaml:"SecretPrefix"` +} + +func (configInstance *MonitorConfig) ReadYAMLMonitorConfig(in io.Reader) error { + data, err := io.ReadAll(in) + if err != nil { + return fmt.Errorf( + "unable to read Host DNS config data from input. Error message: %v", err) + } + + err = yaml.Unmarshal(data, configInstance) + if err != nil { + return fmt.Errorf( + "unable to unmarshal Host DNS config YAML data. Error message: %v", err) + } + + // Use default port value of 8200, if no default port was specified. + if configInstance.DefaultPort == 0 { + configInstance.DefaultPort = 8200 + } + + // Fill in empty ports + for dnsname, addr := range configInstance.OpenbaoAddresses { + if addr.Port == 0 { + addr.Port = configInstance.DefaultPort + configInstance.OpenbaoAddresses[dnsname] = addr + } + } + + // Validate YAML input for OpenbaoAddresses + err = configInstance.validateDNS() + if err != nil { + return err + } + + // Validate YAML input for Tokens + err = configInstance.validateTokens() + if err != nil { + return err + } + + // Validate YAML input for unseal key shards + err = configInstance.validateKeyShards() + if err != nil { + return err + } + + // Validate YAML input for CACert + err = configInstance.validateCACert() + if err != nil { + return err + } + + // Validate YAML input for log configs + err = configInstance.validateLogConfig() + if err != nil { + return err + } + + return nil +} + +func (configInstance MonitorConfig) WriteYAMLMonitorConfig(out io.Writer) error { + data, err := yaml.Marshal(configInstance) + if err != nil { + return fmt.Errorf( + "unable to marshal Host DNS config data to YAML. Error message: %v", err) + } + + _, err = out.Write(data) + if err != nil { + return fmt.Errorf( + "unable to write marshaled Host DNS config YAML data. Error message: %v", err) + } + + return nil +} + +// Create a new openbao config based on the monitor config +func (configInstance MonitorConfig) NewOpenbaoConfig(dnshost string) (*openbao.Config, error) { + slog.Debug(fmt.Sprintf("Setting up api access config for host %v", dnshost)) + defConfig := openbao.DefaultConfig() + + // Check if DefaultConfig has issues + if defConfig.Error != nil { + return defConfig, fmt.Errorf("issue found in openbao default config: %v", defConfig.Error) + } + slog.Debug("No issues found in retrieving openbao default config.") + + // Check if there is a domain name listed under OpenbaoAddresses + dnsAddr, ok := configInstance.OpenbaoAddresses[dnshost] + if !ok { + return defConfig, fmt.Errorf("unable to find %v under the list of available DNS names", dnshost) + } + + // Set the DNS address as the address to openbao + defConfig.Address = strings.Join([]string{"https://", dnsAddr.Host, ":", strconv.Itoa(dnsAddr.Port)}, "") + + slog.Debug(fmt.Sprintf("Openbao address set to %v", defConfig.Address)) + + // Apply CACert entry to openbao config + var newTLSconfig openbao.TLSConfig + slog.Debug("Applying the following cert configs:") + slog.Debug(fmt.Sprintf("CACert: %v", configInstance.CACert)) + slog.Debug(fmt.Sprintf("ClientCert: %v", configInstance.ClientCert)) + slog.Debug(fmt.Sprintf("ClientKey: %v", configInstance.ClientKey)) + + newTLSconfig.CACert = configInstance.CACert + newTLSconfig.ClientCert = configInstance.ClientCert + newTLSconfig.ClientKey = configInstance.ClientKey + + // This does nothing if newTLSconfig is empty + err := defConfig.ConfigureTLS(&newTLSconfig) + if err != nil { + return defConfig, fmt.Errorf("error with configuring TLS for openbao: %v", err) + } + + slog.Debug("Configuring TLS successful") + + // Set the timeout value. Do not set the value if it is negative. + if configInstance.Timeout >= 0 { + defConfig.Timeout = time.Duration(configInstance.Timeout) * time.Second + } + + slog.Debug("Openbao api access config setup complete.") + // Config creation complete. + return defConfig, nil +} + +func (configInstance MonitorConfig) SetupClient(dnshost string) (*openbao.Client, error) { + slog.Debug(fmt.Sprintf("Setting up client for host %v", dnshost)) + newConfig, err := configInstance.NewOpenbaoConfig(dnshost) + if err != nil { + return nil, fmt.Errorf("error in creating new config for openbao: %v", err) + } + + slog.Debug("Creating Openbao client for API access...") + newClient, err := openbao.NewClient(newConfig) + if err != nil { + return nil, fmt.Errorf("error in creating new client for openbao: %v", err) + } + + slog.Debug("Client setup complete.") + return newClient, nil +} + +// Parse the new keys from the init responce into the monitor config +func (configInstance *MonitorConfig) ParseInitResponse(dnshost string, responce *openbao.InitResponse) error { + slog.Debug("Parsing response from /sys/init to monitor configs") + + keyShardheader := strings.Join([]string{"key", "shard", dnshost}, "-") + + slog.Debug("Parsing the root token...") + // Parse in the root token + if _, ok := configInstance.Tokens["root_token"]; ok { + return fmt.Errorf("an entry of the root token was already found") + } + if configInstance.Tokens == nil { + configInstance.Tokens = make(map[string]Token) + } + configInstance.Tokens["root_token"] = Token{ + Duration: 0, + Key: responce.RootToken, + } + + slog.Debug("Parsing the unseal key shards...") + // Parse in the key shards for unseal + for i := range len(responce.Keys) { + keyShardName := strings.Join([]string{keyShardheader, strconv.Itoa(i)}, "-") + if _, ok := configInstance.UnsealKeyShards[keyShardName]; ok { + return fmt.Errorf("an entry of %v was already found under UnsealKeyShards", keyShardName) + } + if configInstance.UnsealKeyShards == nil { + configInstance.UnsealKeyShards = make(map[string]KeyShards) + } + configInstance.UnsealKeyShards[keyShardName] = KeyShards{ + Key: responce.Keys[i], + KeyBase64: responce.KeysB64[i], + } + } + + slog.Debug("Parsing the recovery key shards...") + // Parse in the recovery key shards + for i := range len(responce.RecoveryKeys) { + keyShardName := strings.Join([]string{keyShardheader, "recovery", strconv.Itoa(i)}, "-") + if _, ok := configInstance.UnsealKeyShards[keyShardName]; ok { + return fmt.Errorf("an entry of %v was already found under UnsealKeyShards", keyShardName) + } + if configInstance.UnsealKeyShards == nil { + configInstance.UnsealKeyShards = make(map[string]KeyShards) + } + configInstance.UnsealKeyShards[keyShardName] = KeyShards{ + Key: responce.RecoveryKeys[i], + KeyBase64: responce.RecoveryKeysB64[i], + } + } + + slog.Debug("Parsing init response complete") + return nil +} diff --git a/security/openbao-monitor/source/config/go.mod b/security/openbao-monitor/source/config/go.mod new file mode 100644 index 00000000..d1d8a07f --- /dev/null +++ b/security/openbao-monitor/source/config/go.mod @@ -0,0 +1,73 @@ +// +// Copyright (c) 2025 Wind River Systems, Inc. +// +// SPDX-License-Identifier: Apache-2.0 +// + +module github.com/michel-thebeau-WR/openbao-manager-go/baomon/config + +go 1.24.0 + +toolchain go1.24.2 + +require ( + github.com/go-yaml/yaml v2.1.0+incompatible + github.com/openbao/openbao/api/v2 v2.2.0 + k8s.io/apimachinery v0.33.0 + k8s.io/client-go v0.33.0 +) + +require ( + github.com/cenkalti/backoff/v4 v4.3.0 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/emicklei/go-restful/v3 v3.11.0 // indirect + github.com/fxamacker/cbor/v2 v2.7.0 // indirect + github.com/go-jose/go-jose/v3 v3.0.3 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect + github.com/go-openapi/jsonreference v0.20.2 // indirect + github.com/go-openapi/swag v0.23.0 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/google/gnostic-models v0.6.9 // indirect + github.com/google/go-cmp v0.7.0 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-cleanhttp v0.5.2 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/go-retryablehttp v0.7.7 // indirect + github.com/hashicorp/go-secure-stdlib/parseutil v0.1.9 // indirect + github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect + github.com/hashicorp/go-sockaddr v1.0.6 // indirect + github.com/hashicorp/hcl v1.0.1-vault-5 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/ryanuber/go-glob v1.0.0 // indirect + github.com/x448/float16 v0.8.4 // indirect + golang.org/x/crypto v0.36.0 // indirect + golang.org/x/net v0.38.0 // indirect + golang.org/x/oauth2 v0.27.0 // indirect + golang.org/x/sys v0.31.0 // indirect + golang.org/x/term v0.30.0 // indirect + golang.org/x/text v0.23.0 // indirect + golang.org/x/time v0.9.0 // indirect + google.golang.org/protobuf v1.36.5 // indirect + gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/api v0.33.0 // indirect + k8s.io/klog/v2 v2.130.1 // indirect + k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect + k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect + sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect + sigs.k8s.io/randfill v1.0.0 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect + sigs.k8s.io/yaml v1.4.0 // indirect +) diff --git a/security/openbao-monitor/source/config/go.sum b/security/openbao-monitor/source/config/go.sum new file mode 100644 index 00000000..e4199425 --- /dev/null +++ b/security/openbao-monitor/source/config/go.sum @@ -0,0 +1,228 @@ +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= +github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= +github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= +github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= +github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= +github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7G7k= +github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= +github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= +github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg= +github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= +github.com/go-yaml/yaml v2.1.0+incompatible h1:RYi2hDdss1u4YE7GwixGzWwVo47T8UQwnTLB6vQiq+o= +github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw= +github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo= +github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= +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/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= +github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU= +github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= +github.com/hashicorp/go-secure-stdlib/parseutil v0.1.9 h1:FW0YttEnUNDJ2WL9XcrrfteS1xW8u+sh4ggM8pN5isQ= +github.com/hashicorp/go-secure-stdlib/parseutil v0.1.9/go.mod h1:Ll013mhdmsVDuoIXVfBtvgGJsXDYkTw1kooNcoCXuE0= +github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts= +github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4= +github.com/hashicorp/go-sockaddr v1.0.6 h1:RSG8rKU28VTUTvEKghe5gIhIQpv8evvNpnDEyqO4u9I= +github.com/hashicorp/go-sockaddr v1.0.6/go.mod h1:uoUUmtwU7n9Dv3O4SNLeFvg0SxQ3lyjsj6+CCykpaxI= +github.com/hashicorp/hcl v1.0.1-vault-5 h1:kI3hhbbyzr4dldA8UdTb7ZlVVlI2DACdCfz31RPDgJM= +github.com/hashicorp/hcl v1.0.1-vault-5/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM= +github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= +github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4= +github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= +github.com/openbao/openbao/api/v2 v2.2.0 h1:RPHdUtC/A6ZZSb1uR8dxA1X5Eu71ojH+UiRHz90Pm8g= +github.com/openbao/openbao/api/v2 v2.2.0/go.mod h1:9EkGGfWrjhh/1cqBXGPA15PawB0TOXohYmHPe0Djku8= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= +github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= +github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= +golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +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.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= +golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M= +golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= +golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +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.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y= +golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g= +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.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= +golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY= +golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= +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.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= +golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= +google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= +gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +k8s.io/api v0.33.0 h1:yTgZVn1XEe6opVpP1FylmNrIFWuDqe2H0V8CT5gxfIU= +k8s.io/api v0.33.0/go.mod h1:CTO61ECK/KU7haa3qq8sarQ0biLq2ju405IZAd9zsiM= +k8s.io/apimachinery v0.33.0 h1:1a6kHrJxb2hs4t8EE5wuR/WxKDwGN1FKH3JvDtA0CIQ= +k8s.io/apimachinery v0.33.0/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM= +k8s.io/client-go v0.33.0 h1:UASR0sAYVUzs2kYuKn/ZakZlcs2bEHaizrrHUZg0G98= +k8s.io/client-go v0.33.0/go.mod h1:kGkd+l/gNGg8GYWAPr0xF1rRKvVWvzh9vmZAMXtaKOg= +k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= +k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff h1:/usPimJzUKKu+m+TE36gUyGcf03XZEP0ZIKgKj35LS4= +k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8= +k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro= +k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8= +sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo= +sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= +sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= +sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= +sigs.k8s.io/structured-merge-diff/v4 v4.6.0 h1:IUA9nvMmnKWcj5jl84xn+T5MnlZKThmUW1TdblaLVAc= +sigs.k8s.io/structured-merge-diff/v4 v4.6.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps= +sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= +sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/security/openbao-monitor/source/config/k8s.go b/security/openbao-monitor/source/config/k8s.go new file mode 100644 index 00000000..5068e383 --- /dev/null +++ b/security/openbao-monitor/source/config/k8s.go @@ -0,0 +1,178 @@ +package baoConfig + +import ( + "context" + "encoding/json" + "fmt" + "log/slog" + "regexp" + "strings" + + metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/rest" +) + +// Default values in case the values are not included in the config +var openbaoNamespace string = "openbao" +var podPort int = 8200 +var podPrefix string = "stx-openbao" +var podAddressSuffix string = "pod.cluster.local" +var secretPrefix string = "cluster-key" + +type keySecret struct { + Key []string `json:"keys"` + KeyEncoded []string `json:"keys_base64"` +} + +// Get list of DNS names fro k8s pods +func (configInstance *MonitorConfig) MigratePodConfig(config *rest.Config) error { + slog.Debug("Migrating openbao addresses from kubernetes openbao server pods") + // Use the settings from config if they aren't empty + if configInstance.Namespace != "" { + openbaoNamespace = configInstance.Namespace + } + if configInstance.DefaultPort != 0 { + podPort = configInstance.DefaultPort + } + if configInstance.PodPrefix != "" { + podPrefix = configInstance.PodPrefix + } + if configInstance.PodAddressSuffix != "" { + podAddressSuffix = configInstance.PodAddressSuffix + } + + slog.Debug("Setting up kubernetes client...") + // create clientset + clientset, err := kubernetes.NewForConfig(config) + if err != nil { + return err + } + slog.Debug("Setting up kubernetes client complete") + + // client for core + coreClient := clientset.CoreV1() + ctx := context.Background() + + slog.Debug("Accessing openbao server pods for the addresses...") + // get pod list + pods, err := coreClient.Pods(openbaoNamespace).List(ctx, metaV1.ListOptions{}) + if err != nil { + return err + } + + // clear existing DNS names + configInstance.OpenbaoAddresses = make(map[string]OpenbaoAddress) + + // Use pod and its ip to fill in the "OpenbaoAddresses" section + r, _ := regexp.Compile(fmt.Sprintf("%v-\\d$", podPrefix)) + for _, pod := range pods.Items { + podName := pod.ObjectMeta.Name + if r.Match([]byte(podName)) { + podIP := pod.Status.PodIP + podURL := fmt.Sprintf("%v.%v.%v", strings.ReplaceAll(podIP, ".", "-"), openbaoNamespace, podAddressSuffix) + configInstance.OpenbaoAddresses[podName] = OpenbaoAddress{podURL, podPort} + } + } + slog.Debug("All addresses obtained.") + + // Validate input for OpenbaoAddresses + err = configInstance.validateDNS() + if err != nil { + return err + } + + slog.Debug("Openbao address migration complete.") + return nil +} + +// Get root token and unseal key shards from k8s secrets +func (configInstance *MonitorConfig) MigrateSecretConfig(config *rest.Config) error { + slog.Debug("Migrating root-token and unseal key shards from openbao kubernetes secrets") + // Use the settings from config if they aren't empty + if configInstance.Namespace != "" { + openbaoNamespace = configInstance.Namespace + } + if configInstance.SecretPrefix != "" { + secretPrefix = configInstance.SecretPrefix + } + + slog.Debug("Setting up kubernetes client...") + // create clientset + clientset, err := kubernetes.NewForConfig(config) + if err != nil { + return err + } + slog.Debug("Setting up kubernetes client complete") + + // client for secret + secretClient := clientset.CoreV1().Secrets(openbaoNamespace) + + ctx := context.Background() + + slog.Debug("Accessing openbao secrets for the info...") + // get secrets list + secrets, err := secretClient.List(ctx, metaV1.ListOptions{}) + if err != nil { + return err + } + + // Clear existing configs + configInstance.Tokens = make(map[string]Token) + configInstance.UnsealKeyShards = make(map[string]KeyShards) + + // Use secrets to fill in the "Tokens" and "UnsealKeyShards" section + for _, secret := range secrets.Items { + secretName := secret.ObjectMeta.Name + if strings.HasPrefix(secretName, secretPrefix) { + secretData := secret.Data["strdata"] + if strings.HasSuffix(secretName, "root") { + // secretData should be the root token + configInstance.Tokens[secretName] = Token{Duration: 0, Key: string(secretData)} + } else { + // secretData should be an unseal key shard and its base 64 encoded version + var newKey keySecret + err := json.Unmarshal(secretData, &newKey) + if err != nil { + return err + } + configInstance.UnsealKeyShards[secretName] = KeyShards{ + Key: newKey.Key[0], + KeyBase64: newKey.KeyEncoded[0], + } + } + } + } + slog.Debug("Root token and unseal key shards obtained.") + + // Validate input for Tokens + err = configInstance.validateTokens() + if err != nil { + return err + } + + // Validate input for unseal key shards + err = configInstance.validateKeyShards() + if err != nil { + return err + } + + slog.Debug("Migrating root token and unseal key shards complete.") + return nil +} + +// Get both configs +func (configInstance *MonitorConfig) MigrateK8sConfig(config *rest.Config) error { + + err := configInstance.MigratePodConfig(config) + if err != nil { + return err + } + + err = configInstance.MigrateSecretConfig(config) + if err != nil { + return err + } + + return nil +} diff --git a/security/openbao-monitor/source/config/validate.go b/security/openbao-monitor/source/config/validate.go new file mode 100644 index 00000000..597ffd10 --- /dev/null +++ b/security/openbao-monitor/source/config/validate.go @@ -0,0 +1,94 @@ +package baoConfig + +import ( + "encoding/base64" + "fmt" + "os" + "path" + "regexp" + "slices" +) + +func (configInstance MonitorConfig) validateDNS() error { + for domain_name, url := range configInstance.OpenbaoAddresses { + // If Host is empty, then the domain entry is invalid + // The ports will always at least have the default value of 8200 + if url.Host == "" { + return fmt.Errorf( + "the domain entry %v in OpenbaoAddresses is invalid", domain_name) + } + } + + return nil +} + +func (configInstance MonitorConfig) validateTokens() error { + rootExists := false + r, _ := regexp.Compile("[sbr][.][a-zA-Z0-9]{24,}") + for releaseID, token := range configInstance.Tokens { + if token.Duration == 0 { + // There can only be one root token + if rootExists { + return fmt.Errorf("there are two or more root tokens listed") + } else { + rootExists = true + } + } + // Token key should have s, b, or r as the first character, and . as the second. + // The body of the token (key[2:]) should be 24 characters or more + if !r.MatchString(token.Key) { + return fmt.Errorf( + "the token with release id %v has wrong key format", releaseID) + } + } + + return nil +} + +func (configInstance MonitorConfig) validateKeyShards() error { + for shardName, shard := range configInstance.UnsealKeyShards { + // A shard should have both its key and base64 key non-empty + if shard.Key == "" || shard.KeyBase64 == "" { + return fmt.Errorf("shard %v has missing keys", shardName) + } + // Base64 encoded keys must be able to be decoded with no errors + _, err := base64.StdEncoding.DecodeString(shard.KeyBase64) + if err != nil { + return fmt.Errorf( + "error with validating if %v has a correct base64 encoded key: %v", shardName, err) + } + } + + return nil +} + +func (configInstance MonitorConfig) validateLogConfig() error { + if configInstance.LogPath != "" { + _, err := os.Stat(path.Dir(configInstance.LogPath)) + if err != nil { + return fmt.Errorf( + "error in checking the parent directory of LogPath. Error message: %v", err) + } + } + if configInstance.LogLevel != "" { + availableLogLevels := []string{"DEBUG", "INFO", "WARN", "ERROR"} + if !slices.Contains(availableLogLevels, configInstance.LogLevel) { + return fmt.Errorf( + "the listed LogLevel %v is not a valid log level", configInstance.LogLevel) + } + } + + return nil +} + +func (configInstance MonitorConfig) validateCACert() error { + if configInstance.CACert != "" { + _, err := os.Stat(configInstance.CACert) + if err != nil { + return fmt.Errorf( + "error in checking the path of CACert. Error message: %v", err) + } + } + + return nil +} diff --git a/security/openbao-monitor/source/go.mod b/security/openbao-monitor/source/go.mod new file mode 100644 index 00000000..da1fcff4 --- /dev/null +++ b/security/openbao-monitor/source/go.mod @@ -0,0 +1,80 @@ +// +// Copyright (c) 2025 Wind River Systems, Inc. +// +// SPDX-License-Identifier: Apache-2.0 +// + +module github.com/michel-thebeau-WR/openbao-manager-go/baomon + +go 1.24.0 + +toolchain go1.24.2 + +replace github.com/michel-thebeau-WR/openbao-manager-go/baomon/config => ./config + +replace github.com/michel-thebeau-WR/openbao-manager-go/baomon/commands => ./commands + +require ( + github.com/michel-thebeau-WR/openbao-manager-go/baomon/commands v0.0.0-00010101000000-000000000000 + github.com/michel-thebeau-WR/openbao-manager-go/baomon/config v0.0.0-00010101000000-000000000000 // indirect +) + +require ( + github.com/cenkalti/backoff/v4 v4.3.0 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/emicklei/go-restful/v3 v3.11.0 // indirect + github.com/fxamacker/cbor/v2 v2.7.0 // indirect + github.com/go-jose/go-jose/v3 v3.0.4 // indirect + github.com/go-logr/logr v1.4.2 // indirect + github.com/go-openapi/jsonpointer v0.21.0 // indirect + github.com/go-openapi/jsonreference v0.20.2 // indirect + github.com/go-openapi/swag v0.23.0 // indirect + github.com/go-yaml/yaml v2.1.0+incompatible // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/google/gnostic-models v0.6.9 // indirect + github.com/google/go-cmp v0.7.0 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/hashicorp/errwrap v1.1.0 // indirect + github.com/hashicorp/go-cleanhttp v0.5.2 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/go-retryablehttp v0.7.7 // indirect + github.com/hashicorp/go-secure-stdlib/parseutil v0.2.0 // indirect + github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect + github.com/hashicorp/go-sockaddr v1.0.7 // indirect + github.com/hashicorp/hcl v1.0.1-vault-7 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/openbao/openbao/api/v2 v2.2.0 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/ryanuber/go-glob v1.0.0 // indirect + github.com/spf13/cobra v1.9.1 // indirect + github.com/spf13/pflag v1.0.6 // indirect + github.com/x448/float16 v0.8.4 // indirect + golang.org/x/crypto v0.37.0 // indirect + golang.org/x/net v0.39.0 // indirect + golang.org/x/oauth2 v0.27.0 // indirect + golang.org/x/sys v0.32.0 // indirect + golang.org/x/term v0.31.0 // indirect + golang.org/x/text v0.24.0 // indirect + golang.org/x/time v0.11.0 // indirect + google.golang.org/protobuf v1.36.5 // indirect + gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/api v0.33.0 // indirect + k8s.io/apimachinery v0.33.0 // indirect + k8s.io/client-go v0.33.0 // indirect + k8s.io/klog/v2 v2.130.1 // indirect + k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff // indirect + k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 // indirect + sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 // indirect + sigs.k8s.io/randfill v1.0.0 // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.6.0 // indirect + sigs.k8s.io/yaml v1.4.0 // indirect +) diff --git a/security/openbao-monitor/source/go.sum b/security/openbao-monitor/source/go.sum new file mode 100644 index 00000000..b762db20 --- /dev/null +++ b/security/openbao-monitor/source/go.sum @@ -0,0 +1,234 @@ +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= +github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= +github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= +github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= +github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E= +github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ= +github.com/go-jose/go-jose/v3 v3.0.4 h1:Wp5HA7bLQcKnf6YYao/4kpRpVMp/yf6+pJKV8WFSaNY= +github.com/go-jose/go-jose/v3 v3.0.4/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= +github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= +github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= +github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= +github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= +github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg= +github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE= +github.com/go-yaml/yaml v2.1.0+incompatible h1:RYi2hDdss1u4YE7GwixGzWwVo47T8UQwnTLB6vQiq+o= +github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw= +github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db h1:097atOisP2aRj7vFgYQBbFN4U4JNXUNYpxael3UzMyo= +github.com/google/pprof v0.0.0-20241029153458-d1b30febd7db/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= +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/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= +github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU= +github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= +github.com/hashicorp/go-secure-stdlib/parseutil v0.2.0 h1:U+kC2dOhMFQctRfhK0gRctKAPTloZdMU5ZJxaesJ/VM= +github.com/hashicorp/go-secure-stdlib/parseutil v0.2.0/go.mod h1:Ll013mhdmsVDuoIXVfBtvgGJsXDYkTw1kooNcoCXuE0= +github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts= +github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4= +github.com/hashicorp/go-sockaddr v1.0.7 h1:G+pTkSO01HpR5qCxg7lxfsFEZaG+C0VssTy/9dbT+Fw= +github.com/hashicorp/go-sockaddr v1.0.7/go.mod h1:FZQbEYa1pxkQ7WLpyXJ6cbjpT8q0YgQaK/JakXqGyWw= +github.com/hashicorp/hcl v1.0.1-vault-7 h1:ag5OxFVy3QYTFTJODRzTKVZ6xvdfLLCA1cy/Y6xGI0I= +github.com/hashicorp/hcl v1.0.1-vault-7/go.mod h1:XYhtn6ijBSAj6n4YqAaf7RBPS4I06AItNorpy+MoQNM= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/onsi/ginkgo/v2 v2.21.0 h1:7rg/4f3rB88pb5obDgNZrNHrQ4e6WpjonchcpuBRnZM= +github.com/onsi/ginkgo/v2 v2.21.0/go.mod h1:7Du3c42kxCUegi0IImZ1wUQzMBVecgIHjR1C+NkhLQo= +github.com/onsi/gomega v1.35.1 h1:Cwbd75ZBPxFSuZ6T+rN/WCb/gOc6YgFBXLlZLhC7Ds4= +github.com/onsi/gomega v1.35.1/go.mod h1:PvZbdDc8J6XJEpDK4HCuRBm8a6Fzp9/DmhC9C7yFlog= +github.com/openbao/openbao/api/v2 v2.2.0 h1:RPHdUtC/A6ZZSb1uR8dxA1X5Eu71ojH+UiRHz90Pm8g= +github.com/openbao/openbao/api/v2 v2.2.0/go.mod h1:9EkGGfWrjhh/1cqBXGPA15PawB0TOXohYmHPe0Djku8= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= +github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= +github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= +github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= +github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= +github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= +github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM= +github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= +golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +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.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY= +golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= +golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M= +golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= +golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +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.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o= +golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw= +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.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= +golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= +golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= +golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= +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.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= +golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= +google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4= +gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +k8s.io/api v0.33.0 h1:yTgZVn1XEe6opVpP1FylmNrIFWuDqe2H0V8CT5gxfIU= +k8s.io/api v0.33.0/go.mod h1:CTO61ECK/KU7haa3qq8sarQ0biLq2ju405IZAd9zsiM= +k8s.io/apimachinery v0.33.0 h1:1a6kHrJxb2hs4t8EE5wuR/WxKDwGN1FKH3JvDtA0CIQ= +k8s.io/apimachinery v0.33.0/go.mod h1:BHW0YOu7n22fFv/JkYOEfkUYNRN0fj0BlvMFWA7b+SM= +k8s.io/client-go v0.33.0 h1:UASR0sAYVUzs2kYuKn/ZakZlcs2bEHaizrrHUZg0G98= +k8s.io/client-go v0.33.0/go.mod h1:kGkd+l/gNGg8GYWAPr0xF1rRKvVWvzh9vmZAMXtaKOg= +k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= +k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff h1:/usPimJzUKKu+m+TE36gUyGcf03XZEP0ZIKgKj35LS4= +k8s.io/kube-openapi v0.0.0-20250318190949-c8a335a9a2ff/go.mod h1:5jIi+8yX4RIb8wk3XwBo5Pq2ccx4FP10ohkbSKCZoK8= +k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738 h1:M3sRQVHv7vB20Xc2ybTt7ODCeFj6JSWYFzOFnYeS6Ro= +k8s.io/utils v0.0.0-20241104100929-3ea5e8cea738/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3 h1:/Rv+M11QRah1itp8VhT6HoVx1Ray9eB4DBr+K+/sCJ8= +sigs.k8s.io/json v0.0.0-20241010143419-9aa6b5e7a4b3/go.mod h1:18nIHnGi6636UCz6m8i4DhaJ65T6EruyzmoQqI2BVDo= +sigs.k8s.io/randfill v0.0.0-20250304075658-069ef1bbf016/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= +sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= +sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= +sigs.k8s.io/structured-merge-diff/v4 v4.6.0 h1:IUA9nvMmnKWcj5jl84xn+T5MnlZKThmUW1TdblaLVAc= +sigs.k8s.io/structured-merge-diff/v4 v4.6.0/go.mod h1:dDy58f92j70zLsuZVuUX5Wp9vtxXpaZnkPGWeqDfCps= +sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= +sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/security/openbao-monitor/source/main.go b/security/openbao-monitor/source/main.go new file mode 100644 index 00000000..2a04c9c1 --- /dev/null +++ b/security/openbao-monitor/source/main.go @@ -0,0 +1,15 @@ +// +// Copyright (c) 2025 Wind River Systems, Inc. +// +// SPDX-License-Identifier: Apache-2.0 +// + +package main + +import ( + baoCommands "github.com/michel-thebeau-WR/openbao-manager-go/baomon/commands" +) + +func main() { + baoCommands.Execute() +} diff --git a/security/openbao-monitor/source/test/Dockerfile b/security/openbao-monitor/source/test/Dockerfile new file mode 100644 index 00000000..c8b6e09c --- /dev/null +++ b/security/openbao-monitor/source/test/Dockerfile @@ -0,0 +1,63 @@ +# +# Copyright (c) 2025 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +# Test image for go openbao monitor +# Debian image with openbao and go openbao monitor installed +# Example commands to build: +# test/scripts/gen_certs.sh +# docker build -f test/Dockerfile . +# +# gen_certs.sh only needs to be run once, with the CA cert expiry of +# 10 years and the server/client certs expiring in 30 days. +# gen_certs.sh will not regenerate the CA cert if it exists, so that +# testing with a web browser doesn't require replacing the trusted +# certificate. + +FROM debian:stable-slim + +ENV PKG_LIST="mawk bash coreutils curl grep sed jq uuid-runtime \ + wget procps less file vim bash-completion gzip tar sudo" + +USER root + +# install listed packages, and openbao server +RUN set -ex; \ + apt-get update && apt-get install -y $PKG_LIST \ + && apt-get clean && rm -r /var/lib/apt/lists/* \ + && mkdir -p /tmp \ + && wget -P /tmp/ https://github.com/openbao/openbao/releases/download/v2.1.0/bao_2.1.0_linux_amd64.deb \ + && dpkg -i /tmp/bao_2.1.0_linux_amd64.deb \ + && rm /tmp/bao_2.1.0_linux_amd64.deb + +# Copy over go openbao monitor +# Use the output folder used in the build +COPY ./bin/baomon /usr/bin/ + +# create a non-root user/group for openbao-manager +RUN groupadd --gid 1000 manager \ + && adduser --uid 1000 --gid 1000 manager \ + --home /workdir --shell /bin/bash + +RUN echo "root:root" | chpasswd +RUN echo "manager:manager" | chpasswd +RUN usermod -aG sudo manager + +# Copy and run auto-completion +COPY ./bin/baomon.completion /usr/share/bash-completion/completions/baomon + +RUN echo "source /etc/bash_completion" >> /workdir/.bashrc + +# Copy testing files +COPY ./bin/OpenBaoCA/ /workdir/OpenBaoCA/ +COPY ./bin/OpenBaoServerCert/ /workdir/OpenBaoServerCert/ +COPY ./bin/OpenBaoClientCert/ /workdir/OpenBaoClientCert/ +COPY ./test/* /workdir/ + +RUN chown -R manager:manager /workdir + +USER manager + +CMD ["bash"] diff --git a/security/openbao-monitor/source/test/config/test_examples/exampleAuthToken1.yaml b/security/openbao-monitor/source/test/config/test_examples/exampleAuthToken1.yaml new file mode 100644 index 00000000..786ba5d8 --- /dev/null +++ b/security/openbao-monitor/source/test/config/test_examples/exampleAuthToken1.yaml @@ -0,0 +1,13 @@ +# +# Copyright (c) 2025 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +Tokens: + exampleToken: + duration: 0 + key: s.ACurrectRootTokenWithCorrectFormat + anotherExampleToken: + duration: 1000 + key: b.AnotherKeyThatIsNotARootToken \ No newline at end of file diff --git a/security/openbao-monitor/source/test/config/test_examples/exampleAuthToken2.yaml b/security/openbao-monitor/source/test/config/test_examples/exampleAuthToken2.yaml new file mode 100644 index 00000000..d2282eb4 --- /dev/null +++ b/security/openbao-monitor/source/test/config/test_examples/exampleAuthToken2.yaml @@ -0,0 +1,10 @@ +# +# Copyright (c) 2025 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +Tokens: + wrongFormatToken: + duration: 0 + key: c.KeyWithWrongFirstCharacter \ No newline at end of file diff --git a/security/openbao-monitor/source/test/config/test_examples/exampleAuthToken3.yaml b/security/openbao-monitor/source/test/config/test_examples/exampleAuthToken3.yaml new file mode 100644 index 00000000..328c59f1 --- /dev/null +++ b/security/openbao-monitor/source/test/config/test_examples/exampleAuthToken3.yaml @@ -0,0 +1,10 @@ +# +# Copyright (c) 2025 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +Tokens: + wrongFormatToken: + duration: 0 + key: bbKeyWithWrongSecondCharacter \ No newline at end of file diff --git a/security/openbao-monitor/source/test/config/test_examples/exampleAuthToken4.yaml b/security/openbao-monitor/source/test/config/test_examples/exampleAuthToken4.yaml new file mode 100644 index 00000000..55c393e8 --- /dev/null +++ b/security/openbao-monitor/source/test/config/test_examples/exampleAuthToken4.yaml @@ -0,0 +1,10 @@ +# +# Copyright (c) 2025 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +Tokens: + wrongFormatToken: + duration: 0 + key: r.KeyThatIsTooShort \ No newline at end of file diff --git a/security/openbao-monitor/source/test/config/test_examples/exampleServer1.yaml b/security/openbao-monitor/source/test/config/test_examples/exampleServer1.yaml new file mode 100644 index 00000000..ba223d13 --- /dev/null +++ b/security/openbao-monitor/source/test/config/test_examples/exampleServer1.yaml @@ -0,0 +1,16 @@ +# +# Copyright (c) 2025 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +OpenbaoAddresses: + controller-0: + host: controller-0 + port: 4203 + controller-1: + host: 10.13.14.4 + port: 4203 + worker-0: + host: at.node.example.com + port: 4203 \ No newline at end of file diff --git a/security/openbao-monitor/source/test/config/test_examples/exampleServer2.yaml b/security/openbao-monitor/source/test/config/test_examples/exampleServer2.yaml new file mode 100644 index 00000000..898eeb82 --- /dev/null +++ b/security/openbao-monitor/source/test/config/test_examples/exampleServer2.yaml @@ -0,0 +1,7 @@ +# +# Copyright (c) 2025 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +OpenbaoAddresses: \ No newline at end of file diff --git a/security/openbao-monitor/source/test/config/test_examples/exampleServer3.yaml b/security/openbao-monitor/source/test/config/test_examples/exampleServer3.yaml new file mode 100644 index 00000000..c24ae474 --- /dev/null +++ b/security/openbao-monitor/source/test/config/test_examples/exampleServer3.yaml @@ -0,0 +1,10 @@ +# +# Copyright (c) 2025 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +OpenbaoAddresses: + controller-0: + host: + port: \ No newline at end of file diff --git a/security/openbao-monitor/source/test/config/test_examples/exampleUnsealShards1.yaml b/security/openbao-monitor/source/test/config/test_examples/exampleUnsealShards1.yaml new file mode 100644 index 00000000..409f5cef --- /dev/null +++ b/security/openbao-monitor/source/test/config/test_examples/exampleUnsealShards1.yaml @@ -0,0 +1,39 @@ +# +# Copyright (c) 2025 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +# Correct example + +UnsealKeyShards: + sample_key_1: + key: "df15d06a52ce99c5eb298315d7a8f7e88c68d4be43f0f539176ac7e055ef395344" + key_base64: "3xXQalLOmcXrKYMV16j36Ixo1L5D8PU5F2rH4FXvOVNE" + sample_key_2: + key: "0d9aacaf7184c2b6491e0e69db0388e36eac531bab7cb9f01ccab79a3f9212c350" + key_base64: "DZqsr3GEwrZJHg5p2wOI426sUxurfLnwHMq3mj+SEsNQ" + sample_key_3: + key: "dff28842498b16c403747eda44882b04760985c75a911b1f51499bd37afb952b04" + key_base64: "3/KIQkmLFsQDdH7aRIgrBHYJhcdakRsfUUmb03r7lSsE" + sample_key_4: + key: "db7e106b1ac25248da8a0521426530cf983d8cc63f34d5001755f084b362501f4c" + key_base64: "234QaxrCUkjaigUhQmUwz5g9jMY/NNUAF1XwhLNiUB9M" + sample_key_5: + key: "a23d2664477cd7e1749f79fc0e62f7d0ce16c38ee4cb88524c0372b9cac87ab111" + key_base64: "oj0mZEd81+F0n3n8DmL30M4Ww47ky4hSTANyucrIerER" + sample_key_6: + key: "c8e7f8bbfd7e5eabe82bff709e657793f46fc89622e332979e733add8fd4e3d390" + key_base64: "yOf4u/1+XqvoK/9wnmV3k/RvyJYi4zKXnnM63Y/U49OQ" + sample_key_7: + key: "686284f3cfb4a8785bae80ddd52126dd3c21dd7ebb406705d3b6e8857cf71bb577" + key_base64: "aGKE88+0qHhbroDd1SEm3Twh3X67QGcF07bohXz3G7V3" + sample_key_8: + key: "d8e6d404bdd09e11a96d16044a2024ebce3cc5ee1cd828a202e573b2742cfbc641" + key_base64: "2ObUBL3QnhGpbRYESiAk6848xe4c2CiiAuVzsnQs+8ZB" + sample_key_9: + key: "4be0f5ab94c8f87520d877f76e513013ba5cbd31bda85f1b6070cf445b92de0ba4" + key_base64: "S+D1q5TI+HUg2Hf3blEwE7pcvTG9qF8bYHDPRFuS3guk" + sample_key_10: + key: "bd8be3df76479d7a87b987f4f3d8752a9d9552d889de8b96e292d0b24b3fbff86a" + key_base64: "vYvj33ZHnXqHuYf089h1Kp2VUtiJ3ouW4pLQsks/v/hq" diff --git a/security/openbao-monitor/source/test/config/test_examples/exampleUnsealShards2.yaml b/security/openbao-monitor/source/test/config/test_examples/exampleUnsealShards2.yaml new file mode 100644 index 00000000..3707dc9b --- /dev/null +++ b/security/openbao-monitor/source/test/config/test_examples/exampleUnsealShards2.yaml @@ -0,0 +1,39 @@ +# +# Copyright (c) 2025 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +# Missing keys + +UnsealKeyShards: + sample_key_1: + key: "df15d06a52ce99c5eb298315d7a8f7e88c68d4be43f0f539176ac7e055ef395344" + key_base64: "3xXQalLOmcXrKYMV16j36Ixo1L5D8PU5F2rH4FXvOVNE" + sample_key_2: + key: "0d9aacaf7184c2b6491e0e69db0388e36eac531bab7cb9f01ccab79a3f9212c350" + key_base64: "DZqsr3GEwrZJHg5p2wOI426sUxurfLnwHMq3mj+SEsNQ" + sample_key_3: + key: "dff28842498b16c403747eda44882b04760985c75a911b1f51499bd37afb952b04" + key_base64: + sample_key_4: + key: + key_base64: "234QaxrCUkjaigUhQmUwz5g9jMY/NNUAF1XwhLNiUB9M" + sample_key_5: + key: "a23d2664477cd7e1749f79fc0e62f7d0ce16c38ee4cb88524c0372b9cac87ab111" + key_base64: "oj0mZEd81+F0n3n8DmL30M4Ww47ky4hSTANyucrIerER" + sample_key_6: + key: "c8e7f8bbfd7e5eabe82bff709e657793f46fc89622e332979e733add8fd4e3d390" + key_base64: "yOf4u/1+XqvoK/9wnmV3k/RvyJYi4zKXnnM63Y/U49OQ" + sample_key_7: + key: "686284f3cfb4a8785bae80ddd52126dd3c21dd7ebb406705d3b6e8857cf71bb577" + key_base64: "aGKE88+0qHhbroDd1SEm3Twh3X67QGcF07bohXz3G7V3" + sample_key_8: + key: "d8e6d404bdd09e11a96d16044a2024ebce3cc5ee1cd828a202e573b2742cfbc641" + key_base64: "2ObUBL3QnhGpbRYESiAk6848xe4c2CiiAuVzsnQs+8ZB" + sample_key_9: + key: "4be0f5ab94c8f87520d877f76e513013ba5cbd31bda85f1b6070cf445b92de0ba4" + key_base64: "S+D1q5TI+HUg2Hf3blEwE7pcvTG9qF8bYHDPRFuS3guk" + sample_key_10: + key: "bd8be3df76479d7a87b987f4f3d8752a9d9552d889de8b96e292d0b24b3fbff86a" + key_base64: "vYvj33ZHnXqHuYf089h1Kp2VUtiJ3ouW4pLQsks/v/hq" \ No newline at end of file diff --git a/security/openbao-monitor/source/test/config/test_examples/exampleUnsealShards3.yaml b/security/openbao-monitor/source/test/config/test_examples/exampleUnsealShards3.yaml new file mode 100644 index 00000000..272c6133 --- /dev/null +++ b/security/openbao-monitor/source/test/config/test_examples/exampleUnsealShards3.yaml @@ -0,0 +1,39 @@ +# +# Copyright (c) 2025 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +# One key has incorrect base64 encoding + +UnsealKeyShards: + sample_key_1: + key: "df15d06a52ce99c5eb298315d7a8f7e88c68d4be43f0f539176ac7e055ef395344" + key_base64: "3xXQalLOmcXrKYMV16j36Ixo1L5D8PU5F2rH4FXvOVNE" + sample_key_2: + key: "0d9aacaf7184c2b6491e0e69db0388e36eac531bab7cb9f01ccab79a3f9212c350" + key_base64: "DZqsr3GEwrZJHg5p2wOI426sUxurfLnwHMq3mj+SEsNQ" + sample_key_3: + key: "dff28842498b16c403747eda44882b04760985c75a911b1f51499bd37afb952b04" + key_base64: "3/KIQkmLFsQDdH7aRIgrBHYJhcdakRsfUUmb03r7lSsE" + sample_key_4: + key: "db7e106b1ac25248da8a0521426530cf983d8cc63f34d5001755f084b362501f4c" + key_base64: "234QaxrCUkjaigUhQmUwz5g9jMY/NNUAF1XwhLNiUB9M" + sample_key_5: + key: "a23d2664477cd7e1749f79fc0e62f7d0ce16c38ee4cb88524c0372b9cac87ab111" + key_base64: "ThisKeyHasIncorrectBase64Encoding" + sample_key_6: + key: "c8e7f8bbfd7e5eabe82bff709e657793f46fc89622e332979e733add8fd4e3d390" + key_base64: "yOf4u/1+XqvoK/9wnmV3k/RvyJYi4zKXnnM63Y/U49OQ" + sample_key_7: + key: "686284f3cfb4a8785bae80ddd52126dd3c21dd7ebb406705d3b6e8857cf71bb577" + key_base64: "aGKE88+0qHhbroDd1SEm3Twh3X67QGcF07bohXz3G7V3" + sample_key_8: + key: "d8e6d404bdd09e11a96d16044a2024ebce3cc5ee1cd828a202e573b2742cfbc641" + key_base64: "2ObUBL3QnhGpbRYESiAk6848xe4c2CiiAuVzsnQs+8ZB" + sample_key_9: + key: "4be0f5ab94c8f87520d877f76e513013ba5cbd31bda85f1b6070cf445b92de0ba4" + key_base64: "S+D1q5TI+HUg2Hf3blEwE7pcvTG9qF8bYHDPRFuS3guk" + sample_key_10: + key: "bd8be3df76479d7a87b987f4f3d8752a9d9552d889de8b96e292d0b24b3fbff86a" + key_base64: "vYvj33ZHnXqHuYf089h1Kp2VUtiJ3ouW4pLQsks/v/hq" diff --git a/security/openbao-monitor/source/test/inPodConfig.yaml b/security/openbao-monitor/source/test/inPodConfig.yaml new file mode 100644 index 00000000..a3b3a287 --- /dev/null +++ b/security/openbao-monitor/source/test/inPodConfig.yaml @@ -0,0 +1,6 @@ +CACert: /mnt/data/ca/tls.crt +ClientCert: "" +ClientKey: "" +logPath: /workdir/openbao_monitor.log +logLevel: DEBUG +WaitInterval: 5 diff --git a/security/openbao-monitor/source/test/newRole.yaml b/security/openbao-monitor/source/test/newRole.yaml new file mode 100644 index 00000000..70c31fa2 --- /dev/null +++ b/security/openbao-monitor/source/test/newRole.yaml @@ -0,0 +1,21 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + namespace: openbao + name: stx-openbao-manager-1 +rules: +- apiGroups: [""] # "" indicates the core API group + resources: ["pods"] + verbs: ["get", "watch", "list"] +- apiGroups: [""] # "" indicates the core API group + resources: ["pods/exec"] + verbs: ["create"] +- apiGroups: [""] # "" indicates the core API group + resources: ["secrets"] + verbs: ["get", "list", "create", "delete"] +- apiGroups: ["batch"] + resources: ["jobs"] + verbs: ["get", "create", "delete"] +- apiGroups: [""] # "" indicates the core API group + resources: ["persistentvolumeclaims"] + verbs: ["list", "delete"] \ No newline at end of file diff --git a/security/openbao-monitor/source/test/scripts/gen_certs.sh b/security/openbao-monitor/source/test/scripts/gen_certs.sh new file mode 100755 index 00000000..687dfd96 --- /dev/null +++ b/security/openbao-monitor/source/test/scripts/gen_certs.sh @@ -0,0 +1,110 @@ +#!/bin/bash + +# +# Copyright (c) 2025 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +function usage { + ( + echo "Usage: " + echo " One optional parameter pair:" + echo " --certbase " + echo "The default certbase is ./bin, matching the output of build" + ) >&2 +} + +if [ $# -ne 0 -a $# -ne 2 ]; then + usage + exit 1 +fi + +if [ "$1" != "--certbase" ]; then + CERTBASE=bin +else + if [ -d "$2" ]; then + CERTBASE="$2" + else + echo "'$2' is not a directory" >&2 + exit 1 + fi +fi + +CAPATH="${CERTBASE}/OpenBaoCA" +SERVERPATH="${CERTBASE}/OpenBaoServerCert" +CLIENTPATH="${CERTBASE}/OpenBaoClientCert" +mkdir -p "$CAPATH" "$SERVERPATH" "$CLIENTPATH" + +# for the benefit of the tester, do not recreate their CA +if [ ! -f "${CAPATH}/ca.crt" -o ! -f "${CAPATH}/ca.key" ]; then + # generate the CA key + openssl ecparam -name prime256v1 -genkey -noout \ + -out "${CAPATH}/ca.key" + + # generate a CA cert for test that is valid forever (10 years) + keyUsage="critical, keyCertSign, digitalSignature, keyEncipherment" + openssl req -new -x509 -sha256 \ + -key "${CAPATH}/ca.key" \ + -out "${CAPATH}/ca.crt" \ + -days 3650 \ + -addext "keyUsage = $keyUsage" \ + -subj '/CN=OpenBao Test CA/C=CA/O=StarlingX' +fi + +# generate private key for the openbao server +openssl genrsa -out "${SERVERPATH}/tls.key" 2048 + +# generate certificate signing request for server +openssl req -new \ + -key "${SERVERPATH}/tls.key" \ + -out "${SERVERPATH}/server.csr" \ + -addext "subjectAltName = DNS:OpenBao, DNS:localhost, IP:127.0.0.1, IP:0.0.0.0" \ + -addext "keyUsage = critical, digitalSignature, keyEncipherment" \ + -subj '/CN=OpenBao Test Server/C=CA/O=StarlingX' + +# work around bug in copying extensions when signing the crt +cat < "${SERVERPATH}/ssl-extensions-x509.cnf" +[v3_ca] +basicConstraints = CA:FALSE +keyUsage = critical, digitalSignature, keyEncipherment +subjectAltName = DNS:OpenBao, DNS:localhost, IP:127.0.0.1, IP:0.0.0.0 +EOF + +# sign the csr using CA (create the server cert) +openssl x509 -req -in "${SERVERPATH}/server.csr" \ + -CA "${CAPATH}/ca.crt" -CAkey "${CAPATH}/ca.key" \ + -CAcreateserial \ + -out "${SERVERPATH}/tls.crt" \ + -days 30 \ + -extensions v3_ca \ + -extfile "${SERVERPATH}/ssl-extensions-x509.cnf" + +# generate private key for the baomon client +openssl genrsa -out "${CLIENTPATH}/tls.key" 2048 + +# generate certificate signing request for client +openssl req -new -key "${CLIENTPATH}/tls.key" \ + -out "${CLIENTPATH}/client.csr" \ + -addext "keyUsage = critical, digitalSignature" \ + -addext "extendedKeyUsage = critical, clientAuth" \ + -subj '/CN=OpenBao Test Client/C=CA/O=StarlingX' + +# work around bug in copying extensions when signing the crt +cat < "${CLIENTPATH}/ssl-extensions-x509.cnf" +[v3_ca] +basicConstraints = CA:FALSE +keyUsage = critical, digitalSignature +extendedKeyUsage = critical, clientAuth +EOF + +# sign the csr using CA (create the server cert) +openssl x509 -req -in "${CLIENTPATH}/client.csr" \ + -CA "${CAPATH}/ca.crt" -CAkey "${CAPATH}/ca.key" \ + -CAcreateserial \ + -out "${CLIENTPATH}/tls.crt" \ + -days 30 \ + -extensions v3_ca \ + -extfile "${CLIENTPATH}/ssl-extensions-x509.cnf" + + diff --git a/security/openbao-monitor/source/test/testConfig.yaml b/security/openbao-monitor/source/test/testConfig.yaml new file mode 100644 index 00000000..5643cf89 --- /dev/null +++ b/security/openbao-monitor/source/test/testConfig.yaml @@ -0,0 +1,16 @@ +# +# Copyright (c) 2025 Wind River Systems, Inc. +# +# SPDX-License-Identifier: Apache-2.0 +# + +OpenbaoAddresses: + controller-0: + host: "Openbao" + port: 8200 +CACert: "/workdir/OpenBaoCA/ca.crt" +ClientCert: "/workdir/OpenBaoClientCert/tls.crt" +ClientKey: "/workdir/OpenBaoClientCert/tls.key" +logPath: "/workdir/openbao_monitor.log" +logLevel: "DEBUG" +WaitInterval: 5 diff --git a/security/openbao-monitor/source/test/testInitConfig.json b/security/openbao-monitor/source/test/testInitConfig.json new file mode 100644 index 00000000..cd1819e0 --- /dev/null +++ b/security/openbao-monitor/source/test/testInitConfig.json @@ -0,0 +1,4 @@ +{ + "secret_shares": 5, + "secret_threshold": 3 +} \ No newline at end of file diff --git a/security/openbao-monitor/source/test/testOpenbaoConfig.hcl b/security/openbao-monitor/source/test/testOpenbaoConfig.hcl new file mode 100644 index 00000000..75399079 --- /dev/null +++ b/security/openbao-monitor/source/test/testOpenbaoConfig.hcl @@ -0,0 +1,29 @@ +# Copyright (c) HashiCorp, Inc. +# SPDX-License-Identifier: MPL-2.0 + +# Full configuration options can be found at https://github.com/openbao/openbao/tree/main/website/content/docs/configuration + +ui = true + +storage "file" { + path = "/opt/openbao/data" +} + +# HTTP listener +#listener "tcp" { +# address = "127.0.0.1:8200" +# tls_disable = 1 +#} + +# HTTPS listener +listener "tcp" { + address = "0.0.0.0:8200" + tls_cert_file = "/workdir/OpenBaoServerCert/tls.crt" + tls_key_file = "/workdir/OpenBaoServerCert/tls.key" +} + +# Example AWS KMS auto unseal +#seal "awskms" { +# region = "us-east-1" +# kms_key_id = "REPLACE-ME" +#}