Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 0 additions & 18 deletions Docs/demo.outline

This file was deleted.

130 changes: 115 additions & 15 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
BINARY_NAME = kubectl-oadp
INSTALL_PATH ?= $(HOME)/.local/bin
VERSION ?= $(shell git describe --tags --always --dirty 2>/dev/null || echo "dev")
VELERO_NAMESPACE ?= openshift-adp
ASSUME_DEFAULT ?= false

# Centralized platform definitions to avoid duplication
# Matches architectures supported by Kubernetes: https://kubernetes.io/releases/download/#binaries
Expand All @@ -31,10 +33,12 @@ help: ## Show this help message
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf " \033[36m%-15s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
@echo ""
@echo "Installation options:"
@echo " \033[36mmake install\033[0m # Install to ~/.local/bin (recommended, no sudo)"
@echo " \033[36mmake install-user\033[0m # Same as install (legacy alias)"
@echo " \033[36mmake install-bin\033[0m # Install to ~/bin (alternative, no sudo)"
@echo " \033[36mmake install-system\033[0m # Install to /usr/local/bin (requires sudo)"
@echo " \033[36mmake install\033[0m # Install with auto-detection & interactive prompt"
@echo " \033[36mmake install ASSUME_DEFAULT=true\033[0m # Install with default namespace (no detection/prompt)"
@echo " \033[36mmake install VELERO_NAMESPACE=velero\033[0m # Install with custom namespace (no detection/prompt)"
@echo " \033[36mmake install-user\033[0m # Same as install (legacy alias)"
@echo " \033[36mmake install-bin\033[0m # Install to ~/bin (alternative, no sudo)"
@echo " \033[36mmake install-system\033[0m # Install to /usr/local/bin (requires sudo)"
@echo ""
@echo "Uninstall options:"
@echo " \033[36mmake uninstall\033[0m # Remove from user locations (no sudo)"
Expand All @@ -51,6 +55,11 @@ help: ## Show this help message
@echo " make build PLATFORM=windows/amd64"
@echo " make build PLATFORM=windows/arm64"
@echo ""
@echo "Testing commands:"
@echo " make test # Run all tests (unit + integration)"
@echo " make test-unit # Run unit tests only"
@echo " make test-integration # Run integration tests only"
@echo ""
@echo "Release commands:"
@echo " make release-build # Build binaries for all platforms"
@echo " make release-archives # Create tar.gz archives for all platforms"
Expand All @@ -59,21 +68,38 @@ help: ## Show this help message
.PHONY: build
build: ## Build the kubectl plugin binary (use PLATFORM=os/arch for cross-compilation)
@if [ -n "$(PLATFORM)" ]; then \
if [ "$(GOOS)" = "windows" ]; then \
binary_suffix=".exe"; \
else \
binary_suffix=""; \
fi; \
echo "Building $(BINARY_NAME) for $(PLATFORM)..."; \
GOOS=$(GOOS) GOARCH=$(GOARCH) go build -o $(BINARY_NAME)-$(GOOS)-$(GOARCH) .; \
echo "✅ Built $(BINARY_NAME)-$(GOOS)-$(GOARCH) successfully!"; \
GOOS=$(GOOS) GOARCH=$(GOARCH) go build -o $(BINARY_NAME)-$(GOOS)-$(GOARCH)$$binary_suffix .; \
echo "✅ Built $(BINARY_NAME)-$(GOOS)-$(GOARCH)$$binary_suffix successfully!"; \
else \
echo "Building $(BINARY_NAME) for current platform ($$(go env GOOS)/$$(go env GOARCH))..."; \
go build -o $(BINARY_NAME) .; \
echo "✅ Built $(BINARY_NAME) successfully!"; \
GOOS=$$(go env GOOS); \
if [ "$$GOOS" = "windows" ]; then \
binary_name="$(BINARY_NAME).exe"; \
else \
binary_name="$(BINARY_NAME)"; \
fi; \
echo "Building $$binary_name for current platform ($$GOOS/$$(go env GOARCH))..."; \
go build -o $$binary_name .; \
echo "✅ Built $$binary_name successfully!"; \
fi

