goharbor / goharbor/harbor-cli

[discussion]: Validating Loaded Json/Yaml inputs using schemas

Open
#784 1 comment 0 reactions 0 assignees View on GitHub
discussion
Dominant language
Go
Stars
163
Forks
211
Avg merge
1m
Merged PRs (30d)
1

Description

## Topic

In `harbor-cli`, several commands support creating or updating objects using configuration files provided in YAML or JSON format. To improve robustness and consistency, schema-based validation (e.g., JSON Schema) could be introduced.

This would allow enforcing a well-defined structure for inputs before applying additional business logic validations. For example, a schema for `RobotPermissions` could enforce required fields, types, and conditional constraints depending on the context.

```json
{
"$id": "permissions.json",
"type": "object",
"required": ["access", "kind", "namespace"],
"properties": {
"kind": {
"type": "string",
"enum": ["project", "system"]
},
"namespace": {
"type": "string"
},
"access": {
"type": "array",
"items": {
"type": "object",
"required": ["resource", "actions"],
"properties": {
"resource": { "type": "string" },
"actions": {
"type": "array",
"items": { "type": "string" }
}
}
}
}
},
"if": {
"properties": {
"kind": { "const": "project" }
}
},
"then": {
"properties": {
"namespace": {
"pattern": "^[^*]+$"
}
}
}
}
```

This approach ensures that input files conform to a strict structural contract, while semantic correctness (e.g., valid resource/action combinations) can still be validated separately in the application logic.

Example schema for project-level robot accounts:

```json
{
"$id": "project-robot.json",
"type": "object",
"required": ["name", "duration", "level", "permissions"],
"properties": {
"name": { "type": "string" },
"description": { "type": "string" },
"duration": { "type": "integer", "minimum": 1 },
"level": {
"type": "string",
"enum": ["project"]
},
"permissions": {
"type": "array",
"items": {
"$ref": "permissions.json"
}
}
},
"allOf": [
{
"if": {
"properties": {
"level": { "const": "project" }
}
},
"then": {
"properties": {
"permissions": {
"items": {
"properties": {
"kind": {
"not": { "const": "system" }
},
"namespace": {
"not": { "pattern": "^/.*$" }
}
}
}
}
}
}
}
]
}
```

Example schema for system-level robot accounts:

```json
{
"$id": "system-robot.json",
"type": "object",
"required": ["name", "duration", "level", "permissions"],
"properties": {
"name": { "type": "string" },
"description": { "type": "string" },
"duration": { "type": "integer", "minimum": 1 },
"level": {
"type": "string",
"enum": ["system"]
},
"permissions": {
"type": "array",
"items": {
"$ref": "permissions.json"
}
}
}
}
```

## Context

Currently, validation logic is implemented directly in code, which can lead to duplication, reduced readability, and inconsistent validation behavior across commands. Introducing schema-based validation would centralize structural validation and make expected input formats more explicit and maintainable.

This approach could be applied consistently across multiple commands, including robot accounts and replication policies.

## Possible Ideas / Thoughts

A shared validation layer could be introduced to handle schema loading, validation, and error reporting. This would allow reuse across different command implementations.

One potential drawback is that schemas must be kept in sync with API changes. However, this is comparable to the current situation, where validation logic must also be updated when the API evolves.

Automatic schema generation from the API (e.g., `swagger.yaml`) was evaluated but appears unsuitable, as API models typically include more fields and behaviors than required for CLI input validation.

## Additional Information

Local testing of this approach indicates that it is feasible and improves input validation clarity and reliability. Further evaluation could focus on selecting a suitable JSON Schema library and defining a maintainable schema organization strategy.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.