@flui-cloud/cli 0.1.0 → 0.2.0

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.
@@ -1930,6 +1930,56 @@
1930
1930
  "use.js"
1931
1931
  ]
1932
1932
  },
1933
+ "dns:cleanup": {
1934
+ "aliases": [],
1935
+ "args": {},
1936
+ "description": "Delete all A records from a Hetzner DNS zone",
1937
+ "examples": [
1938
+ "<%= config.bin %> <%= command.id %> --domain example.com",
1939
+ "<%= config.bin %> <%= command.id %> --domain example.com --dry-run",
1940
+ "<%= config.bin %> <%= command.id %> --domain example.com --force"
1941
+ ],
1942
+ "flags": {
1943
+ "domain": {
1944
+ "description": "Hetzner DNS zone domain name",
1945
+ "name": "domain",
1946
+ "required": true,
1947
+ "hasDynamicHelp": false,
1948
+ "multiple": false,
1949
+ "type": "option"
1950
+ },
1951
+ "force": {
1952
+ "char": "f",
1953
+ "description": "Skip confirmation prompt",
1954
+ "name": "force",
1955
+ "allowNo": false,
1956
+ "type": "boolean"
1957
+ },
1958
+ "dry-run": {
1959
+ "description": "Preview without deleting",
1960
+ "name": "dry-run",
1961
+ "allowNo": false,
1962
+ "type": "boolean"
1963
+ }
1964
+ },
1965
+ "hasDynamicHelp": false,
1966
+ "hiddenAliases": [],
1967
+ "id": "dns:cleanup",
1968
+ "pluginAlias": "@flui-cloud/cli",
1969
+ "pluginName": "@flui-cloud/cli",
1970
+ "pluginType": "core",
1971
+ "strict": true,
1972
+ "enableJsonFlag": false,
1973
+ "isESM": false,
1974
+ "relativePath": [
1975
+ "lib",
1976
+ "cli",
1977
+ "src",
1978
+ "commands",
1979
+ "dns",
1980
+ "cleanup.js"
1981
+ ]
1982
+ },
1933
1983
  "dev:creds": {
1934
1984
  "aliases": [],
1935
1985
  "args": {},
@@ -2034,56 +2084,6 @@
2034
2084
  "tunnel.js"
2035
2085
  ]
2036
2086
  },
2037
- "dns:cleanup": {
2038
- "aliases": [],
2039
- "args": {},
2040
- "description": "Delete all A records from a Hetzner DNS zone",
2041
- "examples": [
2042
- "<%= config.bin %> <%= command.id %> --domain example.com",
2043
- "<%= config.bin %> <%= command.id %> --domain example.com --dry-run",
2044
- "<%= config.bin %> <%= command.id %> --domain example.com --force"
2045
- ],
2046
- "flags": {
2047
- "domain": {
2048
- "description": "Hetzner DNS zone domain name",
2049
- "name": "domain",
2050
- "required": true,
2051
- "hasDynamicHelp": false,
2052
- "multiple": false,
2053
- "type": "option"
2054
- },
2055
- "force": {
2056
- "char": "f",
2057
- "description": "Skip confirmation prompt",
2058
- "name": "force",
2059
- "allowNo": false,
2060
- "type": "boolean"
2061
- },
2062
- "dry-run": {
2063
- "description": "Preview without deleting",
2064
- "name": "dry-run",
2065
- "allowNo": false,
2066
- "type": "boolean"
2067
- }
2068
- },
2069
- "hasDynamicHelp": false,
2070
- "hiddenAliases": [],
2071
- "id": "dns:cleanup",
2072
- "pluginAlias": "@flui-cloud/cli",
2073
- "pluginName": "@flui-cloud/cli",
2074
- "pluginType": "core",
2075
- "strict": true,
2076
- "enableJsonFlag": false,
2077
- "isESM": false,
2078
- "relativePath": [
2079
- "lib",
2080
- "cli",
2081
- "src",
2082
- "commands",
2083
- "dns",
2084
- "cleanup.js"
2085
- ]
2086
- },
2087
2087
  "integration:connect": {
2088
2088
  "aliases": [],
2089
2089
  "args": {
@@ -3672,6 +3672,155 @@
3672
3672
  "list.js"
3673
3673
  ]
3674
3674
  },
3675
+ "node:add": {
3676
+ "aliases": [],
3677
+ "args": {},
3678
+ "description": "Add worker node(s) to the cluster. Provisions new servers and joins them to K3s.",
3679
+ "examples": [
3680
+ "<%= config.bin %> <%= command.id %>",
3681
+ "<%= config.bin %> <%= command.id %> --count 2",
3682
+ "<%= config.bin %> <%= command.id %> --count 3 --no-wait"
3683
+ ],
3684
+ "flags": {
3685
+ "cluster": {
3686
+ "char": "c",
3687
+ "description": "Cluster name or ID (default: auto-detect when only one cluster exists)",
3688
+ "name": "cluster",
3689
+ "hasDynamicHelp": false,
3690
+ "multiple": false,
3691
+ "type": "option"
3692
+ },
3693
+ "count": {
3694
+ "char": "n",
3695
+ "description": "Number of workers to add (1-5)",
3696
+ "name": "count",
3697
+ "default": 1,
3698
+ "hasDynamicHelp": false,
3699
+ "multiple": false,
3700
+ "type": "option"
3701
+ },
3702
+ "no-wait": {
3703
+ "description": "Return immediately after queuing the operation",
3704
+ "name": "no-wait",
3705
+ "allowNo": false,
3706
+ "type": "boolean"
3707
+ }
3708
+ },
3709
+ "hasDynamicHelp": false,
3710
+ "hiddenAliases": [],
3711
+ "id": "node:add",
3712
+ "pluginAlias": "@flui-cloud/cli",
3713
+ "pluginName": "@flui-cloud/cli",
3714
+ "pluginType": "core",
3715
+ "strict": true,
3716
+ "enableJsonFlag": false,
3717
+ "isESM": false,
3718
+ "relativePath": [
3719
+ "lib",
3720
+ "cli",
3721
+ "src",
3722
+ "commands",
3723
+ "node",
3724
+ "add.js"
3725
+ ]
3726
+ },
3727
+ "node:list": {
3728
+ "aliases": [],
3729
+ "args": {},
3730
+ "description": "List all nodes in the cluster (master + workers)",
3731
+ "examples": [
3732
+ "<%= config.bin %> <%= command.id %>",
3733
+ "<%= config.bin %> <%= command.id %> --output json"
3734
+ ],
3735
+ "flags": {
3736
+ "cluster": {
3737
+ "char": "c",
3738
+ "description": "Cluster name or ID (default: auto-detect when only one cluster exists)",
3739
+ "name": "cluster",
3740
+ "hasDynamicHelp": false,
3741
+ "multiple": false,
3742
+ "type": "option"
3743
+ },
3744
+ "output": {
3745
+ "char": "o",
3746
+ "description": "Output format",
3747
+ "name": "output",
3748
+ "default": "table",
3749
+ "hasDynamicHelp": false,
3750
+ "multiple": false,
3751
+ "options": [
3752
+ "table",
3753
+ "json"
3754
+ ],
3755
+ "type": "option"
3756
+ }
3757
+ },
3758
+ "hasDynamicHelp": false,
3759
+ "hiddenAliases": [],
3760
+ "id": "node:list",
3761
+ "pluginAlias": "@flui-cloud/cli",
3762
+ "pluginName": "@flui-cloud/cli",
3763
+ "pluginType": "core",
3764
+ "strict": true,
3765
+ "enableJsonFlag": false,
3766
+ "isESM": false,
3767
+ "relativePath": [
3768
+ "lib",
3769
+ "cli",
3770
+ "src",
3771
+ "commands",
3772
+ "node",
3773
+ "list.js"
3774
+ ]
3775
+ },
3776
+ "node:remove": {
3777
+ "aliases": [],
3778
+ "args": {
3779
+ "nodeId": {
3780
+ "description": "Node ID to remove (from `flui node list`)",
3781
+ "name": "nodeId",
3782
+ "required": true
3783
+ }
3784
+ },
3785
+ "description": "Cordon, drain and remove a worker node from the cluster. Cannot remove the master.",
3786
+ "examples": [
3787
+ "<%= config.bin %> <%= command.id %> <node-id>",
3788
+ "<%= config.bin %> <%= command.id %> <node-id> --no-wait"
3789
+ ],
3790
+ "flags": {
3791
+ "cluster": {
3792
+ "char": "c",
3793
+ "description": "Cluster name or ID (default: auto-detect when only one cluster exists)",
3794
+ "name": "cluster",
3795
+ "hasDynamicHelp": false,
3796
+ "multiple": false,
3797
+ "type": "option"
3798
+ },
3799
+ "no-wait": {
3800
+ "description": "Return immediately after queuing the operation",
3801
+ "name": "no-wait",
3802
+ "allowNo": false,
3803
+ "type": "boolean"
3804
+ }
3805
+ },
3806
+ "hasDynamicHelp": false,
3807
+ "hiddenAliases": [],
3808
+ "id": "node:remove",
3809
+ "pluginAlias": "@flui-cloud/cli",
3810
+ "pluginName": "@flui-cloud/cli",
3811
+ "pluginType": "core",
3812
+ "strict": true,
3813
+ "enableJsonFlag": false,
3814
+ "isESM": false,
3815
+ "relativePath": [
3816
+ "lib",
3817
+ "cli",
3818
+ "src",
3819
+ "commands",
3820
+ "node",
3821
+ "remove.js"
3822
+ ]
3823
+ },
3675
3824
  "server-types:list": {
3676
3825
  "aliases": [],
3677
3826
  "args": {},
@@ -3899,43 +4048,105 @@
3899
4048
  "install.js"
3900
4049
  ]