# Installation targets
.PHONY: install
install: build ## Build and install the kubectl plugin to ~/.local/bin (no sudo required)
@echo "Installing $(BINARY_NAME) to $(INSTALL_PATH)..."
@mkdir -p $(INSTALL_PATH)
cp $(BINARY_NAME) $(INSTALL_PATH)/
@GOOS=$$(go env GOOS); \
if [ "$$GOOS" = "windows" ]; then \
binary_name="$(BINARY_NAME).exe"; \
else \
binary_name="$(BINARY_NAME)"; \
fi; \
echo "Installing $$binary_name to $(INSTALL_PATH)..."; \
mkdir -p $(INSTALL_PATH); \
cp $$binary_name $(INSTALL_PATH)/
@echo "✅ Installed to $(INSTALL_PATH)"
@echo ""
@PATH_UPDATED=false; \
Expand Down Expand Up @@ -108,7 +134,66 @@ install: build ## Build and install the kubectl plugin to ~/.local/bin (no sudo
if [[ "$$PATH_UPDATED" == "true" ]] || [[ "$$PATH_IN_CONFIG" == "true" ]]; then \
echo "🔄 Restart terminal or run: source ~/.zshrc"; \
fi; \
echo "Test: kubectl oadp --help"
echo ""; \
echo "📋 Configuration:"; \
NAMESPACE=$(VELERO_NAMESPACE); \
DETECTED=false; \
if [[ "$(ASSUME_DEFAULT)" != "true" && "$(VELERO_NAMESPACE)" == "openshift-adp" ]]; then \
echo ""; \
echo "🔍 Detecting OADP deployment in cluster..."; \
DETECTED_NS=$$(kubectl get deployment openshift-adp-controller-manager --all-namespaces -o jsonpath='{.items[0].metadata.namespace}' 2>/dev/null | head -1); \
if [[ -n "$$DETECTED_NS" ]]; then \
echo "✅ Found OADP controller in namespace: $$DETECTED_NS"; \
NAMESPACE=$$DETECTED_NS; \
DETECTED=true; \
else \
echo " Could not find openshift-adp-controller-manager deployment"; \
echo "🔍 Looking for DataProtectionApplication (DPA) resources..."; \
DETECTED_NS=$$(kubectl get dataprotectionapplication --all-namespaces -o jsonpath='{.items[0].metadata.namespace}' 2>/dev/null | head -1); \
if [[ -n "$$DETECTED_NS" ]]; then \
echo "✅ Found DPA resource in namespace: $$DETECTED_NS"; \
NAMESPACE=$$DETECTED_NS; \
DETECTED=true; \
else \
echo " Could not find DataProtectionApplication resources"; \
echo "🔍 Looking for Velero deployment as fallback..."; \
DETECTED_NS=$$(kubectl get deployment velero --all-namespaces -o jsonpath='{.items[0].metadata.namespace}' 2>/dev/null | head -1); \
if [[ -n "$$DETECTED_NS" ]]; then \
echo "✅ Found Velero deployment in namespace: $$DETECTED_NS"; \
NAMESPACE=$$DETECTED_NS; \
DETECTED=true; \
else \
echo "⚠️ Could not detect OADP or Velero deployment in cluster"; \
fi; \
fi; \
fi; \
if [[ "$$DETECTED" == "false" ]]; then \
echo "🤔 Which namespace should admin commands use for Velero resources?"; \
echo " (Common options: openshift-adp, velero, oadp)"; \
echo ""; \
printf "Enter namespace [default: $(VELERO_NAMESPACE)]: "; \
read -r user_input; \
if [[ -n "$$user_input" ]]; then \
NAMESPACE=$$user_input; \
fi; \
fi; \
echo ""; \
fi; \
echo "Setting Velero namespace to: $$NAMESPACE"; \
GOOS=$$(go env GOOS); \
if [ "$$GOOS" = "windows" ]; then \
binary_name="$(BINARY_NAME).exe"; \
else \
binary_name="$(BINARY_NAME)"; \
fi; \
$(INSTALL_PATH)/$$binary_name client config set namespace=$$NAMESPACE 2>/dev/null || true; \
echo "✅ Client config initialized"; \
echo ""; \
echo "📋 Next steps:"; \
echo " 1. Test admin commands: kubectl oadp backup get"; \
echo " 2. Test non-admin commands: kubectl oadp nonadmin backup get"; \
echo " 3. Manage NABSL requests: kubectl oadp nabsl get"; \
echo " 4. Change namespace: kubectl oadp client config set namespace=<namespace>"

