drove-cli 0.0.3__tar.gz → 0.0.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {drove_cli-0.0.3 → drove_cli-0.0.4}/PKG-INFO +173 -8
- {drove_cli-0.0.3 → drove_cli-0.0.4}/README.md +172 -7
- {drove_cli-0.0.3 → drove_cli-0.0.4}/droveclient.py +11 -4
- drove_cli-0.0.4/plugins/config.py +314 -0
- {drove_cli-0.0.3 → drove_cli-0.0.4}/pyproject.toml +1 -1
- {drove_cli-0.0.3 → drove_cli-0.0.4}/drove.py +0 -0
- {drove_cli-0.0.3 → drove_cli-0.0.4}/drovecli.py +0 -0
- {drove_cli-0.0.3 → drove_cli-0.0.4}/droveutils.py +0 -0
- {drove_cli-0.0.3 → drove_cli-0.0.4}/plugins/__init__.py +0 -0
- {drove_cli-0.0.3 → drove_cli-0.0.4}/plugins/appinstances.py +0 -0
- {drove_cli-0.0.3 → drove_cli-0.0.4}/plugins/applications.py +0 -0
- {drove_cli-0.0.3 → drove_cli-0.0.4}/plugins/cluster.py +0 -0
- {drove_cli-0.0.3 → drove_cli-0.0.4}/plugins/executors.py +0 -0
- {drove_cli-0.0.3 → drove_cli-0.0.4}/plugins/localserviceinstances.py +0 -0
- {drove_cli-0.0.3 → drove_cli-0.0.4}/plugins/localservices.py +0 -0
- {drove_cli-0.0.3 → drove_cli-0.0.4}/plugins/tasks.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: drove-cli
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.4
|
|
4
4
|
Summary: Drove Command Line Interface
|
|
5
5
|
License: Apache-2.0
|
|
6
6
|
Keywords: container,docker,podman,distributed-systems,container-orchestrator
|
|
@@ -118,12 +118,11 @@ To see basic help:
|
|
|
118
118
|
|
|
119
119
|
$ drove -h
|
|
120
120
|
|
|
121
|
-
usage: drove [-h] [--file FILE] [--cluster CLUSTER] [--endpoint ENDPOINT] [--auth-header AUTH_HEADER] [--insecure] [--username USERNAME] [--password PASSWORD] [--debug]
|
|
122
|
-
{
|
|
123
|
-
|
|
121
|
+
usage: drove [-h] [--file FILE] [--cluster CLUSTER] [--endpoint ENDPOINT] [--auth-header AUTH_HEADER] [--insecure INSECURE] [--username USERNAME] [--password PASSWORD] [--debug]
|
|
122
|
+
{executor,cluster,apps,appinstances,tasks,config} ...
|
|
124
123
|
|
|
125
124
|
positional arguments:
|
|
126
|
-
{
|
|
125
|
+
{executor,cluster,apps,appinstances,tasks,config}
|
|
127
126
|
Available plugins
|
|
128
127
|
lsinstances Drove local service instance related commands
|
|
129
128
|
executor Drove cluster executor related commands
|
|
@@ -131,7 +130,7 @@ positional arguments:
|
|
|
131
130
|
apps Drove application related commands
|
|
132
131
|
appinstances Drove application instance related commands
|
|
133
132
|
tasks Drove task related commands
|
|
134
|
-
|
|
133
|
+
config Manage drove cluster configurations
|
|
135
134
|
|
|
136
135
|
options:
|
|
137
136
|
-h, --help show this help message and exit
|
|
@@ -220,6 +219,21 @@ auth_header = %(prod_token)s
|
|
|
220
219
|
..
|
|
221
220
|
```
|
|
222
221
|
|
|
222
|
+
### Setting a Default Cluster
|
|
223
|
+
You can set a default cluster so you don't need to specify `-c cluster` on every command:
|
|
224
|
+
|
|
225
|
+
```ini
|
|
226
|
+
[DEFAULT]
|
|
227
|
+
current_cluster = local
|
|
228
|
+
...
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
When `current_cluster` is set, commands will automatically use that cluster unless overridden with `-c`.
|
|
232
|
+
|
|
233
|
+
Priority order for cluster selection:
|
|
234
|
+
|
|
235
|
+
`-c cluster` command line flag >`current_cluster` in `[DEFAULT]` section > `DEFAULT` section endpoint
|
|
236
|
+
|
|
223
237
|
The `DEFAULT` section can be used to define common variables like Insecure etc. The `local`, `stage`, `production` etc are names for individual clusters and these sections can be used to define configuration for individual clusters. Cluster name is referred to in the command line by using the `-c` command line option.\
|
|
224
238
|
*Interpolation* of values is supported and can be achieved by using `%(variable_name)s` references.
|
|
225
239
|
|
|
@@ -274,8 +288,8 @@ $ drove -e http://localhost:10000 -u guest -p guest ...
|
|
|
274
288
|
The following CLI format is followed:
|
|
275
289
|
|
|
276
290
|
```
|
|
277
|
-
usage: drove [-h] [--file FILE] [--cluster CLUSTER] [--endpoint ENDPOINT] [--auth-header AUTH_HEADER] [--insecure] [--username USERNAME] [--password PASSWORD] [--debug]
|
|
278
|
-
{executor,cluster,apps,appinstances,tasks} ...
|
|
291
|
+
usage: drove [-h] [--file FILE] [--cluster CLUSTER] [--endpoint ENDPOINT] [--auth-header AUTH_HEADER] [--insecure INSECURE] [--username USERNAME] [--password PASSWORD] [--debug]
|
|
292
|
+
{executor,cluster,apps,appinstances,tasks,config} ...
|
|
279
293
|
```
|
|
280
294
|
### Basic Arguments
|
|
281
295
|
```
|
|
@@ -1114,5 +1128,156 @@ drove lsinstances kill [-h] [--parallelism PARALLELISM] [--timeout TIMEOUT] serv
|
|
|
1114
1128
|
--wait, -w Wait to ensure all instances are killed
|
|
1115
1129
|
```
|
|
1116
1130
|
|
|
1131
|
+
### config
|
|
1132
|
+
---
|
|
1133
|
+
Manage drove cluster configurations (similar to kubectl config). These commands do not require an active cluster connection.
|
|
1134
|
+
|
|
1135
|
+
```shell
|
|
1136
|
+
drove config [-h] {get-clusters,current-cluster,use-cluster,view,init,add-cluster,delete-cluster} ...
|
|
1137
|
+
```
|
|
1138
|
+
|
|
1139
|
+
#### Sub-commands
|
|
1140
|
+
|
|
1141
|
+
##### get-clusters
|
|
1142
|
+
|
|
1143
|
+
List all configured clusters
|
|
1144
|
+
|
|
1145
|
+
```shell
|
|
1146
|
+
drove config get-clusters [-h]
|
|
1147
|
+
```
|
|
1148
|
+
|
|
1149
|
+
Example output:
|
|
1150
|
+
```
|
|
1151
|
+
CURRENT NAME ENDPOINT AUTH INSECURE
|
|
1152
|
+
-----------------------------------------------------------------------------------------------
|
|
1153
|
+
* local http://localhost:4000 yes no
|
|
1154
|
+
stage http://stage.drove.com:4000 yes no
|
|
1155
|
+
|
|
1156
|
+
Current cluster: local
|
|
1157
|
+
```
|
|
1158
|
+
|
|
1159
|
+
##### current-cluster
|
|
1160
|
+
|
|
1161
|
+
Show the current default cluster
|
|
1162
|
+
|
|
1163
|
+
```shell
|
|
1164
|
+
drove config current-cluster [-h]
|
|
1165
|
+
```
|
|
1166
|
+
|
|
1167
|
+
##### use-cluster
|
|
1168
|
+
|
|
1169
|
+
Set the default cluster. After setting, all commands will use this cluster unless overridden with `-c`.
|
|
1170
|
+
|
|
1171
|
+
```shell
|
|
1172
|
+
drove config use-cluster [-h] cluster-name
|
|
1173
|
+
```
|
|
1174
|
+
|
|
1175
|
+
###### Positional Arguments
|
|
1176
|
+
|
|
1177
|
+
`cluster-name` - Name of the cluster to set as default
|
|
1178
|
+
|
|
1179
|
+
Example:
|
|
1180
|
+
```shell
|
|
1181
|
+
$ drove config use-cluster stage
|
|
1182
|
+
Switched to cluster "stage".
|
|
1183
|
+
```
|
|
1184
|
+
|
|
1185
|
+
##### view
|
|
1186
|
+
|
|
1187
|
+
Display the full configuration file
|
|
1188
|
+
|
|
1189
|
+
```shell
|
|
1190
|
+
drove config view [-h] [--raw]
|
|
1191
|
+
```
|
|
1192
|
+
|
|
1193
|
+
###### Named Arguments
|
|
1194
|
+
|
|
1195
|
+
```
|
|
1196
|
+
--raw, -r Show raw config file content instead of formatted output
|
|
1197
|
+
```
|
|
1198
|
+
|
|
1199
|
+
##### init
|
|
1200
|
+
|
|
1201
|
+
Initialize a new `~/.drove` config file. Will fail if the file already exists.
|
|
1202
|
+
|
|
1203
|
+
```shell
|
|
1204
|
+
drove config init [-h] --endpoint ENDPOINT [--name NAME] [--username USERNAME] [--password PASSWORD] [--auth-header AUTH_HEADER] [--insecure]
|
|
1205
|
+
```
|
|
1206
|
+
|
|
1207
|
+
###### Named Arguments
|
|
1208
|
+
|
|
1209
|
+
```
|
|
1210
|
+
--endpoint ENDPOINT, -e ENDPOINT
|
|
1211
|
+
Drove endpoint URL (required)
|
|
1212
|
+
--name NAME, -n NAME Cluster name (default: "default")
|
|
1213
|
+
--username USERNAME, -u USERNAME
|
|
1214
|
+
Username for basic auth
|
|
1215
|
+
--password PASSWORD, -p PASSWORD
|
|
1216
|
+
Password for basic auth
|
|
1217
|
+
--auth-header AUTH_HEADER, -t AUTH_HEADER
|
|
1218
|
+
Authorization header value
|
|
1219
|
+
--insecure, -i Skip SSL verification
|
|
1220
|
+
```
|
|
1221
|
+
|
|
1222
|
+
Example:
|
|
1223
|
+
```shell
|
|
1224
|
+
$ drove config init -e http://localhost:4000 -n local -u admin -p admin
|
|
1225
|
+
Config initialized at: /home/user/.drove
|
|
1226
|
+
Current cluster set to: local
|
|
1227
|
+
```
|
|
1228
|
+
|
|
1229
|
+
##### add-cluster
|
|
1230
|
+
|
|
1231
|
+
Add a new cluster to the config file
|
|
1232
|
+
|
|
1233
|
+
```shell
|
|
1234
|
+
drove config add-cluster [-h] --endpoint ENDPOINT [--username USERNAME] [--password PASSWORD] [--auth-header AUTH_HEADER] [--insecure] cluster-name
|
|
1235
|
+
```
|
|
1236
|
+
|
|
1237
|
+
###### Positional Arguments
|
|
1238
|
+
|
|
1239
|
+
`cluster-name` - Name for this cluster
|
|
1240
|
+
|
|
1241
|
+
###### Named Arguments
|
|
1242
|
+
|
|
1243
|
+
```
|
|
1244
|
+
--endpoint ENDPOINT, -e ENDPOINT
|
|
1245
|
+
Drove endpoint URL (required)
|
|
1246
|
+
--username USERNAME, -u USERNAME
|
|
1247
|
+
Username for basic auth
|
|
1248
|
+
--password PASSWORD, -p PASSWORD
|
|
1249
|
+
Password for basic auth
|
|
1250
|
+
--auth-header AUTH_HEADER, -t AUTH_HEADER
|
|
1251
|
+
Authorization header value
|
|
1252
|
+
--insecure, -i Skip SSL verification
|
|
1253
|
+
```
|
|
1254
|
+
|
|
1255
|
+
Example:
|
|
1256
|
+
```shell
|
|
1257
|
+
$ drove config add-cluster production -e https://prod.drove.com -t "Bearer <token>"
|
|
1258
|
+
Cluster 'production' added to /home/user/.drove
|
|
1259
|
+
```
|
|
1260
|
+
|
|
1261
|
+
##### delete-cluster
|
|
1262
|
+
|
|
1263
|
+
Remove a cluster from the config file
|
|
1264
|
+
|
|
1265
|
+
```shell
|
|
1266
|
+
drove config delete-cluster [-h] cluster-name
|
|
1267
|
+
```
|
|
1268
|
+
|
|
1269
|
+
###### Positional Arguments
|
|
1270
|
+
|
|
1271
|
+
`cluster-name` - Name of the cluster to remove
|
|
1272
|
+
|
|
1273
|
+
Example:
|
|
1274
|
+
```shell
|
|
1275
|
+
$ drove config delete-cluster stage
|
|
1276
|
+
|
|
1277
|
+
Cluster 'staging' deleted from /home/user/.drove
|
|
1278
|
+
```
|
|
1279
|
+
|
|
1280
|
+
> **Note:** If you delete the current default cluster, it will be unset and you'll need to use `drove config use-cluster` to set a new default.
|
|
1281
|
+
|
|
1117
1282
|
©2024, Santanu Sinha.
|
|
1118
1283
|
|
|
@@ -85,12 +85,11 @@ To see basic help:
|
|
|
85
85
|
|
|
86
86
|
$ drove -h
|
|
87
87
|
|
|
88
|
-
usage: drove [-h] [--file FILE] [--cluster CLUSTER] [--endpoint ENDPOINT] [--auth-header AUTH_HEADER] [--insecure] [--username USERNAME] [--password PASSWORD] [--debug]
|
|
89
|
-
{
|
|
90
|
-
|
|
88
|
+
usage: drove [-h] [--file FILE] [--cluster CLUSTER] [--endpoint ENDPOINT] [--auth-header AUTH_HEADER] [--insecure INSECURE] [--username USERNAME] [--password PASSWORD] [--debug]
|
|
89
|
+
{executor,cluster,apps,appinstances,tasks,config} ...
|
|
91
90
|
|
|
92
91
|
positional arguments:
|
|
93
|
-
{
|
|
92
|
+
{executor,cluster,apps,appinstances,tasks,config}
|
|
94
93
|
Available plugins
|
|
95
94
|
lsinstances Drove local service instance related commands
|
|
96
95
|
executor Drove cluster executor related commands
|
|
@@ -98,7 +97,7 @@ positional arguments:
|
|
|
98
97
|
apps Drove application related commands
|
|
99
98
|
appinstances Drove application instance related commands
|
|
100
99
|
tasks Drove task related commands
|
|
101
|
-
|
|
100
|
+
config Manage drove cluster configurations
|
|
102
101
|
|
|
103
102
|
options:
|
|
104
103
|
-h, --help show this help message and exit
|
|
@@ -187,6 +186,21 @@ auth_header = %(prod_token)s
|
|
|
187
186
|
..
|
|
188
187
|
```
|
|
189
188
|
|
|
189
|
+
### Setting a Default Cluster
|
|
190
|
+
You can set a default cluster so you don't need to specify `-c cluster` on every command:
|
|
191
|
+
|
|
192
|
+
```ini
|
|
193
|
+
[DEFAULT]
|
|
194
|
+
current_cluster = local
|
|
195
|
+
...
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
When `current_cluster` is set, commands will automatically use that cluster unless overridden with `-c`.
|
|
199
|
+
|
|
200
|
+
Priority order for cluster selection:
|
|
201
|
+
|
|
202
|
+
`-c cluster` command line flag >`current_cluster` in `[DEFAULT]` section > `DEFAULT` section endpoint
|
|
203
|
+
|
|
190
204
|
The `DEFAULT` section can be used to define common variables like Insecure etc. The `local`, `stage`, `production` etc are names for individual clusters and these sections can be used to define configuration for individual clusters. Cluster name is referred to in the command line by using the `-c` command line option.\
|
|
191
205
|
*Interpolation* of values is supported and can be achieved by using `%(variable_name)s` references.
|
|
192
206
|
|
|
@@ -241,8 +255,8 @@ $ drove -e http://localhost:10000 -u guest -p guest ...
|
|
|
241
255
|
The following CLI format is followed:
|
|
242
256
|
|
|
243
257
|
```
|
|
244
|
-
usage: drove [-h] [--file FILE] [--cluster CLUSTER] [--endpoint ENDPOINT] [--auth-header AUTH_HEADER] [--insecure] [--username USERNAME] [--password PASSWORD] [--debug]
|
|
245
|
-
{executor,cluster,apps,appinstances,tasks} ...
|
|
258
|
+
usage: drove [-h] [--file FILE] [--cluster CLUSTER] [--endpoint ENDPOINT] [--auth-header AUTH_HEADER] [--insecure INSECURE] [--username USERNAME] [--password PASSWORD] [--debug]
|
|
259
|
+
{executor,cluster,apps,appinstances,tasks,config} ...
|
|
246
260
|
```
|
|
247
261
|
### Basic Arguments
|
|
248
262
|
```
|
|
@@ -1081,4 +1095,155 @@ drove lsinstances kill [-h] [--parallelism PARALLELISM] [--timeout TIMEOUT] serv
|
|
|
1081
1095
|
--wait, -w Wait to ensure all instances are killed
|
|
1082
1096
|
```
|
|
1083
1097
|
|
|
1098
|
+
### config
|
|
1099
|
+
---
|
|
1100
|
+
Manage drove cluster configurations (similar to kubectl config). These commands do not require an active cluster connection.
|
|
1101
|
+
|
|
1102
|
+
```shell
|
|
1103
|
+
drove config [-h] {get-clusters,current-cluster,use-cluster,view,init,add-cluster,delete-cluster} ...
|
|
1104
|
+
```
|
|
1105
|
+
|
|
1106
|
+
#### Sub-commands
|
|
1107
|
+
|
|
1108
|
+
##### get-clusters
|
|
1109
|
+
|
|
1110
|
+
List all configured clusters
|
|
1111
|
+
|
|
1112
|
+
```shell
|
|
1113
|
+
drove config get-clusters [-h]
|
|
1114
|
+
```
|
|
1115
|
+
|
|
1116
|
+
Example output:
|
|
1117
|
+
```
|
|
1118
|
+
CURRENT NAME ENDPOINT AUTH INSECURE
|
|
1119
|
+
-----------------------------------------------------------------------------------------------
|
|
1120
|
+
* local http://localhost:4000 yes no
|
|
1121
|
+
stage http://stage.drove.com:4000 yes no
|
|
1122
|
+
|
|
1123
|
+
Current cluster: local
|
|
1124
|
+
```
|
|
1125
|
+
|
|
1126
|
+
##### current-cluster
|
|
1127
|
+
|
|
1128
|
+
Show the current default cluster
|
|
1129
|
+
|
|
1130
|
+
```shell
|
|
1131
|
+
drove config current-cluster [-h]
|
|
1132
|
+
```
|
|
1133
|
+
|
|
1134
|
+
##### use-cluster
|
|
1135
|
+
|
|
1136
|
+
Set the default cluster. After setting, all commands will use this cluster unless overridden with `-c`.
|
|
1137
|
+
|
|
1138
|
+
```shell
|
|
1139
|
+
drove config use-cluster [-h] cluster-name
|
|
1140
|
+
```
|
|
1141
|
+
|
|
1142
|
+
###### Positional Arguments
|
|
1143
|
+
|
|
1144
|
+
`cluster-name` - Name of the cluster to set as default
|
|
1145
|
+
|
|
1146
|
+
Example:
|
|
1147
|
+
```shell
|
|
1148
|
+
$ drove config use-cluster stage
|
|
1149
|
+
Switched to cluster "stage".
|
|
1150
|
+
```
|
|
1151
|
+
|
|
1152
|
+
##### view
|
|
1153
|
+
|
|
1154
|
+
Display the full configuration file
|
|
1155
|
+
|
|
1156
|
+
```shell
|
|
1157
|
+
drove config view [-h] [--raw]
|
|
1158
|
+
```
|
|
1159
|
+
|
|
1160
|
+
###### Named Arguments
|
|
1161
|
+
|
|
1162
|
+
```
|
|
1163
|
+
--raw, -r Show raw config file content instead of formatted output
|
|
1164
|
+
```
|
|
1165
|
+
|
|
1166
|
+
##### init
|
|
1167
|
+
|
|
1168
|
+
Initialize a new `~/.drove` config file. Will fail if the file already exists.
|
|
1169
|
+
|
|
1170
|
+
```shell
|
|
1171
|
+
drove config init [-h] --endpoint ENDPOINT [--name NAME] [--username USERNAME] [--password PASSWORD] [--auth-header AUTH_HEADER] [--insecure]
|
|
1172
|
+
```
|
|
1173
|
+
|
|
1174
|
+
###### Named Arguments
|
|
1175
|
+
|
|
1176
|
+
```
|
|
1177
|
+
--endpoint ENDPOINT, -e ENDPOINT
|
|
1178
|
+
Drove endpoint URL (required)
|
|
1179
|
+
--name NAME, -n NAME Cluster name (default: "default")
|
|
1180
|
+
--username USERNAME, -u USERNAME
|
|
1181
|
+
Username for basic auth
|
|
1182
|
+
--password PASSWORD, -p PASSWORD
|
|
1183
|
+
Password for basic auth
|
|
1184
|
+
--auth-header AUTH_HEADER, -t AUTH_HEADER
|
|
1185
|
+
Authorization header value
|
|
1186
|
+
--insecure, -i Skip SSL verification
|
|
1187
|
+
```
|
|
1188
|
+
|
|
1189
|
+
Example:
|
|
1190
|
+
```shell
|
|
1191
|
+
$ drove config init -e http://localhost:4000 -n local -u admin -p admin
|
|
1192
|
+
Config initialized at: /home/user/.drove
|
|
1193
|
+
Current cluster set to: local
|
|
1194
|
+
```
|
|
1195
|
+
|
|
1196
|
+
##### add-cluster
|
|
1197
|
+
|
|
1198
|
+
Add a new cluster to the config file
|
|
1199
|
+
|
|
1200
|
+
```shell
|
|
1201
|
+
drove config add-cluster [-h] --endpoint ENDPOINT [--username USERNAME] [--password PASSWORD] [--auth-header AUTH_HEADER] [--insecure] cluster-name
|
|
1202
|
+
```
|
|
1203
|
+
|
|
1204
|
+
###### Positional Arguments
|
|
1205
|
+
|
|
1206
|
+
`cluster-name` - Name for this cluster
|
|
1207
|
+
|
|
1208
|
+
###### Named Arguments
|
|
1209
|
+
|
|
1210
|
+
```
|
|
1211
|
+
--endpoint ENDPOINT, -e ENDPOINT
|
|
1212
|
+
Drove endpoint URL (required)
|
|
1213
|
+
--username USERNAME, -u USERNAME
|
|
1214
|
+
Username for basic auth
|
|
1215
|
+
--password PASSWORD, -p PASSWORD
|
|
1216
|
+
Password for basic auth
|
|
1217
|
+
--auth-header AUTH_HEADER, -t AUTH_HEADER
|
|
1218
|
+
Authorization header value
|
|
1219
|
+
--insecure, -i Skip SSL verification
|
|
1220
|
+
```
|
|
1221
|
+
|
|
1222
|
+
Example:
|
|
1223
|
+
```shell
|
|
1224
|
+
$ drove config add-cluster production -e https://prod.drove.com -t "Bearer <token>"
|
|
1225
|
+
Cluster 'production' added to /home/user/.drove
|
|
1226
|
+
```
|
|
1227
|
+
|
|
1228
|
+
##### delete-cluster
|
|
1229
|
+
|
|
1230
|
+
Remove a cluster from the config file
|
|
1231
|
+
|
|
1232
|
+
```shell
|
|
1233
|
+
drove config delete-cluster [-h] cluster-name
|
|
1234
|
+
```
|
|
1235
|
+
|
|
1236
|
+
###### Positional Arguments
|
|
1237
|
+
|
|
1238
|
+
`cluster-name` - Name of the cluster to remove
|
|
1239
|
+
|
|
1240
|
+
Example:
|
|
1241
|
+
```shell
|
|
1242
|
+
$ drove config delete-cluster stage
|
|
1243
|
+
|
|
1244
|
+
Cluster 'staging' deleted from /home/user/.drove
|
|
1245
|
+
```
|
|
1246
|
+
|
|
1247
|
+
> **Note:** If you delete the current default cluster, it will be unset and you'll need to use `drove config use-cluster` to set a new default.
|
|
1248
|
+
|
|
1084
1249
|
©2024, Santanu Sinha.
|
|
@@ -173,12 +173,19 @@ def build_drove_client(drove_client: DroveClient, args: SimpleNamespace):
|
|
|
173
173
|
with open(config_file) as stream:
|
|
174
174
|
config_parser.read_string(stream.read())
|
|
175
175
|
drove_config = config_parser['DEFAULT']
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
176
|
+
|
|
177
|
+
# Determine which cluster to use (priority: -c flag > current_cluster in config > DEFAULT)
|
|
178
|
+
cluster_to_use = args.cluster
|
|
179
|
+
if cluster_to_use is None:
|
|
180
|
+
cluster_to_use = config_parser.defaults().get('current_cluster')
|
|
181
|
+
|
|
182
|
+
if cluster_to_use is not None and cluster_to_use != 'DEFAULT':
|
|
183
|
+
if cluster_to_use in config_parser:
|
|
184
|
+
drove_config = config_parser[cluster_to_use]
|
|
179
185
|
else:
|
|
180
|
-
print("error: No cluster definition found for {cluster} in config {config_file}".format(config_file=config_file, cluster=
|
|
186
|
+
print("error: No cluster definition found for {cluster} in config {config_file}".format(config_file=config_file, cluster=cluster_to_use))
|
|
181
187
|
return None
|
|
188
|
+
|
|
182
189
|
endpoint = drove_config.get("endpoint")
|
|
183
190
|
username = drove_config.get("username")
|
|
184
191
|
password = drove_config.get("password")
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Config plugin for drove-cli - cluster configuration management.
|
|
3
|
+
|
|
4
|
+
This plugin adds 'drove config' commands for managing clusters, largely inspired by kubectl context management.
|
|
5
|
+
- drove config current-cluster : Show current default cluster
|
|
6
|
+
- drove config get-clusters : List all configured clusters
|
|
7
|
+
- drove config use-cluster <name> : Set default cluster
|
|
8
|
+
- drove config view : Show full config file
|
|
9
|
+
- drove config init : Initialize a new config file
|
|
10
|
+
- drove config add-cluster <name> : Add a new cluster to config
|
|
11
|
+
- drove config delete-cluster <name> : Remove a cluster from config
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
Usage:
|
|
15
|
+
drove config use-cluster local
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
import argparse
|
|
19
|
+
import configparser
|
|
20
|
+
import os
|
|
21
|
+
import plugins
|
|
22
|
+
|
|
23
|
+
from pathlib import Path
|
|
24
|
+
from types import SimpleNamespace
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def get_config_file_path() -> str:
|
|
28
|
+
return str(Path.home()) + "/.drove"
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def read_config() -> configparser.ConfigParser:
|
|
32
|
+
config_file = get_config_file_path()
|
|
33
|
+
config = configparser.ConfigParser()
|
|
34
|
+
|
|
35
|
+
if os.path.isfile(config_file) and os.access(config_file, os.R_OK):
|
|
36
|
+
with open(config_file) as stream:
|
|
37
|
+
config.read_string(stream.read())
|
|
38
|
+
|
|
39
|
+
return config
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def write_config(config: configparser.ConfigParser) -> None:
|
|
43
|
+
config_file = get_config_file_path()
|
|
44
|
+
with open(config_file, 'w') as f:
|
|
45
|
+
config.write(f)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def get_current_cluster() -> str:
|
|
49
|
+
config = read_config()
|
|
50
|
+
return config.defaults().get('current_cluster')
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def set_current_cluster(cluster_name: str) -> None:
|
|
54
|
+
config = read_config()
|
|
55
|
+
config.set('DEFAULT', 'current_cluster', cluster_name)
|
|
56
|
+
write_config(config)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def get_clusters_from_config(config: configparser.ConfigParser) -> list:
|
|
60
|
+
clusters = []
|
|
61
|
+
for section in config.sections():
|
|
62
|
+
endpoint = config[section].get('endpoint', '')
|
|
63
|
+
if endpoint:
|
|
64
|
+
clusters.append({
|
|
65
|
+
'name': section,
|
|
66
|
+
'endpoint': endpoint,
|
|
67
|
+
'has_auth': bool(config[section].get('username') or config[section].get('auth_header')),
|
|
68
|
+
'insecure': config[section].get('insecure', 'false').lower() == 'true'
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
if config.defaults().get('endpoint'):
|
|
72
|
+
clusters.insert(0, {
|
|
73
|
+
'name': 'DEFAULT',
|
|
74
|
+
'endpoint': config.defaults().get('endpoint'),
|
|
75
|
+
'has_auth': bool(config.defaults().get('username') or config.defaults().get('auth_header')),
|
|
76
|
+
'insecure': config.defaults().get('insecure', 'false').lower() == 'true'
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
return clusters
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
class Config(plugins.DrovePlugin):
|
|
83
|
+
"""Plugin for config/context management commands."""
|
|
84
|
+
|
|
85
|
+
def __init__(self) -> None:
|
|
86
|
+
pass
|
|
87
|
+
|
|
88
|
+
def populate_options(self, drove_client, subparser: argparse.ArgumentParser):
|
|
89
|
+
parser = subparser.add_parser("config", help="Manage drove cluster configurations")
|
|
90
|
+
commands = parser.add_subparsers(help="Available config commands")
|
|
91
|
+
|
|
92
|
+
# get-clusters: List all available clusters
|
|
93
|
+
sub_parser = commands.add_parser("get-clusters", help="List all configured clusters")
|
|
94
|
+
sub_parser.set_defaults(func=self.get_clusters)
|
|
95
|
+
|
|
96
|
+
# current-cluster: Show current default
|
|
97
|
+
sub_parser = commands.add_parser("current-cluster", help="Show current default cluster")
|
|
98
|
+
sub_parser.set_defaults(func=self.current_cluster)
|
|
99
|
+
|
|
100
|
+
# use-cluster: Set default cluster
|
|
101
|
+
sub_parser = commands.add_parser("use-cluster", help="Set default cluster")
|
|
102
|
+
sub_parser.add_argument("cluster_name", metavar="cluster-name", help="Cluster name to use as default")
|
|
103
|
+
sub_parser.set_defaults(func=self.use_cluster)
|
|
104
|
+
|
|
105
|
+
# view: Show full config
|
|
106
|
+
sub_parser = commands.add_parser("view", help="Display the full configuration file")
|
|
107
|
+
sub_parser.add_argument("--raw", "-r", help="Show raw config file content", action="store_true")
|
|
108
|
+
sub_parser.set_defaults(func=self.view_config)
|
|
109
|
+
|
|
110
|
+
# init: Initialize config file
|
|
111
|
+
sub_parser = commands.add_parser("init", help="Initialize a new ~/.drove config file")
|
|
112
|
+
sub_parser.add_argument("--endpoint", "-e", help="Drove endpoint URL", required=True)
|
|
113
|
+
sub_parser.add_argument("--name", "-n", help="Cluster name", default="default")
|
|
114
|
+
sub_parser.add_argument("--username", "-u", help="Username for basic auth")
|
|
115
|
+
sub_parser.add_argument("--password", "-p", help="Password for basic auth")
|
|
116
|
+
sub_parser.add_argument("--auth-header", "-t", dest="auth_header", help="Authorization header value")
|
|
117
|
+
sub_parser.add_argument("--insecure", "-i", help="Skip SSL verification", action="store_true")
|
|
118
|
+
sub_parser.set_defaults(func=self.init_config)
|
|
119
|
+
|
|
120
|
+
# add-cluster: Add a new cluster to config
|
|
121
|
+
sub_parser = commands.add_parser("add-cluster", help="Add a new cluster to config")
|
|
122
|
+
sub_parser.add_argument("cluster_name", metavar="cluster-name", help="Name for this cluster")
|
|
123
|
+
sub_parser.add_argument("--endpoint", "-e", help="Drove endpoint URL", required=True)
|
|
124
|
+
sub_parser.add_argument("--username", "-u", help="Username for basic auth")
|
|
125
|
+
sub_parser.add_argument("--password", "-p", help="Password for basic auth")
|
|
126
|
+
sub_parser.add_argument("--auth-header", "-t", dest="auth_header", help="Authorization header value")
|
|
127
|
+
sub_parser.add_argument("--insecure", "-i", help="Skip SSL verification", action="store_true")
|
|
128
|
+
sub_parser.set_defaults(func=self.add_cluster)
|
|
129
|
+
|
|
130
|
+
# delete-cluster: Remove a cluster from config
|
|
131
|
+
sub_parser = commands.add_parser("delete-cluster", help="Remove a cluster from config")
|
|
132
|
+
sub_parser.add_argument("cluster_name", metavar="cluster-name", help="Cluster name to remove")
|
|
133
|
+
sub_parser.set_defaults(func=self.delete_cluster)
|
|
134
|
+
|
|
135
|
+
super().populate_options(drove_client, parser)
|
|
136
|
+
|
|
137
|
+
def get_clusters(self, options: SimpleNamespace):
|
|
138
|
+
config = read_config()
|
|
139
|
+
clusters = get_clusters_from_config(config)
|
|
140
|
+
current = get_current_cluster()
|
|
141
|
+
|
|
142
|
+
if not clusters:
|
|
143
|
+
print("No clusters configured. Run 'drove config init' to set up.")
|
|
144
|
+
return
|
|
145
|
+
|
|
146
|
+
print(f"{'CURRENT':<10} {'NAME':<20} {'ENDPOINT':<50} {'AUTH':<6} {'INSECURE':<8}")
|
|
147
|
+
print("-" * 95)
|
|
148
|
+
|
|
149
|
+
for cluster in clusters:
|
|
150
|
+
marker = "*" if cluster['name'] == current else ""
|
|
151
|
+
auth = "yes" if cluster['has_auth'] else "no"
|
|
152
|
+
insecure = "yes" if cluster['insecure'] else "no"
|
|
153
|
+
print(f"{marker:<10} {cluster['name']:<20} {cluster['endpoint']:<50} {auth:<6} {insecure:<8}")
|
|
154
|
+
|
|
155
|
+
if current:
|
|
156
|
+
print(f"\nCurrent cluster: {current}")
|
|
157
|
+
|
|
158
|
+
def current_cluster(self, options: SimpleNamespace):
|
|
159
|
+
current = get_current_cluster()
|
|
160
|
+
if current:
|
|
161
|
+
print(current)
|
|
162
|
+
else:
|
|
163
|
+
print("No current cluster set. Use 'drove config use-cluster <name>' to set one.")
|
|
164
|
+
|
|
165
|
+
def use_cluster(self, options: SimpleNamespace):
|
|
166
|
+
config = read_config()
|
|
167
|
+
cluster_name = options.cluster_name
|
|
168
|
+
|
|
169
|
+
# Validate cluster exists
|
|
170
|
+
valid_names = [s for s in config.sections()]
|
|
171
|
+
if cluster_name == 'DEFAULT':
|
|
172
|
+
if config.defaults().get('endpoint'):
|
|
173
|
+
valid_names.append('DEFAULT')
|
|
174
|
+
|
|
175
|
+
if cluster_name not in valid_names and cluster_name != 'DEFAULT':
|
|
176
|
+
print(f"Error: cluster '{cluster_name}' not found in config")
|
|
177
|
+
print(f"Available clusters: {', '.join(valid_names) if valid_names else 'none'}")
|
|
178
|
+
return
|
|
179
|
+
|
|
180
|
+
set_current_cluster(cluster_name)
|
|
181
|
+
print(f"Switched to cluster \"{cluster_name}\".")
|
|
182
|
+
|
|
183
|
+
def view_config(self, options: SimpleNamespace):
|
|
184
|
+
config_file = get_config_file_path()
|
|
185
|
+
|
|
186
|
+
if not os.path.isfile(config_file):
|
|
187
|
+
print(f"Config file not found: {config_file}")
|
|
188
|
+
print("Run 'drove config init' to create one.")
|
|
189
|
+
return
|
|
190
|
+
|
|
191
|
+
if options.raw:
|
|
192
|
+
with open(config_file, 'r') as f:
|
|
193
|
+
print(f.read())
|
|
194
|
+
else:
|
|
195
|
+
config = read_config()
|
|
196
|
+
current = get_current_cluster()
|
|
197
|
+
|
|
198
|
+
print(f"Config file: {config_file}")
|
|
199
|
+
print(f"Current cluster: {current or '(not set)'}")
|
|
200
|
+
print()
|
|
201
|
+
|
|
202
|
+
for section in ['DEFAULT'] + config.sections():
|
|
203
|
+
if section == 'DEFAULT':
|
|
204
|
+
items = dict(config.defaults())
|
|
205
|
+
else:
|
|
206
|
+
items = dict(config[section])
|
|
207
|
+
|
|
208
|
+
if not items.get('endpoint'):
|
|
209
|
+
continue
|
|
210
|
+
|
|
211
|
+
marker = " (current)" if section == current else ""
|
|
212
|
+
print(f"[{section}]{marker}")
|
|
213
|
+
for key, value in items.items():
|
|
214
|
+
# Mask sensitive values
|
|
215
|
+
if key in ('password', 'auth_header') and value:
|
|
216
|
+
display_value = value[:4] + "****" + value[-4:] if len(value) > 8 else "****"
|
|
217
|
+
else:
|
|
218
|
+
display_value = value
|
|
219
|
+
print(f" {key} = {display_value}")
|
|
220
|
+
print()
|
|
221
|
+
|
|
222
|
+
def init_config(self, options: SimpleNamespace):
|
|
223
|
+
config_file = get_config_file_path()
|
|
224
|
+
|
|
225
|
+
if os.path.isfile(config_file):
|
|
226
|
+
print(f"Config file already exists: {config_file}")
|
|
227
|
+
print("Use 'drove config add-context' to add more clusters.")
|
|
228
|
+
return
|
|
229
|
+
|
|
230
|
+
config = configparser.ConfigParser()
|
|
231
|
+
section = options.name if options.name != 'default' else 'DEFAULT'
|
|
232
|
+
|
|
233
|
+
if section != 'DEFAULT':
|
|
234
|
+
config.add_section(section)
|
|
235
|
+
config[section]
|
|
236
|
+
else:
|
|
237
|
+
config.defaults()
|
|
238
|
+
|
|
239
|
+
if section == 'DEFAULT':
|
|
240
|
+
config.set('DEFAULT', 'endpoint', options.endpoint)
|
|
241
|
+
if options.username:
|
|
242
|
+
config.set('DEFAULT', 'username', options.username)
|
|
243
|
+
if options.password:
|
|
244
|
+
config.set('DEFAULT', 'password', options.password)
|
|
245
|
+
if options.auth_header:
|
|
246
|
+
config.set('DEFAULT', 'auth_header', options.auth_header)
|
|
247
|
+
if options.insecure:
|
|
248
|
+
config.set('DEFAULT', 'insecure', 'true')
|
|
249
|
+
else:
|
|
250
|
+
config[section]['endpoint'] = options.endpoint
|
|
251
|
+
if options.username:
|
|
252
|
+
config[section]['username'] = options.username
|
|
253
|
+
if options.password:
|
|
254
|
+
config[section]['password'] = options.password
|
|
255
|
+
if options.auth_header:
|
|
256
|
+
config[section]['auth_header'] = options.auth_header
|
|
257
|
+
if options.insecure:
|
|
258
|
+
config[section]['insecure'] = 'true'
|
|
259
|
+
|
|
260
|
+
with open(config_file, 'w') as f:
|
|
261
|
+
config.write(f)
|
|
262
|
+
|
|
263
|
+
set_current_cluster(section)
|
|
264
|
+
|
|
265
|
+
print(f"Config initialized at: {config_file}")
|
|
266
|
+
print(f"Current cluster set to: {section}")
|
|
267
|
+
|
|
268
|
+
def add_cluster(self, options: SimpleNamespace):
|
|
269
|
+
"""Add a new cluster."""
|
|
270
|
+
config = read_config()
|
|
271
|
+
cluster_name = options.cluster_name
|
|
272
|
+
|
|
273
|
+
if cluster_name in config.sections():
|
|
274
|
+
print(f"Error: cluster '{cluster_name}' already exists")
|
|
275
|
+
return
|
|
276
|
+
|
|
277
|
+
config.add_section(cluster_name)
|
|
278
|
+
config[cluster_name]['endpoint'] = options.endpoint
|
|
279
|
+
if options.username:
|
|
280
|
+
config[cluster_name]['username'] = options.username
|
|
281
|
+
if options.password:
|
|
282
|
+
config[cluster_name]['password'] = options.password
|
|
283
|
+
if options.auth_header:
|
|
284
|
+
config[cluster_name]['auth_header'] = options.auth_header
|
|
285
|
+
if options.insecure:
|
|
286
|
+
config[cluster_name]['insecure'] = 'true'
|
|
287
|
+
|
|
288
|
+
config_file = get_config_file_path()
|
|
289
|
+
with open(config_file, 'w') as f:
|
|
290
|
+
config.write(f)
|
|
291
|
+
|
|
292
|
+
print(f"Cluster '{cluster_name}' added to {config_file}")
|
|
293
|
+
|
|
294
|
+
def delete_cluster(self, options: SimpleNamespace):
|
|
295
|
+
config = read_config()
|
|
296
|
+
cluster_name = options.cluster_name
|
|
297
|
+
|
|
298
|
+
if cluster_name not in config.sections():
|
|
299
|
+
print(f"Error: cluster '{cluster_name}' not found")
|
|
300
|
+
return
|
|
301
|
+
|
|
302
|
+
config.remove_section(cluster_name)
|
|
303
|
+
|
|
304
|
+
config_file = get_config_file_path()
|
|
305
|
+
with open(config_file, 'w') as f:
|
|
306
|
+
config.write(f)
|
|
307
|
+
|
|
308
|
+
current = get_current_cluster()
|
|
309
|
+
if current == cluster_name:
|
|
310
|
+
config.remove_option('DEFAULT', 'current_cluster')
|
|
311
|
+
write_config(config)
|
|
312
|
+
print(f"Cluster '{cluster_name}' deleted and was current cluster (now unset)")
|
|
313
|
+
else:
|
|
314
|
+
print(f"Cluster '{cluster_name}' deleted from {config_file}")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|