3901
4050
  },
3902
- "node:add": {
4051
+ "app:snapshot:create": {
3903
4052
  "aliases": [],
3904
- "args": {},
3905
- "description": "Add worker node(s) to the cluster. Provisions new servers and joins them to K3s.",
3906
- "examples": [
3907
- "<%= config.bin %> <%= command.id %>",
3908
- "<%= config.bin %> <%= command.id %> --count 2",
3909
- "<%= config.bin %> <%= command.id %> --count 3 --no-wait"
4053
+ "args": {
4054
+ "name": {
4055
+ "description": "Application name or slug",
4056
+ "name": "name",
4057
+ "required": true
4058
+ }
4059
+ },
4060
+ "description": "Create a snapshot of an application volume. Today on every provider this is a full PVC clone built via the copy-pod export primitive (sink=pvc-clone) because workload PVCs use local-path. Cost: a full Volume per snapshot.",
4061
+ "examples": [
4062
+ "<%= config.bin %> <%= command.id %> my-app",
4063
+ "<%= config.bin %> <%= command.id %> my-app --description before-upgrade",
4064
+ "<%= config.bin %> <%= command.id %> my-app --volume data"
3910
4065
  ],
3911
4066
  "flags": {
3912
4067
  "cluster": {
3913
4068
  "char": "c",
3914
- "description": "Cluster name or ID (default: auto-detect when only one cluster exists)",
4069
+ "description": "Cluster name or ID (default: auto-detect)",
3915
4070
  "name": "cluster",
3916
4071
  "hasDynamicHelp": false,
3917
4072
  "multiple": false,
3918
4073
  "type": "option"
3919
4074
  },
3920
- "count": {
3921
- "char": "n",
3922
- "description": "Number of workers to add (1-5)",
3923
- "name": "count",
3924
- "default": 1,
4075
+ "volume": {
4076
+ "char": "v",
4077
+ "description": "Volume (PVC) name when the app has multiple volumes. Required if more than one PVC exists.",
4078
+ "name": "volume",
3925
4079
  "hasDynamicHelp": false,
3926
4080
  "multiple": false,
3927
4081
  "type": "option"
3928
4082
  },
3929
- "no-wait": {
3930
- "description": "Return immediately after queuing the operation",
3931
- "name": "no-wait",
4083
+ "description": {
4084
+ "char": "d",
4085
+ "description": "Optional human-friendly tag appended to the snapshot id",
4086
+ "name": "description",
4087
+ "hasDynamicHelp": false,
4088
+ "multiple": false,
4089
+ "type": "option"
4090
+ }
4091
+ },
4092
+ "hasDynamicHelp": false,
4093
+ "hiddenAliases": [],
4094
+ "id": "app:snapshot:create",
4095
+ "pluginAlias": "@flui-cloud/cli",
4096
+ "pluginName": "@flui-cloud/cli",
4097
+ "pluginType": "core",
4098
+ "strict": true,
4099
+ "enableJsonFlag": false,
4100
+ "isESM": false,
4101
+ "relativePath": [
4102
+ "lib",
4103
+ "cli",
4104
+ "src",
4105
+ "commands",
4106
+ "app",
4107
+ "snapshot",
4108
+ "create.js"
4109
+ ]
4110
+ },
4111
+ "app:snapshot:delete": {
4112
+ "aliases": [],
4113
+ "args": {
4114
+ "name": {
4115
+ "description": "Application name or slug",
4116
+ "name": "name",
4117
+ "required": true
4118
+ },
4119
+ "snapshotId": {
4120
+ "description": "Snapshot id (from `flui app snapshot list`)",
4121
+ "name": "snapshotId",
4122
+ "required": true
4123
+ }
4124
+ },
4125
+ "description": "Delete a volume snapshot of an application.",
4126
+ "examples": [
4127
+ "<%= config.bin %> <%= command.id %> my-app my-app-snap-20260510-abcdef",
4128
+ "<%= config.bin %> <%= command.id %> my-app my-app-snap-... --force"
4129
+ ],
4130
+ "flags": {
4131
+ "cluster": {
4132
+ "char": "c",
4133
+ "description": "Cluster name or ID (default: auto-detect)",
4134
+ "name": "cluster",
4135
+ "hasDynamicHelp": false,
4136
+ "multiple": false,
4137
+ "type": "option"
4138
+ },
4139
+ "force": {
4140
+ "char": "f",
4141
+ "description": "Skip confirmation",
4142
+ "name": "force",
3932
4143
  "allowNo": false,
3933
4144
  "type": "boolean"
3934
4145
  }
3935
4146
  },
3936
4147
  "hasDynamicHelp": false,
3937
4148
  "hiddenAliases": [],
3938
- "id": "node:add",
4149
+ "id": "app:snapshot:delete",
3939
4150
  "pluginAlias": "@flui-cloud/cli",
3940
4151
  "pluginName": "@flui-cloud/cli",
3941
4152
  "pluginType": "core",
@@ -3947,27 +4158,36 @@
3947
4158
  "cli",
3948
4159
  "src",
3949
4160
  "commands",
3950
- "node",
3951
- "add.js"
4161
+ "app",
4162
+ "snapshot",
4163
+ "delete.js"
3952
4164
  ]
3953
4165
  },
3954
- "node:list": {
4166
+ "app:snapshot:list": {
3955
4167
  "aliases": [],
3956
4168
  "args": {},
3957
- "description": "List all nodes in the cluster (master + workers)",
4169
+ "description": "List volume snapshots. Use --app to filter to a single app, omit to list cluster-wide.",
3958
4170
  "examples": [
3959
4171
  "<%= config.bin %> <%= command.id %>",
3960
- "<%= config.bin %> <%= command.id %> --output json"
4172
+ "<%= config.bin %> <%= command.id %> --app my-app"
3961
4173
  ],
3962
4174
  "flags": {
3963
4175
  "cluster": {
3964
4176
  "char": "c",
3965
- "description": "Cluster name or ID (default: auto-detect when only one cluster exists)",
4177
+ "description": "Cluster name or ID (default: auto-detect)",
3966
4178
  "name": "cluster",
3967
4179
  "hasDynamicHelp": false,
3968
4180
  "multiple": false,
3969
4181
  "type": "option"
3970
4182
  },
4183
+ "app": {
4184
+ "char": "a",
4185
+ "description": "Filter by application name or slug",
4186
+ "name": "app",
4187
+ "hasDynamicHelp": false,
4188
+ "multiple": false,
4189
+ "type": "option"
4190
+ },
3971
4191
  "output": {
3972
4192
  "char": "o",
3973
4193
  "description": "Output format",
@@ -3984,7 +4204,7 @@
3984
4204
  },
3985
4205
  "hasDynamicHelp": false,
3986
4206
  "hiddenAliases": [],
3987
- "id": "node:list",
4207
+ "id": "app:snapshot:list",
3988
4208
  "pluginAlias": "@flui-cloud/cli",
3989
4209
  "pluginName": "@flui-cloud/cli",
3990
4210
  "pluginType": "core",
@@ -3996,43 +4216,57 @@
3996
4216
  "cli",
3997
4217
  "src",
3998
4218
  "commands",
3999
- "node",
4219
+ "app",
4220
+ "snapshot",
4000
4221
  "list.js"
4001
4222
  ]
4002
4223
  },
4003
- "node:remove": {
4224
+ "app:snapshot:restore": {
4004
4225
  "aliases": [],
4005
4226
  "args": {
4006
- "nodeId": {
4007
- "description": "Node ID to remove (from `flui node list`)",
4008
- "name": "nodeId",
4227
+ "name": {
4228
+ "description": "Application name or slug",
4229
+ "name": "name",
4230
+ "required": true
4231
+ },
4232
+ "snapshotId": {
4233
+ "description": "Snapshot id (from `flui app snapshot list`)",
4234
+ "name": "snapshotId",
4009
4235
  "required": true
4010
4236
  }
4011
4237
  },
4012
- "description": "Cordon, drain and remove a worker node from the cluster. Cannot remove the master.",
4238
+ "description": "Restore a snapshot into a new side-by-side PVC. The application is not touched — the new PVC is created in the same namespace and can be promoted later with `flui app snapshot swap`.",
4013
4239
  "examples": [
4014
- "<%= config.bin %> <%= command.id %> <node-id>",
4015
- "<%= config.bin %> <%= command.id %> <node-id> --no-wait"
4240
+ "<%= config.bin %> <%= command.id %> my-app my-app-snap-20260510-abcdef",
4241
+ "<%= config.bin %> <%= command.id %> my-app my-app-snap-... --swap"
4016
4242
  ],
4017
4243
  "flags": {
4018
4244
  "cluster": {
4019
4245
  "char": "c",
4020
- "description": "Cluster name or ID (default: auto-detect when only one cluster exists)",
4246
+ "description": "Cluster name or ID (default: auto-detect)",
4021
4247
  "name": "cluster",
4022
4248
  "hasDynamicHelp": false,
4023
4249
  "multiple": false,
4024
4250
  "type": "option"
4025
4251
  },
4026
- "no-wait": {
4027
- "description": "Return immediately after queuing the operation",
4028
- "name": "no-wait",
4252
+ "swap": {
4253
+ "description": "Immediately swap the restored PVC into the live application (rolling restart). Old PVC is preserved as a backup.",
4254
+ "name": "swap",
4029
4255
  "allowNo": false,
4030
4256
  "type": "boolean"
4257
+ },
4258
+ "volume": {
4259
+ "char": "v",
4260
+ "description": "Application volume name to swap when --swap is set. Required if the app has multiple volumes.",
4261
+ "name": "volume",
4262
+ "hasDynamicHelp": false,
4263
+ "multiple": false,
4264
+ "type": "option"
4031
4265
  }
4032
4266
  },
4033
4267
  "hasDynamicHelp": false,
4034
4268
  "hiddenAliases": [],
4035
- "id": "node:remove",
4269
+ "id": "app:snapshot:restore",
4036
4270
  "pluginAlias": "@flui-cloud/cli",
4037
4271
  "pluginName": "@flui-cloud/cli",
4038
4272
  "pluginType": "core",
@@ -4044,8 +4278,72 @@
4044
4278
  "cli",
4045
4279
  "src",
4046
4280
  "commands",
4047
- "node",
4048
- "remove.js"
4281
+ "app",
4282
+ "snapshot",
4283
+ "restore.js"
4284
+ ]
4285
+ },
4286
+ "app:snapshot:swap": {
4287
+ "aliases": [],
4288
+ "args": {
4289
+ "name": {
4290
+ "description": "Application name or slug",
4291
+ "name": "name",
4292
+ "required": true
4293
+ },
4294
+ "newPvcName": {
4295
+ "description": "PVC name to swap into the application",
4296
+ "name": "newPvcName",
4297
+ "required": true
4298
+ }
4299
+ },
4300
+ "description": "Swap the application volume to a different PVC (typically one created by `flui app snapshot restore`). Triggers a rolling restart. The previous PVC is preserved as a backup.",
4301
+ "examples": [
4302
+ "<%= config.bin %> <%= command.id %> my-app my-app-data-restored-20260511",
4303
+ "<%= config.bin %> <%= command.id %> my-app new-pvc --volume data --force"
4304
+ ],
4305
+ "flags": {
4306
+ "cluster": {
4307
+ "char": "c",
4308
+ "description": "Cluster name or ID (default: auto-detect)",
4309
+ "name": "cluster",
4310
+ "hasDynamicHelp": false,
4311
+ "multiple": false,
4312
+ "type": "option"
4313
+ },
4314
+ "volume": {
4315
+ "char": "v",
4316
+ "description": "Application volume name (default: the single volume)",
4317
+ "name": "volume",
4318
+ "hasDynamicHelp": false,
4319
+ "multiple": false,
4320
+ "type": "option"
4321
+ },
4322
+ "force": {
4323
+ "char": "f",
4324
+ "description": "Skip confirmation",
4325
+ "name": "force",
4326
+ "allowNo": false,
4327
+ "type": "boolean"
4328
+ }
4329
+ },
4330
+ "hasDynamicHelp": false,
4331
+ "hiddenAliases": [],
4332
+ "id": "app:snapshot:swap",
4333
+ "pluginAlias": "@flui-cloud/cli",
4334
+ "pluginName": "@flui-cloud/cli",
4335
+ "pluginType": "core",
4336
+ "strict": true,
4337
+ "enableJsonFlag": false,
4338
+ "isESM": false,
4339
+ "relativePath": [
4340
+ "lib",
4341
+ "cli",
4342
+ "src",
4343
+ "commands",
4344
+ "app",
4345
+ "snapshot",
4346
+ "swap.js"
4049
4347
  ]
4050
4348
  },
4051
4349
  "template:use": {
@@ -4380,487 +4678,128 @@
4380
4678
  "delete.js"
4381
4679
  ]
4382
4680
  },
4383
- "app:snapshot:create": {
4681
+ "backup:destination:create": {
4384
4682
  "aliases": [],
4385
- "args": {
4386
- "name": {
4387
- "description": "Application name or slug",
4388
- "name": "name",
4389
- "required": true
4390
- }
4391
- },
4392
- "description": "Create a snapshot of an application volume. Today on every provider this is a full PVC clone built via the copy-pod export primitive (sink=pvc-clone) because workload PVCs use local-path. Cost: a full Volume per snapshot.",
4683
+ "args": {},
4684
+ "description": "Create a backup destination (S3-compatible storage target for Velero)",
4393
4685
  "examples": [
4394
- "<%= config.bin %> <%= command.id %> my-app",
4395
- "<%= config.bin %> <%= command.id %> my-app --description before-upgrade",
4396
- "<%= config.bin %> <%= command.id %> my-app --volume data"
4686
+ "<%= config.bin %> <%= command.id %> --name my-s3 --provider hetzner_object_storage --endpoint https://fsn1.your-objectstorage.com --region fsn1 --bucket flui-backups --access-key AK --secret-key SK",
4687
+ "<%= config.bin %> <%= command.id %> --name scw --provider scaleway_object_storage --endpoint https://s3.fr-par.scw.cloud --region fr-par --bucket flui-bkp --access-key AK --secret-key SK"
4397
4688
  ],
4398
4689
  "flags": {
4399
- "cluster": {
4400
- "char": "c",
4401
- "description": "Cluster name or ID (default: auto-detect)",
4402
- "name": "cluster",
4690
+ "name": {
4691
+ "description": "Display name (≤120 chars)",
4692
+ "name": "name",
4693
+ "required": true,
4403
4694
  "hasDynamicHelp": false,
4404
4695
  "multiple": false,
4405
4696
  "type": "option"
4406
4697
  },
4407
- "volume": {
4408
- "char": "v",
4409
- "description": "Volume (PVC) name when the app has multiple volumes. Required if more than one PVC exists.",
4410
- "name": "volume",
4411
- "hasDynamicHelp": false,
4412
- "multiple": false,
4413
- "type": "option"
4414
- },
4415
- "description": {
4416
- "char": "d",
4417
- "description": "Optional human-friendly tag appended to the snapshot id",
4418
- "name": "description",
4419
- "hasDynamicHelp": false,
4420
- "multiple": false,
4421
- "type": "option"
4422
- }
4423
- },
4424
- "hasDynamicHelp": false,
4425
- "hiddenAliases": [],
4426
- "id": "app:snapshot:create",
4427
- "pluginAlias": "@flui-cloud/cli",
4428
- "pluginName": "@flui-cloud/cli",
4429
- "pluginType": "core",
4430
- "strict": true,
4431
- "enableJsonFlag": false,
4432
- "isESM": false,
4433
- "relativePath": [
4434
- "lib",
4435
- "cli",
4436
- "src",
4437
- "commands",
4438
- "app",
4439
- "snapshot",
4440
- "create.js"
4441
- ]
4442
- },
4443
- "app:snapshot:delete": {
4444
- "aliases": [],
4445
- "args": {
4446
- "name": {
4447
- "description": "Application name or slug",
4448
- "name": "name",
4449
- "required": true
4450
- },
4451
- "snapshotId": {
4452
- "description": "Snapshot id (from `flui app snapshot list`)",
4453
- "name": "snapshotId",
4454
- "required": true
4455
- }
4456
- },
4457
- "description": "Delete a volume snapshot of an application.",
4458
- "examples": [
4459
- "<%= config.bin %> <%= command.id %> my-app my-app-snap-20260510-abcdef",
4460
- "<%= config.bin %> <%= command.id %> my-app my-app-snap-... --force"
4461
- ],
4462
- "flags": {
4463
- "cluster": {
4464
- "char": "c",
4465
- "description": "Cluster name or ID (default: auto-detect)",
4466
- "name": "cluster",
4467
- "hasDynamicHelp": false,
4468
- "multiple": false,
4469
- "type": "option"
4470
- },
4471
- "force": {
4472
- "char": "f",
4473
- "description": "Skip confirmation",
4474
- "name": "force",
4475
- "allowNo": false,
4476
- "type": "boolean"
4477
- }
4478
- },
4479
- "hasDynamicHelp": false,
4480
- "hiddenAliases": [],
4481
- "id": "app:snapshot:delete",
4482
- "pluginAlias": "@flui-cloud/cli",
4483
- "pluginName": "@flui-cloud/cli",
4484
- "pluginType": "core",
4485
- "strict": true,
4486
- "enableJsonFlag": false,
4487
- "isESM": false,
4488
- "relativePath": [
4489
- "lib",
4490
- "cli",
4491
- "src",
4492
- "commands",
4493
- "app",
4494
- "snapshot",
4495
- "delete.js"
4496
- ]
4497
- },
4498
- "app:snapshot:list": {
4499
- "aliases": [],
4500
- "args": {},
4501
- "description": "List volume snapshots. Use --app to filter to a single app, omit to list cluster-wide.",
4502
- "examples": [
4503
- "<%= config.bin %> <%= command.id %>",
4504
- "<%= config.bin %> <%= command.id %> --app my-app"
4505
- ],
4506
- "flags": {
4507
- "cluster": {
4508
- "char": "c",
4509
- "description": "Cluster name or ID (default: auto-detect)",
4510
- "name": "cluster",
4511
- "hasDynamicHelp": false,
4512
- "multiple": false,
4513
- "type": "option"
4514
- },
4515
- "app": {
4516
- "char": "a",
4517
- "description": "Filter by application name or slug",
4518
- "name": "app",
4519
- "hasDynamicHelp": false,
4520
- "multiple": false,
4521
- "type": "option"
4522
- },
4523
- "output": {
4524
- "char": "o",
4525
- "description": "Output format",
4526
- "name": "output",
4527
- "default": "table",
4698
+ "provider": {
4699
+ "description": "Storage backend provider",
4700
+ "name": "provider",
4701
+ "required": true,
4528
4702
  "hasDynamicHelp": false,
4529
4703
  "multiple": false,
4530
4704
  "options": [
4531
- "table",
4532
- "json"
4705
+ "hetzner_object_storage",
4706
+ "scaleway_object_storage",
4707
+ "minio",
4708
+ "generic_s3"
4533
4709
  ],
4534
4710
  "type": "option"
4535
- }
4536
- },
4537
- "hasDynamicHelp": false,
4538
- "hiddenAliases": [],
4539
- "id": "app:snapshot:list",
4540
- "pluginAlias": "@flui-cloud/cli",
4541
- "pluginName": "@flui-cloud/cli",
4542
- "pluginType": "core",
4543
- "strict": true,
4544
- "enableJsonFlag": false,
4545
- "isESM": false,
4546
- "relativePath": [
4547
- "lib",
4548
- "cli",
4549
- "src",
4550
- "commands",
4551
- "app",
4552
- "snapshot",
4553
- "list.js"
4554
- ]
4555
- },
4556
- "app:snapshot:restore": {
4557
- "aliases": [],
4558
- "args": {
4559
- "name": {
4560
- "description": "Application name or slug",
4561
- "name": "name",
4562
- "required": true
4563
- },
4564
- "snapshotId": {
4565
- "description": "Snapshot id (from `flui app snapshot list`)",
4566
- "name": "snapshotId",
4567
- "required": true
4568
- }
4569
- },
4570
- "description": "Restore a snapshot into a new side-by-side PVC. The application is not touched — the new PVC is created in the same namespace and can be promoted later with `flui app snapshot swap`.",
4571
- "examples": [
4572
- "<%= config.bin %> <%= command.id %> my-app my-app-snap-20260510-abcdef",
4573
- "<%= config.bin %> <%= command.id %> my-app my-app-snap-... --swap"
4574
- ],
4575
- "flags": {
4576
- "cluster": {
4577
- "char": "c",
4578
- "description": "Cluster name or ID (default: auto-detect)",
4579
- "name": "cluster",
4580
- "hasDynamicHelp": false,
4581
- "multiple": false,
4582
- "type": "option"
4583
- },
4584
- "swap": {
4585
- "description": "Immediately swap the restored PVC into the live application (rolling restart). Old PVC is preserved as a backup.",
4586
- "name": "swap",
4587
- "allowNo": false,
4588
- "type": "boolean"
4589
- },
4590
- "volume": {
4591
- "char": "v",
4592
- "description": "Application volume name to swap when --swap is set. Required if the app has multiple volumes.",
4593
- "name": "volume",
4594
- "hasDynamicHelp": false,
4595
- "multiple": false,
4596
- "type": "option"
4597
- }
4598
- },
4599
- "hasDynamicHelp": false,
4600
- "hiddenAliases": [],
4601
- "id": "app:snapshot:restore",
4602
- "pluginAlias": "@flui-cloud/cli",
4603
- "pluginName": "@flui-cloud/cli",
4604
- "pluginType": "core",
4605
- "strict": true,
4606
- "enableJsonFlag": false,
4607
- "isESM": false,
4608
- "relativePath": [
4609
- "lib",
4610
- "cli",
4611
- "src",
4612
- "commands",
4613
- "app",
4614
- "snapshot",
4615
- "restore.js"
4616
- ]
4617
- },
4618
- "app:snapshot:swap": {
4619
- "aliases": [],
4620
- "args": {
4621
- "name": {
4622
- "description": "Application name or slug",
4623
- "name": "name",
4624
- "required": true
4625
- },
4626
- "newPvcName": {
4627
- "description": "PVC name to swap into the application",
4628
- "name": "newPvcName",
4629
- "required": true
4630
- }
4631
- },
4632
- "description": "Swap the application volume to a different PVC (typically one created by `flui app snapshot restore`). Triggers a rolling restart. The previous PVC is preserved as a backup.",
4633
- "examples": [
4634
- "<%= config.bin %> <%= command.id %> my-app my-app-data-restored-20260511",
4635
- "<%= config.bin %> <%= command.id %> my-app new-pvc --volume data --force"
4636
- ],
4637
- "flags": {
4638
- "cluster": {
4639
- "char": "c",
4640
- "description": "Cluster name or ID (default: auto-detect)",
4641
- "name": "cluster",
4642
- "hasDynamicHelp": false,
4643
- "multiple": false,
4644
- "type": "option"
4645
4711
  },
4646
- "volume": {
4647
- "char": "v",
4648
- "description": "Application volume name (default: the single volume)",
4649
- "name": "volume",
4712
+ "endpoint": {
4713
+ "description": "S3 endpoint URL (e.g. https://s3.fr-par.scw.cloud)",
4714
+ "name": "endpoint",
4715
+ "required": true,
4650
4716
  "hasDynamicHelp": false,
4651
4717
  "multiple": false,
4652
4718
  "type": "option"
4653
4719
  },
4654
- "force": {
4655
- "char": "f",
4656
- "description": "Skip confirmation",
4657
- "name": "force",
4658
- "allowNo": false,
4659
- "type": "boolean"
4660
- }
4661
- },
4662
- "hasDynamicHelp": false,
4663
- "hiddenAliases": [],
4664
- "id": "app:snapshot:swap",
4665
- "pluginAlias": "@flui-cloud/cli",
4666
- "pluginName": "@flui-cloud/cli",
4667
- "pluginType": "core",
4668
- "strict": true,
4669
- "enableJsonFlag": false,
4670
- "isESM": false,
4671
- "relativePath": [
4672
- "lib",
4673
- "cli",
4674
- "src",
4675
- "commands",
4676
- "app",
4677
- "snapshot",
4678
- "swap.js"
4679
- ]
4680
- },
4681
- "backup:policy:create": {
4682
- "aliases": [],
4683
- "args": {},
4684
- "description": "Create a backup policy",
4685
- "examples": [
4686
- "<%= config.bin %> <%= command.id %> --name daily-all --cluster <id> --scope cluster_all --schedule \"0 2 * * *\" --retention-days 14 --destination <destId>",
4687
- "<%= config.bin %> <%= command.id %> --name app-snap --cluster <id> --scope applications --scope-namespaces ns1,ns2 --destination <destId>"
4688
- ],
4689
- "flags": {
4690
- "name": {
4691
- "name": "name",
4720
+ "region": {
4721
+ "name": "region",
4692
4722
  "required": true,
4693
4723
  "hasDynamicHelp": false,
4694
4724
  "multiple": false,
4695
4725
  "type": "option"
4696
4726
  },
4697
- "cluster": {
4698
- "description": "Cluster ID",
4699
- "name": "cluster",
4727
+ "bucket": {
4728
+ "name": "bucket",
4700
4729
  "required": true,
4701
4730
  "hasDynamicHelp": false,
4702
4731
  "multiple": false,
4703
4732
  "type": "option"
4704
4733
  },
4705
- "scope": {
4706
- "name": "scope",
4734
+ "access-key": {
4735
+ "name": "access-key",
4707
4736
  "required": true,
4708
4737
  "hasDynamicHelp": false,
4709
4738
  "multiple": false,
4710
- "options": [
4711
- "cluster_all",
4712
- "namespaces",
4713
- "applications",
4714
- "label_selector"
4715
- ],
4716
4739
  "type": "option"
4717
4740
  },
4718
- "scope-namespaces": {
4719
- "description": "Comma-separated namespaces (for scope=namespaces)",
4720
- "name": "scope-namespaces",
4741
+ "secret-key": {
4742
+ "name": "secret-key",
4743
+ "required": true,
4721
4744
  "hasDynamicHelp": false,
4722
4745
  "multiple": false,
4723
4746
  "type": "option"
4724
4747
  },
4725
- "scope-apps": {
4726
- "description": "Comma-separated application IDs (for scope=applications)",
4727
- "name": "scope-apps",
4748
+ "prefix": {
4749
+ "description": "Optional path prefix inside the bucket",
4750
+ "name": "prefix",
4728
4751
  "hasDynamicHelp": false,
4729
4752
  "multiple": false,
4730
4753
  "type": "option"
4731
4754
  },
4732
- "profile": {
4733
- "name": "profile",
4734
- "default": "single",
4755
+ "encryption-mode": {
4756
+ "description": "Encryption mode (default: flui_managed)",
4757
+ "name": "encryption-mode",
4735
4758
  "hasDynamicHelp": false,
4736
4759
  "multiple": false,
4737
4760
  "options": [
4738
- "single",
4739
- "mirrored",
4740
- "custom"
4761
+ "flui_managed",
4762
+ "byo_passphrase",
4763
+ "none"
4741
4764
  ],
4742
4765
  "type": "option"
4743
4766
  },
4744
- "schedule": {
4745
- "description": "Cron schedule (e.g. \"0 2 * * *\" for daily 02:00 UTC)",
4746
- "name": "schedule",
4747
- "hasDynamicHelp": false,
4748
- "multiple": false,
4749
- "type": "option"
4750
- },
4751
- "retention-days": {
4752
- "name": "retention-days",
4753
- "default": 30,
4754
- "hasDynamicHelp": false,
4755
- "multiple": false,
4756
- "type": "option"
4757
- },
4758
- "retention-max-copies": {
4759
- "name": "retention-max-copies",
4767
+ "encryption-passphrase": {
4768
+ "description": "Required when --encryption-mode=byo_passphrase",
4769
+ "name": "encryption-passphrase",
4760
4770
  "hasDynamicHelp": false,
4761
4771
  "multiple": false,
4762
4772
  "type": "option"
4763
4773
  },
4764
- "include-pvcs": {
4765
- "name": "include-pvcs",
4774
+ "force-path-style": {
4775
+ "description": "Force path-style S3 URLs (needed for MinIO/some providers)",
4776
+ "name": "force-path-style",
4766
4777
  "allowNo": false,
4767
4778
  "type": "boolean"
4768
4779
  },
4769
- "include-etcd-l1": {
4770
- "name": "include-etcd-l1",
4780
+ "use-sse": {
4781
+ "description": "Use server-side encryption (SSE-S3) at the provider",
4782
+ "name": "use-sse",
4771
4783
  "allowNo": false,
4772
4784
  "type": "boolean"
4773
4785
  },
4774
- "enabled": {
4775
- "name": "enabled",
4776
- "allowNo": true,
4777
- "type": "boolean"
4778
- },
4779
- "destination": {
4780
- "description": "Destination spec: <destId>[:primary|replica[:priority]] (repeatable)",
4781
- "name": "destination",
4782
- "required": true,
4783
- "hasDynamicHelp": false,
4784
- "multiple": true,
4785
- "type": "option"
4786
- }
4787
- },
4788
- "hasDynamicHelp": false,
4789
- "hiddenAliases": [],
4790
- "id": "backup:policy:create",
4791
- "pluginAlias": "@flui-cloud/cli",
4792
- "pluginName": "@flui-cloud/cli",
4793
- "pluginType": "core",
4794
- "strict": true,
4795
- "enableJsonFlag": false,
4796
- "isESM": false,
4797
- "relativePath": [
4798
- "lib",
4799
- "cli",
4800
- "src",
4801
- "commands",
4802
- "backup",
4803
- "policy",
4804
- "create.js"
4805
- ]
4806
- },
4807
- "backup:policy:delete": {
4808
- "aliases": [],
4809
- "args": {
4810
- "id": {
4811
- "name": "id",
4812
- "required": true
4813
- }
4814
- },
4815
- "description": "Delete a backup policy (existing artifacts are retained)",
4816
- "flags": {
4817
- "yes": {
4818
- "char": "y",
4819
- "name": "yes",
4786
+ "usable-for-etcd-l1": {
4787
+ "description": "Allow this destination to receive L1 etcd snapshots",
4788
+ "name": "usable-for-etcd-l1",
4820
4789
  "allowNo": false,
4821
4790
  "type": "boolean"
4822
- }
4823
- },
4824
- "hasDynamicHelp": false,
4825
- "hiddenAliases": [],
4826
- "id": "backup:policy:delete",
4827
- "pluginAlias": "@flui-cloud/cli",
4828
- "pluginName": "@flui-cloud/cli",
4829
- "pluginType": "core",
4830
- "strict": true,
4831
- "enableJsonFlag": false,
4832
- "isESM": false,
4833
- "relativePath": [
4834
- "lib",
4835
- "cli",
4836
- "src",
4837
- "commands",
4838
- "backup",
4839
- "policy",
4840
- "delete.js"
4841
- ]
4842
- },
4843
- "backup:policy:list": {
4844
- "aliases": [],
4845
- "args": {},
4846
- "description": "List backup policies",
4847
- "flags": {
4848
- "cluster": {
4849
- "description": "Filter by cluster ID",
4850
- "name": "cluster",
4791
+ },
4792
+ "cost-per-gb-month-cents": {
4793
+ "description": "Provider cost in cents/GB·month (used for billing estimate)",
4794
+ "name": "cost-per-gb-month-cents",
4851
4795
  "hasDynamicHelp": false,
4852
4796
  "multiple": false,
4853
4797
  "type": "option"
4854
- },
4855
- "json": {
4856
- "name": "json",
4857
- "allowNo": false,
4858
- "type": "boolean"
4859
4798
  }
4860
4799
  },
4861
4800
  "hasDynamicHelp": false,
4862
4801
  "hiddenAliases": [],
4863
- "id": "backup:policy:list",
4802
+ "id": "backup:destination:create",
4864
4803
  "pluginAlias": "@flui-cloud/cli",
4865
4804
  "pluginName": "@flui-cloud/cli",
4866
4805
  "pluginType": "core",
@@ -4873,30 +4812,32 @@
4873
4812
  "src",
4874
4813
  "commands",
4875
4814
  "backup",
4876
- "policy",
4877
- "list.js"
4815
+ "destination",
4816
+ "create.js"
4878
4817
  ]
4879
4818
  },
4880
- "backup:policy:show": {
4819
+ "backup:destination:delete": {
4881
4820
  "aliases": [],
4882
4821
  "args": {
4883
4822
  "id": {
4884
- "description": "Policy ID",
4823
+ "description": "Destination ID",
4885
4824
  "name": "id",
4886
4825
  "required": true
4887
4826
  }
4888
4827
  },
4889
- "description": "Show a backup policy by ID",
4828
+ "description": "Delete a backup destination",
4890
4829
  "flags": {
4891
- "json": {
4892
- "name": "json",
4830
+ "yes": {
4831
+ "char": "y",
4832
+ "description": "Skip confirmation",
4833
+ "name": "yes",
4893
4834
  "allowNo": false,
4894
4835
  "type": "boolean"
4895
4836
  }
4896
4837
  },
4897
4838
  "hasDynamicHelp": false,
4898
4839
  "hiddenAliases": [],
4899
- "id": "backup:policy:show",
4840
+ "id": "backup:destination:delete",
4900
4841
  "pluginAlias": "@flui-cloud/cli",
4901
4842
  "pluginName": "@flui-cloud/cli",
4902
4843
  "pluginType": "core",
@@ -4909,24 +4850,20 @@
4909
4850
  "src",
4910
4851
  "commands",
4911
4852
  "backup",
4912
- "policy",
4913
- "show.js"
4853
+ "destination",
4854
+ "delete.js"
4914
4855
  ]
4915
4856
  },
4916
- "backup:job:list": {
4857
+ "backup:destination:list": {
4917
4858
  "aliases": [],
4918
4859
  "args": {},
4919
- "description": "List backup jobs for a cluster",
4860
+ "description": "List backup destinations configured in the API",
4861
+ "examples": [
4862
+ "<%= config.bin %> <%= command.id %>"
4863
+ ],
4920
4864
  "flags": {
4921
- "cluster": {
4922
- "description": "Cluster ID",
4923
- "name": "cluster",
4924
- "required": true,
4925
- "hasDynamicHelp": false,
4926
- "multiple": false,
4927
- "type": "option"
4928
- },
4929
4865
  "json": {
4866
+ "description": "Output as JSON",
4930
4867
  "name": "json",
4931
4868
  "allowNo": false,
4932
4869
  "type": "boolean"
@@ -4934,7 +4871,7 @@
4934
4871
  },
4935
4872
  "hasDynamicHelp": false,
4936
4873
  "hiddenAliases": [],
4937
- "id": "backup:job:list",
4874
+ "id": "backup:destination:list",
4938
4875
  "pluginAlias": "@flui-cloud/cli",
4939
4876
  "pluginName": "@flui-cloud/cli",
4940
4877
  "pluginType": "core",
@@ -4947,27 +4884,31 @@
4947
4884
  "src",
4948
4885
  "commands",
4949
4886
  "backup",
4950
- "job",
4887
+ "destination",
4951
4888
  "list.js"
4952
4889
  ]
4953
4890
  },
4954
- "backup:job:run": {
4891
+ "backup:destination:show": {
4955
4892
  "aliases": [],
4956
- "args": {},
4957
- "description": "Trigger an on-demand backup job for a given policy",
4893
+ "args": {
4894
+ "id": {
4895
+ "description": "Destination ID (UUID)",
4896
+ "name": "id",
4897
+ "required": true
4898
+ }
4899
+ },
4900
+ "description": "Show a backup destination by ID",
4958
4901
  "flags": {
4959
- "policy": {
4960
- "description": "Policy ID",
4961
- "name": "policy",
4962
- "required": true,
4963
- "hasDynamicHelp": false,
4964
- "multiple": false,
4965
- "type": "option"
4902
+ "json": {
4903
+ "description": "Output as JSON",
4904
+ "name": "json",
4905
+ "allowNo": false,
4906
+ "type": "boolean"
4966
4907
  }
4967
4908
  },
4968
4909
  "hasDynamicHelp": false,
4969
4910
  "hiddenAliases": [],
4970
- "id": "backup:job:run",
4911
+ "id": "backup:destination:show",
4971
4912
  "pluginAlias": "@flui-cloud/cli",
4972
4913
  "pluginName": "@flui-cloud/cli",
4973
4914
  "pluginType": "core",
@@ -4980,29 +4921,24 @@
4980
4921
  "src",
4981
4922
  "commands",
4982
4923
  "backup",
4983
- "job",
4984
- "run.js"
4924
+ "destination",
4925
+ "show.js"
4985
4926
  ]
4986
4927
  },
4987
- "backup:job:show": {
4928
+ "backup:destination:test": {
4988
4929
  "aliases": [],
4989
4930
  "args": {
4990
4931
  "id": {
4932
+ "description": "Destination ID",
4991
4933
  "name": "id",
4992
4934
  "required": true
4993
4935
  }
4994
4936
  },
4995
- "description": "Show a backup job by ID",
4996
- "flags": {
4997
- "json": {
4998
- "name": "json",
4999
- "allowNo": false,
5000
- "type": "boolean"
5001
- }
5002
- },
4937
+ "description": "Test connectivity to a backup destination (S3 PUT/GET/DELETE round-trip)",
4938
+ "flags": {},
5003
4939
  "hasDynamicHelp": false,
5004
4940
  "hiddenAliases": [],
5005
- "id": "backup:job:show",
4941
+ "id": "backup:destination:test",
5006
4942
  "pluginAlias": "@flui-cloud/cli",
5007
4943
  "pluginName": "@flui-cloud/cli",
5008
4944
  "pluginType": "core",
@@ -5015,124 +4951,142 @@
5015
4951
  "src",
5016
4952
  "commands",
5017
4953
  "backup",
5018
- "job",
5019
- "show.js"
4954
+ "destination",
4955
+ "test.js"
5020
4956
  ]
5021
4957
  },
5022
- "backup:destination:create": {
4958
+ "backup:restore:create": {
5023
4959
  "aliases": [],
5024
4960
  "args": {},
5025
- "description": "Create a backup destination (S3-compatible storage target for Velero)",
5026
- "examples": [
5027
- "<%= config.bin %> <%= command.id %> --name my-s3 --provider hetzner_object_storage --endpoint https://fsn1.your-objectstorage.com --region fsn1 --bucket flui-backups --access-key AK --secret-key SK",
5028
- "<%= config.bin %> <%= command.id %> --name scw --provider scaleway_object_storage --endpoint https://s3.fr-par.scw.cloud --region fr-par --bucket flui-bkp --access-key AK --secret-key SK"
5029
- ],
4961
+ "description": "Create a restore job",
5030
4962
  "flags": {
5031
- "name": {
5032
- "description": "Display name (≤120 chars)",
5033
- "name": "name",
5034
- "required": true,
5035
- "hasDynamicHelp": false,
5036
- "multiple": false,
5037
- "type": "option"
5038
- },
5039
- "provider": {
5040
- "description": "Storage backend provider",
5041
- "name": "provider",
5042
- "required": true,
5043
- "hasDynamicHelp": false,
5044
- "multiple": false,
5045
- "options": [
5046
- "hetzner_object_storage",
5047
- "scaleway_object_storage",
5048
- "minio",
5049
- "generic_s3"
5050
- ],
5051
- "type": "option"
5052
- },
5053
- "endpoint": {
5054
- "description": "S3 endpoint URL (e.g. https://s3.fr-par.scw.cloud)",
5055
- "name": "endpoint",
4963
+ "artifact": {
4964
+ "description": "Backup artifact ID",
4965
+ "name": "artifact",
5056
4966
  "required": true,
5057
4967
  "hasDynamicHelp": false,
5058
4968
  "multiple": false,
5059
4969
  "type": "option"
5060
4970
  },
5061
- "region": {
5062
- "name": "region",
4971
+ "source-destination": {
4972
+ "name": "source-destination",
5063
4973
  "required": true,
5064
4974
  "hasDynamicHelp": false,
5065
4975
  "multiple": false,
5066
4976
  "type": "option"
5067
4977
  },
5068
- "bucket": {
5069
- "name": "bucket",
4978
+ "target-cluster": {
4979
+ "description": "Cluster to restore into",
4980
+ "name": "target-cluster",
5070
4981
  "required": true,
5071
4982
  "hasDynamicHelp": false,
5072
4983
  "multiple": false,
5073
4984
  "type": "option"
5074
4985
  },
5075
- "access-key": {
5076
- "name": "access-key",
4986
+ "target-kind": {
4987
+ "name": "target-kind",
5077
4988
  "required": true,
5078
4989
  "hasDynamicHelp": false,
5079
4990
  "multiple": false,
4991
+ "options": [
4992
+ "cluster",
4993
+ "namespace",
4994
+ "application",
4995
+ "observability"
4996
+ ],
5080
4997
  "type": "option"
5081
4998
  },
5082
- "secret-key": {
5083
- "name": "secret-key",
5084
- "required": true,
4999
+ "target-namespace": {
5000
+ "description": "Required when --target-kind=namespace",
5001
+ "name": "target-namespace",
5085
5002
  "hasDynamicHelp": false,
5086
5003
  "multiple": false,
5087
5004
  "type": "option"
5088
5005
  },
5089
- "prefix": {
5090
- "description": "Optional path prefix inside the bucket",
5091
- "name": "prefix",
5006
+ "target-app": {
5007
+ "description": "Required when --target-kind=application",
5008
+ "name": "target-app",
5092
5009
  "hasDynamicHelp": false,
5093
5010
  "multiple": false,
5094
5011
  "type": "option"
5095
5012
  },
5096
- "encryption-mode": {
5097
- "description": "Encryption mode (default: flui_managed)",
5098
- "name": "encryption-mode",
5013
+ "strategy": {
5014
+ "name": "strategy",
5099
5015
  "hasDynamicHelp": false,
5100
5016
  "multiple": false,
5101
5017
  "options": [
5102
- "flui_managed",
5103
- "byo_passphrase",
5104
- "none"
5018
+ "velero_rebuild",
5019
+ "os_snapshot"
5105
5020
  ],
5106
5021
  "type": "option"
5107
- },
5108
- "encryption-passphrase": {
5109
- "description": "Required when --encryption-mode=byo_passphrase",
5110
- "name": "encryption-passphrase",
5022
+ }
5023
+ },
5024
+ "hasDynamicHelp": false,
5025
+ "hiddenAliases": [],
5026
+ "id": "backup:restore:create",
5027
+ "pluginAlias": "@flui-cloud/cli",
5028
+ "pluginName": "@flui-cloud/cli",
5029
+ "pluginType": "core",
5030
+ "strict": true,
5031
+ "enableJsonFlag": false,
5032
+ "isESM": false,
5033
+ "relativePath": [
5034
+ "lib",
5035
+ "cli",
5036
+ "src",
5037
+ "commands",
5038
+ "backup",
5039
+ "restore",
5040
+ "create.js"
5041
+ ]
5042
+ },
5043
+ "backup:restore:list": {
5044
+ "aliases": [],
5045
+ "args": {},
5046
+ "description": "List restore jobs",
5047
+ "flags": {
5048
+ "json": {
5049
+ "name": "json",
5050
+ "allowNo": false,
5051
+ "type": "boolean"
5052
+ }
5053
+ },
5054
+ "hasDynamicHelp": false,
5055
+ "hiddenAliases": [],
5056
+ "id": "backup:restore:list",
5057
+ "pluginAlias": "@flui-cloud/cli",
5058
+ "pluginName": "@flui-cloud/cli",
5059
+ "pluginType": "core",
5060
+ "strict": true,
5061
+ "enableJsonFlag": false,
5062
+ "isESM": false,
5063
+ "relativePath": [
5064
+ "lib",
5065
+ "cli",
5066
+ "src",
5067
+ "commands",
5068
+ "backup",
5069
+ "restore",
5070
+ "list.js"
5071
+ ]
5072
+ },
5073
+ "backup:restore:preview": {
5074
+ "aliases": [],
5075
+ "args": {},
5076
+ "description": "Preview what a restore would touch (resources to be created/replaced)",
5077
+ "flags": {
5078
+ "artifact": {
5079
+ "description": "Backup artifact ID",
5080
+ "name": "artifact",
5081
+ "required": true,
5111
5082
  "hasDynamicHelp": false,
5112
5083
  "multiple": false,
5113
5084
  "type": "option"
5114
5085
  },
5115
- "force-path-style": {
5116
- "description": "Force path-style S3 URLs (needed for MinIO/some providers)",
5117
- "name": "force-path-style",
5118
- "allowNo": false,
5119
- "type": "boolean"
5120
- },
5121
- "use-sse": {
5122
- "description": "Use server-side encryption (SSE-S3) at the provider",
5123
- "name": "use-sse",
5124
- "allowNo": false,
5125
- "type": "boolean"
5126
- },
5127
- "usable-for-etcd-l1": {
5128
- "description": "Allow this destination to receive L1 etcd snapshots",
5129
- "name": "usable-for-etcd-l1",
5130
- "allowNo": false,
5131
- "type": "boolean"
5132
- },
5133
- "cost-per-gb-month-cents": {
5134
- "description": "Provider cost in cents/GB·month (used for billing estimate)",
5135
- "name": "cost-per-gb-month-cents",
5086
+ "source-destination": {
5087
+ "description": "Source destination ID (where the artifact lives)",
5088
+ "name": "source-destination",
5089
+ "required": true,
5136
5090
  "hasDynamicHelp": false,
5137
5091
  "multiple": false,
5138
5092
  "type": "option"
@@ -5140,7 +5094,7 @@
5140
5094
  },
5141
5095
  "hasDynamicHelp": false,
5142
5096
  "hiddenAliases": [],
5143
- "id": "backup:destination:create",
5097
+ "id": "backup:restore:preview",
5144
5098
  "pluginAlias": "@flui-cloud/cli",
5145
5099
  "pluginName": "@flui-cloud/cli",
5146
5100
  "pluginType": "core",
@@ -5153,32 +5107,29 @@
5153
5107
  "src",
5154
5108
  "commands",
5155
5109
  "backup",
5156
- "destination",
5157
- "create.js"
5110
+ "restore",
5111
+ "preview.js"
5158
5112
  ]
5159
5113
  },
5160
- "backup:destination:delete": {
5114
+ "backup:restore:show": {
5161
5115
  "aliases": [],
5162
5116
  "args": {
5163
5117
  "id": {
5164
- "description": "Destination ID",
5165
5118
  "name": "id",
5166
5119
  "required": true
5167
5120
  }
5168
5121
  },
5169
- "description": "Delete a backup destination",
5122
+ "description": "Show a restore job by ID",
5170
5123
  "flags": {
5171
- "yes": {
5172
- "char": "y",
5173
- "description": "Skip confirmation",
5174
- "name": "yes",
5124
+ "json": {
5125
+ "name": "json",
5175
5126
  "allowNo": false,
5176
5127
  "type": "boolean"
5177
5128
  }
5178
5129
  },
5179
5130
  "hasDynamicHelp": false,
5180
5131
  "hiddenAliases": [],
5181
- "id": "backup:destination:delete",
5132
+ "id": "backup:restore:show",
5182
5133
  "pluginAlias": "@flui-cloud/cli",
5183
5134
  "pluginName": "@flui-cloud/cli",
5184
5135
  "pluginType": "core",
@@ -5191,20 +5142,24 @@
5191
5142
  "src",
5192
5143
  "commands",
5193
5144
  "backup",
5194
- "destination",
5195
- "delete.js"
5145
+ "restore",
5146
+ "show.js"
5196
5147
  ]
5197
5148
  },
5198
- "backup:destination:list": {
5149
+ "backup:job:list": {
5199
5150
  "aliases": [],
5200
5151
  "args": {},
5201
- "description": "List backup destinations configured in the API",
5202
- "examples": [
5203
- "<%= config.bin %> <%= command.id %>"
5204
- ],
5152
+ "description": "List backup jobs for a cluster",
5205
5153
  "flags": {
5154
+ "cluster": {
5155
+ "description": "Cluster ID",
5156
+ "name": "cluster",
5157
+ "required": true,
5158
+ "hasDynamicHelp": false,
5159
+ "multiple": false,
5160
+ "type": "option"
5161
+ },
5206
5162
  "json": {
5207
- "description": "Output as JSON",
5208
5163
  "name": "json",
5209
5164
  "allowNo": false,
5210
5165
  "type": "boolean"
@@ -5212,7 +5167,7 @@
5212
5167
  },
5213
5168
  "hasDynamicHelp": false,
5214
5169
  "hiddenAliases": [],
5215
- "id": "backup:destination:list",
5170
+ "id": "backup:job:list",
5216
5171
  "pluginAlias": "@flui-cloud/cli",
5217
5172
  "pluginName": "@flui-cloud/cli",
5218
5173
  "pluginType": "core",
@@ -5225,31 +5180,27 @@
5225
5180
  "src",
5226
5181
  "commands",
5227
5182
  "backup",
5228
- "destination",
5183
+ "job",
5229
5184
  "list.js"
5230
5185
  ]
5231
5186
  },
5232
- "backup:destination:show": {
5187
+ "backup:job:run": {
5233
5188
  "aliases": [],
5234
- "args": {
5235
- "id": {
5236
- "description": "Destination ID (UUID)",
5237
- "name": "id",
5238
- "required": true
5239
- }
5240
- },
5241
- "description": "Show a backup destination by ID",
5189
+ "args": {},
5190
+ "description": "Trigger an on-demand backup job for a given policy",
5242
5191
  "flags": {
5243
- "json": {
5244
- "description": "Output as JSON",
5245
- "name": "json",
5246
- "allowNo": false,
5247
- "type": "boolean"
5192
+ "policy": {
5193
+ "description": "Policy ID",
5194
+ "name": "policy",
5195
+ "required": true,
5196
+ "hasDynamicHelp": false,
5197
+ "multiple": false,
5198
+ "type": "option"
5248
5199
  }
5249
5200
  },
5250
5201
  "hasDynamicHelp": false,
5251
5202
  "hiddenAliases": [],
5252
- "id": "backup:destination:show",
5203
+ "id": "backup:job:run",
5253
5204
  "pluginAlias": "@flui-cloud/cli",
5254
5205
  "pluginName": "@flui-cloud/cli",
5255
5206
  "pluginType": "core",
@@ -5262,24 +5213,29 @@
5262
5213
  "src",
5263
5214
  "commands",
5264
5215
  "backup",
5265
- "destination",
5266
- "show.js"
5216
+ "job",
5217
+ "run.js"
5267
5218
  ]
5268
5219
  },
5269
- "backup:destination:test": {
5220
+ "backup:job:show": {
5270
5221
  "aliases": [],
5271
5222
  "args": {
5272
5223
  "id": {
5273
- "description": "Destination ID",
5274
5224
  "name": "id",
5275
5225
  "required": true
5276
5226
  }
5277
5227
  },
5278
- "description": "Test connectivity to a backup destination (S3 PUT/GET/DELETE round-trip)",
5279
- "flags": {},
5228
+ "description": "Show a backup job by ID",
5229
+ "flags": {
5230
+ "json": {
5231
+ "name": "json",
5232
+ "allowNo": false,
5233
+ "type": "boolean"
5234
+ }
5235
+ },
5280
5236
  "hasDynamicHelp": false,
5281
5237
  "hiddenAliases": [],
5282
- "id": "backup:destination:test",
5238
+ "id": "backup:job:show",
5283
5239
  "pluginAlias": "@flui-cloud/cli",
5284
5240
  "pluginName": "@flui-cloud/cli",
5285
5241
  "pluginType": "core",
@@ -5292,8 +5248,8 @@
5292
5248
  "src",
5293
5249
  "commands",
5294
5250
  "backup",
5295
- "destination",
5296
- "test.js"
5251
+ "job",
5252
+ "show.js"
5297
5253
  ]
5298
5254
  },
5299
5255
  "integration:ghcr-pat:revoke": {
@@ -5394,75 +5350,116 @@
5394
5350
  "status.js"
5395
5351
  ]
5396
5352
  },
5397
- "backup:restore:create": {
5353
+ "backup:policy:create": {
5398
5354
  "aliases": [],
5399
5355
  "args": {},
5400
- "description": "Create a restore job",
5356
+ "description": "Create a backup policy",
5357
+ "examples": [
5358
+ "<%= config.bin %> <%= command.id %> --name daily-all --cluster <id> --scope cluster_all --schedule \"0 2 * * *\" --retention-days 14 --destination <destId>",
5359
+ "<%= config.bin %> <%= command.id %> --name app-snap --cluster <id> --scope applications --scope-namespaces ns1,ns2 --destination <destId>"
5360
+ ],
5401
5361
  "flags": {
5402
- "artifact": {
5403
- "description": "Backup artifact ID",
5404
- "name": "artifact",
5362
+ "name": {
5363
+ "name": "name",
5405
5364
  "required": true,
5406
5365
  "hasDynamicHelp": false,
5407
5366
  "multiple": false,
5408
5367
  "type": "option"
5409
5368
  },
5410
- "source-destination": {
5411
- "name": "source-destination",
5369
+ "cluster": {
5370
+ "description": "Cluster ID",
5371
+ "name": "cluster",
5412
5372
  "required": true,
5413
5373
  "hasDynamicHelp": false,
5414
5374
  "multiple": false,
5415
5375
  "type": "option"
5416
5376
  },
5417
- "target-cluster": {
5418
- "description": "Cluster to restore into",
5419
- "name": "target-cluster",
5377
+ "scope": {
5378
+ "name": "scope",
5420
5379
  "required": true,
5421
5380
  "hasDynamicHelp": false,
5422
5381
  "multiple": false,
5382
+ "options": [
5383
+ "cluster_all",
5384
+ "namespaces",
5385
+ "applications",
5386
+ "label_selector"
5387
+ ],
5423
5388
  "type": "option"
5424
5389
  },
5425
- "target-kind": {
5426
- "name": "target-kind",
5427
- "required": true,
5390
+ "scope-namespaces": {
5391
+ "description": "Comma-separated namespaces (for scope=namespaces)",
5392
+ "name": "scope-namespaces",
5393
+ "hasDynamicHelp": false,
5394
+ "multiple": false,
5395
+ "type": "option"
5396
+ },
5397
+ "scope-apps": {
5398
+ "description": "Comma-separated application IDs (for scope=applications)",
5399
+ "name": "scope-apps",
5400
+ "hasDynamicHelp": false,
5401
+ "multiple": false,
5402
+ "type": "option"
5403
+ },
5404
+ "profile": {
5405
+ "name": "profile",
5406
+ "default": "single",
5428
5407
  "hasDynamicHelp": false,
5429
5408
  "multiple": false,
5430
5409
  "options": [
5431
- "cluster",
5432
- "namespace",
5433
- "application",
5434
- "observability"
5410
+ "single",
5411
+ "mirrored",
5412
+ "custom"
5435
5413
  ],
5436
5414
  "type": "option"
5437
5415
  },
5438
- "target-namespace": {
5439
- "description": "Required when --target-kind=namespace",
5440
- "name": "target-namespace",
5416
+ "schedule": {
5417
+ "description": "Cron schedule (e.g. \"0 2 * * *\" for daily 02:00 UTC)",
5418
+ "name": "schedule",
5441
5419
  "hasDynamicHelp": false,
5442
5420
  "multiple": false,
5443
5421
  "type": "option"
5444
5422
  },
5445
- "target-app": {
5446
- "description": "Required when --target-kind=application",
5447
- "name": "target-app",
5423
+ "retention-days": {
5424
+ "name": "retention-days",
5425
+ "default": 30,
5448
5426
  "hasDynamicHelp": false,
5449
5427
  "multiple": false,
5450
5428
  "type": "option"
5451
5429
  },
5452
- "strategy": {
5453
- "name": "strategy",
5430
+ "retention-max-copies": {
5431
+ "name": "retention-max-copies",
5454
5432
  "hasDynamicHelp": false,
5455
5433
  "multiple": false,
5456
- "options": [
5457
- "velero_rebuild",
5458
- "os_snapshot"
5459
- ],
5434
+ "type": "option"
5435
+ },
5436
+ "include-pvcs": {
5437
+ "name": "include-pvcs",
5438
+ "allowNo": false,
5439
+ "type": "boolean"
5440
+ },
5441
+ "include-etcd-l1": {
5442
+ "name": "include-etcd-l1",
5443
+ "allowNo": false,
5444
+ "type": "boolean"
5445
+ },
5446
+ "enabled": {
5447
+ "name": "enabled",
5448
+ "allowNo": true,
5449
+ "type": "boolean"
5450
+ },
5451
+ "destination": {
5452
+ "description": "Destination spec: <destId>[:primary|replica[:priority]] (repeatable)",
5453
+ "name": "destination",
5454
+ "required": true,
5455
+ "hasDynamicHelp": false,
5456
+ "multiple": true,
5460
5457
  "type": "option"
5461
5458
  }
5462
5459
  },
5463
5460
  "hasDynamicHelp": false,
5464
5461
  "hiddenAliases": [],
5465
- "id": "backup:restore:create",
5462
+ "id": "backup:policy:create",
5466
5463
  "pluginAlias": "@flui-cloud/cli",
5467
5464
  "pluginName": "@flui-cloud/cli",
5468
5465
  "pluginType": "core",
@@ -5475,24 +5472,30 @@
5475
5472
  "src",
5476
5473
  "commands",
5477
5474
  "backup",
5478
- "restore",
5475
+ "policy",
5479
5476
  "create.js"
5480
5477
  ]
5481
5478
  },
5482
- "backup:restore:list": {
5479
+ "backup:policy:delete": {
5483
5480
  "aliases": [],
5484
- "args": {},
5485
- "description": "List restore jobs",
5481
+ "args": {
5482
+ "id": {
5483
+ "name": "id",
5484
+ "required": true
5485
+ }
5486
+ },
5487
+ "description": "Delete a backup policy (existing artifacts are retained)",
5486
5488
  "flags": {
5487
- "json": {
5488
- "name": "json",
5489
+ "yes": {
5490
+ "char": "y",
5491
+ "name": "yes",
5489
5492
  "allowNo": false,
5490
5493
  "type": "boolean"
5491
5494
  }
5492
5495
  },
5493
5496
  "hasDynamicHelp": false,
5494
5497
  "hiddenAliases": [],
5495
- "id": "backup:restore:list",
5498
+ "id": "backup:policy:delete",
5496
5499
  "pluginAlias": "@flui-cloud/cli",
5497
5500
  "pluginName": "@flui-cloud/cli",
5498
5501
  "pluginType": "core",
@@ -5505,35 +5508,31 @@
5505
5508
  "src",
5506
5509
  "commands",
5507
5510
  "backup",
5508
- "restore",
5509
- "list.js"
5511
+ "policy",
5512
+ "delete.js"
5510
5513
  ]
5511
5514
  },
5512
- "backup:restore:preview": {
5515
+ "backup:policy:list": {
5513
5516
  "aliases": [],
5514
5517
  "args": {},
5515
- "description": "Preview what a restore would touch (resources to be created/replaced)",
5518
+ "description": "List backup policies",
5516
5519
  "flags": {
5517
- "artifact": {
5518
- "description": "Backup artifact ID",
5519
- "name": "artifact",
5520
- "required": true,
5520
+ "cluster": {
5521
+ "description": "Filter by cluster ID",
5522
+ "name": "cluster",
5521
5523
  "hasDynamicHelp": false,
5522
5524
  "multiple": false,
5523
5525
  "type": "option"
5524
5526
  },
5525
- "source-destination": {
5526
- "description": "Source destination ID (where the artifact lives)",
5527
- "name": "source-destination",
5528
- "required": true,
5529
- "hasDynamicHelp": false,
5530
- "multiple": false,
5531
- "type": "option"
5527
+ "json": {
5528
+ "name": "json",
5529
+ "allowNo": false,
5530
+ "type": "boolean"
5532
5531
  }
5533
5532
  },
5534
5533
  "hasDynamicHelp": false,
5535
5534
  "hiddenAliases": [],
5536
- "id": "backup:restore:preview",
5535
+ "id": "backup:policy:list",
5537
5536
  "pluginAlias": "@flui-cloud/cli",
5538
5537
  "pluginName": "@flui-cloud/cli",
5539
5538
  "pluginType": "core",
@@ -5546,19 +5545,20 @@
5546
5545
  "src",
5547
5546
  "commands",
5548
5547
  "backup",
5549
- "restore",
5550
- "preview.js"
5548
+ "policy",
5549
+ "list.js"
5551
5550
  ]
5552
5551
  },
5553
- "backup:restore:show": {
5552
+ "backup:policy:show": {
5554
5553
  "aliases": [],
5555
5554
  "args": {
5556
5555
  "id": {
5556
+ "description": "Policy ID",
5557
5557
  "name": "id",
5558
5558
  "required": true
5559
5559
  }
5560
5560
  },
5561
- "description": "Show a restore job by ID",
5561
+ "description": "Show a backup policy by ID",
5562
5562
  "flags": {
5563
5563
  "json": {
5564
5564
  "name": "json",
@@ -5568,7 +5568,7 @@
5568
5568
  },
5569
5569
  "hasDynamicHelp": false,
5570
5570
  "hiddenAliases": [],
5571
- "id": "backup:restore:show",
5571
+ "id": "backup:policy:show",
5572
5572
  "pluginAlias": "@flui-cloud/cli",
5573
5573
  "pluginName": "@flui-cloud/cli",
5574
5574
  "pluginType": "core",
@@ -5581,10 +5581,10 @@
5581
5581
  "src",
5582
5582
  "commands",
5583
5583
  "backup",
5584
- "restore",
5584
+ "policy",
5585
5585
  "show.js"
5586
5586
  ]
5587
5587
  }
5588
5588
  },
5589
- "version": "0.1.0"
5589
+ "version": "0.2.0"
5590
5590
  }