Skip to content

Commit

Permalink
feat: use RELATED_IMAGES_ environment variables for manager
Browse files Browse the repository at this point in the history
  • Loading branch information
osmman committed Jan 15, 2025
1 parent b95b887 commit dc7b201
Show file tree
Hide file tree
Showing 32 changed files with 392 additions and 88 deletions.
21 changes: 12 additions & 9 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ SHELL = /usr/bin/env bash -o pipefail

OPENSHIFT ?= true

CONFIG_DEFAULT=config/env/kubernetes
ifeq ($(OPENSHIFT), true)
CONFIG_DEFAULT=config/env/openshift
endif

.PHONY: all
all: build

Expand Down Expand Up @@ -136,9 +141,9 @@ test-e2e:
.PHONY: dev-images
dev-images:
@if [ "$(shell uname)" = "Darwin" ]; then \
sed -E -i '' -f ci/dev-images.sed internal/controller/constants/images.go; \
sed -E -i '' -f ci/dev-images.sed internal/images/images.env; \
else \
sed -E -i -f ci/dev-images.sed internal/controller/constants/images.go; \
sed -E -i -f ci/dev-images.sed internal/images/images.env; \
fi

.PHONY: lint
Expand Down Expand Up @@ -195,7 +200,7 @@ docker-buildx: ## Build and push docker image for the manager for cross-platform
build-installer: manifests generate kustomize ## Generate a consolidated YAML with CRDs and deployment.
mkdir -p dist
cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
$(KUSTOMIZE) build config/default > dist/install.yaml
$(KUSTOMIZE) build ${CONFIG_DEFAULT} | hack/process_manifest.sh internal/images/images.env > dist/install.yaml

##@ Deployment

Expand All @@ -214,14 +219,12 @@ uninstall: manifests kustomize ## Uninstall CRDs from the K8s cluster specified
.PHONY: deploy
deploy: manifests kustomize ## Deploy controller to the K8s cluster specified in ~/.kube/config.
cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
$(KUSTOMIZE) build config/default | $(KUBECTL) apply -f -
@if [ "$(OPENSHIFT)" == "false" ]; then \
$(KUBECTL) patch deploy -n openshift-rhtas-operator -p '{"spec": {"template": {"spec": {"containers": [{"name": "manager","env": [{"name": "OPENSHIFT","value":"false"}]}]}}}}' rhtas-operator-controller-manager; \
fi
$(KUSTOMIZE) build ${CONFIG_DEFAULT} | hack/process_manifest.sh internal/images/images.env | $(KUBECTL) apply -f -


.PHONY: undeploy
undeploy: kustomize ## Undeploy controller from the K8s cluster specified in ~/.kube/config. Call with ignore-not-found=true to ignore resource not found errors during deletion.
$(KUSTOMIZE) build config/default | $(KUBECTL) delete --ignore-not-found=$(ignore-not-found) -f -
$(KUSTOMIZE) build ${CONFIG_DEFAULT} | hack/process_manifest.sh internal/images/images.env | $(KUBECTL) delete --ignore-not-found=$(ignore-not-found) -f -

##@ Dependencies

Expand Down Expand Up @@ -298,7 +301,7 @@ endif
bundle: manifests kustomize operator-sdk ## Generate bundle manifests and metadata, then validate generated files.
$(OPERATOR_SDK) generate kustomize manifests -q
cd config/manager && $(KUSTOMIZE) edit set image controller=$(IMG)
$(KUSTOMIZE) build config/manifests | $(OPERATOR_SDK) generate bundle $(BUNDLE_GEN_FLAGS)
$(KUSTOMIZE) build config/manifests | hack/process_manifest.sh internal/images/images.env | $(OPERATOR_SDK) generate bundle $(BUNDLE_GEN_FLAGS)
$(OPERATOR_SDK) bundle validate ./bundle

