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
355 changes: 295 additions & 60 deletions api/proto/gen/v1/devnet.pb.go

Large diffs are not rendered by default.

27 changes: 27 additions & 0 deletions api/proto/v1/devnet.proto
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ message DevnetMetadata {
google.protobuf.Timestamp updated_at = 4;
map<string, string> labels = 5;
map<string, string> annotations = 6;
string namespace = 7; // Namespace for resource isolation (defaults to "default")
}

message DevnetSpec {
Expand Down Expand Up @@ -86,6 +87,7 @@ message CreateDevnetRequest {
string name = 1;
DevnetSpec spec = 2;
map<string, string> labels = 3;
string namespace = 4; // Target namespace (defaults to "default")
}

message CreateDevnetResponse {
Expand All @@ -94,6 +96,7 @@ message CreateDevnetResponse {

message GetDevnetRequest {
string name = 1;
string namespace = 2; // Namespace to look in (defaults to "default")
}

message GetDevnetResponse {
Expand All @@ -102,6 +105,7 @@ message GetDevnetResponse {

message ListDevnetsRequest {
string label_selector = 1;
string namespace = 2; // Filter by namespace, empty = all namespaces
}

message ListDevnetsResponse {
Expand All @@ -110,6 +114,7 @@ message ListDevnetsResponse {

message DeleteDevnetRequest {
string name = 1;
string namespace = 2; // Namespace (defaults to "default")
}

message DeleteDevnetResponse {
Expand All @@ -118,6 +123,7 @@ message DeleteDevnetResponse {

message StartDevnetRequest {
string name = 1;
string namespace = 2; // Namespace (defaults to "default")
}

message StartDevnetResponse {
Expand All @@ -126,6 +132,7 @@ message StartDevnetResponse {

message StopDevnetRequest {
string name = 1;
string namespace = 2; // Namespace (defaults to "default")
}

message StopDevnetResponse {
Expand All @@ -137,6 +144,7 @@ message ApplyDevnetRequest {
DevnetSpec spec = 2;
map<string, string> labels = 3;
map<string, string> annotations = 4;
string namespace = 5; // Namespace (defaults to "default")
}

message ApplyDevnetResponse {
Expand All @@ -149,6 +157,7 @@ message UpdateDevnetRequest {
DevnetSpec spec = 2;
map<string, string> labels = 3;
map<string, string> annotations = 4;
string namespace = 5; // Namespace (defaults to "default")
}

message UpdateDevnetResponse {
Expand All @@ -173,6 +182,7 @@ message NodeMetadata {
int64 generation = 4;
google.protobuf.Timestamp created_at = 5;
google.protobuf.Timestamp updated_at = 6;
string namespace = 7; // Parent devnet's namespace (defaults to "default")
}

message NodeSpec {
Expand Down Expand Up @@ -231,6 +241,7 @@ service NodeService {
message StartNodeRequest {
string devnet_name = 1;
int32 index = 2;
string namespace = 3; // Namespace (defaults to "default")
}

message StartNodeResponse {
Expand All @@ -241,6 +252,7 @@ message StopNodeRequest {
string devnet_name = 1;
int32 index = 2;
int32 timeout_seconds = 3; // Grace period, default 30
string namespace = 4; // Namespace (defaults to "default")
}

message StopNodeResponse {
Expand All @@ -250,6 +262,7 @@ message StopNodeResponse {
message RestartNodeRequest {
string devnet_name = 1;
int32 index = 2;
string namespace = 3; // Namespace (defaults to "default")
}

message RestartNodeResponse {
Expand All @@ -259,6 +272,7 @@ message RestartNodeResponse {
message GetNodeRequest {
string devnet_name = 1;
int32 index = 2;
string namespace = 3; // Namespace (defaults to "default")
}

message GetNodeResponse {
Expand All @@ -267,6 +281,7 @@ message GetNodeResponse {

message ListNodesRequest {
string devnet_name = 1; // Required: filter by devnet
string namespace = 2; // Namespace (defaults to "default")
}

message ListNodesResponse {
Expand All @@ -276,6 +291,7 @@ message ListNodesResponse {
message GetNodeHealthRequest {
string devnet_name = 1;
int32 index = 2;
string namespace = 3; // Namespace (defaults to "default")
}

message GetNodeHealthResponse {
Expand All @@ -288,6 +304,7 @@ message StreamNodeLogsRequest {
bool follow = 3;
string since = 4; // RFC3339 timestamp
int32 tail = 5; // Number of lines from end
string namespace = 6; // Namespace (defaults to "default")
}

message StreamNodeLogsResponse {
Expand All @@ -301,6 +318,7 @@ message ExecInNodeRequest {
int32 index = 2;
repeated string command = 3;
int32 timeout_seconds = 4;
string namespace = 5; // Namespace (defaults to "default")
}

message ExecInNodeResponse {
Expand All @@ -325,6 +343,7 @@ message UpgradeMetadata {
int64 generation = 2;
google.protobuf.Timestamp created_at = 3;
google.protobuf.Timestamp updated_at = 4;
string namespace = 5; // Namespace for isolation (defaults to "default")
}

message UpgradeSpec {
Expand All @@ -334,6 +353,8 @@ message UpgradeSpec {
BinarySource new_binary = 4; // Upgraded binary source
bool with_export = 5; // Enable state export before/after
bool auto_vote = 6; // Auto-vote yes with all validators
// Field 7 reserved for future use
string namespace = 8; // Namespace for the devnet reference (defaults to "default")
}

message BinarySource {
Expand Down Expand Up @@ -372,6 +393,7 @@ service UpgradeService {
message CreateUpgradeRequest {
string name = 1; // Unique upgrade name
UpgradeSpec spec = 2;
string namespace = 3; // Namespace (defaults to "default")
}

message CreateUpgradeResponse {
Expand All @@ -380,6 +402,7 @@ message CreateUpgradeResponse {

message GetUpgradeRequest {
string name = 1;
string namespace = 2; // Namespace (defaults to "default")
}

message GetUpgradeResponse {
Expand All @@ -388,6 +411,7 @@ message GetUpgradeResponse {

message ListUpgradesRequest {
string devnet_name = 1; // Optional: filter by devnet
string namespace = 2; // Namespace (defaults to "default", empty = all namespaces)
}

message ListUpgradesResponse {
Expand All @@ -396,6 +420,7 @@ message ListUpgradesResponse {

message DeleteUpgradeRequest {
string name = 1;
string namespace = 2; // Namespace (defaults to "default")
}

message DeleteUpgradeResponse {
Expand All @@ -404,6 +429,7 @@ message DeleteUpgradeResponse {

message CancelUpgradeRequest {
string name = 1;
string namespace = 2; // Namespace (defaults to "default")
}

message CancelUpgradeResponse {
Expand All @@ -412,6 +438,7 @@ message CancelUpgradeResponse {

message RetryUpgradeRequest {
string name = 1;
string namespace = 2; // Namespace (defaults to "default")
}

message RetryUpgradeResponse {
Expand Down
23 changes: 16 additions & 7 deletions cmd/dvb/apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,13 @@ func runApply(cmd *cobra.Command, filePath string, dryRun bool) error {
func applyDevnet(cmd *cobra.Command, devnet *config.YAMLDevnet) (*v1.ApplyDevnetResponse, error) {
ctx := cmd.Context()
name := devnet.Metadata.Name
namespace := devnet.Metadata.Namespace

// Convert YAML to proto spec
spec := yamlToProtoSpec(&devnet.Spec)

// Call ApplyDevnet (idempotent create or update)
resp, err := daemonClient.ApplyDevnet(ctx, name, spec, devnet.Metadata.Labels, devnet.Metadata.Annotations)
// Call ApplyDevnet (idempotent create or update) with namespace
resp, err := daemonClient.ApplyDevnet(ctx, namespace, name, spec, devnet.Metadata.Labels, devnet.Metadata.Annotations)
if err != nil {
return nil, fmt.Errorf("failed to apply devnet %q: %w", name, err)
}
Expand Down Expand Up @@ -150,8 +151,12 @@ func yamlToProtoSpec(yamlSpec *config.YAMLDevnetSpec) *v1.DevnetSpec {
// printApplyDryRun prints dry-run information for a devnet
func printApplyDryRun(devnet *config.YAMLDevnet) {
name := devnet.Metadata.Name
namespace := devnet.Metadata.Namespace
if namespace == "" {
namespace = "default"
}

fmt.Printf("\ndevnet/%s (dry-run)\n", name)
fmt.Printf("\ndevnet/%s (namespace: %s, dry-run)\n", name, namespace)
fmt.Printf(" network: %s\n", devnet.Spec.Network)
if devnet.Spec.NetworkVersion != "" {
fmt.Printf(" version: %s\n", devnet.Spec.NetworkVersion)
Expand Down Expand Up @@ -188,17 +193,21 @@ func printApplyDryRun(devnet *config.YAMLDevnet) {
// printApplyResult prints the result of applying a devnet with kubectl-style output
func printApplyResult(devnet *config.YAMLDevnet, resp *v1.ApplyDevnetResponse) {
name := devnet.Metadata.Name
namespace := devnet.Metadata.Namespace
if namespace == "" {
namespace = "default"
}

// Color based on action
switch resp.Action {
case "created":
color.Green("devnet/%s created", name)
color.Green("devnet/%s created (namespace: %s)", name, namespace)
case "configured":
color.Yellow("devnet/%s configured", name)
color.Yellow("devnet/%s configured (namespace: %s)", name, namespace)
case "unchanged":
fmt.Printf("devnet/%s unchanged\n", name)
fmt.Printf("devnet/%s unchanged (namespace: %s)\n", name, namespace)
default:
// Fallback for unknown action
fmt.Printf("devnet/%s %s\n", name, resp.Action)
fmt.Printf("devnet/%s %s (namespace: %s)\n", name, resp.Action, namespace)
}
}
30 changes: 18 additions & 12 deletions cmd/dvb/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ import (

func newDeleteCmd() *cobra.Command {
var (
filePath string
force bool
dryRun bool
filePath string
namespace string
force bool
dryRun bool
)

cmd := &cobra.Command{
Expand All @@ -26,6 +27,9 @@ Examples:
# Delete a devnet by name
dvb delete devnet my-devnet

# Delete a devnet in a specific namespace
dvb delete devnet my-devnet -n production

# Delete devnets defined in a YAML file
dvb delete -f devnet.yaml

Expand All @@ -51,14 +55,15 @@ Examples:

switch resourceType {
case "devnet", "devnets", "dn":
return runDeleteDevnet(cmd, name, force, dryRun)
return runDeleteDevnet(cmd, namespace, name, force, dryRun)
default:
return fmt.Errorf("unknown resource type: %s", resourceType)
}
},
}

cmd.Flags().StringVarP(&filePath, "file", "f", "", "Path to YAML file containing resources to delete")
cmd.Flags().StringVarP(&namespace, "namespace", "n", "", "Namespace (defaults to server default)")
cmd.Flags().BoolVar(&force, "force", false, "Skip confirmation prompt")
cmd.Flags().BoolVar(&dryRun, "dry-run", false, "Preview what would be deleted without actually deleting")

Expand Down Expand Up @@ -116,13 +121,14 @@ func runDeleteFromFile(cmd *cobra.Command, filePath string, force, dryRun bool)
var hasErrors bool
for i := range devnets {
name := devnets[i].Metadata.Name
err := daemonClient.DeleteDevnet(cmd.Context(), name)
namespace := devnets[i].Metadata.Namespace
err := daemonClient.DeleteDevnet(cmd.Context(), namespace, name)
if err != nil {
color.Red("devnet/%s deletion failed: %v", name, err)
color.Red("devnet/%s (namespace: %s) deletion failed: %v", name, namespace, err)
hasErrors = true
continue
}
color.Green("devnet/%s deleted", name)
color.Green("devnet/%s deleted (namespace: %s)", name, namespace)
}

if hasErrors {
Expand All @@ -133,17 +139,17 @@ func runDeleteFromFile(cmd *cobra.Command, filePath string, force, dryRun bool)
}

// runDeleteDevnet deletes a single devnet by name
func runDeleteDevnet(cmd *cobra.Command, name string, force, dryRun bool) error {
func runDeleteDevnet(cmd *cobra.Command, namespace, name string, force, dryRun bool) error {
// Preview mode
if dryRun {
fmt.Printf("Would delete devnet/%s\n", name)
fmt.Printf("Would delete devnet/%s (namespace: %s)\n", name, namespace)
fmt.Println("\nRun without --dry-run to delete.")
return nil
}

// Confirm if not forced
if !force {
fmt.Printf("Are you sure you want to delete devnet %q? [y/N] ", name)
fmt.Printf("Are you sure you want to delete devnet %q (namespace: %s)? [y/N] ", name, namespace)
var response string
if _, err := fmt.Scanln(&response); err != nil || (response != "y" && response != "Y") {
fmt.Println("Cancelled")
Expand All @@ -156,11 +162,11 @@ func runDeleteDevnet(cmd *cobra.Command, name string, force, dryRun bool) error
return fmt.Errorf("daemon not running - start with: devnetd")
}

err := daemonClient.DeleteDevnet(cmd.Context(), name)
err := daemonClient.DeleteDevnet(cmd.Context(), namespace, name)
if err != nil {
return err
}

color.Green("devnet/%s deleted", name)
color.Green("devnet/%s deleted (namespace: %s)", name, namespace)
return nil
}
3 changes: 2 additions & 1 deletion cmd/dvb/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,9 +157,10 @@ func parseDiffYAMLFile(path string) ([]*config.YAMLDevnet, error) {
func showDiff(cmd *cobra.Command, yamlDevnet *config.YAMLDevnet, output string) (bool, error) {
ctx := cmd.Context()
name := yamlDevnet.Metadata.Name
namespace := yamlDevnet.Metadata.Namespace

// Check if devnet exists
existing, err := daemonClient.GetDevnet(ctx, name)
existing, err := daemonClient.GetDevnet(ctx, namespace, name)
exists := err == nil && existing != nil

if !exists {
Expand Down
Loading
Loading