.PHONY: install-user
install-user: build ## Build and install the kubectl plugin to ~/.local/bin (no sudo required)
Expand Down Expand Up @@ -185,14 +270,29 @@ uninstall-all: ## Uninstall the kubectl plugin from all locations (user + system
.PHONY: test
test: ## Run all tests
@echo "Running tests..."
go test ./...
@echo "🧪 Running unit tests..."
go test ./cmd/... ./internal/...
@echo "🔗 Running integration tests..."
go test . -v
@echo "✅ Tests completed!"

.PHONY: test-unit
test-unit: ## Run unit tests only
@echo "Running unit tests..."
go test ./cmd/... ./internal/...
@echo "✅ Unit tests completed!"

.PHONY: test-integration
test-integration: ## Run integration tests only
@echo "Running integration tests..."
go test . -v
@echo "✅ Integration tests completed!"

# Cleanup targets
.PHONY: clean
clean: ## Remove built binaries
@echo "Cleaning up..."
@rm -f $(BINARY_NAME) $(BINARY_NAME)-linux-* $(BINARY_NAME)-darwin-* $(BINARY_NAME)-windows-*
@rm -f $(BINARY_NAME) $(BINARY_NAME).exe $(BINARY_NAME)-linux-* $(BINARY_NAME)-darwin-* $(BINARY_NAME)-windows-*
@rm -f *.tar.gz *.sha256
@rm -f oadp-*.yaml oadp-*.yaml.tmp
@echo "✅ Cleanup complete!"
Expand Down
34 changes: 20 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ kubectl oadp
├── backup # Velero cluster-wide backups (admin)
├── restore # Velero cluster-wide restores (admin)
├── version # Version information
├── nabsl-request # Manage NonAdminBackupStorageLocation approval requests
└── nonadmin (na) # Namespace-scoped operations (non-admin)
└── backup
├── create
Expand All @@ -30,23 +31,10 @@ kubectl oadp

## Installation

### Using Krew (Available soon!)

```sh
# Install Krew if you haven't already
kubectl krew install krew

# Install the OADP plugin
kubectl krew install oadp

# Verify installation
kubectl oadp --help
```

### Manual Build and Install

```sh
# Recommended: Rootless install (no sudo required)
# Recommended: Smart install with auto-detection (no sudo required)
make install

# After install, refresh your terminal:
Expand All @@ -60,8 +48,26 @@ kubectl oadp --help
make install-system
```

The `make install` command automatically detects your OADP deployment namespace by looking for:
1. **OADP Controller** (`openshift-adp-controller-manager` deployment)
2. **DPA Resources** (`DataProtectionApplication` custom resources)
3. **Velero Deployment** (fallback for vanilla Velero installations)

If no OADP resources are detected, you'll be prompted to specify the namespace manually.

**Installation Options:**
```sh
make install # Smart detection + interactive prompt
make install ASSUME_DEFAULT=true # Use default namespace (no detection)
make install VELERO_NAMESPACE=custom # Use specific namespace (no detection)
```

**💡 Important:** After installation, you may need to refresh your terminal or run `source ~/.zshrc` (or `~/.bashrc`) for the `kubectl oadp` command to work.

You can set the velero namespace afterwards using the oadp client command



## Usage Guide

### Non-Admin Backup Operations
Expand Down
Loading
Loading