.PHONY: bundle-build
Expand Down
63 changes: 62 additions & 1 deletion bundle/manifests/rhtas-operator.clusterserviceversion.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ metadata:
]
capabilities: Seamless Upgrades
containerImage: registry.redhat.io/rhtas/rhtas-rhel9-operator@sha256:52ba6cd82bc400a08c6f89811e8086126596a873b9b12619de8c5064a2d4faf7
createdAt: "2024-11-07T12:56:22Z"
createdAt: "2025-01-15T11:05:40Z"
features.operators.openshift.io/cnf: "false"
features.operators.openshift.io/cni: "false"
features.operators.openshift.io/csi: "false"
Expand Down Expand Up @@ -892,6 +892,36 @@ spec:
env:
- name: OPENSHIFT
value: "true"
- name: RELATED_IMAGE_TRILLIAN_LOG_SIGNER
value: registry.redhat.io/rhtas/trillian-logsigner-rhel9@sha256:2d707d12e4f65e1a92b4de11465a5976d55e15ad6c9fefe994646ccd44c83840
- name: RELATED_IMAGE_TRILLIAN_LOG_SERVER
value: registry.redhat.io/rhtas/trillian-logserver-rhel9@sha256:7af78c7bc4df097ffeeef345f1d13289695f715221957579ee65daeef2fa3f5b
- name: RELATED_IMAGE_TRILLIAN_DB
value: registry.redhat.io/rhtas/trillian-database-rhel9@sha256:501612745e63e5504017079388bec191ffacf00ffdebde7be6ca5b8e4fd9d323
- name: RELATED_IMAGE_TRILLIAN_NETCAT
value: registry.redhat.io/openshift4/ose-tools-rhel8@sha256:486b4d2dd0d10c5ef0212714c94334e04fe8a3d36cf619881986201a50f123c7
- name: RELATED_IMAGE_FULCIO_SERVER
value: registry.redhat.io/rhtas/fulcio-rhel9@sha256:4b5765bbfd3dac5fa027d2fb3d672b6ebffbc573b9413ab4cb189c50fa6f9a09
- name: RELATED_IMAGE_REKOR_REDIS
value: registry.redhat.io/rhtas/trillian-redis-rhel9@sha256:18820b1fbdbc2cc3e917822974910332d937b03cfe781628bd986fd6a5ee318e
- name: RELATED_IMAGE_REKOR_SERVER
value: registry.redhat.io/rhtas/rekor-server-rhel9@sha256:81e10e34f02b21bb8295e7b5c93797fc8c0e43a1a0d8304cca1b07415a3ed6f5
- name: RELATED_IMAGE_REKOR_SEARCH_UI
value: registry.redhat.io/rhtas/rekor-search-ui-rhel9@sha256:3c93c15fc5c918a91b3da9f5bf2276e4d46d881b1031287e6ab28e6aeb23e019
- name: RELATED_IMAGE_BACKFILL_REDIS
value: registry.redhat.io/rhtas/rekor-backfill-redis-rhel9@sha256:6aa3ca40e0f9e32a0a211a930b21ff009b83e46609bfa5bb328979e4799d13c7
- name: RELATED_IMAGE_TUF
value: registry.redhat.io/rhtas/tuffer-rhel9@sha256:79340be7918034c68a334a210ab872161827c99c2a1551a4fce8d5d27560a234
- name: RELATED_IMAGE_CTLOG
value: registry.redhat.io/rhtas/certificate-transparency-rhel9@sha256:31e7318a9b19ed04ef0f25949f1f1709d293b532316b27a06f83fa5174547b17
- name: RELATED_IMAGE_HTTP_SERVER
value: registry.access.redhat.com/ubi9/httpd-24@sha256:7874b82335a80269dcf99e5983c2330876f5fe8bdc33dc6aa4374958a2ffaaee
- name: RELATED_IMAGE_SEGMENT_REPORTING
value: registry.redhat.io/rhtas/segment-reporting-rhel9@sha256:1b87ff1ad02c476c08e06038a26af7abe61f177e491a9ff42d507550a8587ac8
- name: RELATED_IMAGE_TIMESTAMP_AUTHORITY
value: registry.redhat.io/rhtas/timestamp-authority-rhel9@sha256:fce0a22c8872309554236bab3457715dda0a83eb40dc6a9ecd3477b8023369d0
- name: RELATED_IMAGE_CLIENT_SERVER
value: registry.redhat.io/rhtas/client-server-rhel9@sha256:9537329d0166b8d41ffd5f5d79c052fc27abe426a20cba5733c84030013c4e29
image: registry.redhat.io/rhtas/rhtas-rhel9-operator@sha256:52ba6cd82bc400a08c6f89811e8086126596a873b9b12619de8c5064a2d4faf7
livenessProbe:
httpGet:
Expand Down Expand Up @@ -998,4 +1028,35 @@ spec:
provider:
name: Red Hat
url: https://github.com/securesign/secure-sign-operator
relatedImages:
- image: registry.redhat.io/rhtas/trillian-logsigner-rhel9@sha256:2d707d12e4f65e1a92b4de11465a5976d55e15ad6c9fefe994646ccd44c83840
name: trillian-log-signer
- image: registry.redhat.io/rhtas/trillian-logserver-rhel9@sha256:7af78c7bc4df097ffeeef345f1d13289695f715221957579ee65daeef2fa3f5b
name: trillian-log-server
- image: registry.redhat.io/rhtas/trillian-database-rhel9@sha256:501612745e63e5504017079388bec191ffacf00ffdebde7be6ca5b8e4fd9d323
name: trillian-db
- image: registry.redhat.io/openshift4/ose-tools-rhel8@sha256:486b4d2dd0d10c5ef0212714c94334e04fe8a3d36cf619881986201a50f123c7
name: trillian-netcat
- image: registry.redhat.io/rhtas/fulcio-rhel9@sha256:4b5765bbfd3dac5fa027d2fb3d672b6ebffbc573b9413ab4cb189c50fa6f9a09
name: fulcio-server
- image: registry.redhat.io/rhtas/trillian-redis-rhel9@sha256:18820b1fbdbc2cc3e917822974910332d937b03cfe781628bd986fd6a5ee318e
name: rekor-redis
- image: registry.redhat.io/rhtas/rekor-server-rhel9@sha256:81e10e34f02b21bb8295e7b5c93797fc8c0e43a1a0d8304cca1b07415a3ed6f5
name: rekor-server
- image: registry.redhat.io/rhtas/rekor-search-ui-rhel9@sha256:3c93c15fc5c918a91b3da9f5bf2276e4d46d881b1031287e6ab28e6aeb23e019
name: rekor-search-ui
- image: registry.redhat.io/rhtas/rekor-backfill-redis-rhel9@sha256:6aa3ca40e0f9e32a0a211a930b21ff009b83e46609bfa5bb328979e4799d13c7
name: backfill-redis
- image: registry.redhat.io/rhtas/tuffer-rhel9@sha256:79340be7918034c68a334a210ab872161827c99c2a1551a4fce8d5d27560a234
name: tuf
- image: registry.redhat.io/rhtas/certificate-transparency-rhel9@sha256:31e7318a9b19ed04ef0f25949f1f1709d293b532316b27a06f83fa5174547b17
name: ctlog
- image: registry.access.redhat.com/ubi9/httpd-24@sha256:7874b82335a80269dcf99e5983c2330876f5fe8bdc33dc6aa4374958a2ffaaee
name: http-server
- image: registry.redhat.io/rhtas/segment-reporting-rhel9@sha256:1b87ff1ad02c476c08e06038a26af7abe61f177e491a9ff42d507550a8587ac8
name: segment-reporting
- image: registry.redhat.io/rhtas/timestamp-authority-rhel9@sha256:fce0a22c8872309554236bab3457715dda0a83eb40dc6a9ecd3477b8023369d0
name: timestamp-authority
- image: registry.redhat.io/rhtas/client-server-rhel9@sha256:9537329d0166b8d41ffd5f5d79c052fc27abe426a20cba5733c84030013c4e29
name: client-server
version: 1.2.0
32 changes: 17 additions & 15 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import (
"crypto/tls"
"flag"

"github.com/securesign/operator/internal/images"

"net/http"
"os"
"strconv"
Expand Down Expand Up @@ -104,22 +106,22 @@ func main() {
"If set, HTTP/2 will be enabled for the metrics and webhook servers")
flag.Int64Var(&constants.CreateTreeDeadline, "create-tree-deadline", constants.CreateTreeDeadline, "The time allowance (in seconds) for the create tree job to run before failing.")
utils.BoolFlagOrEnv(&constants.Openshift, "openshift", "OPENSHIFT", false, "Enable to ensures the operator applies OpenShift specific configurations.")
utils.StringFlagOrEnv(&constants.TrillianLogSignerImage, "trillian-log-signer-image", "TRILLIAN_LOG_SIGNER_IMAGE", constants.TrillianLogSignerImage, "The image used for trillian log signer.")
utils.StringFlagOrEnv(&constants.TrillianServerImage, "trillian-log-server-image", "TRILLIAN_LOG_SERVER_IMAGE", constants.TrillianServerImage, "The image used for trillian log server.")
utils.StringFlagOrEnv(&constants.TrillianDbImage, "trillian-db-image", "TRILLIAN_DB_IMAGE", constants.TrillianDbImage, "The image used for trillian's database.")
utils.StringFlagOrEnv(&constants.TrillianNetcatImage, "trillian-netcat-image", "TRILLIAN_NETCAT_IMAGE", constants.TrillianNetcatImage, "The image used for trillian netcat.")
utils.StringFlagOrEnv(&constants.FulcioServerImage, "fulcio-server-image", "FULCIO_SERVER_IMAGE", constants.FulcioServerImage, "The image used for the fulcio server.")
utils.StringFlagOrEnv(&constants.RekorRedisImage, "rekor-redis-image", "REKOR_REDIS_IMAGE", constants.RekorRedisImage, "The image used for redis.")
utils.StringFlagOrEnv(&constants.RekorServerImage, "rekor-server-image", "REKOR_SERVER_IMAGE", constants.RekorServerImage, "The image used for rekor server.")
utils.StringFlagOrEnv(&constants.RekorSearchUiImage, "rekor-search-ui-image", "REKOR_SEARCH_UI_IMAGE", constants.RekorSearchUiImage, "The image used for rekor search ui.")
utils.StringFlagOrEnv(&constants.BackfillRedisImage, "backfill-redis-image", "BACKFILL_REDIS_IMAGE", constants.BackfillRedisImage, "The image used for backfill redis.")
utils.StringFlagOrEnv(&constants.TufImage, "tuf-image", "TUF_IMAGE", constants.TufImage, "The image used for TUF.")
utils.StringFlagOrEnv(&constants.CTLogImage, "ctlog-image", "CTLOG_IMAGE", constants.CTLogImage, "The image used for ctlog.")
utils.StringFlagOrEnv(&constants.HttpServerImage, "http-server-image", "HTTP_SERVER_IMAGE", constants.HttpServerImage, "The image used to serve our cli binary's.")
utils.StringFlagOrEnv(&constants.ClientServerImage, "client-server-image", "CLIENT_SERVER_IMAGE", constants.ClientServerImage, "The image used to serve cosign and gitsign.")
utils.StringFlagOrEnv(&constants.SegmentBackupImage, "segment-backup-job-image", "SEGMENT_BACKUP_JOB_IMAGE", constants.SegmentBackupImage, "The image used for the segment backup job")
utils.RelatedImageFlag("trillian-log-signer-image", images.TrillianLogSigner, "The image used for trillian log signer.")
utils.RelatedImageFlag("trillian-log-server-image", images.TrillianServer, "The image used for trillian log server.")
utils.RelatedImageFlag("trillian-db-image", images.TrillianDb, "The image used for trillian's database.")
utils.RelatedImageFlag("trillian-netcat-image", images.TrillianNetcat, "The image used for trillian netcat.")
utils.RelatedImageFlag("fulcio-server-image", images.FulcioServer, "The image used for the fulcio server.")
utils.RelatedImageFlag("rekor-redis-image", images.RekorRedis, "The image used for redis.")
utils.RelatedImageFlag("rekor-server-image", images.RekorServer, "The image used for rekor server.")
utils.RelatedImageFlag("rekor-search-ui-image", images.RekorSearchUi, "The image used for rekor search ui.")
utils.RelatedImageFlag("backfill-redis-image", images.BackfillRedis, "The image used for backfill redis.")
utils.RelatedImageFlag("tuf-image", images.Tuf, "The image used for TUF.")
utils.RelatedImageFlag("ctlog-image", images.CTLog, "The image used for ctlog.")
utils.RelatedImageFlag("http-server-image", images.HttpServer, "The image used to serve our cli binary's.")
utils.RelatedImageFlag("client-server-image", images.ClientServer, "The image used to serve cosign and gitsign.")
utils.RelatedImageFlag("segment-backup-job-image", images.SegmentBackup, "The image used for the segment backup job")
utils.RelatedImageFlag("timestamp-authority-image", images.TimestampAuthority, "The image used for Timestamp Authority")
flag.StringVar(&clidownload.CliHostName, "cli-server-hostname", "", "The hostname for the cli server")
utils.StringFlagOrEnv(&constants.TimestampAuthorityImage, "timestamp-authority-image", "TIMESTAMP_AUTHORITY_IMAGE", constants.TimestampAuthorityImage, "The image used for Timestamp Authority")

klog.InitFlags(flag.CommandLine)
flag.Parse()
Expand Down
5 changes: 3 additions & 2 deletions config/default/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,15 @@ resources:
- ../prometheus

patches:
- path: manager_openshift_patch.yaml
- path: manager_metrics_patch.yaml
target:
kind: Deployment
name: operator-controller-manager
- path: manager_metrics_patch.yaml
- path: manager_images_patch.yaml
target:
kind: Deployment
name: operator-controller-manager

# Protect the /metrics endpoint by putting it behind auth.
# If you want your controller-manager to expose the /metrics
# endpoint w/o any authn/z, please comment the following line.
Expand Down
40 changes: 40 additions & 0 deletions config/default/manager_images_patch.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: operator-controller-manager
spec:
template:
spec:
containers:
- name: manager
env:
- name: RELATED_IMAGE_TRILLIAN_LOG_SIGNER
value: "<<RELATED_IMAGE_TRILLIAN_LOG_SIGNER>>"
- name: RELATED_IMAGE_TRILLIAN_LOG_SERVER
value: "<<RELATED_IMAGE_TRILLIAN_LOG_SERVER>>"
- name: RELATED_IMAGE_TRILLIAN_DB
value: "<<RELATED_IMAGE_TRILLIAN_DB>>"
- name: RELATED_IMAGE_TRILLIAN_NETCAT
value: "<<RELATED_IMAGE_TRILLIAN_NETCAT>>"
- name: RELATED_IMAGE_FULCIO_SERVER
value: "<<RELATED_IMAGE_FULCIO_SERVER>>"
- name: RELATED_IMAGE_REKOR_REDIS
value: "<<RELATED_IMAGE_REKOR_REDIS>>"
- name: RELATED_IMAGE_REKOR_SERVER
value: "<<RELATED_IMAGE_REKOR_SERVER>>"
- name: RELATED_IMAGE_REKOR_SEARCH_UI
value: "<<RELATED_IMAGE_REKOR_SEARCH_UI>>"
- name: RELATED_IMAGE_BACKFILL_REDIS
value: "<<RELATED_IMAGE_BACKFILL_REDIS>>"
- name: RELATED_IMAGE_TUF
value: "<<RELATED_IMAGE_TUF>>"
- name: RELATED_IMAGE_CTLOG
value: "<<RELATED_IMAGE_CTLOG>>"
- name: RELATED_IMAGE_HTTP_SERVER
value: "<<RELATED_IMAGE_HTTP_SERVER>>"
- name: RELATED_IMAGE_SEGMENT_REPORTING
value: "<<RELATED_IMAGE_SEGMENT_REPORTING>>"
- name: RELATED_IMAGE_TIMESTAMP_AUTHORITY
value: "<<RELATED_IMAGE_TIMESTAMP_AUTHORITY>>"
- name: RELATED_IMAGE_CLIENT_SERVER
value: "<<RELATED_IMAGE_CLIENT_SERVER>>"
5 changes: 5 additions & 0 deletions config/env/kubernetes/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
- ../../default
11 changes: 11 additions & 0 deletions config/env/openshift/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

resources:
- ../../default

patches:
- path: manager_openshift_patch.yaml
target:
kind: Deployment
name: operator-controller-manager
File renamed without changes.
2 changes: 1 addition & 1 deletion config/manifests/kustomization.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ kind: Kustomization
# used to generate the 'manifests/' directory in a bundle.
resources:
- bases/rhtas-operator.clusterserviceversion.yaml
- ../default
- ../env/openshift
- ../samples
- ../scorecard

Expand Down
58 changes: 58 additions & 0 deletions hack/process_manifest.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#!/usr/bin/env sh

# Function to display help message
display_help() {
echo "Usage: $0 <path_to_variable_file>"
echo
echo "This script replaces placeholders in the format <<VARIABLE_NAME>> with values"
echo "from the specified variable file. The variable file must have entries in the format:"
echo " VARIABLE_NAME=value"
echo
exit 1
}

# Check if the variable file is provided
if [ -z "$1" ]; then
echo "Error: Path to the variable file is not provided."
display_help
fi

# Load the variable file
variable_file="$1"

# Check if the variable file exists and is readable
if [ ! -f "$variable_file" ] || [ ! -r "$variable_file" ]; then
echo "Error: The specified variable file does not exist or is not readable."
exit 1
fi


# Function to get the value of a variable from the file
get_variable_value() {
local var_name="$1"
grep -E "^${var_name}=" "$variable_file" | cut -d '=' -f 2-
}
# Function to process a single line and replace placeholders
process_line() {
local line="$1"

# Find all placeholders (in the format <<VAR_NAME>>)
while [[ "$line" =~ \<\<([a-zA-Z_][a-zA-Z0-9_]*)\>\> ]]; do
local placeholder="${BASH_REMATCH[0]}"
local var_name="${BASH_REMATCH[1]}"
local value=$(get_variable_value "$var_name")

# If a value is found, replace the placeholder with the value
if [ -n "$value" ]; then
line="${line//$placeholder/$value}"
else
line="${line//$placeholder/}"
fi
done

printf "%s\n" "$line"
}

while IFS= read -r line; do
process_line "$line"
done
4 changes: 3 additions & 1 deletion internal/clidownload/component.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"context"
"fmt"

"github.com/securesign/operator/internal/images"

"github.com/go-logr/logr"
consolev1 "github.com/openshift/api/console/v1"
rhtasv1alpha1 "github.com/securesign/operator/api/v1alpha1"
Expand Down Expand Up @@ -136,7 +138,7 @@ func (c *Component) createDeployment(namespace string, labels map[string]string)
Containers: []core.Container{
{
Name: cliServerName,
Image: constants.ClientServerImage,
Image: images.Registry.Get(images.ClientServer),
ImagePullPolicy: core.PullAlways,
Ports: []core.ContainerPort{
{
Expand Down
8 changes: 8 additions & 0 deletions internal/controller/common/utils/flag_or_env.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"flag"
"os"
"strconv"

"github.com/securesign/operator/internal/images"
)

// StringFlagOrEnv defines a string flag which can be set by an environment variable.
Expand All @@ -16,6 +18,12 @@ func StringFlagOrEnv(p *string, name string, envName string, defaultValue string
flag.StringVar(p, name, defaultValue, usage)
}

func RelatedImageFlag(name string, image images.Image, usage string) {
p := new(string)
StringFlagOrEnv(p, name, string(image), images.Registry.Get(image), usage)
images.Registry.Setter(image)(*p)
}

// BoolFlagOrEnv defines a bool flag which can be set by an environment variable.
// Precedence: flag > env var > default value.
func BoolFlagOrEnv(p *bool, name string, envName string, defaultValue bool, usage string) {
Expand Down
Loading

0 comments on commit dc7b201

Please sign in to comment.