diff --git a/.gitignore b/.gitignore index 801c9ce..f33879e 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,5 @@ dist/ openapi/ .DS_Store .vscode -.idea \ No newline at end of file +.idea +rechnung* diff --git a/bats/create_role.bats b/bats/create_role.bats index 51a47ec..28bae26 100644 --- a/bats/create_role.bats +++ b/bats/create_role.bats @@ -15,42 +15,171 @@ function teardown_file() { } -@test "create role api permission: ok" { - run ./cntb create role apiPermission --name="foo${TEST_SUFFIX}" --apiPermission='[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' +@test "create role without resources : ok" { + run ./cntb create role --name "foo${TEST_SUFFIX}" --permissions '[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' assert_success roleId="$output" + run ./cntb get role $roleId -o yaml + assert_success + assert_output --partial 'admin: false' + assert_output --partial 'accessAllResources: false' + + # clean up + run ./cntb delete role "${roleId}" + assert_success +} + +@test "create role with admin : ok" { + run ./cntb create role --name "foo${TEST_SUFFIX}" --admin + assert_success + roleId="$output" + + run ./cntb get role $roleId -o yaml + assert_success + assert_output --partial 'admin: true' + + # clean up + run ./cntb delete role "${roleId}" + assert_success +} + +@test "create role with accessAllResources : ok" { + run ./cntb create role --name "foo${TEST_SUFFIX}" -p '[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' --accessAllResources + assert_success + roleId="$output" + + run ./cntb get role $roleId -o yaml + assert_success + assert_output --partial 'accessAllResources: true' + # clean up - run ./cntb delete role apiPermission "${roleId}" + run ./cntb delete role "${roleId}" assert_success } -@test "create role wrong permission type: nok" { - run ./cntb create role aa --name="foo${TEST_SUFFIX}" --apiPermission='[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' +@test "create role without resources short flags : ok" { + run ./cntb create role -n "foo${TEST_SUFFIX}" -p '[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' + assert_success + roleId="$output" + + # clean up + run ./cntb delete role "${roleId}" + assert_success +} + +@test "create role without resources multiple endpoints : ok" { + run ./cntb create role --name "foo${TEST_SUFFIX}" --permissions '[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}, {"apiName":"/v1/tags","actions":["READ"]}]' + assert_success + roleId="$output" + + # clean up + run ./cntb delete role "${roleId}" + assert_success +} + +@test "create role with resources : ok" { + run ./cntb create tag --name "foo${TEST_SUFFIX}" + assert_success + tagid="$output" + + run ./cntb create role --name "foo${TEST_SUFFIX}" --permissions "[{\"apiName\" : \"/v1/users\", \"actions\": [\"READ\", \"CREATE\"], \"resources\": [$tagid]}]" + assert_success + roleId="$output" + + # clean up + run ./cntb delete role "${roleId}" + assert_success +} + +@test "create role with resources multiple endpoints : ok" { + run ./cntb create tag --name "foo${TEST_SUFFIX}" + assert_success + tagid="$output" + + run ./cntb create role --name "foo${TEST_SUFFIX}" --permissions "[{\"apiName\" : \"/v1/users\", \"actions\": [\"READ\", \"CREATE\"], \"resources\": [$tagid]}, {\"apiName\":\"/v1/tags\",\"actions\":[\"READ\"], \"resources\": [$tagid]}]" + assert_success + roleId="$output" + + # clean up + run ./cntb delete role "${roleId}" + assert_success +} + + +@test "create role with resources multiple endpoints only one with tag : ok" { + run ./cntb create tag --name "foo${TEST_SUFFIX}" + assert_success + tagid="$output" + + run ./cntb create role --name "foo${TEST_SUFFIX}" --permissions "[{\"apiName\" : \"/v1/users\", \"actions\": [\"READ\", \"CREATE\"], \"resources\": [$tagid]},{\"apiName\":\"/v1/tags\",\"actions\":[\"READ\"]}]" + assert_success + roleId="$output" + + run ./cntb get role $roleId -o yaml + assert_success + assert_output --partial 'admin: false' + assert_output --partial 'accessAllResources: false' + + # clean up + run ./cntb delete role "${roleId}" + assert_success +} + +@test "create role with foreign tagId : nok : check error" { + run ./cntb create --name "foo${TEST_SUFFIX}" role --permissions '[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"], "resources": [0]}]' + assert_failure + assert_output --partial 'not found' + assert_output --partial '404' +} + +@test "create role without name : nok" { + run ./cntb create role --permissions '[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' assert_failure } -@test "create role wrong number of inputs: nok" { - run ./cntb create role --name="foo${TEST_SUFFIX}" --apiPermission='[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' +@test "create role without permissions : nok" { + run ./cntb create role --name="foo${TEST_SUFFIX}" assert_failure +} - run .run ./cntb create role apiPermission apiPermission --name="foo${TEST_SUFFIX}" --apiPermission='[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' +@test "create role without name and permissions: nok" { + run ./cntb create role + assert_failure +} + +@test "create role with wrong action in permissions : nok" { + run ./cntb create role -n foo${TEST_SUFFIX} --permissions '[{"apiName": "/v1/tags", "actions": ["UNKNOWN"]}]' + assert_failure +} + +@test "create role with unknown api endpoint : nok" { + run ./cntb create role -n foo${TEST_SUFFIX} --permissions '[{"apiName": "/unkown/api/endpoint", "actions": ["CREATE"]}]' + assert_failure +} + +@test "create role with wrong JSON permissions : nok" { + run ./cntb create role -n foo${TEST_SUFFIX} --permissions '["apiName": "/unkown/api/endpoint", "actions": ["CREATE"]}]' assert_failure } wrapperCreateApiPermissionFile() { - echo "$1" | ./cntb create role apiPermission -f - + echo "$1" | ./cntb create role -f - } -@test "create from file api permission: ok" { - run wrapperCreateApiPermissionFile '{"name": "foo", "apiPermissions": [{"apiName": "/v1/users", "actions": ["READ", "CREATE"]}]}' +@test "create from file api permission : ok" { + run wrapperCreateApiPermissionFile '{"name": "foo", "permissions": [{"apiName": "/v1/users", "actions": ["READ", "CREATE"], "resources": []}]}' assert_success roleId="$output" # clean up - run ./cntb delete role apiPermission "$roleId" + run ./cntb delete role "$roleId" assert_success } +@test "create from file missing name : nok" { + run wrapperCreateApiPermissionFile '{"permissions": [{"apiName": "/v1/users", "actions": ["READ", "CREATE"]}]}' + assert_failure +} diff --git a/bats/create_user.bats b/bats/create_user.bats index 6f590b5..8d810c7 100644 --- a/bats/create_user.bats +++ b/bats/create_user.bats @@ -14,12 +14,12 @@ function teardown_file() { restore_config_files } @test "create user normal: ok" { - run ./cntb create role apiPermission --name="foo${TEST_SUFFIX}" --apiPermission='[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' + run ./cntb create role -n "foo${TEST_SUFFIX}" -p '[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' assert_success roleId="$output" - run ./cntb create user --firstName="foo${TEST_SUFFIX}" --lastName="bar${TEST_SUFFIX}" --email="testuser${TEST_SUFFIX}@contabo.com" --enabled=true --admin=true --accessAllResources=true --roles="$roleId" + run ./cntb create user --firstName="foo${TEST_SUFFIX}" --lastName="bar${TEST_SUFFIX}" --email="testuser${TEST_SUFFIX}@contabo.com" --enabled=true --roles="$roleId" --locale de assert_success userId="$output" @@ -27,44 +27,73 @@ function teardown_file() { #clean up run ./cntb delete user "$userId" assert_success - run ./cntb delete role apiPermission "$roleId" + run ./cntb delete role "$roleId" assert_success } @test "create user duplicate: nok" { - run ./cntb create role apiPermission --name="foo${TEST_SUFFIX}" --apiPermission='[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' + run ./cntb create role -n "foo${TEST_SUFFIX}" -p '[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' assert_success roleId="$output" - run ./cntb create user --firstName="foo${TEST_SUFFIX}" --lastName="bar${TEST_SUFFIX}" --email="testuser${TEST_SUFFIX}@contabo.com" --enabled=true --admin=true --accessAllResources=true --roles="$roleId" + run ./cntb create user --firstName="foo${TEST_SUFFIX}" --lastName="bar${TEST_SUFFIX}" --email="testuser${TEST_SUFFIX}@contabo.com" --enabled=true --roles="$roleId" --locale de assert_success userId="$output" - run ./cntb create user --firstName="foo${TEST_SUFFIX}" --lastName="bar${TEST_SUFFIX}" --email="testuser${TEST_SUFFIX}@contabo.com" --enabled=true --admin=true --accessAllResources=true --roles="$roleId" + run ./cntb create user --firstName="foo${TEST_SUFFIX}" --lastName="bar${TEST_SUFFIX}" --email="testuser${TEST_SUFFIX}@contabo.com" --enabled=true --roles="$roleId" --locale de assert_failure #clean up run ./cntb delete user "$userId" assert_success - run ./cntb delete role apiPermission "$roleId" + run ./cntb delete role "$roleId" assert_success } @test "create user missing e-mail: nok" { - run ./cntb create user --firstName="foo${TEST_SUFFIX}" --lastName="bar${TEST_SUFFIX}" --enabled=true --admin=true --accessAllResources=true --roles="$roleId" + run ./cntb create user --firstName="foo${TEST_SUFFIX}" --lastName="bar${TEST_SUFFIX}" --enabled=true --roles="$roleId" --locale de assert_failure + export CNTB_FIRSTNAME="foo${TEST_SUFFIX}" + export CNTB_LASTNAME="bar${TEST_SUFFIX}" + export CNTB_ENABLED=true + export CNTB_LOCALE=de + + run ./cntb create user + assert_failure + + unset CNTB_FIRSTNAME CNTB_LASTNAME CNTB_ENABLED CNTB_LOCALE } @test "create user missing firstName: nok" { - run ./cntb create user --lastName="bar${TEST_SUFFIX}" --email="testuser${TEST_SUFFIX}@contabo.com" --enabled=true --admin=true --accessAllResources=true --roles="$roleId" + run ./cntb create user --lastName="bar${TEST_SUFFIX}" --email="testuser${TEST_SUFFIX}@contabo.com" --enabled=true --roles="$roleId" --locale de + assert_failure + + export CNTB_LASTNAME="bar${TEST_SUFFIX}" + export CNTB_ENABLED=true + export CNTB_LOCALE=de + export CNTB_EMAIL="testuser${TEST_SUFFIX}@contabo.com" + + run ./cntb create user assert_failure + + unset CNTB_EMAIL CNTB_LASTNAME CNTB_ENABLED CNTB_LOCALE } @test "create user missing lastName: nok" { - run ./cntb create user --firstName="foo${TEST_SUFFIX}" --email="testuser${TEST_SUFFIX}@contabo.com" --enabled=true --admin=true --accessAllResources=true --roles="$roleId" + run ./cntb create user --firstName="foo${TEST_SUFFIX}" --email="testuser${TEST_SUFFIX}@contabo.com" --enabled=true --roles="$roleId" --locale de assert_failure + + export CNTB_FIRSTNAME="foo${TEST_SUFFIX}" + export CNTB_ENABLED=true + export CNTB_LOCALE=de + export CNTB_EMAIL="testuser${TEST_SUFFIX}@contabo.com" + + run ./cntb create user + assert_failure + + unset CNTB_FIRSTNAME CNTB_EMAIL CNTB_ENABLED CNTB_LOCALE } diff --git a/bats/delete_role.bats b/bats/delete_role.bats index 0cbd718..2bc8636 100644 --- a/bats/delete_role.bats +++ b/bats/delete_role.bats @@ -14,41 +14,42 @@ function teardown_file() { restore_config_files } -@test "delete role ok:" { - run ./cntb create role apiPermission --name="foo${TEST_SUFFIX}" --apiPermission='[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' +@test "delete role : ok" { + run ./cntb create role --name "foo${TEST_SUFFIX}" --permissions '[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' assert_success roleId="$output" - run ./cntb delete role apiPermission "$roleId" + run ./cntb get role "$roleId" assert_success + run ./cntb delete role "$roleId" + assert_success - run ./cntb get role apiPermission "$roleId" + run ./cntb get role "$roleId" assert_failure } -@test "delete not existing role" { - run ./cntb delete role apiPermission 0 +@test "delete not existing role : nok" { + run ./cntb delete role 0 assert_failure assert_output --partial "Error while deleting role: 404 - Entry Role not found by roleId" } -@test "use wrong permission type: nok" { - run ./cntb delete role akdslfj 0 - assert_failure -} - -@test "use only 1 input: nok" { - run ./cntb delete role apiPermission +@test "delete without roleId : nok" { + run ./cntb delete role assert_failure } -@test "user more than 2 inputs: nok" { - run ./cntb delete role apiPermission 2 apiPermission +@test "delete with role type and roleId : nok" { + run ./cntb delete role apiPermission 2 + assert_failure +} +@test "delete with roleId and role type : nok" { + run ./cntb delete role 2 apiPermission assert_failure } -@test "user string instead of number for role id" { - run ./cntb delete role apiPermission test +@test "user string instead of number for role id : nok" { + run ./cntb delete role twelve assert_failure } diff --git a/bats/delete_user.bats b/bats/delete_user.bats index ce8de18..931be31 100644 --- a/bats/delete_user.bats +++ b/bats/delete_user.bats @@ -15,11 +15,11 @@ function teardown_file() { } @test "delete user ok" { - run ./cntb create role apiPermission --name="foo${TEST_SUFFIX}" --apiPermission='[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' + run ./cntb create role -n "foo${TEST_SUFFIX}" -p '[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' assert_success roleId="$output" - run ./cntb create user --firstName="foo${TEST_SUFFIX}" --lastName="bar${TEST_SUFFIX}" --email="testuser${TEST_SUFFIX}@contabo.com" --enabled=true --admin=true --accessAllResources=true --roles="$roleId" + run ./cntb create user --firstName="foo${TEST_SUFFIX}" --lastName="bar${TEST_SUFFIX}" --email="testuser${TEST_SUFFIX}@contabo.com" --enabled=true --roles="$roleId" --locale de assert_success userId="$output" @@ -27,7 +27,7 @@ function teardown_file() { assert_success #cleanup - run ./cntb delete role apiPermission "${roleId}" + run ./cntb delete role "${roleId}" assert_success } diff --git a/bats/get_permissions.bats b/bats/get_permissions.bats new file mode 100644 index 0000000..d3aa5f5 --- /dev/null +++ b/bats/get_permissions.bats @@ -0,0 +1,39 @@ +#!/usr/bin/env bats + +load handling_conf_files.bash +load globals.bash +load_lib bats-support +load_lib bats-assert + +function setup_file() { + store_config_files + ensureTestConfig + deleteCache +} + +function teardown_file() { + restore_config_files +} + +@test "get permissions with different outputs" { + run ./cntb get permissions + assert_success + + assert_output --partial 'APINAME' + assert_output --partial 'ACTIONS' + + run ./cntb get permissions -o wide + assert_success + assert_output --partial 'APINAME' + assert_output --partial 'ACTIONS' + + run ./cntb get permissions -o json + assert_success + assert_output --partial 'apiName' + assert_output --partial 'actions' + + run ./cntb get permissions -o yaml + assert_success + assert_output --partial 'apiName:' + assert_output --partial 'actions:' +} \ No newline at end of file diff --git a/bats/get_role.bats b/bats/get_role.bats index b33539b..fc64a65 100644 --- a/bats/get_role.bats +++ b/bats/get_role.bats @@ -16,54 +16,64 @@ function teardown_file() { } -@test "get api permission role with different outputs" { - run ./cntb create role apiPermission --name="foo${TEST_SUFFIX}" --apiPermission='[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' +@test "get api permission role with different outputs : ok" { + run ./cntb create role -n "foo${TEST_SUFFIX}" -p '[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' assert_success roleId="$output" - run ./cntb get role apiPermission "$roleId" + run ./cntb get role "$roleId" assert_success assert_output --partial 'ROLEID' assert_output --partial 'NAME' assert_output --partial "${roleId}" - run ./cntb get role apiPermission "$roleId" -o wide + run ./cntb get role "$roleId" -o wide assert_success assert_output --partial 'ROLEID' assert_output --partial 'NAME' + assert_output --partial 'ADMIN' + assert_output --partial 'ACCESSALLRESOURCES' assert_output --partial "${roleId}" - run ./cntb get role apiPermission "$roleId" -o json + run ./cntb get role "$roleId" -o json assert_success assert_output --partial 'roleId' assert_output --partial 'name' - assert_output --partial 'apiPermissions' + assert_output --partial 'admin' + assert_output --partial 'accessAllResources' + assert_output --partial 'permissions' assert_output --partial 'apiName' - run ./cntb get role apiPermission "$roleId" -o yaml + run ./cntb get role "$roleId" -o yaml assert_success assert_output --partial 'roleId:' assert_output --partial 'name:' - assert_output --partial 'apiPermissions:' + assert_output --partial 'admin:' + assert_output --partial 'accessAllResources:' + assert_output --partial 'permissions:' assert_output --partial 'apiName:' + # clean up - run ./cntb delete role apiPermission "${roleId}" + run ./cntb delete role "${roleId}" assert_success } -@test "get role wrong permission type: nok" { - run ./cntb get role aa 1 - assert_failure -} +@test "get role with wrong flags : nok" { + run ./cntb create role -n "foo${TEST_SUFFIX}" -p '[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' + assert_success + roleId="$output" -@test "create role wrong number of inputs: nok" { - run ./cntb get role - assert_failure + run ./cntb get role + assert_failure - run .run ./cntb create role apiPermission apiPermission - assert_failure + run ./cntb get role resourcePermission $roleId + assert_failure - run .run ./cntb create role apiPermission apiPermission - assert_failure -} \ No newline at end of file + run ./cntb get role $roleId apiPermission + assert_failure + + # clean up + run ./cntb delete role "${roleId}" + assert_success +} diff --git a/bats/get_roles.bats b/bats/get_roles.bats index cd644b6..a340d3a 100644 --- a/bats/get_roles.bats +++ b/bats/get_roles.bats @@ -17,35 +17,43 @@ function teardown_file() { @test "get roles: normal ok" { - run ./cntb create role apiPermission --name="foo${TEST_SUFFIX}" --apiPermission='[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' + run ./cntb create role -n "foo${TEST_SUFFIX}" -p '[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' assert_success roleId="$output" - run ./cntb get role apiPermission "$roleId" + run ./cntb get roles assert_success assert_output --partial 'ROLEID' assert_output --partial 'NAME' assert_output --partial "${roleId}" - run ./cntb get roles apiPermission -o wide + run ./cntb get roles -o wide assert_success assert_output --partial 'ROLEID' assert_output --partial 'NAME' + assert_output --partial 'PERMISSIONS' + assert_output --partial 'ADMIN' + assert_output --partial 'ACCESSALLRESOURCES' - # clean uo - run ./cntb delete role apiPermission "$roleId" -} + run ./cntb get roles -o json + assert_success + assert_output --partial 'roleId' + assert_output --partial 'name' + assert_output --partial 'admin' + assert_output --partial 'accessAllResources' + assert_output --partial 'permissions' + assert_output --partial 'apiName' + + run ./cntb get roles -o yaml + assert_success + assert_output --partial 'roleId:' + assert_output --partial 'name:' + assert_output --partial 'admin:' + assert_output --partial 'accessAllResources:' + assert_output --partial 'permissions:' + assert_output --partial 'apiName:' -@test "get role wrong permission type: nok" { - run ./cntb get roles aa - assert_failure + # clean uo + run ./cntb delete role "$roleId" } - -@test "create role wrong number of inputs: nok" { - run ./cntb get role - assert_failure - - run .run ./cntb create role apiPermission apiPermission - assert_failure -} \ No newline at end of file diff --git a/bats/get_tag.bats b/bats/get_tag.bats index eabefe1..793b6db 100644 --- a/bats/get_tag.bats +++ b/bats/get_tag.bats @@ -58,6 +58,10 @@ function teardown_file() { assert_success } +@test 'get tag : ok : environment variables' { + +} + @test 'get tag: nok : non existing tag' { run ./cntb get tag 0 assert_failure diff --git a/bats/get_user.bats b/bats/get_user.bats index b483612..a1b934f 100644 --- a/bats/get_user.bats +++ b/bats/get_user.bats @@ -16,12 +16,12 @@ function teardown_file() { } @test "get user multiple output: ok" { - run ./cntb create role apiPermission --name="foo${TEST_SUFFIX}" --apiPermission='[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' + run ./cntb create role -n "foo${TEST_SUFFIX}" -p '[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' assert_success roleId="$output" - run ./cntb create user --firstName="foo${TEST_SUFFIX}" --lastName="bar${TEST_SUFFIX}" --email="testuser${TEST_SUFFIX}@contabo.com" --enabled=true --admin=true --accessAllResources=true --roles="$roleId" + run ./cntb create user --firstName="foo${TEST_SUFFIX}" --lastName="bar${TEST_SUFFIX}" --email="testuser${TEST_SUFFIX}@contabo.com" --enabled=true --roles="$roleId" --locale de assert_success userId="$output" @@ -43,7 +43,6 @@ function teardown_file() { assert_output --partial "EMAIL" assert_output --partial "ENABLED" assert_output --partial "TOTP" - assert_output --partial "ADMIN" run ./cntb get user "$userId" -o json assert_success @@ -53,7 +52,6 @@ function teardown_file() { assert_output --partial '"email"' assert_output --partial '"enabled"' assert_output --partial '"totp"' - assert_output --partial '"admin"' assert_output --partial '"roles"' run ./cntb get user "$userId" -o yaml @@ -64,12 +62,12 @@ function teardown_file() { assert_output --partial 'email:' assert_output --partial 'enabled:' assert_output --partial 'totp:' - assert_output --partial 'admin:' assert_output --partial 'roles:' - #clean up + + # clean up run ./cntb delete user "$userId" assert_success - run ./cntb delete role apiPermission "$roleId" + run ./cntb delete role "$roleId" assert_success } diff --git a/bats/get_users.bats b/bats/get_users.bats index 38e6ed8..1e3282d 100644 --- a/bats/get_users.bats +++ b/bats/get_users.bats @@ -16,16 +16,16 @@ function teardown_file() { } @test "get users : ok" { - run ./cntb create role apiPermission --name="foo${TEST_SUFFIX}" --apiPermission='[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' + run ./cntb create role -n "foo${TEST_SUFFIX}" -p '[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' assert_success roleId="$output" - run ./cntb create user --firstName="foo${TEST_SUFFIX}" --lastName="bar${TEST_SUFFIX}" --email="testuser${TEST_SUFFIX}@contabo.com" --enabled=true --admin=true --accessAllResources=true --roles="$roleId" + run ./cntb create user --firstName="foo${TEST_SUFFIX}" --lastName="bar${TEST_SUFFIX}" --email="testuser${TEST_SUFFIX}@contabo.com" --enabled=true --roles="$roleId" --locale de assert_success userId="$output" - run ./cntb create user --firstName="bar${TEST_SUFFIX}" --lastName="bar${TEST_SUFFIX}" --email="testuser2${TEST_SUFFIX}@contabo.com" --enabled=true --admin=true --accessAllResources=true --roles="$roleId" + run ./cntb create user --firstName="bar${TEST_SUFFIX}" --lastName="bar${TEST_SUFFIX}" --email="testuser2${TEST_SUFFIX}@contabo.com" --enabled=true --roles="$roleId" --locale de assert_success userId2="$output" @@ -39,27 +39,26 @@ function teardown_file() { assert_output --partial "$userId" assert_output --partial "$userId2" - #clean up + # clean up run ./cntb delete user "$userId" assert_success run ./cntb delete user "$userId2" assert_success - run ./cntb delete role apiPermission "$roleId" + run ./cntb delete role "$roleId" assert_success } @test "get users filter email: ok" { - - run ./cntb create role apiPermission --name="foo${TEST_SUFFIX}" --apiPermission='[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' + run ./cntb create role -n "foo${TEST_SUFFIX}" -p '[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' assert_success roleId="$output" - run ./cntb create user --firstName="foo${TEST_SUFFIX}" --lastName="bar${TEST_SUFFIX}" --email="testuser${TEST_SUFFIX}@contabo.com" --enabled=true --admin=true --accessAllResources=true --roles="$roleId" + run ./cntb create user --firstName="foo${TEST_SUFFIX}" --lastName="bar${TEST_SUFFIX}" --email="testuser${TEST_SUFFIX}@contabo.com" --enabled=true --roles="$roleId" --locale de assert_success userId="$output" - run ./cntb create user --firstName="bar${TEST_SUFFIX}" --lastName="barbar${TEST_SUFFIX}" --email="testuser2${TEST_SUFFIX}@contabo.com" --enabled=true --admin=true --accessAllResources=true --roles="$roleId" + run ./cntb create user --firstName="bar${TEST_SUFFIX}" --lastName="barbar${TEST_SUFFIX}" --email="testuser2${TEST_SUFFIX}@contabo.com" --enabled=true --roles="$roleId" --locale de assert_success userId2="$output" @@ -68,11 +67,11 @@ function teardown_file() { assert_output --partial "testuser2${TEST_SUFFIX}" - #clean up + # clean up run ./cntb delete user "$userId" assert_success run ./cntb delete user "$userId2" assert_success - run ./cntb delete role apiPermission "$roleId" + run ./cntb delete role "$roleId" assert_success } \ No newline at end of file diff --git a/bats/globals.bash b/bats/globals.bash index e987013..84f49df 100644 --- a/bats/globals.bash +++ b/bats/globals.bash @@ -1,9 +1,10 @@ #!/bin/bash -CURRENTEPOCTIME=`date +%s` +CURRENTEPOCTIME=`date +%s%N` +CURRENTEPOCTIME_SECONDS=`date +%s` USER_ID="${OAUTH2_USER_ID:-3e97f2b0-eccd-497b-8516-79a6708a9cf4}" TEST_SUFFIX="$CURRENTEPOCTIME-integration-cli" -IMAGE_DOWNLOAD_URL="https://dl-cdn.alpinelinux.org/alpine/v3.13/releases/s390x/alpine-standard-3.13.5-s390x.iso" +IMAGE_DOWNLOAD_URL='https://dl-cdn.alpinelinux.org/alpine/v3.13/releases/s390x/alpine-standard-3.13.5-s390x.iso' INSTANCE_ID=100 REINSTALL_INSTANCE_ID=105 STANDARD_IMAGE_ID="db1409d2-ed92-4f2f-978e-7b2fa4a1ec90" diff --git a/bats/history_role.bats b/bats/history_role.bats index d8c506a..8dda9cd 100644 --- a/bats/history_role.bats +++ b/bats/history_role.bats @@ -17,7 +17,7 @@ function teardown_file() { @test "get role history: normal ok" { - run ./cntb create role apiPermission --name="foo${TEST_SUFFIX}" --apiPermission='[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' + run ./cntb create role -n "foo${TEST_SUFFIX}" -p '[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' assert_success roleId="$output" @@ -30,14 +30,13 @@ function teardown_file() { assert_output --partial 'USERNAME' assert_output --partial 'TIMESTAMP' - #clean up - run ./cntb delete role apiPermission "$roleId" + # clean up + run ./cntb delete role "$roleId" assert_success } @test "get role wide: ok" { - - run ./cntb create role apiPermission --name="foo${TEST_SUFFIX}" --apiPermission='[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' + run ./cntb create role -n "foo${TEST_SUFFIX}" -p '[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' assert_success roleId="$output" @@ -55,8 +54,7 @@ function teardown_file() { assert_output --partial 'TIMESTAMP' assert_output --partial 'CHANGED' - #clean up - run ./cntb delete role apiPermission "$roleId" + # clean up + run ./cntb delete role "$roleId" assert_success - } \ No newline at end of file diff --git a/bats/history_user.bats b/bats/history_user.bats index 6920fd4..5138f0f 100644 --- a/bats/history_user.bats +++ b/bats/history_user.bats @@ -16,12 +16,12 @@ function teardown_file() { } @test "get user history: normal ok" { - run ./cntb create role apiPermission --name="foo${TEST_SUFFIX}" --apiPermission='[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' + run ./cntb create role -n "foo${TEST_SUFFIX}" -p '[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' assert_success roleId="$output" - run ./cntb create user --firstName="foo${TEST_SUFFIX}" --lastName="bar${TEST_SUFFIX}" --email="testuser${TEST_SUFFIX}@contabo.com" --enabled=true --admin=true --accessAllResources=true --roles="$roleId" + run ./cntb create user --firstName="foo${TEST_SUFFIX}" --lastName="bar${TEST_SUFFIX}" --email="testuser${TEST_SUFFIX}@contabo.com" --enabled=true --locale de --roles="$roleId" assert_success userId="$output" @@ -36,18 +36,17 @@ function teardown_file() { #clean up run ./cntb delete user "$userId" assert_success - run ./cntb delete role apiPermission "$roleId" + run ./cntb delete role "$roleId" assert_success } @test "get user wide: ok" { - - run ./cntb create role apiPermission --name="foo${TEST_SUFFIX}" --apiPermission='[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' + run ./cntb create role -n "foo${TEST_SUFFIX}" -p '[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' assert_success roleId="$output" - run ./cntb create user --firstName="foo${TEST_SUFFIX}" --lastName="bar${TEST_SUFFIX}" --email="testuser${TEST_SUFFIX}@contabo.com" --enabled=true --admin=true --accessAllResources=true --roles="$roleId" + run ./cntb create user --firstName="foo${TEST_SUFFIX}" --lastName="bar${TEST_SUFFIX}" --email="testuser${TEST_SUFFIX}@contabo.com" --enabled=true --locale de --roles="$roleId" assert_success userId="$output" @@ -68,7 +67,7 @@ function teardown_file() { #clean up run ./cntb delete user "$userId" assert_success - run ./cntb delete role apiPermission "$roleId" + run ./cntb delete role "$roleId" assert_success } \ No newline at end of file diff --git a/bats/reinstall_instance.bats b/bats/reinstall_instance.bats index 6e935b7..6dbc6ff 100644 --- a/bats/reinstall_instance.bats +++ b/bats/reinstall_instance.bats @@ -34,7 +34,7 @@ function teardown_file() { fi } -@test "reinstall instance wrong instance id type: nok" { +@test "reinstall instance wrong instance id type : nok" { run ./cntb reinstall instance abc --imageId="${STANDARD_IMAGE_ID}" assert_failure } @@ -44,14 +44,7 @@ function teardown_file() { assert_failure } -@test 'reinstall instance without image id: ok' { +@test 'reinstall instance without image id : nok' { run ./cntb reinstall instance "${REINSTALL_INSTANCE_ID}" - assert_success - - poll_instance "${REINSTALL_INSTANCE_ID}" - - if [ $? -ne 0 ]; then - run test - assert_success - fi + assert_failure } diff --git a/bats/resend_email_verification_user.bats b/bats/resend_email_verification_user.bats index e68839c..19f4cc4 100644 --- a/bats/resend_email_verification_user.bats +++ b/bats/resend_email_verification_user.bats @@ -19,12 +19,12 @@ function teardown_file() { ### @test 'resend email verification : ok' { - run ./cntb create role apiPermission --name="foo${TEST_SUFFIX}" --apiPermission='[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' + run ./cntb create role -n "foo${TEST_SUFFIX}" -p '[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' assert_success roleId="$output" - run ./cntb create user --firstName="foo${TEST_SUFFIX}" --lastName="bar${TEST_SUFFIX}" --email="testuser${TEST_SUFFIX}@contabo.com" --enabled=true --admin=true --accessAllResources=true --roles="$roleId" + run ./cntb create user --firstName="foo${TEST_SUFFIX}" --lastName="bar${TEST_SUFFIX}" --email="testuser${TEST_SUFFIX}@contabo.com" --enabled=true --locale de --roles="$roleId" assert_success userId="$output" @@ -34,7 +34,7 @@ function teardown_file() { #clean up run ./cntb delete user "$userId" assert_success - run ./cntb delete role apiPermission "$roleId" + run ./cntb delete role "$roleId" assert_success } diff --git a/bats/reset_user_password.bats b/bats/reset_user_password.bats index f33b297..555c7fb 100644 --- a/bats/reset_user_password.bats +++ b/bats/reset_user_password.bats @@ -19,12 +19,12 @@ function teardown_file() { ### @test 'reset password : ok' { - run ./cntb create role apiPermission --name="foo${TEST_SUFFIX}" --apiPermission='[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' + run ./cntb create role -n "foo${TEST_SUFFIX}" -p '[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' assert_success roleId="$output" - run ./cntb create user --firstName="foo${TEST_SUFFIX}" --lastName="bar${TEST_SUFFIX}" --email="testuser${TEST_SUFFIX}@contabo.com" --enabled=true --admin=true --accessAllResources=true --roles="$roleId" + run ./cntb create user --firstName="foo${TEST_SUFFIX}" --lastName="bar${TEST_SUFFIX}" --email="testuser${TEST_SUFFIX}@contabo.com" --enabled=true --locale de --roles="$roleId" assert_success userId="$output" @@ -34,7 +34,7 @@ function teardown_file() { #clean up run ./cntb delete user "$userId" assert_success - run ./cntb delete role apiPermission "$roleId" + run ./cntb delete role "$roleId" assert_success } diff --git a/bats/update_role.bats b/bats/update_role.bats index 928d627..c742cfc 100644 --- a/bats/update_role.bats +++ b/bats/update_role.bats @@ -15,35 +15,51 @@ function teardown_file() { } -@test "update role: ok : set different action to api" { - run ./cntb create role apiPermission --name="foo${TEST_SUFFIX}" --apiPermission='[{"apiName" : "/v1/users", "actions": ["READ"]}]' +@test "update role : ok" { + name="foo${TEST_SUFFIX}" + run ./cntb create role -n "$name" -p '[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' assert_success roleId="$output" - run ./cntb update role apiPermission "$roleId" --name="foo${TEST_SUFFIX}" -a='[{"apiName": "/v1/users", "actions": ["READ", "CREATE"] }]' + run ./cntb get role "$roleId" assert_success + assert_output --partial "$name" - run ./cntb get role apiPermission "$roleId" -o json + run ./cntb update role "$roleId" --name="updated$name" -p '[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' assert_success - assert_output --partial "CREATE" + + run ./cntb get role "$roleId" + assert_success + assert_output --partial "updated$name" # cleanup + run ./cntb delete role "$roleId" + assert_success +} + - run ./cntb delete role apiPermission "$roleId" +@test "update role without name nor permissions : nok" { + run ./cntb create role -n "foo${TEST_SUFFIX}" -p '[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' assert_success + roleId="$output" + run ./cntb update role "$roleId" + assert_failure + + # cleanup + run ./cntb delete role "$roleId" + assert_success } -@test "update role not available action: nok" { - run ./cntb create role apiPermission --name="foo${TEST_SUFFIX}" --apiPermission='[{"apiName" : "/v1/users", "actions": ["READ"]}]' +@test "update role not available action : nok" { + run ./cntb create role -n "foo${TEST_SUFFIX}" -p '[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' assert_success roleId="$output" - run ./cntb update role apiPermission "$roleId" --name="foo${TEST_SUFFIX}" -a='[{"apiName": "/v1/users", "actions": ["READ", "UPDATE"] }]' + run ./cntb update role "$roleId" --name="foo${TEST_SUFFIX}" -p '[{"apiName": "/v1/users", "actions": ["READ", "UPDATE"] }]' assert_failure # cleanup - - run ./cntb delete role apiPermission "$roleId" + run ./cntb delete role "$roleId" assert_success } diff --git a/bats/update_user.bats b/bats/update_user.bats index feaef9c..5b85c75 100644 --- a/bats/update_user.bats +++ b/bats/update_user.bats @@ -15,12 +15,12 @@ function teardown_file() { } @test "update user ok: set firstName" { - run ./cntb create role apiPermission --name="foo${TEST_SUFFIX}" --apiPermission='[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' + run ./cntb create role -n "foo${TEST_SUFFIX}" -p '[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' assert_success roleId="$output" - run ./cntb create user --firstName="foo${TEST_SUFFIX}" --lastName="bar${TEST_SUFFIX}" --email="testuser${TEST_SUFFIX}@contabo.com" --enabled=true --admin=true --accessAllResources=true --roles="$roleId" + run ./cntb create user --firstName="foo${TEST_SUFFIX}" --lastName="bar${TEST_SUFFIX}" --email="testuser${TEST_SUFFIX}@contabo.com" --enabled=true --locale de --roles="$roleId" assert_success userId="$output" @@ -35,17 +35,17 @@ function teardown_file() { #clean up run ./cntb delete user "$userId" assert_success - run ./cntb delete role apiPermission "$roleId" + run ./cntb delete role "$roleId" assert_success } @test "update user ok: set lastName" { - run ./cntb create role apiPermission --name="foo${TEST_SUFFIX}" --apiPermission='[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' + run ./cntb create role -n "foo${TEST_SUFFIX}" -p '[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' assert_success roleId="$output" - run ./cntb create user --firstName="foo${TEST_SUFFIX}" --lastName="bar${TEST_SUFFIX}" --email="testuser${TEST_SUFFIX}@contabo.com" --enabled=true --admin=true --accessAllResources=true --roles="$roleId" + run ./cntb create user --firstName="foo${TEST_SUFFIX}" --lastName="bar${TEST_SUFFIX}" --email="testuser${TEST_SUFFIX}@contabo.com" --enabled=true --locale de --roles="$roleId" assert_success userId="$output" @@ -60,17 +60,17 @@ function teardown_file() { #clean up run ./cntb delete user "$userId" assert_success - run ./cntb delete role apiPermission "$roleId" + run ./cntb delete role "$roleId" assert_success } @test "update user ok: set email" { - run ./cntb create role apiPermission --name="foo${TEST_SUFFIX}" --apiPermission='[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' + run ./cntb create role -n "foo${TEST_SUFFIX}" -p '[{"apiName" : "/v1/users", "actions": ["READ", "CREATE"]}]' assert_success roleId="$output" - run ./cntb create user --firstName="foo${TEST_SUFFIX}" --lastName="bar${TEST_SUFFIX}" --email="testuser${TEST_SUFFIX}@contabo.com" --enabled=true --admin=true --accessAllResources=true --roles="$roleId" + run ./cntb create user --firstName="foo${TEST_SUFFIX}" --lastName="bar${TEST_SUFFIX}" --email="testuser${TEST_SUFFIX}@contabo.com" --enabled=true --locale de --roles="$roleId" assert_success userId="$output" @@ -85,6 +85,6 @@ function teardown_file() { #clean up run ./cntb delete user "$userId" assert_success - run ./cntb delete role apiPermission "$roleId" + run ./cntb delete role "$roleId" assert_success } \ No newline at end of file diff --git a/cmd/globalVars.go b/cmd/globalVars.go index 2eda8ae..1dae341 100644 --- a/cmd/globalVars.go +++ b/cmd/globalVars.go @@ -8,7 +8,6 @@ var ( OrderBy string DefaultPage = 1 DefaultPageSize = 100 - defaultOrderBy = "name:asc" RequestIdFilter string ChangedByFilter string ) diff --git a/cmd/images/create.go b/cmd/images/create.go index c66509e..57d5a11 100644 --- a/cmd/images/create.go +++ b/cmd/images/create.go @@ -19,7 +19,7 @@ import ( // createCmd represents the create command var imageCreateCmd = &cobra.Command{ Use: "image", - Short: "Creates a new image", + Short: "Creates a new image.", Long: `Creates a new image based on json / yaml input or arguments.`, Example: `cntb create image --name 'Ubuntu Custom Image' ` + `--description 'Base image for webservers.' --url https://example.com/image.iso ` + @@ -30,12 +30,12 @@ var imageCreateCmd = &cobra.Command{ switch content { case nil: - createImageRequest.Name = imageName - createImageRequest.Url = imageUrl - createImageRequest.OsType = strings.Title(strings.ToLower(imageOsType)) - createImageRequest.Version = imageVersion - if (imageDescription) != "" { - createImageRequest.Description = &imageDescription + createImageRequest.Name = createImageName + createImageRequest.Url = createImageUrl + createImageRequest.OsType = strings.Title(strings.ToLower(createImageOsType)) + createImageRequest.Version = createImageVersion + if (createImageDescription) != "" { + createImageRequest.Description = &createImageDescription } default: // from file / stdin @@ -56,46 +56,50 @@ var imageCreateCmd = &cobra.Command{ XRequestId(uuid.NewV4().String()). CreateCustomImageRequest(createImageRequest).Execute() - util.HandleErrors(err, httpResp, "while creating image") + util.HandleErrors(err, httpResp, "while creating image.") fmt.Printf("%v\n", resp.Data[0].ImageId) }, Args: func(cmd *cobra.Command, args []string) error { contaboCmd.ValidateCreateInput() - if viper.GetString("name") != "" { - imageName = viper.GetString("name") - } - if viper.GetString("description") != "" { - imageDescription = viper.GetString("description") - } - if viper.GetString("url") != "" { - imageUrl = viper.GetString("url") - } - if viper.GetString("osType") != "" { - imageOsType = viper.GetString("osType") - } - if viper.GetString("version") != "" { - imageVersion = viper.GetString("version") + if len(args) > 0 { + cmd.Help() + log.Fatal("Too many positional arguments.") } + viper.BindPFlag("name", cmd.Flags().Lookup("name")) + createImageName = viper.GetString("name") + + viper.BindPFlag("description", cmd.Flags().Lookup("description")) + createImageDescription = viper.GetString("description") + + viper.BindPFlag("url", cmd.Flags().Lookup("url")) + createImageUrl = viper.GetString("url") + + viper.BindPFlag("osType", cmd.Flags().Lookup("osType")) + createImageOsType = viper.GetString("osType") + + viper.BindPFlag("version", cmd.Flags().Lookup("version")) + createImageVersion = viper.GetString("version") + if contaboCmd.InputFile == "" { // arguments required - if imageName == "" { + if createImageName == "" { cmd.Help() log.Fatal("Argument name is empty. Please provide one.") } - if imageUrl == "" { + if createImageUrl == "" { cmd.Help() log.Fatal("Argument url is empty. Please provide one.") } - if imageOsType == "" { + if createImageOsType == "" { cmd.Help() - log.Fatal("Argument osType is empty please provide one") + log.Fatal("Argument osType is empty please provide one.") } - if imageVersion == "" { + if createImageVersion == "" { cmd.Help() - log.Fatal("Argument version is empty please provide one") + log.Fatal("Argument version is empty please provide one.") } } @@ -106,23 +110,18 @@ var imageCreateCmd = &cobra.Command{ func init() { contaboCmd.CreateCmd.AddCommand(imageCreateCmd) - imageCreateCmd.Flags().StringVar(&imageName, "name", "", - `custom name of the image`) - viper.BindPFlag("name", imageCreateCmd.Flags().Lookup("name")) + imageCreateCmd.Flags().StringVarP(&createImageName, "name", "n", "", + `Name of the custom image.`) - imageCreateCmd.Flags().StringVar(&imageDescription, "description", "", - `description of the image`) - viper.BindPFlag("description", imageCreateCmd.Flags().Lookup("description")) + imageCreateCmd.Flags().StringVar(&createImageDescription, "description", "", + `Description of the custom image.`) - imageCreateCmd.Flags().StringVar(&imageUrl, "url", "", - `a url from where the image gets downloaded`) - viper.BindPFlag("url", imageCreateCmd.Flags().Lookup("url")) + imageCreateCmd.Flags().StringVar(&createImageUrl, "url", "", + `An url from where the image gets downloaded.`) - imageCreateCmd.Flags().StringVar(&imageOsType, "osType", "", - `os type of the image`) - viper.BindPFlag("osType", imageCreateCmd.Flags().Lookup("osType")) + imageCreateCmd.Flags().StringVar(&createImageOsType, "osType", "", + `Os type of the custom image.`) - imageCreateCmd.Flags().StringVar(&imageVersion, "version", "", - `version of the image`) - viper.BindPFlag("version", imageCreateCmd.Flags().Lookup("version")) + imageCreateCmd.Flags().StringVar(&createImageVersion, "version", "", + `Version of the custom image.`) } diff --git a/cmd/images/delete.go b/cmd/images/delete.go index 8ba32a1..bb608b8 100644 --- a/cmd/images/delete.go +++ b/cmd/images/delete.go @@ -3,7 +3,6 @@ package cmd import ( "context" "fmt" - "os" "contabo.com/cli/cntb/client" contaboCmd "contabo.com/cli/cntb/cmd" @@ -20,7 +19,7 @@ var deleteCmd = &cobra.Command{ Example: `cntb delete image 9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d`, Run: func(cmd *cobra.Command, args []string) { httpResp, err := client.ApiClient().ImagesApi. - DeleteImage(context.Background(), imageId). + DeleteImage(context.Background(), deleteImageId). XRequestId(uuid.NewV4().String()).Execute() util.HandleErrors(err, httpResp, "while deleting image") @@ -28,19 +27,22 @@ var deleteCmd = &cobra.Command{ fmt.Printf("Image deleted\n") }, Args: func(cmd *cobra.Command, args []string) error { - contaboCmd.ValidateOutputFormat() - if len(args) > 1 { cmd.Help() - os.Exit(0) + log.Fatal("Too many positional arguments.") } if len(args) < 1 { cmd.Help() - log.Fatal("please provide only imageId") + log.Fatal("Please provide an imageId") } - imageId = args[0] + deleteImageId = args[0] + + if deleteImageId == "" { + cmd.Help() + log.Fatal("Argument imageId is empty. Please provide a non empty imageId.") + } return nil }, diff --git a/cmd/images/get.go b/cmd/images/get.go index 55a5ece..dcb3878 100644 --- a/cmd/images/get.go +++ b/cmd/images/get.go @@ -21,7 +21,7 @@ var imageGetCmd = &cobra.Command{ Example: `cntb get image 9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d`, Run: func(cmd *cobra.Command, args []string) { resp, httpResp, err := client.ApiClient(). - ImagesApi.RetrieveImage(context.Background(), imageId). + ImagesApi.RetrieveImage(context.Background(), getImageId). XRequestId(uuid.NewV4().String()).Execute() util.HandleErrors(err, httpResp, "while retrieving image") @@ -44,11 +44,22 @@ var imageGetCmd = &cobra.Command{ Args: func(cmd *cobra.Command, args []string) error { contaboCmd.ValidateOutputFormat() + if len(args) > 1 { + cmd.Help() + log.Fatal("Too many positional arguments.") + } + if len(args) < 1 { cmd.Help() - log.Fatal("Please specify imageId") + log.Fatal("Please provide an imageId.") + } + + getImageId = args[0] + + if getImageId == "" { + cmd.Help() + log.Fatal("Argument imageId is empty. Please provide a non empty imageId.") } - imageId = args[0] return nil }, diff --git a/cmd/images/history.go b/cmd/images/history.go index 84249f0..e8209bf 100644 --- a/cmd/images/history.go +++ b/cmd/images/history.go @@ -9,6 +9,7 @@ import ( "contabo.com/cli/cntb/cmd/util" "contabo.com/cli/cntb/outputFormatter" uuid "github.com/satori/go.uuid" + log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" ) @@ -20,7 +21,6 @@ var historyCmd = &cobra.Command{ Long: `Show what happend to your images over time.`, Example: `cntb history images --imageId 9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d`, Run: func(cmd *cobra.Command, args []string) { - historyRequest := client.ApiClient().ImagesAuditsApi. RetrieveImageAuditsList(context.Background()). XRequestId(uuid.NewV4().String()). @@ -28,20 +28,12 @@ var historyCmd = &cobra.Command{ Size(contaboCmd.Size). OrderBy([]string{contaboCmd.OrderBy}) - if cmd.Flags().Changed("imageId") { + if historyImageIdFilter != "" { historyRequest = historyRequest.ImageId( - imageIdFilter, + historyImageIdFilter, ) } - if cmd.Flags().Changed("requestId") { - historyRequest = historyRequest.RequestId(contaboCmd.RequestIdFilter) - } - - if cmd.Flags().Changed("changedBy") { - historyRequest = historyRequest.ChangedBy(contaboCmd.ChangedByFilter) - } - resp, httpResp, err := historyRequest.Execute() util.HandleErrors(err, httpResp, "while retrieving image history") @@ -64,6 +56,14 @@ var historyCmd = &cobra.Command{ Args: func(cmd *cobra.Command, args []string) error { contaboCmd.ValidateOutputFormat() + if len(args) > 0 { + cmd.Help() + log.Fatal("Too many positional arguments.") + } + + viper.BindPFlag("imageId", cmd.Flags().Lookup("imageId")) + historyImageIdFilter = viper.GetString("imageId") + return nil }, } @@ -71,7 +71,6 @@ var historyCmd = &cobra.Command{ func init() { contaboCmd.HistoryCmd.AddCommand(historyCmd) - historyCmd.Flags().StringVar(&imageIdFilter, "imageId", "", + historyCmd.Flags().StringVarP(&historyImageIdFilter, "imageId", "i", "", `Filter by a specific image via its imageId.`) - viper.BindPFlag("imageId", historyCmd.Flags().Lookup("imageId")) } diff --git a/cmd/images/list.go b/cmd/images/list.go index 0bcd9d9..6c142c5 100644 --- a/cmd/images/list.go +++ b/cmd/images/list.go @@ -3,13 +3,14 @@ package cmd import ( "context" "encoding/json" - "log" + "fmt" "contabo.com/cli/cntb/client" contaboCmd "contabo.com/cli/cntb/cmd" "contabo.com/cli/cntb/cmd/util" "contabo.com/cli/cntb/outputFormatter" uuid "github.com/satori/go.uuid" + log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" ) @@ -29,7 +30,7 @@ var imagesGetCmd = &cobra.Command{ OrderBy([]string{contaboCmd.OrderBy}) if cmd.Flags().Changed("name") { - ApiRetrieveImageListRequest = ApiRetrieveImageListRequest.Name(nameFilter) + ApiRetrieveImageListRequest = ApiRetrieveImageListRequest.Name(listImageNameFilter) } imageType, _ := cmd.Flags().GetString("imageType") @@ -55,18 +56,34 @@ var imagesGetCmd = &cobra.Command{ "imageId", "name", "sizeMb", "uploadedSizeMb", "osType", "tags", "version", "url", "description", "status", "errorMessage", "standardImage", }, - JsonPath: contaboCmd.OutputFormatDetails} + JsonPath: contaboCmd.OutputFormatDetails, + } util.HandleResponse(responseJson, configFormatter) }, Args: func(cmd *cobra.Command, args []string) error { - givenImageType := viper.GetString("imageType") - if givenImageType != "" { - if givenImageType != "standard" && givenImageType != "custom" { - cmd.Help() - log.Fatal("Argument imageType was given. Please provide one of `standard` or `custom`.") - } + contaboCmd.ValidateOutputFormat() + + if len(args) > 0 { + cmd.Help() + log.Fatal("Too many positional arguments.") + } + + viper.BindPFlag("name", cmd.Flags().Lookup("name")) + listImageNameFilter = viper.GetString("name") + + viper.BindPFlag("imageType", cmd.Flags().Lookup("imageType")) + listImageTypeFilter = viper.GetString("imageType") + + if listImageTypeFilter != "" && listImageTypeFilter != "standard" && listImageTypeFilter != "custom" { + cmd.Help() + log.Fatal( + fmt.Sprintf( + "Invalid value `%v` for imageType. Please provide one of `standard` or `custom`.", + listImageTypeFilter, + )) } + return nil }, } @@ -74,12 +91,9 @@ var imagesGetCmd = &cobra.Command{ func init() { contaboCmd.GetCmd.AddCommand(imagesGetCmd) - imagesGetCmd.Flags().StringVarP( - &nameFilter, "name", "", "", `Filter by custom image name.`) - viper.BindPFlag("name", imagesGetCmd.Flags().Lookup("name")) + imagesGetCmd.Flags().StringVarP(&listImageNameFilter, "name", "n", "", + `Filter by image name.`) - imagesGetCmd.Flags().StringVarP( - &imageTypeFilter, "imageType", "", "", + imagesGetCmd.Flags().StringVar(&listImageTypeFilter, "imageType", "", `Filter by type of image. Available values are 'standard' or 'custom'.`) - viper.BindPFlag("imageType", imagesGetCmd.Flags().Lookup("imageType")) } diff --git a/cmd/images/stats.go b/cmd/images/stats.go index b9b9705..5848387 100644 --- a/cmd/images/stats.go +++ b/cmd/images/stats.go @@ -9,6 +9,7 @@ import ( "contabo.com/cli/cntb/cmd/util" "contabo.com/cli/cntb/outputFormatter" uuid "github.com/satori/go.uuid" + log "github.com/sirupsen/logrus" "github.com/spf13/cobra" ) @@ -39,6 +40,16 @@ var imageStatsGetCmd = &cobra.Command{ util.HandleResponse(responseJson, configFormatter) }, + Args: func(cmd *cobra.Command, args []string) error { + contaboCmd.ValidateOutputFormat() + + if len(args) > 0 { + cmd.Help() + log.Fatal("Too many positional arguments.") + } + + return nil + }, } func init() { diff --git a/cmd/images/update.go b/cmd/images/update.go index 10d5826..c25ce31 100644 --- a/cmd/images/update.go +++ b/cmd/images/update.go @@ -4,7 +4,6 @@ import ( "context" "encoding/json" "fmt" - "os" "strings" "contabo.com/cli/cntb/client" @@ -29,8 +28,8 @@ var imageUpdateCmd = &cobra.Command{ switch content { case nil: - if imageName != "" { - updateImageRequest.Name = &imageName + if updateImageName != "" { + updateImageRequest.Name = &updateImageName } default: // from file / stdin @@ -47,7 +46,7 @@ var imageUpdateCmd = &cobra.Command{ } resp, httpResp, err := client.ApiClient().ImagesApi. - UpdateImage(context.Background(), imageId). + UpdateImage(context.Background(), updateImageId). UpdateCustomImageRequest(updateImageRequest). XRequestId(uuid.NewV4().String()). Execute() @@ -60,20 +59,22 @@ var imageUpdateCmd = &cobra.Command{ Args: func(cmd *cobra.Command, args []string) error { contaboCmd.ValidateCreateInput() - if viper.GetString("name") != "" { - imageName = viper.GetString("name") - } - if len(args) > 1 { cmd.Help() - os.Exit(0) + log.Fatal("Too many positional arguments.") } if len(args) < 1 { cmd.Help() - log.Fatal("please provide a imageId") + log.Fatal("Please provide an imageId.") + } + updateImageId = args[0] + if updateImageId == "" { + cmd.Help() + log.Fatal("Argument imageId is empty. Please provide a non empty imageId.") } - imageId = args[0] + viper.BindPFlag("name", cmd.Flags().Lookup("name")) + updateImageName = viper.GetString("name") return nil }, @@ -82,8 +83,6 @@ var imageUpdateCmd = &cobra.Command{ func init() { contaboCmd.UpdateCmd.AddCommand(imageUpdateCmd) - imageUpdateCmd.Flags().StringVar(&imageName, "name", "", + imageUpdateCmd.Flags().StringVarP(&updateImageName, "name", "n", "", `new name of the image`) - viper.BindPFlag("name", imageUpdateCmd.Flags().Lookup("name")) - viper.SetDefault("name", "") } diff --git a/cmd/images/vars.go b/cmd/images/vars.go index ce81d3d..ee31b99 100644 --- a/cmd/images/vars.go +++ b/cmd/images/vars.go @@ -1,13 +1,37 @@ package cmd +// create var ( - imageId string - imageName string - imageDescription string - imageUrl string - imageOsType string - imageVersion string - nameFilter string - imageTypeFilter string - imageIdFilter string + createImageName string + createImageDescription string + createImageUrl string + createImageOsType string + createImageVersion string +) + +// delete +var ( + deleteImageId string +) + +// get +var ( + getImageId string +) + +// history +var ( + historyImageIdFilter string +) + +// list +var ( + listImageTypeFilter string + listImageNameFilter string +) + +// update +var ( + updateImageId string + updateImageName string ) diff --git a/cmd/instanceActions/history.go b/cmd/instanceActions/history.go index 74a9c5d..50ce803 100644 --- a/cmd/instanceActions/history.go +++ b/cmd/instanceActions/history.go @@ -9,6 +9,7 @@ import ( "contabo.com/cli/cntb/cmd/util" "contabo.com/cli/cntb/outputFormatter" uuid "github.com/satori/go.uuid" + log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" ) @@ -26,16 +27,8 @@ var historyCmd = &cobra.Command{ Size(contaboCmd.Size). OrderBy([]string{contaboCmd.OrderBy}) - if cmd.Flags().Changed("instanceId") { - historyRequest = historyRequest.InstanceId(instanceIdFilter) - } - - if cmd.Flags().Changed("requestId") { - historyRequest = historyRequest.RequestId(contaboCmd.RequestIdFilter) - } - - if cmd.Flags().Changed("changedBy") { - historyRequest = historyRequest.ChangedBy(contaboCmd.ChangedByFilter) + if historyInstanceId != 0 { + historyRequest = historyRequest.InstanceId(historyInstanceId) } resp, httpResp, err := historyRequest.Execute() @@ -60,6 +53,14 @@ var historyCmd = &cobra.Command{ Args: func(cmd *cobra.Command, args []string) error { contaboCmd.ValidateOutputFormat() + if len(args) > 0 { + cmd.Help() + log.Fatal("Too many positional arguments.") + } + + viper.BindPFlag("instanceId", cmd.Flags().Lookup("instanceId")) + historyInstanceId = viper.GetInt64("instanceId") + return nil }, } @@ -67,7 +68,6 @@ var historyCmd = &cobra.Command{ func init() { contaboCmd.HistoryCmd.AddCommand(historyCmd) - historyCmd.Flags().Int64VarP(&instanceIdFilter, "instanceId", "i", -1, + historyCmd.Flags().Int64VarP(&historyInstanceId, "instanceId", "i", 0, `To filter audits using Instance Id`) - viper.BindPFlag("instanceId", historyCmd.Flags().Lookup("instanceId")) } diff --git a/cmd/instanceActions/restart.go b/cmd/instanceActions/restart.go index 2b9f155..840ca81 100644 --- a/cmd/instanceActions/restart.go +++ b/cmd/instanceActions/restart.go @@ -23,7 +23,7 @@ var restartInstanceCmd = &cobra.Command{ Example: `cntb restart instance 12345`, Run: func(cmd *cobra.Command, args []string) { resp, httpResp, err := client.ApiClient(). - InstanceActionsApi.Restart(context.Background(), instanceId). + InstanceActionsApi.Restart(context.Background(), restartInstanceId). XRequestId(uuid.NewV4().String()).Execute() util.HandleErrors(err, httpResp, "while restarting instance") @@ -48,7 +48,7 @@ var restartInstanceCmd = &cobra.Command{ if err != nil { log.Fatal(fmt.Sprintf("Specified instanceId %v is not valid", args[0])) } - instanceId = instanceId64 + restartInstanceId = instanceId64 contaboCmd.ValidateOutputFormat() return nil diff --git a/cmd/instanceActions/start.go b/cmd/instanceActions/start.go index 9fc629b..9fe8db3 100644 --- a/cmd/instanceActions/start.go +++ b/cmd/instanceActions/start.go @@ -23,7 +23,7 @@ var startInstanceCmd = &cobra.Command{ Example: `cntb start instance 12345`, Run: func(cmd *cobra.Command, args []string) { resp, httpResp, err := client.ApiClient(). - InstanceActionsApi.Start(context.Background(), instanceId). + InstanceActionsApi.Start(context.Background(), startInstanceId). XRequestId(uuid.NewV4().String()).Execute() util.HandleErrors(err, httpResp, "while starting instance") @@ -39,17 +39,23 @@ var startInstanceCmd = &cobra.Command{ util.HandleResponse(responseJson, configFormatter) }, Args: func(cmd *cobra.Command, args []string) error { + contaboCmd.ValidateOutputFormat() + + if len(args) > 1 { + cmd.Help() + log.Fatal("Too many positional arguments.") + } + if len(args) < 1 { cmd.Help() - log.Fatal("Please specify instanceId") + log.Fatal("Please provide an instanceId.") } instanceId64, err := strconv.ParseInt(args[0], 10, 64) if err != nil { - log.Fatal(fmt.Sprintf("Specified instanceId %v is not valid", args[0])) + log.Fatal(fmt.Sprintf("Provided instanceId %v is not valid.", args[0])) } - instanceId = instanceId64 - contaboCmd.ValidateOutputFormat() + startInstanceId = instanceId64 return nil }, diff --git a/cmd/instanceActions/stop.go b/cmd/instanceActions/stop.go index d4deeba..397df86 100644 --- a/cmd/instanceActions/stop.go +++ b/cmd/instanceActions/stop.go @@ -23,7 +23,7 @@ var stopInstanceCmd = &cobra.Command{ Example: `cntb stop instance 12345`, Run: func(cmd *cobra.Command, args []string) { resp, httpResp, err := client.ApiClient(). - InstanceActionsApi.Stop(context.Background(), instanceId). + InstanceActionsApi.Stop(context.Background(), stopInstanceId). XRequestId(uuid.NewV4().String()).Execute() util.HandleErrors(err, httpResp, "while stopping instance") @@ -39,17 +39,22 @@ var stopInstanceCmd = &cobra.Command{ util.HandleResponse(responseJson, configFormatter) }, Args: func(cmd *cobra.Command, args []string) error { + contaboCmd.ValidateOutputFormat() + + if len(args) > 1 { + cmd.Help() + log.Fatal("Too many positional arguments.") + } if len(args) < 1 { cmd.Help() - log.Fatal("Please specify instanceId") + log.Fatal("Please provide an instanceId") } instanceId64, err := strconv.ParseInt(args[0], 10, 64) if err != nil { - log.Fatal(fmt.Sprintf("Specified instanceId %v is not valid", args[0])) + log.Fatal(fmt.Sprintf("Provided instanceId %v is not valid.", args[0])) } - instanceId = instanceId64 - contaboCmd.ValidateOutputFormat() + stopInstanceId = instanceId64 return nil }, diff --git a/cmd/instanceActions/vars.go b/cmd/instanceActions/vars.go index 148fe04..57db611 100644 --- a/cmd/instanceActions/vars.go +++ b/cmd/instanceActions/vars.go @@ -1,6 +1,21 @@ package cmd +// history var ( - instanceId int64 - instanceIdFilter int64 + historyInstanceId int64 +) + +// restart +var ( + restartInstanceId int64 +) + +// start +var ( + startInstanceId int64 +) + +// stop +var ( + stopInstanceId int64 ) diff --git a/cmd/instances/cancel.go b/cmd/instances/cancel.go index af5e71e..d021eab 100644 --- a/cmd/instances/cancel.go +++ b/cmd/instances/cancel.go @@ -17,11 +17,13 @@ import ( var instanceCancelCmd = &cobra.Command{ Use: "instance [instanceId]", - Short: "Cancel specific instance by id", + Short: "Cancel specific instance by id.", Long: `Your are free to cancel a previously created instances at any time.`, Example: `cntb cancel instance 12345`, Run: func(cmd *cobra.Command, args []string) { - resp, httpResp, err := client.ApiClient().InstancesApi.CancelInstance(context.Background(), instanceId).XRequestId(uuid.NewV4().String()).Execute() + resp, httpResp, err := client.ApiClient().InstancesApi. + CancelInstance(context.Background(), cancelInstanceId). + XRequestId(uuid.NewV4().String()).Execute() util.HandleErrors(err, httpResp, "while canceling the instance") @@ -41,21 +43,22 @@ var instanceCancelCmd = &cobra.Command{ }, Args: func(cmd *cobra.Command, args []string) error { contaboCmd.ValidateCreateInput() - if len(args) < 1 { - cmd.Help() - log.Fatal("please provide instance id") - } + contaboCmd.ValidateOutputFormat() if len(args) > 1 { cmd.Help() - log.Fatal("the instance id is the only argument allowed") + log.Fatal("Too many positional arguments.") + } + if len(args) < 1 { + cmd.Help() + log.Fatal("Please provide an instanceId.") } instanceId64, err := strconv.ParseInt(args[0], 10, 64) if err != nil { - log.Fatal(fmt.Sprintf("Specified instanceId %v is not valid", args[0])) + log.Fatal(fmt.Sprintf("Provided instanceId %v is not valid.", args[0])) } - instanceId = instanceId64 + cancelInstanceId = instanceId64 return nil }, diff --git a/cmd/instances/create.go b/cmd/instances/create.go index 63d4c01..c86723d 100644 --- a/cmd/instances/create.go +++ b/cmd/instances/create.go @@ -18,9 +18,9 @@ import ( var instanceCreateCmd = &cobra.Command{ Use: "instance", - Short: "Creates a new compute instance", - Long: `Create a new compute instances in your account`, - Example: `create instance -p 12 --imageId "1234absv-331vc-776hg-376bgt" ` + + Short: "Create a new compute instance.", + Long: `Create a new compute instance.`, + Example: `create instance -p 12 --imageId "111eebb0-dc70-4bc2-a7d0-c525dbe016a9" ` + `--license "PleskHost" --productId "V1" -r "EU"`, Run: func(cmd *cobra.Command, args []string) { createInstanceRequest := *instancesClient.NewCreateInstanceRequestWithDefaults() @@ -28,28 +28,28 @@ var instanceCreateCmd = &cobra.Command{ switch content { case nil: - // from arguments - createInstanceRequest.ImageId = instanceImageId - createInstanceRequest.ProductId = instanceProductId - createInstanceRequest.Region = instanceRegion - createInstanceRequest.Period = instancePeriod - - if instanceLicense != "" { - createInstanceRequest.License = &instanceLicense + // flags with default values + createInstanceRequest.ImageId = createInstanceImageId + createInstanceRequest.ProductId = createInstanceProductId + createInstanceRequest.Region = createInstanceRegion + createInstanceRequest.Period = createInstancePeriod + + // optional flags + if createInstanceSshKeys != nil { + createInstanceRequest.SshKeys = &createInstanceSshKeys } - - if instanceRootPassword != 0 { - createInstanceRequest.RootPassword = &instanceRootPassword + if createInstanceRootPassword != 0 { + createInstanceRequest.RootPassword = &createInstanceRootPassword } - if instanceUserData != "" { + if createInstanceUserData != "" { // user data from argument needs to replace newline char in order to work - userData := strings.Replace(instanceUserData, "\\n", "\n", -1) + userData := strings.Replace(createInstanceUserData, "\\n", "\n", -1) // for debugging user data log.Debug(userData) createInstanceRequest.UserData = &userData } - if len(instanceSshKeys) != 0 { - createInstanceRequest.SshKeys = &instanceSshKeys + if createInstanceLicense != "" { + createInstanceRequest.License = &createInstanceLicense } default: @@ -57,13 +57,14 @@ var instanceCreateCmd = &cobra.Command{ var requestFromFile instancesClient.CreateInstanceRequest err := json.Unmarshal(content, &requestFromFile) if err != nil { - log.Fatal(fmt.Sprintf("Format invalid. Please check your syntax: %v", err)) + log.Fatal(fmt.Sprintf("format invalid. Please check your syntax: %v", err)) } // merge createTagRequest with one from file to have the defaults there json.NewDecoder(strings.NewReader(string(content))).Decode(&createInstanceRequest) } - resp, httpResp, err := client.ApiClient().InstancesApi.CreateInstance(context.Background()).XRequestId(uuid.NewV4().String()).CreateInstanceRequest(createInstanceRequest).Execute() + resp, httpResp, err := client.ApiClient().InstancesApi.CreateInstance(context.Background()). + XRequestId(uuid.NewV4().String()).CreateInstanceRequest(createInstanceRequest).Execute() util.HandleErrors(err, httpResp, "while creating instance") @@ -72,50 +73,39 @@ var instanceCreateCmd = &cobra.Command{ Args: func(cmd *cobra.Command, args []string) error { contaboCmd.ValidateCreateInput() - if instanceImageId == "" && viper.GetString("imageId") != "" { - instanceImageId = viper.GetString("imageId") - } - if viper.GetString("productId") != "" { - instanceProductId = viper.GetString("productId") - } - if viper.GetString("region") != "" { - instanceRegion = viper.GetString("region") - } - if viper.GetString("license") != "" { - instanceLicense = viper.GetString("license") + if len(args) > 0 { + cmd.Help() + log.Fatal("Too many positional arguments.") } - if viper.GetString("userData") != "" { - instanceUserData = viper.GetString("userData") - } + // flags with default values + viper.BindPFlag("imageId", cmd.Flags().Lookup("imageId")) + createInstanceImageId = viper.GetString("imageId") - if viper.GetInt64("period") != 0 { - instancePeriod = viper.GetInt64("period") - } - if viper.GetInt64("rootPassword") != 0 { - instanceRootPassword = viper.GetInt64("rootPassword") - } + viper.BindPFlag("productId", cmd.Flags().Lookup("productId")) + createInstanceProductId = viper.GetString("productId") - if contaboCmd.InputFile == "" { - // arguments required - if instanceImageId == "" { - cmd.Help() - log.Fatal("Argument imageId is empty. Please provide one.") - } - if instanceProductId == "" { - cmd.Help() - log.Fatal("Argument productId is empty. Please provide one.") - } - if instanceRegion == "" { - cmd.Help() - log.Fatal("Argument region is empty. Please provide one.") - } + viper.BindPFlag("region", cmd.Flags().Lookup("region")) + createInstanceRegion = viper.GetString("region") - if instancePeriod == 0 { - cmd.Help() - log.Fatal("Argument period is empty. Please provide one.") - } + viper.BindPFlag("period", cmd.Flags().Lookup("period")) + createInstancePeriod = viper.GetInt64("period") + + // optional flags + viper.BindPFlag("sshKeys", cmd.Flags().Lookup("sshKeys")) + for i := range viper.GetIntSlice("sshKeys") { + createInstanceSshKeys[i] = int64(viper.GetIntSlice("sshKeys")[i]) } + + viper.BindPFlag("rootPassword", cmd.Flags().Lookup("rootPassword")) + createInstanceRootPassword = viper.GetInt64("rootPassword") + + viper.BindPFlag("userData", cmd.Flags().Lookup("userData")) + createInstanceUserData = viper.GetString("userData") + + viper.BindPFlag("license", cmd.Flags().Lookup("license")) + createInstanceLicense = viper.GetString("license") + return nil }, } @@ -123,34 +113,32 @@ var instanceCreateCmd = &cobra.Command{ func init() { contaboCmd.CreateCmd.AddCommand(instanceCreateCmd) - instanceCreateCmd.Flags().Int64VarP(&instancePeriod, "period", "p", 1, `period contract length (1, 3, 6 or 12 months)`) - viper.BindPFlag("period", instanceCreateCmd.Flags().Lookup("period")) - viper.SetDefault("period", &instancePeriod) + // flags with default values + instanceCreateCmd.Flags().StringVar(&createInstanceImageId, "imageId", "db1409d2-ed92-4f2f-978e-7b2fa4a1ec90", + `Standard or custom image id. Defaults to 'Ubuntu 20.04'.`) - instanceCreateCmd.Flags().Int64SliceVar(&instanceSshKeys, "sshKeys", nil, `ids of stored ssh public keys`) - viper.BindPFlag("sshKeys", instanceCreateCmd.Flags().Lookup("sshKeys")) + instanceCreateCmd.Flags().StringVar(&createInstanceProductId, "productId", "V1", + `Id of product to be used. See https://contabo.com/en/product-list/?show_ids=true`) - instanceCreateCmd.Flags().Int64VarP(&instanceRootPassword, "rootPassword", "", 0, `id of stored password`) - viper.BindPFlag("rootPassword", instanceCreateCmd.Flags().Lookup("rootPassword")) + instanceCreateCmd.Flags().StringVarP(&createInstanceRegion, "region", "r", "EU", + `Region where instance should be created [EU, US-central, US-east, US-west or SIN]`) - instanceCreateCmd.Flags().StringVarP(&instanceUserData, "userData", "", "", `cloud-init script (user data)`) - viper.BindPFlag("userData", instanceCreateCmd.Flags().Lookup("userData")) + instanceCreateCmd.Flags().Int64VarP(&createInstancePeriod, "period", "p", 1, + `Period contract length (1, 3, 6 or 12 months)`) - instanceCreateCmd.Flags().StringVarP(&instanceImageId, "imageId", "", "db1409d2-ed92-4f2f-978e-7b2fa4a1ec90", `standard or custom image id. Defaults to Ubuntu 20.04`) - viper.BindPFlag("imageId", instanceCreateCmd.Flags().Lookup("imageId")) - viper.SetDefault("imageId", "db1409d2-ed92-4f2f-978e-7b2fa4a1ec90") + // optional flags + instanceCreateCmd.Flags().Int64SliceVar(&createInstanceSshKeys, "sshKeys", nil, + `Ids of stored ssh public keys.`) - instanceCreateCmd.Flags().StringVarP(&instanceLicense, "license", "", "", `additional licence in order to enhance your chosen product. - Valid licenses: "PleskHost" "PleskPro" "PleskAdmin" "cPanel5" "cPanel30" "cPanel50" "cPanel100" "cPanel150" - "cPanel200" "cPanel250" "cPanel300" "cPanel350" "cPanel400" "cPanel450" "cPanel500" "cPanel550" "cPanel600" - "cPanel650" "cPanel700" "cPanel750" "cPanel800" "cPanel850" "cPanel900" "cPanel950" "cPanel1000"`) - viper.BindPFlag("license", instanceCreateCmd.Flags().Lookup("license")) + instanceCreateCmd.Flags().Int64Var(&createInstanceRootPassword, "rootPassword", 0, + `Id of stored password.`) - instanceCreateCmd.Flags().StringVarP(&instanceProductId, "productId", "", "V1", `id of product to be used. See https://contabo.com/en/product-list/?show_ids=true`) - viper.BindPFlag("productId", instanceCreateCmd.Flags().Lookup("productId")) - viper.SetDefault("productId", "V1") + instanceCreateCmd.Flags().StringVar(&createInstanceUserData, "userData", "", + `Cloud-init script (user data)`) - instanceCreateCmd.Flags().StringVarP(&instanceRegion, "region", "r", "EU", `region where instance should be created [EU, US-central, US-east, US-west or SIN].`) - viper.BindPFlag("region", instanceCreateCmd.Flags().Lookup("region")) - viper.SetDefault("region", "EU") + instanceCreateCmd.Flags().StringVar(&createInstanceLicense, "license", "", + `Additional licence in order to enhance your chosen product. + Valid licenses: "PleskHost" "PleskPro" "PleskAdmin" "cPanel5" "cPanel30" "cPanel50" "cPanel100" "cPanel150" + "cPanel200" "cPanel250" "cPanel300" "cPanel350" "cPanel400" "cPanel450" "cPanel500" "cPanel550" "cPanel600" + "cPanel650" "cPanel700" "cPanel750" "cPanel800" "cPanel850" "cPanel900" "cPanel950" "cPanel1000"`) } diff --git a/cmd/instances/get.go b/cmd/instances/get.go index 564fe0b..1b3d0ab 100644 --- a/cmd/instances/get.go +++ b/cmd/instances/get.go @@ -19,10 +19,12 @@ type jmap map[string]interface{} var instanceGetCmd = &cobra.Command{ Use: "instance [instanceId]", - Short: "Info about a specific instance", + Short: "Info about a specific instance.", Long: `Retrieves information about an instance identified by id.`, Run: func(cmd *cobra.Command, args []string) { - resp, httpResp, err := client.ApiClient().InstancesApi.RetrieveInstance(context.Background(), instanceId).XRequestId(uuid.NewV4().String()).Execute() + resp, httpResp, err := client.ApiClient().InstancesApi. + RetrieveInstance(context.Background(), getInstanceId). + XRequestId(uuid.NewV4().String()).Execute() util.HandleErrors(err, httpResp, "while retrieving instance") @@ -39,22 +41,30 @@ var instanceGetCmd = &cobra.Command{ configFormatter := outputFormatter.FormatterConfig{ Filter: []string{"instanceId", "name", "status", "imageId", "ipv4", "ipv6"}, WideFilter: []string{ - "instanceId", "name", "status", "imageId", "region", "productId", "customerId", "ipv4", "ipv6"}, - JsonPath: contaboCmd.OutputFormatDetails} + "instanceId", "name", "status", "imageId", "region", "productId", "customerId", "ipv4", "ipv6", + }, + JsonPath: contaboCmd.OutputFormatDetails, + } util.HandleResponse(responseJson, configFormatter) }, Args: func(cmd *cobra.Command, args []string) error { + contaboCmd.ValidateOutputFormat() + + if len(args) > 1 { + cmd.Help() + log.Fatal("Too many positional arguments.") + } if len(args) < 1 { cmd.Help() - log.Fatal("Please specify instanceId") + log.Fatal("Please provide an instanceId.") } instanceId64, err := strconv.ParseInt(args[0], 10, 64) if err != nil { - log.Fatal(fmt.Sprintf("Specified instanceId %v is not valid", args[0])) + log.Fatal(fmt.Sprintf("Provided instanceId %v is not valid.", args[0])) } - instanceId = instanceId64 - contaboCmd.ValidateOutputFormat() + getInstanceId = instanceId64 + return nil }, } diff --git a/cmd/instances/history.go b/cmd/instances/history.go index afab825..d8ca489 100644 --- a/cmd/instances/history.go +++ b/cmd/instances/history.go @@ -9,6 +9,7 @@ import ( "contabo.com/cli/cntb/cmd/util" "contabo.com/cli/cntb/outputFormatter" uuid "github.com/satori/go.uuid" + log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" ) @@ -27,8 +28,8 @@ var instanceHistoryCmd = &cobra.Command{ Size(contaboCmd.Size). OrderBy([]string{contaboCmd.OrderBy}) - if cmd.Flags().Changed("instanceId") { - historyRequest = historyRequest.InstanceId(viper.GetInt64("instanceId")) + if historyInstanceIdFilter != 0 { + historyRequest = historyRequest.InstanceId(historyInstanceIdFilter) } resp, httpResp, err := historyRequest.Execute() @@ -53,10 +54,14 @@ var instanceHistoryCmd = &cobra.Command{ Args: func(cmd *cobra.Command, args []string) error { contaboCmd.ValidateOutputFormat() - if cmd.Flags().Changed("instanceId") { - instanceIdFilter = viper.GetInt64("instanceId") + if len(args) > 0 { + cmd.Help() + log.Fatal("Too many positional arguments.") } + viper.BindPFlag("instanceId", cmd.Flags().Lookup("instanceId")) + historyInstanceIdFilter = viper.GetInt64("instanceId") + return nil }, } @@ -64,7 +69,6 @@ var instanceHistoryCmd = &cobra.Command{ func init() { contaboCmd.HistoryCmd.AddCommand(instanceHistoryCmd) - instanceHistoryCmd.Flags().Int64VarP(&instanceIdFilter, "instanceId", "i", instanceId, + instanceHistoryCmd.Flags().Int64VarP(&historyInstanceIdFilter, "instanceId", "i", 0, `Filter by a specific instance via its instanceId.`) - viper.BindPFlag("instanceId", instanceHistoryCmd.Flags().Lookup("instanceId")) } diff --git a/cmd/instances/list.go b/cmd/instances/list.go index 83525a2..acf1f01 100644 --- a/cmd/instances/list.go +++ b/cmd/instances/list.go @@ -3,20 +3,20 @@ package cmd import ( "context" "encoding/json" - "os" "contabo.com/cli/cntb/client" contaboCmd "contabo.com/cli/cntb/cmd" "contabo.com/cli/cntb/cmd/util" "contabo.com/cli/cntb/outputFormatter" uuid "github.com/satori/go.uuid" + log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" ) var instancesGetCmd = &cobra.Command{ Use: "instances", - Short: "All about your instances", + Short: "All about your instances.", Long: `Retrieves information about one or multiple instances. Filter by name.`, Example: `cntb get instances`, Run: func(cmd *cobra.Command, args []string) { @@ -27,8 +27,8 @@ var instancesGetCmd = &cobra.Command{ Size(contaboCmd.Size). OrderBy([]string{contaboCmd.OrderBy}) - if cmd.Flags().Changed("name") { - ApiRetrieveInstanceListRequest = ApiRetrieveInstanceListRequest.Name(instanceNameFilter) + if listInstanceNameFilter != "" { + ApiRetrieveInstanceListRequest = ApiRetrieveInstanceListRequest.Name(listInstanceNameFilter) } resp, httpResp, err := ApiRetrieveInstanceListRequest.Execute() @@ -59,11 +59,15 @@ var instancesGetCmd = &cobra.Command{ }, Args: func(cmd *cobra.Command, args []string) error { contaboCmd.ValidateOutputFormat() + if len(args) > 1 { cmd.Help() - os.Exit(0) + log.Fatal("Too many positional arguments.") } + viper.BindPFlag("name", cmd.Flags().Lookup("name")) + listInstanceNameFilter = viper.GetString("name") + return nil }, } @@ -71,7 +75,6 @@ var instancesGetCmd = &cobra.Command{ func init() { contaboCmd.GetCmd.AddCommand(instancesGetCmd) - instancesGetCmd.Flags().StringVarP( - &instanceNameFilter, "name", "n", "", `Filter by instance name`) - viper.BindPFlag("name", instancesGetCmd.Flags().Lookup("name")) + instancesGetCmd.Flags().StringVarP(&listInstanceNameFilter, "name", "n", "", + `Filter by instance name`) } diff --git a/cmd/instances/reinstall.go b/cmd/instances/reinstall.go index 05898a4..9532322 100644 --- a/cmd/instances/reinstall.go +++ b/cmd/instances/reinstall.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "fmt" + "os" "strconv" "strings" @@ -22,22 +23,24 @@ var instanceReinstallCmd = &cobra.Command{ Short: "Reinstall specific instance by id", Long: `Reinstall an existing instance using a different image or settings.`, Run: func(cmd *cobra.Command, args []string) { - instanceReinstallRequest := *instancesClient.NewReinstallInstanceRequestWithDefaults() + instanceReinstallRequest := *instancesClient. + NewReinstallInstanceRequestWithDefaults() content := contaboCmd.OpenStdinOrFile() switch content { case nil: // from arguments - instanceReinstallRequest.ImageId = instanceImageId - - if len(instanceSshKeys) != 0 { - instanceReinstallRequest.SshKeys = &instanceSshKeys + if reinstallInstanceImageId != "" { + instanceReinstallRequest.ImageId = reinstallInstanceImageId + } + if reinstallInstanceSshKeys != nil { + instanceReinstallRequest.SshKeys = &reinstallInstanceSshKeys } - if instanceRootPassword != 0 { - instanceReinstallRequest.RootPassword = &instanceRootPassword + if reinstallInstanceRootPassword != 0 { + instanceReinstallRequest.RootPassword = &reinstallInstanceRootPassword } - if instanceUserData != "" { - instanceReinstallRequest.UserData = &instanceUserData + if reinstallInstanceUserData != "" { + instanceReinstallRequest.UserData = &reinstallInstanceUserData } default: @@ -48,10 +51,14 @@ var instanceReinstallCmd = &cobra.Command{ log.Fatal(fmt.Sprintf("Format invalid. Please check your syntax: %v", err)) } - json.NewDecoder(strings.NewReader(string(content))).Decode(&instanceReinstallRequest) + json.NewDecoder(strings.NewReader(string(content))). + Decode(&instanceReinstallRequest) } - resp, httpResp, err := client.ApiClient().InstancesApi.ReinstallInstance(context.Background(), instanceId).XRequestId(uuid.NewV4().String()).ReinstallInstanceRequest(instanceReinstallRequest).Execute() + resp, httpResp, err := client.ApiClient().InstancesApi. + ReinstallInstance(context.Background(), reinstallInstanceId). + XRequestId(uuid.NewV4().String()). + ReinstallInstanceRequest(instanceReinstallRequest).Execute() util.HandleErrors(err, httpResp, "while reinstalling instance") @@ -61,35 +68,60 @@ var instanceReinstallCmd = &cobra.Command{ }, Args: func(cmd *cobra.Command, args []string) error { contaboCmd.ValidateCreateInput() + + if len(args) > 1 { + cmd.Help() + os.Exit(1) + } if len(args) < 1 { cmd.Help() - log.Fatal("Missing instanceId. Please specify a valid instanceId.") + log.Fatal("Please provide an instanceId") } + + viper.BindPFlag("imageId", cmd.Flags().Lookup("imageId")) + reinstallInstanceImageId = viper.GetString("imageId") + + viper.BindPFlag("sshKeys", cmd.Flags().Lookup("sshKeys")) + for i := range viper.GetIntSlice("sshKeys") { + reinstallInstanceSshKeys[i] = int64(viper.GetIntSlice("sshKeys")[i]) + } + + viper.BindPFlag("rootPassword", cmd.Flags().Lookup("rootPassword")) + reinstallInstanceRootPassword = viper.GetInt64("rootPassword") + + viper.BindPFlag("userData", cmd.Flags().Lookup("userData")) + reinstallInstanceUserData = viper.GetString("userData") + instanceId64, err := strconv.ParseInt(args[0], 10, 64) if err != nil { - log.Fatal(fmt.Sprintf("Specified instanceId %v is not valid", args[0])) + log.Fatal(fmt.Sprintf("Provided instanceId %v is not valid", args[0])) } - instanceId = instanceId64 - if viper.GetString("imageId") != "" { - instanceImageId = viper.GetString("imageId") + if contaboCmd.InputFile == "" { + // arguments required + if reinstallInstanceImageId == "" { + cmd.Help() + log.Fatal("Argument imageId is empty. Please provide one.") + } } + reinstallInstanceId = instanceId64 + return nil }, } func init() { contaboCmd.ReinstallCmd.AddCommand(instanceReinstallCmd) - instanceReinstallCmd.Flags().StringVarP(&instanceImageId, "imageId", "", "", `instance image id. Defaults to last used imageId and falls back to Ubuntu 20.04 in case it is no longer available.`) - viper.BindPFlag("imageId", instanceReinstallCmd.Flags().Lookup("imageId")) + instanceReinstallCmd.Flags().StringVar(&reinstallInstanceImageId, "imageId", "", + `instance image id.`) - instanceReinstallCmd.Flags().Int64SliceVar(&instanceSshKeys, "sshKeys", nil, `ids of stored SSH public keys. Applicable for Linux/BSD systems.`) - viper.BindPFlag("sshKeys", instanceReinstallCmd.Flags().Lookup("sshKeys")) + instanceReinstallCmd.Flags().Int64SliceVar(&reinstallInstanceSshKeys, "sshKeys", nil, + `ids of stored SSH public keys. Applicable for Linux/BSD systems.`) - instanceReinstallCmd.Flags().Int64VarP(&instanceRootPassword, "rootPassword", "", 0, `id of stored password. User is admin with admistrative/root privileges. For Linux/BSD based systems please use SSH. For Windows please use RDP.`) - viper.BindPFlag("rootPassword", instanceReinstallCmd.Flags().Lookup("rootPassword")) + instanceReinstallCmd.Flags().Int64Var(&reinstallInstanceRootPassword, "rootPassword", 0, + `id of stored password. User is admin with admistrative/root privileges. For Linux/BSD based systems please use SSH. For Windows please use RDP.`) - instanceReinstallCmd.Flags().StringVarP(&instanceUserData, "userData", "", "", `instance user data`) - viper.BindPFlag("userData", instanceReinstallCmd.Flags().Lookup("userData")) + instanceReinstallCmd.Flags().StringVar(&reinstallInstanceUserData, "userData", "", + `instance user data`) } diff --git a/cmd/instances/vars.go b/cmd/instances/vars.go index aff1195..e77930f 100644 --- a/cmd/instances/vars.go +++ b/cmd/instances/vars.go @@ -1,15 +1,42 @@ package cmd +// cancel var ( - instanceIdFilter int64 - instanceNameFilter string - instanceId int64 - instanceImageId string - instanceProductId string - instanceRegion string - instanceSshKeys []int64 - instanceRootPassword int64 - instanceUserData string - instancePeriod int64 - instanceLicense string + cancelInstanceId int64 +) + +// create +var ( + createInstanceImageId string + createInstanceProductId string + createInstanceRegion string + createInstanceSshKeys []int64 + createInstanceRootPassword int64 + createInstanceUserData string + createInstancePeriod int64 + createInstanceLicense string +) + +// get +var ( + getInstanceId int64 +) + +// history +var ( + historyInstanceIdFilter int64 +) + +// list +var ( + listInstanceNameFilter string +) + +// reinstall +var ( + reinstallInstanceId int64 + reinstallInstanceImageId string + reinstallInstanceSshKeys []int64 + reinstallInstanceRootPassword int64 + reinstallInstanceUserData string ) diff --git a/cmd/roles/create.go b/cmd/roles/create.go index cab5c40..5c50d45 100644 --- a/cmd/roles/create.go +++ b/cmd/roles/create.go @@ -17,29 +17,41 @@ import ( ) var roleCreateCmd = &cobra.Command{ - Use: "role [permissionType]", - Short: "Creates a new role", - Long: `Creates a new role based on a json/yaml that is provided`, + Use: "role", + Short: "Creates a new role.", + Long: `Creates a new role based on a json/yaml that is provided.`, Run: func(cmd *cobra.Command, args []string) { createRoleRequest := *userManagementClient.NewCreateRoleRequestWithDefaults() content := contaboCmd.OpenStdinOrFile() switch content { case nil: - // fdk rom arguments - createRoleRequest.Name = name - if permissionType == "apiPermission" { - var apiPermissionType []userManagementClient.ApiPermissionsResponse - err := json.Unmarshal([]byte(apiPermissions), &apiPermissionType) - + // from arguments + createRoleRequest.Name = createName + createRoleRequest.Admin = createAdmin + createRoleRequest.AccessAllResources = createAccessAllResources + + if createPermissions != "" { + var permissionsRequest []userManagementClient.PermissionRequest + err := json.Unmarshal([]byte(createPermissions), &permissionsRequest) if err != nil { - log.Error("I am going to fail now as there is an error") - log.Fatal(fmt.Sprintf("Format of api permission invalid. Please check you syntax: %v", err)) + log.Error("Invalid `permissions`. Please check the JSON syntax.") + log.Fatal(fmt.Sprintf("Error: %v", err)) } - createRoleRequest.ApiPermissions = &apiPermissionType - } - if permissionType == "resourcePermission" { - createRoleRequest.ResourcePermissions = resourceTagList + for index, permission := range permissionsRequest { + if len(permission.Actions) < 1 { + log.Fatal("Please make sure each permission has at least one action.") + } + // add empty array to resources list if it is not given + if permission.Resources == nil { + resources := make([]int64, 0) + permissionsRequest[index].Resources = &resources + } + } + createRoleRequest.Permissions = &permissionsRequest + } else if createAdmin { + createdAdmin := make([]userManagementClient.PermissionRequest, 0) + createRoleRequest.Permissions = &createdAdmin } default: // from file / stdin @@ -51,7 +63,8 @@ var roleCreateCmd = &cobra.Command{ // merge createRoleRequest with one from file to have the defaults there json.NewDecoder(strings.NewReader(string(content))).Decode(&createRoleRequest) } - resp, httpResp, err := client.ApiClient().RolesApi.CreateRole(context.Background(), "apiPermission"). + + resp, httpResp, err := client.ApiClient().RolesApi.CreateRole(context.Background()). XRequestId(uuid.NewV4().String()).CreateRoleRequest(createRoleRequest).Execute() util.HandleErrors(err, httpResp, "creating role") @@ -61,31 +74,35 @@ var roleCreateCmd = &cobra.Command{ Args: func(cmd *cobra.Command, args []string) error { contaboCmd.ValidateCreateInput() - if len(args) > 1 { + if len(args) > 0 { cmd.Help() - log.Fatal("you can only provide one permission type") + log.Fatal("Too many positional arguments.") } - if len(args) < 1 { - cmd.Help() - log.Fatal("Missing permission type please provide one of the following apiPermission or resourcePermission") - } + viper.BindPFlag("name", cmd.Flags().Lookup("name")) + createName = viper.GetString("name") - if viper.GetString("name") != "" { - name = viper.GetString("name") - } + viper.BindPFlag("permissions", cmd.Flags().Lookup("permissions")) + createPermissions = viper.GetString("permissions") - permissionType = args[0] + viper.BindPFlag("admin", cmd.Flags().Lookup("admin")) + createAdmin = viper.GetBool("admin") - if permissionType != "apiPermission" && permissionType != "resourcePermission" { - cmd.Help() - log.Fatal("Permission type can only be on of the following either apiPermission or resourcePermission") - } + viper.BindPFlag("accessAllResources", cmd.Flags().Lookup("accessAllResources")) + createAccessAllResources = viper.GetBool("accessAllResources") if contaboCmd.InputFile == "" { // arguments required - if name == "" { - log.Fatal("name is empty. Please provide one.") + if createName == "" { + cmd.Help() + log.Fatal("Argument name is empty. Please provide one.") + } + if createPermissions == "" && !createAdmin { + cmd.Help() + log.Fatal("Argument permissions is empty. Please provide at least one permission.") + } + if createAdmin { + createAccessAllResources = true } } return nil @@ -95,12 +112,14 @@ var roleCreateCmd = &cobra.Command{ func init() { contaboCmd.CreateCmd.AddCommand(roleCreateCmd) - roleCreateCmd.Flags().StringVar(&name, "name", "", `name of the role`) - viper.BindPFlag("name", roleCreateCmd.Flags().Lookup("name")) + roleCreateCmd.Flags().StringVarP(&createName, "name", "n", "", `name of the role`) + + roleCreateCmd.Flags().StringVarP(&createPermissions, "permissions", "p", "", + "provide an array of json objects with the permissions including the apiName, the actions and the resources") - roleCreateCmd.Flags().StringVarP(&apiPermissions, "apiPermission", "a", "", - "provide an array of json objects with the permissions including the api and the actions") + roleCreateCmd.Flags().BoolVar(&createAdmin, "admin", false, + `If user is admin he will have permissions to all API endpoints and resources.`) - roleCreateCmd.Flags().Int64SliceVarP(&resourceTagList, "resourcePermission", "r", nil, - "provide an array of json objects with the permissions including the api and the actions") + roleCreateCmd.Flags().BoolVar(&createAccessAllResources, "accessAllResources", false, + `Allow access to all resources. This will superseed all assigned resources in a role.`) } diff --git a/cmd/roles/delete.go b/cmd/roles/delete.go index fbfb1fa..697ef21 100644 --- a/cmd/roles/delete.go +++ b/cmd/roles/delete.go @@ -14,37 +14,32 @@ import ( ) var roleDeleteCmd = &cobra.Command{ - Use: "role [permissionType] [roleId]", + Use: "role [roleId]", Short: "Deletes a specific role", - Long: `Specify a role id to delete the specified tag. A role might not be deleted if it is still assigned.`, + Long: `Specify a role id to delete. A role might not be deleted if it is still assigned.`, Run: func(cmd *cobra.Command, args []string) { httpResp, err := client.ApiClient(). - RolesApi.DeleteRole(context.Background(), permissionType, roleId). + RolesApi.DeleteRole(context.Background(), deleteRoleId). XRequestId(uuid.NewV4().String()).Execute() util.HandleErrors(err, httpResp, "while deleting role") }, Args: func(cmd *cobra.Command, args []string) error { - if len(args) < 2 { + if len(args) > 1 { cmd.Help() - log.Fatal("Please specify permission type and roleId") + log.Fatal("Too many positional arguments.") } - if len(args) > 2 { + if len(args) < 1 { cmd.Help() - log.Fatal("you can only provide a permission type (apiPermission, resourcePermission) and roleId") + log.Fatal("Please provide a roleId") } - permissionType = args[0] - if permissionType != "apiPermission" && permissionType != "resourcePermission" { - cmd.Help() - log.Fatal("Permission type can only be on of the following either apiPermission or resourcePermission") - } - roleId64, err := strconv.ParseInt(args[1], 10, 64) + roleId64, err := strconv.ParseInt(args[0], 10, 64) if err != nil { - log.Fatal(fmt.Sprintf("Specified roleId %v is not valid", args[0])) + log.Fatal(fmt.Sprintf("Provided roleId %v is not valid.", args[0])) } - roleId = roleId64 + deleteRoleId = roleId64 return nil }, } diff --git a/cmd/roles/edit.go b/cmd/roles/edit.go index 756897b..fd1b9dc 100644 --- a/cmd/roles/edit.go +++ b/cmd/roles/edit.go @@ -19,12 +19,14 @@ import ( ) var roleEditCmd = &cobra.Command{ - Use: "role [permissionType] [roleId]", - Short: "Edit a specific role", - Long: `Modify an existing role in your editor`, + Use: "role [roleId]", + Short: "Edit a specific role.", + Long: `Modify an existing role in your editor.`, Run: func(cmd *cobra.Command, args []string) { // get original content - resp, httpResp, err := client.ApiClient().RolesApi.RetrieveRole(context.Background(), permissionType, roleId).XRequestId(uuid.NewV4().String()).Execute() + resp, httpResp, err := client.ApiClient().RolesApi. + RetrieveRole(context.Background(), editRoleId). + XRequestId(uuid.NewV4().String()).Execute() util.HandleErrors(err, httpResp, "while editing role") @@ -40,17 +42,6 @@ var roleEditCmd = &cobra.Command{ var requestFromNewContent userManagementClient.UpdateRoleRequest json.Unmarshal(normalizedContent, &requestFromNewContent) - if permissionType == "resourcePermission" { - // get tagIds - tagObject := resp.Data[0].ResourcePermissions - var tagIds []int64 - - for i := 0; i < len(tagObject); i++ { - tagIds = append(tagIds, tagObject[i].TagId) - } - requestFromNewContent.ResourcePermissions = tagIds - } - originalContent, _ := json.MarshalIndent(requestFromNewContent, "", " ") // launch editor with originalContent and expect newContent to be returned @@ -70,7 +61,9 @@ var roleEditCmd = &cobra.Command{ // merge updateRoleRequest with one from file to have the defaults there json.NewDecoder(strings.NewReader(string(newContent))).Decode(&updateRoleRequest) - resp, httpResp, err := client.ApiClient().RolesApi.UpdateRole(context.Background(), permissionType, roleId).UpdateRoleRequest(updateRoleRequest).XRequestId(uuid.NewV4().String()).Execute() + resp, httpResp, err := client.ApiClient().RolesApi. + UpdateRole(context.Background(), editRoleId). + UpdateRoleRequest(updateRoleRequest).XRequestId(uuid.NewV4().String()).Execute() util.HandleErrors(err, httpResp, "while editing role") @@ -79,26 +72,21 @@ var roleEditCmd = &cobra.Command{ } }, Args: func(cmd *cobra.Command, args []string) error { - if len(args) < 2 { + if len(args) < 1 { cmd.Help() - log.Fatal("Please specify permission type and roleId") + log.Fatal("Please specify a roleId.") } - if len(args) > 2 { + if len(args) > 1 { cmd.Help() - log.Fatal("you can only provide a permission type (apiPermission, resourcePermission) and roleId") + log.Fatal("Too many positional arguments.") } - permissionType = args[0] - if permissionType != "apiPermission" && permissionType != "resourcePermission" { - cmd.Help() - log.Fatal("Permission type can only be on of the following either apiPermission or resourcePermission") - } roleId64, err := strconv.ParseInt(args[1], 10, 64) if err != nil { - log.Fatal(fmt.Sprintf("Specified roleId %v is not valid", args[0])) + log.Fatal(fmt.Sprintf("Specified roleId %v is not valid.", args[0])) } - roleId = roleId64 + editRoleId = roleId64 return nil }, } diff --git a/cmd/roles/get.go b/cmd/roles/get.go index d027876..4c9db31 100644 --- a/cmd/roles/get.go +++ b/cmd/roles/get.go @@ -16,42 +16,44 @@ import ( ) var roleGetCmd = &cobra.Command{ - Use: "role [type] [roleId]", + Use: "role [roleId]", Short: "Info about a specific role", - Long: `Retrieves information about one role identified by type and id. available permission types are resourcePermission and apiPermission`, + Long: `Retrieves information about one role identified by id.`, Run: func(cmd *cobra.Command, args []string) { - resp, httpResp, err := client.ApiClient().RolesApi.RetrieveRole(context.Background(), permissionType, roleId). + resp, httpResp, err := client.ApiClient().RolesApi. + RetrieveRole(context.Background(), getRoleId). XRequestId(uuid.NewV4().String()).Execute() util.HandleErrors(err, httpResp, "while retrieving role") responseJson, _ := json.Marshal(resp.Data) - configFormatter = outputFormatter.FormatterConfig{ + configFormatter := outputFormatter.FormatterConfig{ Filter: []string{"roleId", "name"}, - WideFilter: []string{"roleId", "name"}, + WideFilter: []string{"roleId", "name", "admin", "accessAllResources", "permissions"}, JsonPath: contaboCmd.OutputFormatDetails, } util.HandleResponse(responseJson, configFormatter) }, Args: func(cmd *cobra.Command, args []string) error { - if len(args) < 2 { + contaboCmd.ValidateOutputFormat() + + if len(args) < 1 { cmd.Help() - log.Fatal("Please specify type and ") + log.Fatal("Please provide a roleId.") } - permissionType = args[0] - if permissionType != "apiPermission" && permissionType != "resourcePermission" { + if len(args) > 1 { cmd.Help() - log.Fatal("Permission type can only be on of the following either apiPermission or resourcePermission") + log.Fatal("Too many positional arguments.") } - permissionId64, err := strconv.ParseInt(args[1], 10, 64) + roleId, err := strconv.ParseInt(args[0], 10, 64) if err != nil { - log.Fatal(fmt.Sprintf("Specified permissionId64 %v is not valid", args[0])) + log.Fatal(fmt.Sprintf("Provided roleId %v is not valid.", args[0])) } - roleId = permissionId64 - contaboCmd.ValidateOutputFormat() + getRoleId = roleId + return nil }, } diff --git a/cmd/roles/history.go b/cmd/roles/history.go index 7c22788..684863e 100644 --- a/cmd/roles/history.go +++ b/cmd/roles/history.go @@ -8,6 +8,7 @@ import ( "contabo.com/cli/cntb/cmd/util" "contabo.com/cli/cntb/outputFormatter" uuid "github.com/satori/go.uuid" + log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" ) @@ -24,16 +25,8 @@ var roleHistoryCmd = &cobra.Command{ Size(contaboCmd.Size). OrderBy([]string{contaboCmd.OrderBy}) - if cmd.Flags().Changed("roleId") { - historyRequest = historyRequest.RoleId(roleIdFilter) - } - - if cmd.Flags().Changed("requestId") { - historyRequest = historyRequest.RequestId(contaboCmd.RequestIdFilter) - } - - if cmd.Flags().Changed("changedBy") { - historyRequest = historyRequest.ChangedBy(contaboCmd.ChangedByFilter) + if historyRoleIdFilter != 0 { + historyRequest = historyRequest.RoleId(historyRoleIdFilter) } resp, httpResp, err := historyRequest.Execute() @@ -53,6 +46,14 @@ var roleHistoryCmd = &cobra.Command{ Args: func(cmd *cobra.Command, args []string) error { contaboCmd.ValidateOutputFormat() + if len(args) > 0 { + cmd.Help() + log.Fatal("Too many positional arguments.") + } + + viper.BindPFlag("roleId", cmd.Flags().Lookup("roleId")) + historyRoleIdFilter = viper.GetInt64("roleId") + return nil }, } @@ -60,7 +61,6 @@ var roleHistoryCmd = &cobra.Command{ func init() { contaboCmd.HistoryCmd.AddCommand(roleHistoryCmd) - roleHistoryCmd.Flags().Int64VarP(&roleIdFilter, "roleId", "u", -1, + roleHistoryCmd.Flags().Int64VarP(&historyRoleIdFilter, "roleId", "u", 0, `to filter audits using role id`) - viper.BindPFlag("roleId", roleHistoryCmd.Flags().Lookup("roleId")) } diff --git a/cmd/roles/list.go b/cmd/roles/list.go index 3815ab2..2de3837 100644 --- a/cmd/roles/list.go +++ b/cmd/roles/list.go @@ -3,7 +3,6 @@ package cmd import ( "context" "encoding/json" - "os" "contabo.com/cli/cntb/client" contaboCmd "contabo.com/cli/cntb/cmd" @@ -16,23 +15,25 @@ import ( ) var rolesGetCmd = &cobra.Command{ - Use: "roles [type]", + Use: "roles", Short: "All about your role for a specific type", Long: `Retrieves information about one or multiple roles for a specific permission type. Filter by name and apiName or tag name`, Run: func(cmd *cobra.Command, args []string) { ApiRetrieveRolesList := client.ApiClient().RolesApi. - RetrieveRoleList(context.Background(), permissionType). + RetrieveRoleList(context.Background()). XRequestId(uuid.NewV4().String()). Page(contaboCmd.Page). Size(contaboCmd.Size). OrderBy([]string{contaboCmd.OrderBy}) - if cmd.Flags().Changed("tagName") { - ApiRetrieveRolesList = ApiRetrieveRolesList.Name(nameFilter) + if listRoleNameFilter != "" { + ApiRetrieveRolesList = ApiRetrieveRolesList.Name(listRoleNameFilter) } - - if cmd.Flags().Changed("apiName") { - ApiRetrieveRolesList = ApiRetrieveRolesList.ApiName(apiNameFilter) + if listTagNameFilter != "" { + ApiRetrieveRolesList = ApiRetrieveRolesList.TagName(listTagNameFilter) + } + if listApiNameFilter != "" { + ApiRetrieveRolesList = ApiRetrieveRolesList.ApiName(listApiNameFilter) } resp, httpResp, err := ApiRetrieveRolesList.Execute() @@ -41,51 +42,30 @@ var rolesGetCmd = &cobra.Command{ responseJson, _ := json.Marshal(resp.Data) - if permissionType == "resourcePermission" { - configFormatter = outputFormatter.FormatterConfig{ - Filter: []string{"roleId", "name"}, - WideFilter: []string{"roleId", "tenantId", "customerId", "name", "resourcePermissions"}, - JsonPath: contaboCmd.OutputFormatDetails} - } else { - configFormatter = outputFormatter.FormatterConfig{ - Filter: []string{"roleId", "name"}, - WideFilter: []string{"roleId", "name"}, - JsonPath: contaboCmd.OutputFormatDetails} - } + configFormatter := outputFormatter.FormatterConfig{ + Filter: []string{"roleId", "name"}, + WideFilter: []string{"roleId", "name", "admin", "accessAllResources", "permissions"}, + JsonPath: contaboCmd.OutputFormatDetails} util.HandleResponse(responseJson, configFormatter) }, Args: func(cmd *cobra.Command, args []string) error { contaboCmd.ValidateOutputFormat() - if len(args) > 1 { - cmd.Help() - os.Exit(0) - } - if len(args) < 1 { - cmd.Help() - log.Fatal("please provide a permission type ") - } - - permissionType = args[0] - if permissionType != "apiPermission" && permissionType != "resourcePermission" { + if len(args) > 0 { cmd.Help() - log.Fatal("Permission type can only be on of the following either apiPermission or resourcePermission") + log.Fatal("Too many positional arguments.") } - if permissionType == "resourcePermission" && apiNameFilter != "" { - cmd.Help() - log.Fatal("you can't filter on API name with type resource permission") - } + viper.BindPFlag("name", cmd.Flags().Lookup("name")) + listRoleNameFilter = viper.GetString("name") - if permissionType == "apiPermission" && resourceNameFilter != "" { - cmd.Help() - log.Fatal("you can't filter on resource name with type api permission") - } + viper.BindPFlag("tagName", cmd.Flags().Lookup("tagName")) + listTagNameFilter = viper.GetString("tagName") + + viper.BindPFlag("apiName", cmd.Flags().Lookup("apiName")) + listApiNameFilter = viper.GetString("apiName") - if cmd.Flags().Changed("name") { - nameFilter = viper.GetString("name") - } return nil }, } @@ -93,12 +73,12 @@ var rolesGetCmd = &cobra.Command{ func init() { contaboCmd.GetCmd.AddCommand(rolesGetCmd) - rolesGetCmd.Flags().StringVarP(&nameFilter, "tagName", "n", "", + rolesGetCmd.Flags().StringVarP(&listRoleNameFilter, "name", "n", "", + `Filter by role name`) + + rolesGetCmd.Flags().StringVar(&listTagNameFilter, "tagName", "", `Filter by tag name`) - viper.BindPFlag("tagName", rolesGetCmd.Flags().Lookup("tagName")) - rolesGetCmd.Flags().StringVarP(&apiNameFilter, "apiName", "a", "", + rolesGetCmd.Flags().StringVar(&listApiNameFilter, "apiName", "", `filter by api name if the type of role is an api role`) - viper.BindPFlag("apiName", rolesGetCmd.Flags().Lookup("apiName")) - } diff --git a/cmd/roles/listApiPermission.go b/cmd/roles/listApiPermission.go index 489d2a6..eb388c2 100644 --- a/cmd/roles/listApiPermission.go +++ b/cmd/roles/listApiPermission.go @@ -2,23 +2,25 @@ package cmd import ( "context" + "encoding/json" "contabo.com/cli/cntb/client" contaboCmd "contabo.com/cli/cntb/cmd" "contabo.com/cli/cntb/cmd/util" "contabo.com/cli/cntb/outputFormatter" uuid "github.com/satori/go.uuid" + log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" ) var permissionGetCommand = &cobra.Command{ Use: "permissions", - Short: "All about the available servies and actions allowed", - Long: `Retrieves information about one or multiple apis and the actions that are allowed to be performed on them. Filter by apiName`, + Short: "All about the available servies and actions allowed.", + Long: `Retrieves information about one or multiple apis and the actions that are allowed to be performed on them. Filter by apiName.`, Run: func(cmd *cobra.Command, args []string) { - ApiPermissionRetrivelList := client.ApiClient().RolesApi. + ApiPermissionRetrieveList := client.ApiClient().RolesApi. RetrieveApiPermissionsList(context.Background()). XRequestId(uuid.NewV4().String()). Page(contaboCmd.Page). @@ -26,28 +28,41 @@ var permissionGetCommand = &cobra.Command{ OrderBy([]string{contaboCmd.OrderBy}) if cmd.Flags().Changed("apiName") { - ApiPermissionRetrivelList = ApiPermissionRetrivelList.ApiName(apiNameFilter) + ApiPermissionRetrieveList = ApiPermissionRetrieveList.ApiName(listapipermissionsApiNameFilter) } - resp, httpResp, err := ApiPermissionRetrivelList.Execute() + resp, httpResp, err := ApiPermissionRetrieveList.Execute() util.HandleErrors(err, httpResp, "while retrieving api permissions") - responseJson, _ := resp.MarshalJSON() + responseJson, _ := json.Marshal(resp.Data) - configFormatter = outputFormatter.FormatterConfig{ - Filter: []string{"apiname", "actions"}, - WideFilter: []string{"tenantId", "customerId", "apiname", "actions"}, - JsonPath: contaboCmd.OutputFormatDetails} + configFormatter := outputFormatter.FormatterConfig{ + Filter: []string{"apiName", "actions"}, + WideFilter: []string{"tenantId", "customerId", "apiName", "actions"}, + JsonPath: contaboCmd.OutputFormatDetails, + } util.HandleResponse(responseJson, configFormatter) }, + Args: func(cmd *cobra.Command, args []string) error { + contaboCmd.ValidateOutputFormat() + + if len(args) > 0 { + cmd.Help() + log.Fatal("Too many positional arguments.") + } + + viper.BindPFlag("apiName", cmd.Flags().Lookup("apiName")) + listapipermissionsApiNameFilter = viper.GetString("apiName") + + return nil + }, } func init() { contaboCmd.GetCmd.AddCommand(permissionGetCommand) - permissionGetCommand.Flags().StringVarP(&apiNameFilter, "apiName", "a", "", + permissionGetCommand.Flags().StringVarP(&listapipermissionsApiNameFilter, "apiName", "a", "", `filter by api name if the type of role is an api role`) - viper.BindPFlag("apiName", permissionGetCommand.Flags().Lookup("apiName")) } diff --git a/cmd/roles/update.go b/cmd/roles/update.go index 673c977..f04ce70 100644 --- a/cmd/roles/update.go +++ b/cmd/roles/update.go @@ -18,9 +18,9 @@ import ( ) var roleUpdateCmd = &cobra.Command{ - Use: "role [permissionType] [roleId]", - Short: "Updates a specific tag", - Long: `Updates the specific tag by setting new values either by file input or flags / environment variables`, + Use: "role [roleId]", + Short: "Updates a specific tag.", + Long: `Updates the specific tag by setting new values either by file input or flags / environment variables.`, Run: func(cmd *cobra.Command, args []string) { roleUpdateRequest := *userManagementClient.NewUpdateRoleRequestWithDefaults() @@ -28,35 +28,48 @@ var roleUpdateCmd = &cobra.Command{ switch content { case nil: // from arguments - roleUpdateRequest.Name = name + roleUpdateRequest.Name = updateName + roleUpdateRequest.Admin = updateAdmin + roleUpdateRequest.AccessAllResources = updateAccessAllResources - if permissionType == "apiPermission" { - - var apiPermissionType []userManagementClient.ApiPermissionsResponse - err := json.Unmarshal([]byte(apiPermissions), &apiPermissionType) + if updatePermissions != "" { + var permissionsRequest []userManagementClient.PermissionRequest + err := json.Unmarshal([]byte(updatePermissions), &permissionsRequest) if err != nil { - log.Fatal(fmt.Sprintf("Format of api permission invalid. Please check you syntax: %v", err)) + log.Error("Invalid `permissions`. Please check the JSON syntax.") + log.Fatal(fmt.Sprintf("Error: %v", err)) } - roleUpdateRequest.ApiPermissions = &apiPermissionType - } + for index, permission := range permissionsRequest { + if len(permission.Actions) < 1 { + log.Fatal("Please make sure each permission has at least one action.") + } + // add empty array to resources list if it is not given + if permission.Resources == nil { + resources := make([]int64, 0) + permissionsRequest[index].Resources = &resources + } + } - if permissionType == "requestPermission" { - roleUpdateRequest.ResourcePermissions = resourceTagList + roleUpdateRequest.Permissions = &permissionsRequest + } else if updateAdmin { + // make permissions empty array if admin is set + updatedAdmin := make([]userManagementClient.PermissionRequest, 0) + roleUpdateRequest.Permissions = &updatedAdmin } - default: // from file / stdin var requestFromFile userManagementClient.UpdateRoleRequest err := json.Unmarshal(content, &requestFromFile) if err != nil { - log.Fatal(fmt.Sprintf("Format invalid. Please check your syntax: %v", err)) + log.Fatal(fmt.Sprintf("Format invalid. Please check the syntax: %v", err)) } // merge roleUpdateRequest with one from file to have the defaults there json.NewDecoder(strings.NewReader(string(content))).Decode(&roleUpdateRequest) } - resp, httpResp, err := client.ApiClient().RolesApi.UpdateRole(context.Background(), permissionType, roleId).XRequestId(uuid.NewV4().String()). + resp, httpResp, err := client.ApiClient().RolesApi. + UpdateRole(context.Background(), updateRoleId).XRequestId(uuid.NewV4().String()). UpdateRoleRequest(roleUpdateRequest).Execute() util.HandleErrors(err, httpResp, "while updating role") @@ -66,38 +79,46 @@ var roleUpdateCmd = &cobra.Command{ }, Args: func(cmd *cobra.Command, args []string) error { contaboCmd.ValidateCreateInput() - if len(args) < 2 { + + if len(args) > 1 { cmd.Help() - log.Fatal("please provide permission type and permission id") + log.Fatal("Too many positional arguments.") } - - if len(args) > 2 { + if len(args) < 1 { cmd.Help() - log.Fatal("you can only provide permission type (apiPermission, resourcePermission) and permission id") + log.Fatal("Please provide a roleId") } - permissionType = args[0] + viper.BindPFlag("name", cmd.Flags().Lookup("name")) + updateName = viper.GetString("name") - if permissionType != "apiPermission" && permissionType != "resourcePermission" { - cmd.Help() - log.Fatal("Permission type can only be on of the following either apiPermission or resourcePermission") - } + viper.BindPFlag("permissions", cmd.Flags().Lookup("permissions")) + updatePermissions = viper.GetString("permissions") + + viper.BindPFlag("admin", cmd.Flags().Lookup("admin")) + updateAdmin = viper.GetBool("admin") - permissionId64, err := strconv.ParseInt(args[1], 10, 64) + viper.BindPFlag("accessAllResources", cmd.Flags().Lookup("accessAllResources")) + updateAccessAllResources = viper.GetBool("accessAllResources") + + roleId, err := strconv.ParseInt(args[0], 10, 64) if err != nil { - log.Fatal(fmt.Sprintf("Specified permissionId %v is not valid", args[1])) + log.Fatal(fmt.Sprintf("Provided roleId %v is not valid.", args[1])) } - roleId = permissionId64 + updateRoleId = roleId - if viper.GetString("name") != "" { - name = viper.GetString("name") - } if contaboCmd.InputFile == "" { // arguments required - if name == "" && apiPermissions == "" && resourceTagList == nil { - log.Fatal("missing file") + if updateName == "" { + cmd.Help() + log.Fatal("Argument name is empty. Please provide one.") + } + if updatePermissions == "" && !updateAdmin { + cmd.Help() + log.Fatal("Argument permissions is empty. Please provide one or set admin flag.") } } + return nil }, } @@ -105,13 +126,14 @@ var roleUpdateCmd = &cobra.Command{ func init() { contaboCmd.UpdateCmd.AddCommand(roleUpdateCmd) - roleUpdateCmd.Flags().StringVar(&name, "name", "", `name of the role`) - viper.BindPFlag("name", roleUpdateCmd.Flags().Lookup("name")) - viper.SetDefault("name", "") + roleUpdateCmd.Flags().StringVarP(&updateName, "name", "n", "", `Name of the role.`) + + roleUpdateCmd.Flags().StringVarP(&updatePermissions, "permissions", "p", "", + "Provide an array of json objects with the permissions including the apiName, the actions and the resources.") - roleUpdateCmd.Flags().StringVarP(&apiPermissions, "apiPermission", "a", "", "provide an array of json objects with the permissions including the api and the actions") - viper.BindPFlag("apiPermission", roleUpdateCmd.Flags().Lookup("apiPermission")) + roleUpdateCmd.Flags().BoolVar(&updateAdmin, "admin", false, + `If user is admin he will have permissions to all API endpoints and resources.`) - roleUpdateCmd.Flags().Int64SliceVarP(&resourceTagList, "resourcePermission", "r", nil, "provide an array of json objects with the permissions including the api and the actions") - viper.BindPFlag("resourcePermission", roleCreateCmd.Flags().Lookup("resourcePermission")) + roleUpdateCmd.Flags().BoolVar(&updateAccessAllResources, "accessAllResources", false, + `Allow access to all resources. This will superseed all assigned resources in a role.`) } diff --git a/cmd/roles/vars.go b/cmd/roles/vars.go index f0430cd..bc0e350 100644 --- a/cmd/roles/vars.go +++ b/cmd/roles/vars.go @@ -1,18 +1,50 @@ package cmd -import "contabo.com/cli/cntb/outputFormatter" - -var ( - name string - action []string - apiPermissions string - resourceTagList []int64 - roleId int64 - roleIdFilter int64 - parseError error - nameFilter string - apiNameFilter string - resourceNameFilter string - permissionType string - configFormatter outputFormatter.FormatterConfig +// create +var ( + createName string + createPermissions string + createAccessAllResources bool + createAdmin bool +) + +// delete +var ( + deleteRoleId int64 +) + +// edit +var ( + editRoleId int64 +) + +// get +var ( + getRoleId int64 +) + +// history +var ( + historyRoleIdFilter int64 +) + +// list +var ( + listRoleNameFilter string + listTagNameFilter string + listApiNameFilter string +) + +// listApiPermissions +var ( + listapipermissionsApiNameFilter string +) + +// update +var ( + updateName string + updatePermissions string + updateRoleId int64 + updateAccessAllResources bool + updateAdmin bool ) diff --git a/cmd/secrets/create.go b/cmd/secrets/create.go index 62a7f6a..addf9db 100644 --- a/cmd/secrets/create.go +++ b/cmd/secrets/create.go @@ -4,7 +4,6 @@ import ( "context" "encoding/json" "fmt" - "os" "strings" "contabo.com/cli/cntb/client" @@ -19,7 +18,7 @@ import ( var secretCreateCmd = &cobra.Command{ Use: "secret", - Short: "Creates a new secret", + Short: "Creates a new secret.", Long: `Creates a new secret based on json / yaml input or arguments.`, Example: `cntb create secret --name 'First Secret' ` + `--value 'secret' ` + @@ -31,9 +30,9 @@ var secretCreateCmd = &cobra.Command{ switch content { case nil: - createSecretRequest.Name = secretName - createSecretRequest.Type = secretType - createSecretRequest.Value = secretValue + createSecretRequest.Name = createSecretName + createSecretRequest.Type = createSecretType + createSecretRequest.Value = createSecretValue default: // from file / stdin var requestFromFile secretClient.CreateSecretRequest @@ -59,39 +58,36 @@ var secretCreateCmd = &cobra.Command{ Args: func(cmd *cobra.Command, args []string) error { contaboCmd.ValidateCreateInput() - if viper.GetString("name") != "" { - secretName = viper.GetString("name") + if len(args) > 0 { + cmd.Help() + log.Fatal("Too many positional arguments.") } - if viper.GetString("value") != "" { - secretValue = viper.GetString("value") - } + viper.BindPFlag("name", cmd.Flags().Lookup("name")) + createSecretName = viper.GetString("name") - if viper.GetString("type") != "" { - secretType = viper.GetString("type") - } + viper.BindPFlag("value", cmd.Flags().Lookup("value")) + createSecretValue = viper.GetString("value") + + viper.BindPFlag("type", cmd.Flags().Lookup("type")) + createSecretType = viper.GetString("type") if contaboCmd.InputFile == "" { // arguments required - if secretName == "" { + if createSecretName == "" { cmd.Help() log.Fatal("Argument name is empty. Please provide one.") } - if secretValue == "" { + if createSecretValue == "" { cmd.Help() log.Fatal("Argument value is empty. Please provide one.") } - if secretType == "" { + if createSecretType == "" { cmd.Help() log.Fatal("Argument type is empty. Please provide one.") } } - if len(args) > 0 { - cmd.Help() - os.Exit(0) - } - return nil }, } @@ -99,15 +95,12 @@ var secretCreateCmd = &cobra.Command{ func init() { contaboCmd.CreateCmd.AddCommand(secretCreateCmd) - secretCreateCmd.Flags().StringVar(&secretName, "name", "", + secretCreateCmd.Flags().StringVar(&createSecretName, "name", "", `name of the secret`) - viper.BindPFlag("name", secretCreateCmd.Flags().Lookup("name")) - secretCreateCmd.Flags().StringVar(&secretValue, "value", "", + secretCreateCmd.Flags().StringVar(&createSecretValue, "value", "", `value of the secret`) - viper.BindPFlag("value", secretCreateCmd.Flags().Lookup("value")) - secretCreateCmd.Flags().StringVar(&secretType, "type", "", + secretCreateCmd.Flags().StringVar(&createSecretType, "type", "", `type of the secret, either password or ssh`) - viper.BindPFlag("type", secretCreateCmd.Flags().Lookup("type")) } diff --git a/cmd/secrets/delete.go b/cmd/secrets/delete.go index b00bc91..dfd09b2 100644 --- a/cmd/secrets/delete.go +++ b/cmd/secrets/delete.go @@ -3,7 +3,6 @@ package cmd import ( "context" "fmt" - "os" "strconv" "contabo.com/cli/cntb/client" @@ -21,7 +20,7 @@ var secretDeleteCmd = &cobra.Command{ Example: `cntb delete secret 21`, Run: func(cmd *cobra.Command, args []string) { httpResp, err := client.ApiClient().SecretsApi. - DeleteSecret(context.Background(), secretId). + DeleteSecret(context.Background(), deleteSecretId). XRequestId(uuid.NewV4().String()).Execute() util.HandleErrors(err, httpResp, "while deleting secret") @@ -33,18 +32,18 @@ var secretDeleteCmd = &cobra.Command{ if len(args) > 1 { cmd.Help() - os.Exit(0) + log.Fatal("Too many positional arguments.") } if len(args) < 1 { cmd.Help() - log.Fatal("please provide a secretId") + log.Fatal("Please provide a secretId.") } secretId64, err := strconv.ParseInt(args[0], 10, 64) if err != nil { - log.Fatal(fmt.Sprintf("Specified secretId %v is not valid", args[0])) + log.Fatal(fmt.Sprintf("Provided secretId %v is not valid.", args[0])) } - secretId = secretId64 + deleteSecretId = secretId64 return nil }, diff --git a/cmd/secrets/edit.go b/cmd/secrets/edit.go index ddc192b..06ccb01 100644 --- a/cmd/secrets/edit.go +++ b/cmd/secrets/edit.go @@ -25,7 +25,7 @@ var secretEditCmd = &cobra.Command{ Run: func(cmd *cobra.Command, args []string) { // get original content resp, httpResp, err := client.ApiClient(). - SecretsApi.RetrieveSecret(context.Background(), secretId). + SecretsApi.RetrieveSecret(context.Background(), editSecretId). XRequestId(uuid.NewV4().String()). Execute() @@ -63,7 +63,7 @@ var secretEditCmd = &cobra.Command{ json.NewDecoder(strings.NewReader(string(newContent))).Decode(&updateSecretRequest) resp, httpResp, err := client.ApiClient().SecretsApi. - UpdateSecret(context.Background(), secretId). + UpdateSecret(context.Background(), editSecretId). UpdateSecretRequest(updateSecretRequest). XRequestId(uuid.NewV4().String()). Execute() @@ -75,16 +75,22 @@ var secretEditCmd = &cobra.Command{ } }, Args: func(cmd *cobra.Command, args []string) error { + contaboCmd.ValidateCreateInput() + + if len(args) > 1 { + cmd.Help() + log.Fatal("Too many positional arguments.") + } if len(args) < 1 { cmd.Help() - log.Fatal("Please specify secretId") + log.Fatal("Please provide a secretId.") } secretId64, err := strconv.ParseInt(args[0], 10, 64) if err != nil { - log.Fatal(fmt.Sprintf("Specified secretId %v is not valid", args[0])) + log.Fatal(fmt.Sprintf("Provided secretId %v is not valid.", args[0])) } - secretId = secretId64 + editSecretId = secretId64 return nil }, diff --git a/cmd/secrets/get.go b/cmd/secrets/get.go index f4660f7..1cb5cde 100644 --- a/cmd/secrets/get.go +++ b/cmd/secrets/get.go @@ -5,7 +5,6 @@ import ( "encoding/json" "fmt" "log" - "os" "strconv" "contabo.com/cli/cntb/client" @@ -23,7 +22,7 @@ var secretGetCmd = &cobra.Command{ Example: `cntb get secret 21`, Run: func(cmd *cobra.Command, args []string) { ApiRetrieveSecretRequest := client.ApiClient(). - SecretsApi.RetrieveSecret(context.Background(), secretId). + SecretsApi.RetrieveSecret(context.Background(), getSecretId). XRequestId(uuid.NewV4().String()) resp, httpResp, err := ApiRetrieveSecretRequest.Execute() @@ -46,20 +45,21 @@ var secretGetCmd = &cobra.Command{ }, Args: func(cmd *cobra.Command, args []string) error { contaboCmd.ValidateOutputFormat() + if len(args) > 1 { cmd.Help() - os.Exit(0) + log.Fatal("Too many positional arguments.") } if len(args) < 1 { cmd.Help() - log.Fatal("please provide the secretId") + log.Fatal("Please provide a secretId.") } secretId64, err := strconv.ParseInt(args[0], 10, 64) if err != nil { - log.Fatal(fmt.Sprintf("Specified secretId %v is not valid", args[0])) + log.Fatal(fmt.Sprintf("Specified secretId %v is not valid.", args[0])) } - secretId = secretId64 + getSecretId = secretId64 return nil }, diff --git a/cmd/secrets/history.go b/cmd/secrets/history.go index 347c744..b6a64dd 100644 --- a/cmd/secrets/history.go +++ b/cmd/secrets/history.go @@ -9,6 +9,7 @@ import ( "contabo.com/cli/cntb/cmd/util" "contabo.com/cli/cntb/outputFormatter" uuid "github.com/satori/go.uuid" + log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" ) @@ -25,16 +26,8 @@ var secretsHistoryCmd = &cobra.Command{ Size(contaboCmd.Size). OrderBy([]string{contaboCmd.OrderBy}) - if cmd.Flags().Changed("secretId") { - historyRequest = historyRequest.SecretId(secretIdFilter) - } - - if cmd.Flags().Changed("requestId") { - historyRequest = historyRequest.RequestId(contaboCmd.RequestIdFilter) - } - - if cmd.Flags().Changed("changedBy") { - historyRequest = historyRequest.ChangedBy(contaboCmd.ChangedByFilter) + if historySecretIdFilter != 0 { + historyRequest = historyRequest.SecretId(historySecretIdFilter) } resp, httpResp, err := historyRequest.Execute() @@ -54,6 +47,14 @@ var secretsHistoryCmd = &cobra.Command{ Args: func(cmd *cobra.Command, args []string) error { contaboCmd.ValidateOutputFormat() + if len(args) > 0 { + cmd.Help() + log.Fatal("Too many positional arguments.") + } + + viper.BindPFlag("secretId", cmd.Flags().Lookup("secretId")) + historySecretIdFilter = viper.GetInt64("secretId") + return nil }, } @@ -61,7 +62,6 @@ var secretsHistoryCmd = &cobra.Command{ func init() { contaboCmd.HistoryCmd.AddCommand(secretsHistoryCmd) - secretsHistoryCmd.Flags().Int64Var(&secretIdFilter, "secretId", -1, + secretsHistoryCmd.Flags().Int64Var(&historySecretIdFilter, "secretId", 0, `To filter audits using Secret Id`) - viper.BindPFlag("secretId", secretsHistoryCmd.Flags().Lookup("secretId")) } diff --git a/cmd/secrets/list.go b/cmd/secrets/list.go index 1b7d3bf..f0aecbe 100644 --- a/cmd/secrets/list.go +++ b/cmd/secrets/list.go @@ -3,13 +3,13 @@ package cmd import ( "context" "encoding/json" - "os" "contabo.com/cli/cntb/client" contaboCmd "contabo.com/cli/cntb/cmd" "contabo.com/cli/cntb/cmd/util" "contabo.com/cli/cntb/outputFormatter" uuid "github.com/satori/go.uuid" + log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" ) @@ -27,12 +27,14 @@ var secretsGetCmd = &cobra.Command{ Size(contaboCmd.Size). OrderBy([]string{contaboCmd.OrderBy}) - if cmd.Flags().Changed("name") { - ApiRetrieveSecretsListRequest = ApiRetrieveSecretsListRequest.Name(secretNameFilter) + if listSecretNameFilter != "" { + ApiRetrieveSecretsListRequest = ApiRetrieveSecretsListRequest. + Name(listSecretNameFilter) } - if cmd.Flags().Changed("type") { - ApiRetrieveSecretsListRequest = ApiRetrieveSecretsListRequest.Type_(secretTypeFilter) + if listSecretTypeFilter != "" { + ApiRetrieveSecretsListRequest = ApiRetrieveSecretsListRequest. + Type_(listSecretTypeFilter) } resp, httpResp, err := ApiRetrieveSecretsListRequest.Execute() @@ -43,20 +45,30 @@ var secretsGetCmd = &cobra.Command{ configFormatter := outputFormatter.FormatterConfig{ Filter: []string{ - "secretId", "name", "type"}, + "secretId", "name", "type", + }, WideFilter: []string{ - "secretId", "name", "type", "customerId", "tenantId"}, - JsonPath: contaboCmd.OutputFormatDetails} + "secretId", "name", "type", "customerId", "tenantId", + }, + JsonPath: contaboCmd.OutputFormatDetails, + } util.HandleResponse(responseJson, configFormatter) }, Args: func(cmd *cobra.Command, args []string) error { contaboCmd.ValidateOutputFormat() + if len(args) > 1 { cmd.Help() - os.Exit(0) + log.Fatal("Too many positional arguments.") } + viper.BindPFlag("name", cmd.Flags().Lookup("name")) + listSecretNameFilter = viper.GetString("name") + + viper.BindPFlag("type", cmd.Flags().Lookup("type")) + listSecretTypeFilter = viper.GetString("type") + return nil }, } @@ -64,11 +76,9 @@ var secretsGetCmd = &cobra.Command{ func init() { contaboCmd.GetCmd.AddCommand(secretsGetCmd) - secretsGetCmd.Flags().StringVarP( - &secretNameFilter, "name", "n", "", `Filter by secret name`) - viper.BindPFlag("name", secretsGetCmd.Flags().Lookup("name")) + secretsGetCmd.Flags().StringVarP(&listSecretNameFilter, "name", "n", "", + `Filter by secret name`) - secretsGetCmd.Flags().StringVarP( - &secretTypeFilter, "type", "t", "", `Filter by secret type [ssh|password]`) - viper.BindPFlag("type", secretsGetCmd.Flags().Lookup("type")) + secretsGetCmd.Flags().StringVarP(&listSecretTypeFilter, "type", "t", "", + `Filter by secret type [ssh|password]`) } diff --git a/cmd/secrets/update.go b/cmd/secrets/update.go index 6055752..8059174 100644 --- a/cmd/secrets/update.go +++ b/cmd/secrets/update.go @@ -4,7 +4,6 @@ import ( "context" "encoding/json" "fmt" - "os" "strconv" "strings" @@ -30,11 +29,11 @@ var secretUpdateCmd = &cobra.Command{ switch content { case nil: - if secretName != "" { - updateSecretRequest.Name = &secretName + if updateSecretName != "" { + updateSecretRequest.Name = &updateSecretName } - if secretValue != "" { - updateSecretRequest.Value = &secretValue + if updateSecretValue != "" { + updateSecretRequest.Value = &updateSecretValue } default: // from file / stdin @@ -50,7 +49,7 @@ var secretUpdateCmd = &cobra.Command{ } resp, httpResp, err := client.ApiClient().SecretsApi. - UpdateSecret(context.Background(), secretId). + UpdateSecret(context.Background(), updateSecretId). UpdateSecretRequest(updateSecretRequest). XRequestId(uuid.NewV4().String()). Execute() @@ -63,27 +62,26 @@ var secretUpdateCmd = &cobra.Command{ Args: func(cmd *cobra.Command, args []string) error { contaboCmd.ValidateCreateInput() - if viper.GetString("name") != "" { - secretName = viper.GetString("name") - } - if viper.GetString("value") != "" { - secretValue = viper.GetString("value") - } - if len(args) > 1 { cmd.Help() - os.Exit(0) + log.Fatal("Too many positional arguments.") } if len(args) < 1 { cmd.Help() - log.Fatal("please provide a secretId") + log.Fatal("Please provide a secretId.") } + viper.BindPFlag("name", cmd.Flags().Lookup("name")) + updateSecretName = viper.GetString("name") + + viper.BindPFlag("value", cmd.Flags().Lookup("value")) + updateSecretValue = viper.GetString("value") + secretId64, err := strconv.ParseInt(args[0], 10, 64) if err != nil { - log.Fatal(fmt.Sprintf("Specified secretId %v is not valid", args[0])) + log.Fatal(fmt.Sprintf("Provided secretId %v is not valid.", args[0])) } - secretId = secretId64 + updateSecretId = secretId64 return nil }, @@ -92,12 +90,9 @@ var secretUpdateCmd = &cobra.Command{ func init() { contaboCmd.UpdateCmd.AddCommand(secretUpdateCmd) - secretUpdateCmd.Flags().StringVar(&secretName, "name", "", + secretUpdateCmd.Flags().StringVar(&updateSecretName, "name", "", `name of the secret`) - viper.BindPFlag("name", secretUpdateCmd.Flags().Lookup("name")) - viper.SetDefault("name", "") - secretUpdateCmd.Flags().StringVar(&secretValue, "value", "", + + secretUpdateCmd.Flags().StringVar(&updateSecretValue, "value", "", `value of the secret`) - viper.BindPFlag("value", secretUpdateCmd.Flags().Lookup("value")) - viper.SetDefault("value", "") } diff --git a/cmd/secrets/vars.go b/cmd/secrets/vars.go index b434928..6ada242 100644 --- a/cmd/secrets/vars.go +++ b/cmd/secrets/vars.go @@ -1,13 +1,41 @@ package cmd +// create var ( - secretId int64 - secretIdFilter int64 - secretNameFilter string - secretTypeFilter string - secretCustomerIdFilter string - secretTenantIdFilter string - secretType string - secretName string - secretValue string + createSecretType string + createSecretName string + createSecretValue string +) + +// delete +var ( + deleteSecretId int64 +) + +// edit +var ( + editSecretId int64 +) + +// get +var ( + getSecretId int64 +) + +// history +var ( + historySecretIdFilter int64 +) + +// list +var ( + listSecretNameFilter string + listSecretTypeFilter string +) + +// update +var ( + updateSecretId int64 + updateSecretName string + updateSecretValue string ) diff --git a/cmd/snapshots/create.go b/cmd/snapshots/create.go index 6cd25a4..0c5dec5 100644 --- a/cmd/snapshots/create.go +++ b/cmd/snapshots/create.go @@ -4,7 +4,6 @@ import ( "context" "encoding/json" "fmt" - "os" "strconv" "strings" @@ -29,9 +28,9 @@ var snapshotCreateCmd = &cobra.Command{ switch content { case nil: - createSnapshotRequest.Name = name - if (description) != "" { - createSnapshotRequest.Description = &description + createSnapshotRequest.Name = createName + if createDescription != "" { + createSnapshotRequest.Description = &createDescription } default: // from file / stdin @@ -47,7 +46,7 @@ var snapshotCreateCmd = &cobra.Command{ } resp, httpResp, err := client.ApiClient().SnapshotsApi. - CreateSnapshot(context.Background(), instanceId). + CreateSnapshot(context.Background(), createInstanceId). XRequestId(uuid.NewV4().String()). CreateSnapshotRequest(createSnapshotRequest).Execute() @@ -58,35 +57,34 @@ var snapshotCreateCmd = &cobra.Command{ Args: func(cmd *cobra.Command, args []string) error { contaboCmd.ValidateCreateInput() - if viper.GetString("name") != "" { - name = viper.GetString("name") + if len(args) > 1 { + cmd.Help() + log.Fatal("Too many positional arguments.") } - if viper.GetString("description") != "" { - description = viper.GetString("description") + if len(args) < 1 { + cmd.Help() + log.Fatal("Please provide an instanceId") } + viper.BindPFlag("name", cmd.Flags().Lookup("name")) + createName = viper.GetString("name") + + viper.BindPFlag("description", cmd.Flags().Lookup("description")) + createDescription = viper.GetString("description") + if contaboCmd.InputFile == "" { // arguments required - if name == "" { + if createName == "" { cmd.Help() log.Fatal("Argument name is empty. Please provide one.") } } - if len(args) > 1 { - cmd.Help() - os.Exit(0) - } - if len(args) < 1 { - cmd.Help() - log.Fatal("please provide a instanceId") - } - instanceId64, err := strconv.ParseInt(args[0], 10, 64) if err != nil { - log.Fatal(fmt.Sprintf("Specified instanceId %v is not valid", args[0])) + log.Fatal(fmt.Sprintf("Provided instanceId %v is not valid", args[0])) } - instanceId = instanceId64 + createInstanceId = instanceId64 return nil }, @@ -95,11 +93,9 @@ var snapshotCreateCmd = &cobra.Command{ func init() { contaboCmd.CreateCmd.AddCommand(snapshotCreateCmd) - snapshotCreateCmd.Flags().StringVar(&name, "name", "", + snapshotCreateCmd.Flags().StringVar(&createName, "name", "", `name of the snapshot`) - viper.BindPFlag("name", snapshotCreateCmd.Flags().Lookup("name")) - snapshotCreateCmd.Flags().StringVar(&description, "description", "", + snapshotCreateCmd.Flags().StringVar(&createDescription, "description", "", `description of the snapshot`) - viper.BindPFlag("description", snapshotCreateCmd.Flags().Lookup("description")) } diff --git a/cmd/snapshots/delete.go b/cmd/snapshots/delete.go index 5ef8727..97ec3b1 100644 --- a/cmd/snapshots/delete.go +++ b/cmd/snapshots/delete.go @@ -3,7 +3,6 @@ package cmd import ( "context" "fmt" - "os" "strconv" "contabo.com/cli/cntb/client" @@ -21,7 +20,7 @@ var snapshotDeleteCmd = &cobra.Command{ Example: `cntb delete snapshot 101 5d011d21-41f2-4994-9c05-dbf6bb82221e`, Run: func(cmd *cobra.Command, args []string) { httpResp, err := client.ApiClient().SnapshotsApi. - DeleteSnapshot(context.Background(), instanceId, snapshotId). + DeleteSnapshot(context.Background(), deleteInstanceId, deleteSnapshotId). XRequestId(uuid.NewV4().String()).Execute() util.HandleErrors(err, httpResp, "while deleting snapshot") @@ -33,20 +32,20 @@ var snapshotDeleteCmd = &cobra.Command{ if len(args) > 2 { cmd.Help() - os.Exit(0) + log.Fatal("Too many positional arguments.") } if len(args) < 2 { cmd.Help() - log.Fatal("please provide a instanceId and snapshotId") + log.Fatal("Please provide an instanceId and a snapshotId.") } instanceId64, err := strconv.ParseInt(args[0], 10, 64) if err != nil { - log.Fatal(fmt.Sprintf("Specified instanceId %v is not valid", args[0])) + log.Fatal(fmt.Sprintf("Provided instanceId %v is not valid.", args[0])) } - instanceId = instanceId64 + deleteInstanceId = instanceId64 - snapshotId = args[1] + deleteSnapshotId = args[1] return nil }, diff --git a/cmd/snapshots/get.go b/cmd/snapshots/get.go index 1ba3899..f066c8b 100644 --- a/cmd/snapshots/get.go +++ b/cmd/snapshots/get.go @@ -5,7 +5,6 @@ import ( "encoding/json" "fmt" "log" - "os" "strconv" "contabo.com/cli/cntb/client" @@ -23,7 +22,7 @@ var snapshotGetCmd = &cobra.Command{ Example: `cntb get snapshot 101 5d011d21-41f2-4994-9c05-dbf6bb82221e`, Run: func(cmd *cobra.Command, args []string) { ApiRetrieveSnapshotRequest := client.ApiClient(). - SnapshotsApi.RetrieveSnapshot(context.Background(), instanceId, snapshotId). + SnapshotsApi.RetrieveSnapshot(context.Background(), getInstanceId, getSnapshotId). XRequestId(uuid.NewV4().String()) resp, httpResp, err := ApiRetrieveSnapshotRequest.Execute() @@ -34,31 +33,35 @@ var snapshotGetCmd = &cobra.Command{ configFormatter := outputFormatter.FormatterConfig{ Filter: []string{ - "snapshotId", "name", "description", "instanceId", "createdDate"}, + "snapshotId", "name", "description", "instanceId", "createdDate", + }, WideFilter: []string{ - "snapshotId", "name", "description", "instanceId", "createdDate", "customerId", "tenantId"}, - JsonPath: contaboCmd.OutputFormatDetails} + "snapshotId", "name", "description", "instanceId", "createdDate", "customerId", "tenantId", + }, + JsonPath: contaboCmd.OutputFormatDetails, + } util.HandleResponse(responseJson, configFormatter) }, Args: func(cmd *cobra.Command, args []string) error { contaboCmd.ValidateOutputFormat() + if len(args) > 2 { cmd.Help() - os.Exit(0) + log.Fatal("Too many positional arguments.") } if len(args) < 2 { cmd.Help() - log.Fatal("please provide a instanceId and snapshotId") + log.Fatal("Please provide an instanceId and a snapshotId.") } instanceId64, err := strconv.ParseInt(args[0], 10, 64) if err != nil { - log.Fatal(fmt.Sprintf("Specified instanceId %v is not valid", args[0])) + log.Fatal(fmt.Sprintf("Provided instanceId %v is not valid.", args[0])) } - instanceId = instanceId64 + getInstanceId = instanceId64 - snapshotId = args[1] + getSnapshotId = args[1] return nil }, diff --git a/cmd/snapshots/history.go b/cmd/snapshots/history.go index 575ff2c..96fc515 100644 --- a/cmd/snapshots/history.go +++ b/cmd/snapshots/history.go @@ -9,6 +9,7 @@ import ( "contabo.com/cli/cntb/cmd/util" "contabo.com/cli/cntb/outputFormatter" uuid "github.com/satori/go.uuid" + log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" ) @@ -25,20 +26,12 @@ var snapshotsHistoryCmd = &cobra.Command{ Size(contaboCmd.Size). OrderBy([]string{contaboCmd.OrderBy}) - if cmd.Flags().Changed("instanceId") { - historyRequest = historyRequest.InstanceId(instanceIdFilter) + if historyInstanceIdFilter != 0 { + historyRequest = historyRequest.InstanceId(historyInstanceIdFilter) } - if cmd.Flags().Changed("snapshotId") { - historyRequest = historyRequest.SnapshotId(snapshotIdFilter) - } - - if cmd.Flags().Changed("requestId") { - historyRequest = historyRequest.RequestId(contaboCmd.RequestIdFilter) - } - - if cmd.Flags().Changed("changedBy") { - historyRequest = historyRequest.ChangedBy(contaboCmd.ChangedByFilter) + if historySnapshotIdFilter != "" { + historyRequest = historyRequest.SnapshotId(historySnapshotIdFilter) } resp, httpResp, err := historyRequest.Execute() @@ -58,6 +51,17 @@ var snapshotsHistoryCmd = &cobra.Command{ Args: func(cmd *cobra.Command, args []string) error { contaboCmd.ValidateOutputFormat() + if len(args) > 0 { + cmd.Help() + log.Fatal("Too many positional arguments.") + } + + viper.BindPFlag("instanceId", cmd.Flags().Lookup("instanceId")) + historyInstanceIdFilter = viper.GetInt64("instanceId") + + viper.BindPFlag("snapshotId", cmd.Flags().Lookup("snapshotId")) + historySnapshotIdFilter = viper.GetString("snapshotId") + return nil }, } @@ -65,11 +69,9 @@ var snapshotsHistoryCmd = &cobra.Command{ func init() { contaboCmd.HistoryCmd.AddCommand(snapshotsHistoryCmd) - snapshotsHistoryCmd.Flags().Int64Var(&instanceIdFilter, "instanceId", -1, + snapshotsHistoryCmd.Flags().Int64Var(&historyInstanceIdFilter, "instanceId", 0, `To filter audits using Instance Id`) - viper.BindPFlag("instanceId", snapshotsHistoryCmd.Flags().Lookup("instanceId")) - snapshotsHistoryCmd.Flags().StringVar(&snapshotIdFilter, "snapshotId", "", + snapshotsHistoryCmd.Flags().StringVar(&historySnapshotIdFilter, "snapshotId", "", `To filter audits using Snapshot Id`) - viper.BindPFlag("snapshotId", snapshotsHistoryCmd.Flags().Lookup("snapshotId")) } diff --git a/cmd/snapshots/list.go b/cmd/snapshots/list.go index fee3448..98f8f54 100644 --- a/cmd/snapshots/list.go +++ b/cmd/snapshots/list.go @@ -5,7 +5,6 @@ import ( "encoding/json" "fmt" "log" - "os" "strconv" "contabo.com/cli/cntb/client" @@ -24,14 +23,15 @@ var snapshotsGetCmd = &cobra.Command{ Example: `cntb get snapshots 101`, Run: func(cmd *cobra.Command, args []string) { ApiRetrieveSnapshotListRequest := client.ApiClient(). - SnapshotsApi.RetrieveSnapshotList(context.Background(), instanceId). + SnapshotsApi.RetrieveSnapshotList(context.Background(), listInstanceId). XRequestId(uuid.NewV4().String()). Page(contaboCmd.Page). Size(contaboCmd.Size). OrderBy([]string{contaboCmd.OrderBy}) - if cmd.Flags().Changed("name") { - ApiRetrieveSnapshotListRequest = ApiRetrieveSnapshotListRequest.Name(snapshotNameFilter) + if listSnapshotNameFilter != "" { + ApiRetrieveSnapshotListRequest = ApiRetrieveSnapshotListRequest. + Name(listSnapshotNameFilter) } resp, httpResp, err := ApiRetrieveSnapshotListRequest.Execute() @@ -42,29 +42,36 @@ var snapshotsGetCmd = &cobra.Command{ configFormatter := outputFormatter.FormatterConfig{ Filter: []string{ - "snapshotId", "name", "description", "instanceId", "createdDate"}, + "snapshotId", "name", "description", "instanceId", "createdDate", + }, WideFilter: []string{ - "snapshotId", "name", "description", "instanceId", "createdDate", "customerId", "tenantId"}, - JsonPath: contaboCmd.OutputFormatDetails} + "snapshotId", "name", "description", "instanceId", "createdDate", "customerId", "tenantId", + }, + JsonPath: contaboCmd.OutputFormatDetails, + } util.HandleResponse(responseJson, configFormatter) }, Args: func(cmd *cobra.Command, args []string) error { contaboCmd.ValidateOutputFormat() + if len(args) > 1 { cmd.Help() - os.Exit(0) + log.Fatal("Too many positional arguments.") } if len(args) < 1 { cmd.Help() - log.Fatal("please provide a instanceId") + log.Fatal("Please provide an instanceId") } + viper.BindPFlag("name", cmd.Flags().Lookup("name")) + listSnapshotNameFilter = viper.GetString("name") + instanceId64, err := strconv.ParseInt(args[0], 10, 64) if err != nil { - log.Fatal(fmt.Sprintf("Specified instanceId %v is not valid", args[0])) + log.Fatal(fmt.Sprintf("Provided instanceId %v is not valid.", args[0])) } - instanceId = instanceId64 + listInstanceId = instanceId64 return nil }, @@ -73,7 +80,6 @@ var snapshotsGetCmd = &cobra.Command{ func init() { contaboCmd.GetCmd.AddCommand(snapshotsGetCmd) - snapshotsGetCmd.Flags().StringVarP( - &snapshotNameFilter, "name", "n", "", `Filter by snapshot name`) - viper.BindPFlag("name", snapshotsGetCmd.Flags().Lookup("name")) + snapshotsGetCmd.Flags().StringVarP(&listSnapshotNameFilter, "name", "n", "", + `Filter by snapshot name`) } diff --git a/cmd/snapshots/rollback.go b/cmd/snapshots/rollback.go index 322920d..92d7a2e 100644 --- a/cmd/snapshots/rollback.go +++ b/cmd/snapshots/rollback.go @@ -3,7 +3,6 @@ package cmd import ( "context" "fmt" - "os" "strconv" "contabo.com/cli/cntb/client" @@ -21,14 +20,14 @@ var rollbackGetCmd = &cobra.Command{ Example: `cntb rollback snapshot 101 5d011d21-41f2-4994-9c05-dbf6bb82221e`, Run: func(cmd *cobra.Command, args []string) { ApiRollbackSnapshotRequest := client.ApiClient(). - SnapshotsApi.RollbackSnapshot(context.Background(), instanceId, snapshotId). + SnapshotsApi.RollbackSnapshot(context.Background(), rollbackInstanceId, rollbackSnapshotId). XRequestId(uuid.NewV4().String()) resp, httpResp, err := ApiRollbackSnapshotRequest.Execute() util.HandleErrors(err, httpResp, "while doing rollback for instance") - fmt.Printf("Instance %v rollback to snapshotId %v\n", instanceId, snapshotId) + fmt.Printf("Instance %v rollback to snapshotId %v\n", rollbackInstanceId, rollbackSnapshotId) responseJSON, _ := resp.MarshalJSON() log.Info(fmt.Sprintf("%v", string(responseJSON))) @@ -37,20 +36,20 @@ var rollbackGetCmd = &cobra.Command{ contaboCmd.ValidateOutputFormat() if len(args) > 2 { cmd.Help() - os.Exit(0) + log.Fatal("Too many positional arguments.") } if len(args) < 2 { cmd.Help() - log.Fatal("please provide a instanceId and snapshotId") + log.Fatal("Please provide an instanceId and a snapshotId.") } instanceId64, err := strconv.ParseInt(args[0], 10, 64) if err != nil { - log.Fatal(fmt.Sprintf("Specified instanceId %v is not valid", args[0])) + log.Fatal(fmt.Sprintf("Provided instanceId %v is not valid.", args[0])) } - instanceId = instanceId64 + rollbackInstanceId = instanceId64 - snapshotId = args[1] + rollbackSnapshotId = args[1] return nil }, diff --git a/cmd/snapshots/update.go b/cmd/snapshots/update.go index b0a9101..a552259 100644 --- a/cmd/snapshots/update.go +++ b/cmd/snapshots/update.go @@ -4,7 +4,6 @@ import ( "context" "encoding/json" "fmt" - "os" "strconv" "strings" @@ -32,11 +31,11 @@ var snapshotUpdateCmd = &cobra.Command{ switch content { case nil: - if name != "" { - updateSnapshotRequest.Name = &name + if updateName != "" { + updateSnapshotRequest.Name = &updateName } - if description != "" { - updateSnapshotRequest.Description = &description + if updateDescription != "" { + updateSnapshotRequest.Description = &updateDescription } default: // from file / stdin @@ -52,7 +51,7 @@ var snapshotUpdateCmd = &cobra.Command{ } resp, httpResp, err := client.ApiClient().SnapshotsApi. - UpdateSnapshot(context.Background(), instanceId, snapshotId). + UpdateSnapshot(context.Background(), updateInstanceId, updateSnapshotId). UpdateSnapshotRequest(updateSnapshotRequest). XRequestId(uuid.NewV4().String()). Execute() @@ -65,29 +64,28 @@ var snapshotUpdateCmd = &cobra.Command{ Args: func(cmd *cobra.Command, args []string) error { contaboCmd.ValidateCreateInput() - if viper.GetString("name") != "" { - name = viper.GetString("name") - } - if viper.GetString("description") != "" { - description = viper.GetString("description") - } - if len(args) > 2 { cmd.Help() - os.Exit(0) + log.Fatal("Too many positional arguments.") } if len(args) < 2 { cmd.Help() - log.Fatal("please provide a instanceId and snapshotId") + log.Fatal("Please provide an instanceId and a snapshotId.") } + viper.BindPFlag("name", cmd.Flags().Lookup("name")) + updateName = viper.GetString("name") + + viper.BindPFlag("description", cmd.Flags().Lookup("description")) + updateDescription = viper.GetString("description") + instanceId64, err := strconv.ParseInt(args[0], 10, 64) if err != nil { - log.Fatal(fmt.Sprintf("Specified instanceId %v is not valid", args[0])) + log.Fatal(fmt.Sprintf("Provided instanceId %v is not valid.", args[0])) } - instanceId = instanceId64 + updateInstanceId = instanceId64 - snapshotId = args[1] + updateSnapshotId = args[1] return nil }, @@ -96,13 +94,10 @@ var snapshotUpdateCmd = &cobra.Command{ func init() { contaboCmd.UpdateCmd.AddCommand(snapshotUpdateCmd) - snapshotUpdateCmd.Flags().StringVar(&name, "name", "", + snapshotUpdateCmd.Flags().StringVar(&updateName, "name", "", `name of the snapshot`) - viper.BindPFlag("name", snapshotUpdateCmd.Flags().Lookup("name")) - viper.SetDefault("name", "") - snapshotUpdateCmd.Flags().StringVar(&description, "description", "", + + snapshotUpdateCmd.Flags().StringVar(&updateDescription, "description", "", `description of the snapshot`) - viper.BindPFlag("description", snapshotUpdateCmd.Flags().Lookup("description")) - viper.SetDefault("description", "") } diff --git a/cmd/snapshots/vars.go b/cmd/snapshots/vars.go index 1a1f88b..d877007 100644 --- a/cmd/snapshots/vars.go +++ b/cmd/snapshots/vars.go @@ -1,11 +1,46 @@ package cmd +// create var ( - instanceId int64 - snapshotId string - instanceIdFilter int64 - snapshotIdFilter string - snapshotNameFilter string - name string - description string + createInstanceId int64 + createName string + createDescription string +) + +// delete +var ( + deleteInstanceId int64 + deleteSnapshotId string +) + +// get +var ( + getInstanceId int64 + getSnapshotId string +) + +// history +var ( + historyInstanceIdFilter int64 + historySnapshotIdFilter string +) + +// list +var ( + listInstanceId int64 + listSnapshotNameFilter string +) + +// rollback +var ( + rollbackInstanceId int64 + rollbackSnapshotId string +) + +// update +var ( + updateInstanceId int64 + updateSnapshotId string + updateName string + updateDescription string ) diff --git a/cmd/tagAssignment/create.go b/cmd/tagAssignment/create.go index 4ae2eb4..54db20f 100644 --- a/cmd/tagAssignment/create.go +++ b/cmd/tagAssignment/create.go @@ -25,13 +25,19 @@ var createTagAssignmentCmd = &cobra.Command{ util.HandleErrors(err, httpResp, "while creating tag assignment") }, Args: func(cmd *cobra.Command, args []string) error { + contaboCmd.ValidateCreateInput() + + if len(args) > 3 { + cmd.Help() + log.Fatal("Too many positional arguments.") + } if len(args) < 3 { cmd.Help() - log.Fatal("Too little arguments please specify tagId, resourceType and resourceId") + log.Fatal("Please provide a tagId, a resourceType and a resourceId.") } tagId64, err := strconv.ParseInt(args[0], 10, 64) if err != nil { - log.Fatal(fmt.Sprintf("specified tagId %v is not valid", args[0])) + log.Fatal(fmt.Sprintf("Provided tagId %v is not valid.", args[0])) } tagId = tagId64 diff --git a/cmd/tagAssignment/delete.go b/cmd/tagAssignment/delete.go index 9194757..d4e4515 100644 --- a/cmd/tagAssignment/delete.go +++ b/cmd/tagAssignment/delete.go @@ -25,14 +25,18 @@ var deleteTagAssignmentCmd = &cobra.Command{ util.HandleErrors(err, httpResp, "while deleting tag assignment") }, Args: func(cmd *cobra.Command, args []string) error { + if len(args) > 3 { + cmd.Help() + log.Fatal("Too many positional arguments.") + } if len(args) < 3 { cmd.Help() - log.Fatal("Too little arguments please specify tagId, resourceType and resourceId") + log.Fatal("Please provide a tagId, a resourceType and a resourceId.") } tagId64, err := strconv.ParseInt(args[0], 10, 64) if err != nil { - log.Fatal(fmt.Sprintf("Specified tagId %v is not valid", args[0])) + log.Fatal(fmt.Sprintf("Provided tagId %v is not valid.", args[0])) } tagId = tagId64 resourceType = args[1] diff --git a/cmd/tagAssignment/get.go b/cmd/tagAssignment/get.go index 55b9663..d396ed0 100644 --- a/cmd/tagAssignment/get.go +++ b/cmd/tagAssignment/get.go @@ -38,13 +38,17 @@ var tagAssignmentGetCmd = &cobra.Command{ util.HandleResponse(responseJson, configFormatter) }, Args: func(cmd *cobra.Command, args []string) error { + if len(args) > 3 { + cmd.Help() + log.Fatal("Too many positional arguments.") + } if len(args) < 3 { cmd.Help() log.Fatal("Too little arguments please specify tagId, resourceType and resourceId") } tagId64, err := strconv.ParseInt(args[0], 10, 64) if err != nil { - log.Fatal(fmt.Sprintf("specified tagId %v is not valid", args[0])) + log.Fatal(fmt.Sprintf("Provided tagId %v is not valid.", args[0])) } tagId = tagId64 diff --git a/cmd/tagAssignment/history.go b/cmd/tagAssignment/history.go index 60d39cd..9d7ab34 100644 --- a/cmd/tagAssignment/history.go +++ b/cmd/tagAssignment/history.go @@ -9,6 +9,7 @@ import ( "contabo.com/cli/cntb/cmd/util" "contabo.com/cli/cntb/outputFormatter" uuid "github.com/satori/go.uuid" + log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" ) @@ -26,11 +27,11 @@ var tagAssignmentHistoryCmd = &cobra.Command{ Size(contaboCmd.Size). OrderBy([]string{contaboCmd.OrderBy}) - if cmd.Flags().Changed("tagId") { + if tagIdFilter != 0 { historyRequest = historyRequest.TagId(tagIdFilter) } - if cmd.Flags().Changed("resourceId") { + if resourceIdFilter != "" { historyRequest = historyRequest.ResourceId(resourceIdFilter) } @@ -48,16 +49,30 @@ var tagAssignmentHistoryCmd = &cobra.Command{ util.HandleResponse(responseJson, configFormatter) }, + Args: func(cmd *cobra.Command, args []string) error { + contaboCmd.ValidateOutputFormat() + + if len(args) > 0 { + cmd.Help() + log.Fatal("Too many positional arguments.") + } + + viper.BindPFlag("tagId", cmd.Flags().Lookup("tagId")) + tagIdFilter = viper.GetInt64("tagId") + + viper.BindPFlag("resourceId", cmd.Flags().Lookup("resourceId")) + resourceIdFilter = viper.GetString("resourceId") + + return nil + }, } func init() { contaboCmd.HistoryCmd.AddCommand(tagAssignmentHistoryCmd) - tagAssignmentHistoryCmd.Flags().Int64VarP(&tagIdFilter, "tagId", "t", -1, + tagAssignmentHistoryCmd.Flags().Int64VarP(&tagIdFilter, "tagId", "t", 0, `filter by tagId`) - viper.BindPFlag("tagId", tagAssignmentHistoryCmd.Flags().Lookup("tagId")) tagAssignmentHistoryCmd.Flags().StringVarP(&resourceIdFilter, "resourceId", "r", "", `filter by resourceId`) - viper.BindPFlag("resourceId", tagAssignmentHistoryCmd.Flags().Lookup("resourceId")) } diff --git a/cmd/tagAssignment/list.go b/cmd/tagAssignment/list.go index 68146d8..c84babf 100644 --- a/cmd/tagAssignment/list.go +++ b/cmd/tagAssignment/list.go @@ -17,9 +17,9 @@ import ( var listTagAssignmentsCmd = &cobra.Command{ Use: "tagAssignments [tagId] [filter]", - Short: "List all assignments for specific tag", + Short: "List all assignments for specific tag.", Long: `Retrive information about many or a single tag assignment that belong to a specific tag. - you can filter by resource type`, + you can filter by resource type.`, Run: func(cmd *cobra.Command, args []string) { resp, httpResp, err := client.ApiClient().TagAssignmentsApi. RetrieveAssignmentList(context.Background(), tagId). @@ -45,16 +45,16 @@ var listTagAssignmentsCmd = &cobra.Command{ Args: func(cmd *cobra.Command, args []string) error { contaboCmd.ValidateOutputFormat() if len(args) > 1 { - contaboCmd.GetCmd.Help() - log.Fatal("Please only specify tagId") + cmd.Help() + log.Fatal("Too many positional arguments.") } if len(args) < 1 { - contaboCmd.GetCmd.Help() + cmd.Help() log.Fatal("Please specify tagId") } tagId64, err := strconv.ParseInt(args[0], 10, 64) if err != nil { - log.Fatal(fmt.Sprintf("Specified tagId %v is not valid", args[0])) + log.Fatal(fmt.Sprintf("Provided tagId %v is not valid.", args[0])) } tagId = tagId64 diff --git a/cmd/tags/create.go b/cmd/tags/create.go index 80a1bab..bc4fd92 100644 --- a/cmd/tags/create.go +++ b/cmd/tags/create.go @@ -27,9 +27,9 @@ var tagCreateCmd = &cobra.Command{ switch content { case nil: // from arguments - createTagRequest.Name = TagName - if TagColor != "" { - createTagRequest.Color = TagColor + createTagRequest.Name = createTagName + if createTagColor != "" { + createTagRequest.Color = createTagColor } default: // from file / stdin @@ -50,16 +50,22 @@ var tagCreateCmd = &cobra.Command{ }, Args: func(cmd *cobra.Command, args []string) error { contaboCmd.ValidateCreateInput() - if viper.GetString("name") != "" { - TagName = viper.GetString("name") - } - if viper.GetString("color") != "" { - TagColor = viper.GetString("color") + + if len(args) > 0 { + cmd.Help() + log.Fatal("Too many positional arguments.") } + + viper.BindPFlag("name", cmd.Flags().Lookup("name")) + createTagName = viper.GetString("name") + + viper.BindPFlag("color", cmd.Flags().Lookup("color")) + createTagColor = viper.GetString("color") + if contaboCmd.InputFile == "" { // arguments required - if TagName == "" { - log.Fatal("name is empty. Please provide one.") + if createTagName == "" { + log.Fatal("Argument name is empty. Please provide one.") } } return nil @@ -69,9 +75,7 @@ var tagCreateCmd = &cobra.Command{ func init() { contaboCmd.CreateCmd.AddCommand(tagCreateCmd) - tagCreateCmd.Flags().StringVarP(&TagName, "name", "n", "", `name of the tag`) - viper.BindPFlag("name", tagCreateCmd.Flags().Lookup("name")) + tagCreateCmd.Flags().StringVarP(&createTagName, "name", "n", "", `Name of the tag.`) - tagCreateCmd.Flags().StringVarP(&TagColor, "color", "c", "", `color of the tag`) - viper.BindPFlag("color", tagCreateCmd.Flags().Lookup("color")) + tagCreateCmd.Flags().StringVarP(&createTagColor, "color", "c", "", `Color of the tag.`) } diff --git a/cmd/tags/delete.go b/cmd/tags/delete.go index 776fcb5..89c08c2 100644 --- a/cmd/tags/delete.go +++ b/cmd/tags/delete.go @@ -15,24 +15,32 @@ import ( var tagDeleteCmd = &cobra.Command{ Use: "tag [tagId]", - Short: "Deletes a specific tag", + Short: "Deletes a specific tag.", Long: `Specify a tag id to delete the specified tag. A tag might not be deleted if it is still assigned.`, Run: func(cmd *cobra.Command, args []string) { - httpResp, err := client.ApiClient().TagsApi.DeleteTag(context.Background(), tagId).XRequestId(uuid.NewV4().String()).Execute() + httpResp, err := client.ApiClient().TagsApi. + DeleteTag(context.Background(), deleteTagId). + XRequestId(uuid.NewV4().String()).Execute() util.HandleErrors(err, httpResp, "while deleting tag") }, Args: func(cmd *cobra.Command, args []string) error { + contaboCmd.ValidateCreateInput() + + if len(args) > 1 { + cmd.Help() + log.Fatal("Too many positional arguments.") + } if len(args) < 1 { cmd.Help() - log.Fatal("Please specify tagId") + log.Fatal("Please provide a tagId.") } tagId64, err := strconv.ParseInt(args[0], 10, 64) if err != nil { - log.Fatal(fmt.Sprintf("Specified tagId %v is not valid", args[0])) + log.Fatal(fmt.Sprintf("Specified tagId %v is not valid.", args[0])) } - tagId = tagId64 - contaboCmd.ValidateOutputFormat() + deleteTagId = tagId64 + return nil }, } diff --git a/cmd/tags/edit.go b/cmd/tags/edit.go index 19269de..662a829 100644 --- a/cmd/tags/edit.go +++ b/cmd/tags/edit.go @@ -20,11 +20,13 @@ import ( var tagEditCmd = &cobra.Command{ Use: "tag [tagId]", - Short: "Edit a specific tag", + Short: "Edit a specific tag.", Long: `Modify an existing tag in your editor`, Run: func(cmd *cobra.Command, args []string) { // get original content - resp, httpResp, err := client.ApiClient().TagsApi.RetrieveTag(context.Background(), tagId).XRequestId(uuid.NewV4().String()).Execute() + resp, httpResp, err := client.ApiClient().TagsApi. + RetrieveTag(context.Background(), editTagId). + XRequestId(uuid.NewV4().String()).Execute() util.HandleErrors(err, httpResp, "while editing tags") @@ -58,7 +60,9 @@ var tagEditCmd = &cobra.Command{ // merge updateTagRequest with one from file to have the defaults there json.NewDecoder(strings.NewReader(string(newContent))).Decode(&updateTagRequest) - resp, httpResp, err := client.ApiClient().TagsApi.UpdateTag(context.Background(), tagId).UpdateTagRequest(updateTagRequest).XRequestId(uuid.NewV4().String()).Execute() + resp, httpResp, err := client.ApiClient().TagsApi. + UpdateTag(context.Background(), editTagId).UpdateTagRequest(updateTagRequest). + XRequestId(uuid.NewV4().String()).Execute() util.HandleErrors(err, httpResp, "while editing tags") @@ -67,15 +71,22 @@ var tagEditCmd = &cobra.Command{ } }, Args: func(cmd *cobra.Command, args []string) error { + contaboCmd.ValidateCreateInput() + + if len(args) > 1 { + cmd.Help() + log.Fatal("Too many positional arguments.") + } if len(args) < 1 { cmd.Help() - log.Fatal("Please specify tagId") + log.Fatal("Please provide a tagId.") } tagId64, err := strconv.ParseInt(args[0], 10, 64) if err != nil { - log.Fatal(fmt.Sprintf("Specified tagId %v is not valid", args[0])) + log.Fatal(fmt.Sprintf("Specified tagId %v is not valid.", args[0])) } - tagId = tagId64 + editTagId = tagId64 + return nil }, } diff --git a/cmd/tags/get.go b/cmd/tags/get.go index ae645e5..9861931 100644 --- a/cmd/tags/get.go +++ b/cmd/tags/get.go @@ -20,7 +20,9 @@ var tagGetCmd = &cobra.Command{ Short: "Info about a specific tag", Long: `Retrieves information about one tag identified by id.`, Run: func(cmd *cobra.Command, args []string) { - resp, httpResp, err := client.ApiClient().TagsApi.RetrieveTag(context.Background(), tagId).XRequestId(uuid.NewV4().String()).Execute() + resp, httpResp, err := client.ApiClient().TagsApi. + RetrieveTag(context.Background(), getTagId). + XRequestId(uuid.NewV4().String()).Execute() util.HandleErrors(err, httpResp, "while retrieving tag") @@ -35,16 +37,23 @@ var tagGetCmd = &cobra.Command{ util.HandleResponse(responseJson, configFormatter) }, Args: func(cmd *cobra.Command, args []string) error { + contaboCmd.ValidateOutputFormat() + + if len(args) > 1 { + cmd.Help() + log.Fatal("Too many positional arguments.") + } if len(args) < 1 { cmd.Help() - log.Fatal("Please specify tagId") + log.Fatal("Please provide a tagId.") } + tagId64, err := strconv.ParseInt(args[0], 10, 64) if err != nil { - log.Fatal(fmt.Sprintf("Specified tagId %v is not valid", args[0])) + log.Fatal(fmt.Sprintf("Provided tagId %v is not valid.", args[0])) } - tagId = tagId64 - contaboCmd.ValidateOutputFormat() + getTagId = tagId64 + return nil }, } diff --git a/cmd/tags/history.go b/cmd/tags/history.go index 71e6a55..1b35daa 100644 --- a/cmd/tags/history.go +++ b/cmd/tags/history.go @@ -9,6 +9,7 @@ import ( "contabo.com/cli/cntb/cmd/util" "contabo.com/cli/cntb/outputFormatter" uuid "github.com/satori/go.uuid" + log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" ) @@ -25,16 +26,8 @@ var tagsCmd = &cobra.Command{ Size(contaboCmd.Size). OrderBy([]string{contaboCmd.OrderBy}) - if cmd.Flags().Changed("tagId") { - historyRequest = historyRequest.TagId(tagIdFilter) - } - - if cmd.Flags().Changed("requestId") { - historyRequest = historyRequest.RequestId(contaboCmd.RequestIdFilter) - } - - if cmd.Flags().Changed("changedBy") { - historyRequest = historyRequest.ChangedBy(contaboCmd.ChangedByFilter) + if historyTagIdFilter != 0 { + historyRequest = historyRequest.TagId(historyTagIdFilter) } resp, httpResp, err := historyRequest.Execute() @@ -54,6 +47,13 @@ var tagsCmd = &cobra.Command{ Args: func(cmd *cobra.Command, args []string) error { contaboCmd.ValidateOutputFormat() + if len(args) > 1 { + cmd.Help() + log.Fatal("Too many positional arguments.") + } + + viper.BindPFlag("tagId", cmd.Flags().Lookup("tagId")) + historyTagIdFilter = viper.GetInt64("tagId") return nil }, } @@ -61,7 +61,6 @@ var tagsCmd = &cobra.Command{ func init() { contaboCmd.HistoryCmd.AddCommand(tagsCmd) - tagsCmd.Flags().Int64VarP(&tagIdFilter, "tagId", "t", -1, + tagsCmd.Flags().Int64VarP(&historyTagIdFilter, "tagId", "t", 0, `To filter audits using Tag Id`) - viper.BindPFlag("tagId", tagsCmd.Flags().Lookup("tagId")) } diff --git a/cmd/tags/list.go b/cmd/tags/list.go index 48a0a14..02ac409 100644 --- a/cmd/tags/list.go +++ b/cmd/tags/list.go @@ -3,13 +3,13 @@ package cmd import ( "context" "encoding/json" - "os" "contabo.com/cli/cntb/client" contaboCmd "contabo.com/cli/cntb/cmd" "contabo.com/cli/cntb/cmd/util" "contabo.com/cli/cntb/outputFormatter" uuid "github.com/satori/go.uuid" + log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" ) @@ -26,8 +26,8 @@ var tagsGetCmd = &cobra.Command{ Size(contaboCmd.Size). OrderBy([]string{contaboCmd.OrderBy}) - if cmd.Flags().Changed("tagName") { - ApiRetrieveTagListRequest = ApiRetrieveTagListRequest.Name(tagNameFilter) + if listTagNameFilter != "" { + ApiRetrieveTagListRequest = ApiRetrieveTagListRequest.Name(listTagNameFilter) } resp, httpResp, err := ApiRetrieveTagListRequest.Execute() @@ -39,17 +39,22 @@ var tagsGetCmd = &cobra.Command{ configFormatter := outputFormatter.FormatterConfig{ Filter: []string{"tagId", "name", "color"}, WideFilter: []string{"tagId", "name", "color"}, - JsonPath: contaboCmd.OutputFormatDetails} + JsonPath: contaboCmd.OutputFormatDetails, + } util.HandleResponse(responseJson, configFormatter) }, Args: func(cmd *cobra.Command, args []string) error { contaboCmd.ValidateOutputFormat() + if len(args) > 1 { cmd.Help() - os.Exit(0) + log.Fatal("Too many positional arguments.") } + viper.BindPFlag("tagName", cmd.Flags().Lookup("tagName")) + listTagNameFilter = viper.GetString("tagName") + return nil }, } @@ -57,6 +62,6 @@ var tagsGetCmd = &cobra.Command{ func init() { contaboCmd.GetCmd.AddCommand(tagsGetCmd) - tagsGetCmd.Flags().StringVarP(&tagNameFilter, "tagName", "t", "", `Filter by tag name`) - viper.BindPFlag("tagName", tagsGetCmd.Flags().Lookup("tagName")) + tagsGetCmd.Flags().StringVarP(&listTagNameFilter, "tagName", "t", "", + `Filter by tag name`) } diff --git a/cmd/tags/update.go b/cmd/tags/update.go index 8351e3f..43df675 100644 --- a/cmd/tags/update.go +++ b/cmd/tags/update.go @@ -28,11 +28,11 @@ var tagUpdateCmd = &cobra.Command{ switch content { case nil: // from arguments - if TagName != "" { - updateTagRequest.Name = &TagName + if updateTagName != "" { + updateTagRequest.Name = &updateTagName } - if TagColor != "" { - updateTagRequest.Color = &TagColor + if updateTagColor != "" { + updateTagRequest.Color = &updateTagColor } default: // from file / stdin @@ -45,7 +45,9 @@ var tagUpdateCmd = &cobra.Command{ json.NewDecoder(strings.NewReader(string(content))).Decode(&updateTagRequest) } - resp, httpResp, err := client.ApiClient().TagsApi.UpdateTag(context.Background(), tagId).UpdateTagRequest(updateTagRequest).XRequestId(uuid.NewV4().String()).Execute() + resp, httpResp, err := client.ApiClient().TagsApi. + UpdateTag(context.Background(), updateTagId).UpdateTagRequest(updateTagRequest). + XRequestId(uuid.NewV4().String()).Execute() util.HandleErrors(err, httpResp, "while updating tag") @@ -54,21 +56,27 @@ var tagUpdateCmd = &cobra.Command{ }, Args: func(cmd *cobra.Command, args []string) error { contaboCmd.ValidateCreateInput() + + if len(args) > 1 { + cmd.Help() + log.Fatal("Too many positional arguments.") + } if len(args) < 1 { cmd.Help() - log.Fatal("Please specify tagId") + log.Fatal("Please provide a tagId.") } + + viper.BindPFlag("name", cmd.Flags().Lookup("name")) + updateTagName = viper.GetString("name") + viper.BindPFlag("color", cmd.Flags().Lookup("color")) + updateTagColor = viper.GetString("color") + tagId64, err := strconv.ParseInt(args[0], 10, 64) if err != nil { log.Fatal(fmt.Sprintf("Specified tagId %v is not valid", args[0])) } - tagId = tagId64 - if viper.GetString("name") != "" { - TagName = viper.GetString("name") - } - if viper.GetString("color") != "" { - TagColor = viper.GetString("color") - } + updateTagId = tagId64 + return nil }, } @@ -76,10 +84,9 @@ var tagUpdateCmd = &cobra.Command{ func init() { contaboCmd.UpdateCmd.AddCommand(tagUpdateCmd) - tagUpdateCmd.Flags().StringVarP(&TagName, "name", "n", "", `name of the tag`) - viper.BindPFlag("name", tagUpdateCmd.Flags().Lookup("name")) - viper.SetDefault("name", "") - tagUpdateCmd.Flags().StringVarP(&TagColor, "color", "c", "", `color of the tag`) - viper.BindPFlag("color", tagUpdateCmd.Flags().Lookup("color")) - viper.SetDefault("color", "") + tagUpdateCmd.Flags().StringVarP(&updateTagName, "name", "n", "", + `name of the tag`) + + tagUpdateCmd.Flags().StringVarP(&updateTagColor, "color", "c", "", + `color of the tag`) } diff --git a/cmd/tags/vars.go b/cmd/tags/vars.go index d87d06c..0f4a09d 100644 --- a/cmd/tags/vars.go +++ b/cmd/tags/vars.go @@ -1,10 +1,39 @@ package cmd +// create var ( - TagName string - TagColor string - tagId int64 - tagIdFilter int64 - parseError error - tagNameFilter string + createTagName string + createTagColor string +) + +// delete +var ( + deleteTagId int64 +) + +// edit +var ( + editTagId int64 +) + +// get +var ( + getTagId int64 +) + +// history +var ( + historyTagIdFilter int64 +) + +// list +var ( + listTagNameFilter string +) + +// update +var ( + updateTagId int64 + updateTagName string + updateTagColor string ) diff --git a/cmd/users/create.go b/cmd/users/create.go index ee98554..51a1728 100644 --- a/cmd/users/create.go +++ b/cmd/users/create.go @@ -27,17 +27,14 @@ var userManagementCreateCmd = &cobra.Command{ switch content { case nil: // from arguments - createUserRequest.Email = userEmail - createUserRequest.FirstName = userFirstName - createUserRequest.LastName = userLastName - createUserRequest.Enabled = isUserEnabled - createUserRequest.Admin = isAdmin - createUserRequest.Locale = locale - if roles != nil { - createUserRequest.Roles = &roles - } - if canAccessAllResources { - createUserRequest.AccessAllResources = canAccessAllResources + createUserRequest.Email = createUserEmail + createUserRequest.FirstName = &createUserFirstName + createUserRequest.LastName = &createUserLastName + createUserRequest.Enabled = createIsUserEnabled + createUserRequest.Totp = createIsTotpEnabeld + createUserRequest.Locale = createLocale + if createRoles != nil { + createUserRequest.Roles = &createRoles } default: // from file / stdin @@ -57,26 +54,52 @@ var userManagementCreateCmd = &cobra.Command{ }, Args: func(cmd *cobra.Command, args []string) error { contaboCmd.ValidateCreateInput() - if viper.GetString("email") != "" { - userEmail = viper.GetString("email") + + if len(args) > 0 { + cmd.Help() + log.Fatal("Too many positional arguments.") + } + + viper.BindPFlag("firstName", cmd.Flags().Lookup("firstName")) + createUserFirstName = viper.GetString("firstName") + + viper.BindPFlag("lastName", cmd.Flags().Lookup("lastName")) + createUserLastName = viper.GetString("lastName") + + viper.BindPFlag("email", cmd.Flags().Lookup("email")) + createUserEmail = viper.GetString("email") + + viper.BindPFlag("enabled", cmd.Flags().Lookup("enabled")) + createIsUserEnabled = viper.GetBool("enabled") + + viper.BindPFlag("totp", cmd.Flags().Lookup("totp")) + createIsTotpEnabeld = viper.GetBool("totp") + + viper.BindPFlag("roles", cmd.Flags().Lookup("roles")) + for i := range viper.GetIntSlice("roles") { + createRoles[i] = int64(viper.GetIntSlice("roles")[i]) } + + viper.BindPFlag("locale", cmd.Flags().Lookup("locale")) + createLocale = viper.GetString("locale") + if contaboCmd.InputFile == "" { // arguments required - if userFirstName == "" { + if createUserFirstName == "" { cmd.Help() - log.Fatal("firstName is empty please provide one") + log.Fatal("Argument firstName is empty. Please provide one.") } - if userLastName == "" { + if createUserLastName == "" { cmd.Help() - log.Fatal("lastName is empty please provide one") + log.Fatal("Argument lastName is empty. Please provide one.") } - if userEmail == "" { + if createUserEmail == "" { cmd.Help() - log.Fatal("email is empty please provide one") + log.Fatal("Argument email is empty. Please provide one.") } - if locale == "" { + if createLocale == "" { cmd.Help() - log.Fatal("locale must be set") + log.Fatal("Argument locale is empty. Please provide one.") } } return nil @@ -86,35 +109,24 @@ var userManagementCreateCmd = &cobra.Command{ func init() { contaboCmd.CreateCmd.AddCommand(userManagementCreateCmd) - userManagementCreateCmd.Flags().StringVar(&userFirstName, "firstName", "", + userManagementCreateCmd.Flags().StringVar(&createUserFirstName, "firstName", "", `user name of the user`) - viper.BindPFlag("firstName", userManagementCreateCmd.Flags().Lookup("firstName")) - userManagementCreateCmd.Flags().StringVar(&userLastName, "lastName", "", + userManagementCreateCmd.Flags().StringVar(&createUserLastName, "lastName", "", `user name of the user`) - viper.BindPFlag("lastName", userManagementCreateCmd.Flags().Lookup("lastName")) - userManagementCreateCmd.Flags().StringVar(&userEmail, "email", "", + userManagementCreateCmd.Flags().StringVar(&createUserEmail, "email", "", `email of the user`) - viper.BindPFlag("email", userManagementCreateCmd.Flags().Lookup("email")) - userManagementCreateCmd.Flags().BoolVar(&isUserEnabled, "enabled", false, + userManagementCreateCmd.Flags().BoolVar(&createIsUserEnabled, "enabled", false, `is the user enabled`) - viper.BindPFlag("enabled", userManagementCreateCmd.Flags().Lookup("userEnabled")) - - userManagementCreateCmd.Flags().BoolVar(&isAdmin, "admin", false, - `sets the user as an admin and allows him to perform all tasks`) - viper.BindPFlag("admin", userManagementCreateCmd.Flags().Lookup("admin")) - userManagementCreateCmd.Flags().BoolVar(&canAccessAllResources, "accessAllResources", false, - `can the user access all resources for permissions he has`) - viper.BindPFlag("accessAllResources", userManagementCreateCmd.Flags().Lookup("accessAllResources")) + userManagementCreateCmd.Flags().BoolVar(&createIsTotpEnabeld, "totp", false, + `Enable or disable two-factor authentication (2FA) via time based OTP.`) - userManagementCreateCmd.Flags().Int64SliceVarP(&roles, "roles", "r", nil, + userManagementCreateCmd.Flags().Int64SliceVarP(&createRoles, "roles", "r", nil, `list of role ids the user should have`) - viper.BindPFlag("roles", userManagementCreateCmd.Flags().Lookup("roles")) - userManagementCreateCmd.Flags().StringVar(&locale, "locale", "en", - `the locale that the user would like to use (de/en)`) - viper.BindPFlag("locale", userManagementCreateCmd.Flags().Lookup("locale")) + userManagementCreateCmd.Flags().StringVar(&createLocale, "locale", "", + `The locale of the user. This can be de-DE, de, en-US, en`) } diff --git a/cmd/users/delete.go b/cmd/users/delete.go index fa4e495..93b2c28 100644 --- a/cmd/users/delete.go +++ b/cmd/users/delete.go @@ -16,18 +16,26 @@ var userDeleteCmd = &cobra.Command{ Short: "Deletes a specific user", Long: `Specify a tag id to delete the specified user.`, Run: func(cmd *cobra.Command, args []string) { - httpResp, err := client.ApiClient().UsersApi.DeleteUser(context.Background(), userId).XRequestId(uuid.NewV4().String()).Execute() + httpResp, err := client.ApiClient().UsersApi. + DeleteUser(context.Background(), deleteUserId). + XRequestId(uuid.NewV4().String()).Execute() util.HandleErrors(err, httpResp, "while deleting user") }, Args: func(cmd *cobra.Command, args []string) error { + contaboCmd.ValidateOutputFormat() + + if len(args) > 1 { + cmd.Help() + log.Fatal("Too many positional arguments.") + } if len(args) < 1 { cmd.Help() - log.Fatal("Please specify userId") + log.Fatal("Please provide an userId.") } - userId = args[0] - contaboCmd.ValidateOutputFormat() + deleteUserId = args[0] + return nil }, } diff --git a/cmd/users/edit.go b/cmd/users/edit.go index 2ee7890..588b6dc 100644 --- a/cmd/users/edit.go +++ b/cmd/users/edit.go @@ -24,7 +24,7 @@ var userEditCmd = &cobra.Command{ Long: `Modify an existing user in your editor`, Run: func(cmd *cobra.Command, args []string) { // get original content - resp, httpResp, err := client.ApiClient().UsersApi.RetrieveUser(context.Background(), userId).XRequestId(uuid.NewV4().String()).Execute() + resp, httpResp, err := client.ApiClient().UsersApi.RetrieveUser(context.Background(), editUserId).XRequestId(uuid.NewV4().String()).Execute() util.HandleErrors(err, httpResp, "while editing users") @@ -37,12 +37,12 @@ var userEditCmd = &cobra.Command{ json.Unmarshal(respContent, &normalized) // get role ids - rolesObject, err := json.Marshal(normalized[0]["roles"]) + rolesObject, _ := json.Marshal(normalized[0]["roles"]) var actualRoles []map[string]interface{} json.Unmarshal(rolesObject, &actualRoles) var roleIds []int64 for i := 0; i < len(actualRoles); i++ { - var roleIdString = actualRoles[i]["roleId"] + roleIdString := actualRoles[i]["roleId"] value := reflect.ValueOf(roleIdString) roleId64 := value.Convert(reflect.TypeOf(float64(0))) var roleId int64 = int64(roleId64.Float()) @@ -72,7 +72,7 @@ var userEditCmd = &cobra.Command{ // merge updateUserRequest with one from file to have the defaults there json.NewDecoder(strings.NewReader(string(newContent))).Decode(&updateUserRequest) - resp, httpResp, err := client.ApiClient().UsersApi.UpdateUser(context.Background(), userId). + resp, httpResp, err := client.ApiClient().UsersApi.UpdateUser(context.Background(), editUserId). XRequestId(uuid.NewV4().String()).UpdateUserRequest(updateUserRequest).Execute() util.HandleErrors(err, httpResp, "while editing users") @@ -80,14 +80,18 @@ var userEditCmd = &cobra.Command{ responseJSON, _ := resp.MarshalJSON() log.Info(fmt.Sprintf("%v", string(responseJSON))) } - }, Args: func(cmd *cobra.Command, args []string) error { + + if len(args) > 1 { + cmd.Help() + log.Fatal("Too many positional arguments.") + } if len(args) < 1 { cmd.Help() - log.Fatal("Please specify tagId") + log.Fatal("Please provide an userId.") } - userId = args[0] + editUserId = args[0] return nil }, } diff --git a/cmd/users/generateSecret.go b/cmd/users/generateSecret.go index ed34a95..857d866 100644 --- a/cmd/users/generateSecret.go +++ b/cmd/users/generateSecret.go @@ -17,7 +17,8 @@ var generateSecretUserCmd = &cobra.Command{ Long: `Generate a new client secret and return it`, Example: `cntb generateSecret user`, Run: func(cmd *cobra.Command, args []string) { - resp, httpResp, err := client.ApiClient().UsersApi.GenerateClientSecret(context.Background()). + resp, httpResp, err := client.ApiClient().UsersApi. + GenerateClientSecret(context.Background()). XRequestId(uuid.NewV4().String()).Execute() util.HandleErrors(err, httpResp, "while generating client secret") diff --git a/cmd/users/get.go b/cmd/users/get.go index 5d6c61c..ba7747b 100644 --- a/cmd/users/get.go +++ b/cmd/users/get.go @@ -18,27 +18,34 @@ var userGetCmd = &cobra.Command{ Short: "Info about a specific user", Long: `Retrieves information about one user identified by id.`, Run: func(cmd *cobra.Command, args []string) { + resp, httpResp, err := client.ApiClient(). + UsersApi.RetrieveUser(context.Background(), getUserId). + XRequestId(uuid.NewV4().String()).Execute() - resp, httpResp, err := client.ApiClient().UsersApi.RetrieveUser(context.Background(), userId).XRequestId(uuid.NewV4().String()).Execute() util.HandleErrors(err, httpResp, "while retrieving user") responseJson, _ := json.Marshal(resp.Data) configFormatter := outputFormatter.FormatterConfig{ Filter: []string{"userId", "firstName", "lastName", "email", "enabled"}, - WideFilter: []string{"userId", "firstName", "lastName", "email", "enabled", "totp", "admin"}, + WideFilter: []string{"userId", "firstName", "lastName", "email", "enabled", "totp", "roles"}, JsonPath: contaboCmd.OutputFormatDetails} util.HandleResponse(responseJson, configFormatter) }, Args: func(cmd *cobra.Command, args []string) error { + contaboCmd.ValidateOutputFormat() + + if len(args) > 1 { + cmd.Help() + log.Fatal("Too many positional arguments.") + } if len(args) < 1 { cmd.Help() - log.Fatal("Please specify tagId") + log.Fatal("Please provide an userId.") } + getUserId = args[0] - userId = args[0] - contaboCmd.ValidateOutputFormat() return nil }, } diff --git a/cmd/users/history.go b/cmd/users/history.go index a102a99..62aeb48 100644 --- a/cmd/users/history.go +++ b/cmd/users/history.go @@ -8,6 +8,7 @@ import ( "contabo.com/cli/cntb/cmd/util" "contabo.com/cli/cntb/outputFormatter" uuid "github.com/satori/go.uuid" + log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" ) @@ -17,7 +18,6 @@ var userHistoryCmd = &cobra.Command{ Short: "History of your users", Long: `Show what happend to your users over time.`, Run: func(cmd *cobra.Command, args []string) { - historyRequest := client.ApiClient().UsersAuditsApi. RetrieveUserAuditsList(context.Background()). XRequestId(uuid.NewV4().String()). @@ -25,16 +25,8 @@ var userHistoryCmd = &cobra.Command{ Size(contaboCmd.Size). OrderBy([]string{contaboCmd.OrderBy}) - if cmd.Flags().Changed("userId") { - historyRequest = historyRequest.UserId(userIdFilter) - } - - if cmd.Flags().Changed("requestId") { - historyRequest = historyRequest.RequestId(contaboCmd.RequestIdFilter) - } - - if cmd.Flags().Changed("changedBy") { - historyRequest = historyRequest.ChangedBy(contaboCmd.ChangedByFilter) + if historyUserId != "" { + historyRequest = historyRequest.UserId(historyUserId) } resp, httpResp, err := historyRequest.Execute() @@ -46,20 +38,29 @@ var userHistoryCmd = &cobra.Command{ configFormatter := outputFormatter.FormatterConfig{ Filter: []string{"id", "userId", "action", "username", "timestamp"}, WideFilter: []string{"id", "userId", "action", "username", "changedBy", "requestId", "traceId", "tenantId", "customerId", "timestamp", "changes"}, - JsonPath: contaboCmd.OutputFormatDetails} + JsonPath: contaboCmd.OutputFormatDetails, + } util.HandleResponse(responseJson, configFormatter) }, Args: func(cmd *cobra.Command, args []string) error { contaboCmd.ValidateOutputFormat() + if len(args) > 0 { + cmd.Help() + log.Fatal("Too many positional arguments.") + } + + viper.BindPFlag("userId", cmd.Flags().Lookup("userId")) + historyUserIdFilter = viper.GetString("userId") + return nil - }} + }, +} func init() { contaboCmd.HistoryCmd.AddCommand(userHistoryCmd) - userHistoryCmd.Flags().StringVarP(&userIdFilter, "userId", "u", "", + userHistoryCmd.Flags().StringVarP(&historyUserIdFilter, "userId", "u", "", `To filter audits using Tag Id`) - viper.BindPFlag("tagId", userHistoryCmd.Flags().Lookup("userId")) } diff --git a/cmd/users/list.go b/cmd/users/list.go index 3ccd361..ac10d39 100644 --- a/cmd/users/list.go +++ b/cmd/users/list.go @@ -3,12 +3,14 @@ package cmd import ( "context" "encoding/json" + "strconv" "contabo.com/cli/cntb/client" contaboCmd "contabo.com/cli/cntb/cmd" "contabo.com/cli/cntb/cmd/util" "contabo.com/cli/cntb/outputFormatter" uuid "github.com/satori/go.uuid" + log "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" ) @@ -25,8 +27,13 @@ var usersGetCmd = &cobra.Command{ Size(contaboCmd.Size). OrderBy([]string{contaboCmd.OrderBy}) - if cmd.Flags().Changed("email") { - apiRetrieveUserListRequest = apiRetrieveUserListRequest.Email(userEmailFilter) + if listUserEmailFilter != "" { + apiRetrieveUserListRequest = apiRetrieveUserListRequest.Email(listUserEmailFilter) + } + + if listIsEnabledFilter != "" { + enabledFilter, _ := strconv.ParseBool(listIsEnabledFilter) + apiRetrieveUserListRequest = apiRetrieveUserListRequest.Enabled(enabledFilter) } resp, httpResp, err := apiRetrieveUserListRequest.Execute() @@ -37,17 +44,41 @@ var usersGetCmd = &cobra.Command{ configFormatter := outputFormatter.FormatterConfig{ Filter: []string{"userId", "firstName", "lastName", "email", "enabled"}, - WideFilter: []string{"userId", "tenantId", "customerId", "firstName", "lastName", "email", "enabled", "totp", "admin", "accessAllResources", "roles"}, + WideFilter: []string{"userId", "tenantId", "customerId", "firstName", "lastName", "email", "enabled", "totp", "roles"}, JsonPath: contaboCmd.OutputFormatDetails} util.HandleResponse(responseJson, configFormatter) }, + Args: func(cmd *cobra.Command, args []string) error { + contaboCmd.ValidateOutputFormat() + + if len(args) > 0 { + cmd.Help() + log.Fatal("Too many positional arguments.") + + } + + viper.BindPFlag("email", cmd.Flags().Lookup("email")) + listUserEmailFilter = viper.GetString("email") + + viper.BindPFlag("enabled", cmd.Flags().Lookup("enabled")) + listIsEnabledFilter = viper.GetString("enabled") + + if listIsEnabledFilter != "true" && listIsEnabledFilter != "false" && listIsEnabledFilter != "" { + cmd.Help() + log.Fatal("Invalid Argument enabled, please provide 'true' or 'false'.") + } + + return nil + }, } func init() { contaboCmd.GetCmd.AddCommand(usersGetCmd) - usersGetCmd.Flags().StringVarP(&userEmailFilter, "email", "e", "", + usersGetCmd.Flags().StringVarP(&listUserEmailFilter, "email", "e", "", `Filter by email`) - viper.BindPFlag("email", usersGetCmd.Flags().Lookup("email")) + + usersGetCmd.Flags().StringVar(&listIsEnabledFilter, "enabled", "", + `Filter if user is enabled`) } diff --git a/cmd/users/resendEmailVerification.go b/cmd/users/resendEmailVerification.go index f9a0668..e4bbae2 100644 --- a/cmd/users/resendEmailVerification.go +++ b/cmd/users/resendEmailVerification.go @@ -18,18 +18,24 @@ var resendEmailVerificationUserCmd = &cobra.Command{ Example: `cntb resendEmailVerification user 6cdf5968-f9fe-4192-97c2-f349e813c5e8`, Run: func(cmd *cobra.Command, args []string) { httpResp, err := client.ApiClient().UsersApi. - ResendEmailVerification(context.Background(), userId). + ResendEmailVerification(context.Background(), resendEmailVerificationUserId). XRequestId(uuid.NewV4().String()).Execute() util.HandleErrors(err, httpResp, "while resending email verification to user") }, Args: func(cmd *cobra.Command, args []string) error { contaboCmd.ValidateCreateInput() + + if len(args) > 1 { + cmd.Help() + log.Fatal("Too many positional arguments.") + } if len(args) < 1 { cmd.Help() - log.Fatal("Please specify userId") + log.Fatal("Please provide an userId.") } - userId = args[0] + + resendEmailVerificationUserId = args[0] return nil }, diff --git a/cmd/users/resetPassword.go b/cmd/users/resetPassword.go index 3dee9a3..a6432a1 100644 --- a/cmd/users/resetPassword.go +++ b/cmd/users/resetPassword.go @@ -17,18 +17,25 @@ var resetPasswordUserCmd = &cobra.Command{ Long: `Send email for password reset for a specific user`, Example: `cntb resetPassword user 6cdf5968-f9fe-4192-97c2-f349e813c5e8`, Run: func(cmd *cobra.Command, args []string) { - httpResp, err := client.ApiClient().UsersApi.ResetPassword(context.Background(), userId). + httpResp, err := client.ApiClient().UsersApi. + ResetPassword(context.Background(), resetPasswordUserId). XRequestId(uuid.NewV4().String()).Execute() util.HandleErrors(err, httpResp, "while resetting user password") }, Args: func(cmd *cobra.Command, args []string) error { contaboCmd.ValidateCreateInput() + + if len(args) > 1 { + cmd.Help() + log.Fatal("Too many positional arguments.") + } if len(args) < 1 { cmd.Help() - log.Fatal("Please specify userId") + log.Fatal("Please provide an userId.") } - userId = args[0] + + resetPasswordUserId = args[0] return nil }, diff --git a/cmd/users/update.go b/cmd/users/update.go index 17f4585..94cf6f3 100644 --- a/cmd/users/update.go +++ b/cmd/users/update.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "fmt" + "strconv" "strings" "contabo.com/cli/cntb/client" @@ -26,26 +27,28 @@ var userUpdateCmd = &cobra.Command{ switch content { case nil: // from arguments - if cmd.Flags().Changed("email") { - updateUserRequest.Email = &userEmail + if updateUserEmail != "" { + updateUserRequest.Email = &updateUserEmail } - if cmd.Flags().Changed("firstName") { - updateUserRequest.FirstName = &userFirstName + if updateUserFirstName != "" { + updateUserRequest.FirstName = &updateUserFirstName } - if cmd.Flags().Changed("lastName") { - updateUserRequest.LastName = &userLastName + if updateUserLastName != "" { + updateUserRequest.LastName = &updateUserLastName } - if cmd.Flags().Changed("enabled") { - updateUserRequest.Enabled = &isUserEnabled + if updateIsUserEnabled != "" { + isEnabled, _ := strconv.ParseBool(updateIsUserEnabled) + updateUserRequest.Enabled = &isEnabled } - if cmd.Flags().Changed("admin") { - updateUserRequest.Admin = &isAdmin + if updateIsTotpEnabeld != "" { + isTotp, _ := strconv.ParseBool(updateIsTotpEnabeld) + updateUserRequest.Totp = &isTotp } - if roles != nil { - updateUserRequest.Roles = &roles + if updateLocale != "" { + updateUserRequest.Locale = &updateLocale } - if canAccessAllResources { - updateUserRequest.AccessAllResources = &canAccessAllResources + if updateRoles != nil { + updateUserRequest.Roles = &updateRoles } default: // from file / stdin @@ -59,7 +62,7 @@ var userUpdateCmd = &cobra.Command{ } resp, httpResp, err := client.ApiClient().UsersApi. - UpdateUser(context.Background(), userId). + UpdateUser(context.Background(), updateUserId). UpdateUserRequest(updateUserRequest). XRequestId(uuid.NewV4().String()). Execute() @@ -71,11 +74,50 @@ var userUpdateCmd = &cobra.Command{ }, Args: func(cmd *cobra.Command, args []string) error { contaboCmd.ValidateCreateInput() + if len(args) < 1 { cmd.Help() - log.Fatal("Please specify tagId") + log.Fatal("Please provide an userId.") + } + if len(args) > 1 { + cmd.Help() + log.Fatal("Too many positional arguments.") + } + + viper.BindPFlag("firstName", cmd.Flags().Lookup("firstName")) + updateUserFirstName = viper.GetString("firstName") + + viper.BindPFlag("lastName", cmd.Flags().Lookup("lastName")) + updateUserLastName = viper.GetString("lastName") + + viper.BindPFlag("email", cmd.Flags().Lookup("email")) + updateUserEmail = viper.GetString("email") + + viper.BindPFlag("enabled", cmd.Flags().Lookup("enabled")) + updateIsUserEnabled = viper.GetString("enabled") + + if updateIsUserEnabled != "true" && updateIsUserEnabled != "false" && updateIsUserEnabled != "" { + cmd.Help() + log.Fatal("Invalid Argument enabled, please provide 'true' or 'false'.") } - userId = args[0] + + viper.BindPFlag("totp", cmd.Flags().Lookup("totp")) + updateIsTotpEnabeld = viper.GetString("totp") + + if updateIsTotpEnabeld != "true" && updateIsTotpEnabeld != "false" && updateIsTotpEnabeld != "" { + cmd.Help() + log.Fatal("Invalid Argument totp, please provide 'true' or 'false'.") + } + + viper.BindPFlag("roles", cmd.Flags().Lookup("roles")) + for i := range viper.GetIntSlice("roles") { + updateRoles[i] = int64(viper.GetIntSlice("roles")[i]) + } + + viper.BindPFlag("locale", cmd.Flags().Lookup("locale")) + updateLocale = viper.GetString("locale") + + updateUserId = args[0] return nil }, @@ -84,32 +126,24 @@ var userUpdateCmd = &cobra.Command{ func init() { contaboCmd.UpdateCmd.AddCommand(userUpdateCmd) - userUpdateCmd.Flags().StringVar(&userFirstName, "firstName", "", `first name of the user`) - viper.BindPFlag("firstName", userUpdateCmd.Flags().Lookup("firstName")) - viper.SetDefault("firstName", "") - - userUpdateCmd.Flags().StringVar(&userLastName, "lastName", "", `last name of the user`) - viper.BindPFlag("lastName", userUpdateCmd.Flags().Lookup("lastName")) - viper.SetDefault("lastName", "") + userUpdateCmd.Flags().StringVar(&updateUserFirstName, "firstName", "", + `first name of the user`) - userUpdateCmd.Flags().StringVar(&userEmail, "email", "", `email of the user`) - viper.BindPFlag("email", userUpdateCmd.Flags().Lookup("email")) - viper.SetDefault("email", "") + userUpdateCmd.Flags().StringVar(&updateUserLastName, "lastName", "", + `last name of the user`) - userUpdateCmd.Flags().BoolVar(&isUserEnabled, "enabled", false, `is the user enabled`) - viper.BindPFlag("enabled", userUpdateCmd.Flags().Lookup("userEnabled")) - viper.SetDefault("enabled", false) + userUpdateCmd.Flags().StringVar(&updateUserEmail, "email", "", + `email of the user`) - userUpdateCmd.Flags().BoolVar(&isAdmin, "admin", false, `sets the user as an admin and allows him to perform all tasks`) - viper.BindPFlag("admin", userUpdateCmd.Flags().Lookup("admin")) - viper.SetDefault("admin", false) + userUpdateCmd.Flags().StringVar(&updateIsUserEnabled, "enabled", "", + `is the user enabled. ('true' or 'false')`) - userUpdateCmd.Flags().BoolVar(&canAccessAllResources, "accessAllResources", false, `can the user access all resources for permissions he has`) - viper.BindPFlag("accessAllResources", userUpdateCmd.Flags().Lookup("accessAllResources")) - viper.SetDefault("accessAllResources", false) + userUpdateCmd.Flags().StringVar(&updateIsTotpEnabeld, "totp", "", + `Enable or disable two-factor authentication (2FA) via time based OTP. ('true' or 'false')`) - userUpdateCmd.Flags().Int64SliceVarP(&roles, "roles", "r", nil, `list of role ids the user should have`) - viper.BindPFlag("roles", userUpdateCmd.Flags().Lookup("roles")) - viper.SetDefault("roles", nil) + userUpdateCmd.Flags().Int64SliceVarP(&updateRoles, "roles", "r", nil, + `list of role ids the user should have.`) + userUpdateCmd.Flags().StringVar(&updateLocale, "locale", "", + `The locale of the user. This can be de-DE, de, en-US, en`) } diff --git a/cmd/users/vars.go b/cmd/users/vars.go index 729e7c4..35687dc 100644 --- a/cmd/users/vars.go +++ b/cmd/users/vars.go @@ -1,17 +1,61 @@ package cmd +// create var ( - userFirstName string - userLastName string - userEmail string - isUserEnabled bool - isAdmin bool - canAccessAllResources bool - roles []int64 - locale string - userId string - userIdFilter string - parseError error - userEmailFilter string - isEnabledFilter bool + createUserFirstName string + createUserLastName string + createUserEmail string + createIsUserEnabled bool + createIsTotpEnabeld bool + createRoles []int64 + createLocale string +) + +// delete +var ( + deleteUserId string +) + +// edit +var ( + editUserId string +) + +// get +var ( + getUserId string +) + +// history +var ( + historyUserId string + historyUserIdFilter string +) + +// list +var ( + listUserEmailFilter string + listIsEnabledFilter string +) + +// resendEmailVerification +var ( + resendEmailVerificationUserId string +) + +// resetPassword +var ( + resetPasswordUserId string +) + +// update +var ( + updateUserFirstName string + updateUserLastName string + updateUserEmail string + updateIsUserEnabled string + updateIsTotpEnabeld string + updateRoles []int64 + updateLocale string + updateUserId string )