mygithub.libinneed.workers.dev/stackitcloud/stackit-cli
Advanced tools
| package auth | ||
| import ( | ||
| "fmt" | ||
| "io" | ||
| "net/http" | ||
| "strings" | ||
| "testing" | ||
| "github.com/google/go-cmp/cmp" | ||
| "github.com/zalando/go-keyring" | ||
| ) | ||
| type apiClientMocked struct { | ||
| getFails bool | ||
| getResponse string | ||
| } | ||
| func (a *apiClientMocked) Do(_ *http.Request) (*http.Response, error) { | ||
| if a.getFails { | ||
| return &http.Response{ | ||
| StatusCode: http.StatusNotFound, | ||
| }, fmt.Errorf("not found") | ||
| } | ||
| return &http.Response{ | ||
| Status: "200 OK", | ||
| StatusCode: http.StatusAccepted, | ||
| Body: io.NopCloser(strings.NewReader(a.getResponse)), | ||
| }, nil | ||
| } | ||
| func TestParseWellKnownConfig(t *testing.T) { | ||
| tests := []struct { | ||
| name string | ||
| getFails bool | ||
| getResponse string | ||
| isValid bool | ||
| expected *wellKnownConfig | ||
| }{ | ||
| { | ||
| name: "success", | ||
| getFails: false, | ||
| getResponse: `{"issuer":"issuer","authorization_endpoint":"auth","token_endpoint":"token"}`, | ||
| isValid: true, | ||
| expected: &wellKnownConfig{ | ||
| Issuer: "issuer", | ||
| AuthorizationEndpoint: "auth", | ||
| TokenEndpoint: "token", | ||
| }, | ||
| }, | ||
| { | ||
| name: "get_fails", | ||
| getFails: true, | ||
| getResponse: "", | ||
| isValid: false, | ||
| expected: nil, | ||
| }, | ||
| { | ||
| name: "empty_response", | ||
| getFails: true, | ||
| getResponse: "", | ||
| isValid: false, | ||
| expected: nil, | ||
| }, | ||
| { | ||
| name: "missing_issuer", | ||
| getFails: true, | ||
| getResponse: `{"authorization_endpoint":"auth","token_endpoint":"token"}`, | ||
| isValid: false, | ||
| expected: nil, | ||
| }, | ||
| { | ||
| name: "missing_authorization", | ||
| getFails: true, | ||
| getResponse: `{"issuer":"issuer","token_endpoint":"token"}`, | ||
| isValid: false, | ||
| expected: nil, | ||
| }, | ||
| { | ||
| name: "missing_token", | ||
| getFails: true, | ||
| getResponse: `{"issuer":"issuer","authorization_endpoint":"auth"}`, | ||
| isValid: false, | ||
| expected: nil, | ||
| }, | ||
| } | ||
| for _, tt := range tests { | ||
| t.Run(tt.name, func(t *testing.T) { | ||
| keyring.MockInit() | ||
| testClient := apiClientMocked{ | ||
| tt.getFails, | ||
| tt.getResponse, | ||
| } | ||
| got, err := parseWellKnownConfiguration(&testClient, "") | ||
| if tt.isValid && err != nil { | ||
| t.Fatalf("expected no error, got %v", err) | ||
| } | ||
| if !tt.isValid && err == nil { | ||
| t.Fatalf("expected error, got none") | ||
| } | ||
| if tt.isValid && !cmp.Equal(*got, *tt.expected) { | ||
| t.Fatalf("expected %v, got %v", tt.expected, got) | ||
| } | ||
| }) | ||
| } | ||
| } |
@@ -32,29 +32,29 @@ ## stackit config set | ||
| ``` | ||
| --allowed-url-domain string Domain name, used for the verification of the URLs that are given in the custom identity provider endpoint and "STACKIT curl" command | ||
| --authorization-custom-endpoint string Authorization API base URL, used in calls to this API | ||
| --dns-custom-endpoint string DNS API base URL, used in calls to this API | ||
| -h, --help Help for "stackit config set" | ||
| --iaas-custom-endpoint string IaaS API base URL, used in calls to this API | ||
| --identity-provider-custom-client-id string Identity Provider client ID, used for user authentication | ||
| --identity-provider-custom-endpoint string Identity Provider base URL, used for user authentication | ||
| --load-balancer-custom-endpoint string Load Balancer API base URL, used in calls to this API | ||
| --logme-custom-endpoint string LogMe API base URL, used in calls to this API | ||
| --mariadb-custom-endpoint string MariaDB API base URL, used in calls to this API | ||
| --mongodbflex-custom-endpoint string MongoDB Flex API base URL, used in calls to this API | ||
| --object-storage-custom-endpoint string Object Storage API base URL, used in calls to this API | ||
| --observability-custom-endpoint string Observability API base URL, used in calls to this API | ||
| --opensearch-custom-endpoint string OpenSearch API base URL, used in calls to this API | ||
| --postgresflex-custom-endpoint string PostgreSQL Flex API base URL, used in calls to this API | ||
| --rabbitmq-custom-endpoint string RabbitMQ API base URL, used in calls to this API | ||
| --redis-custom-endpoint string Redis API base URL, used in calls to this API | ||
| --resource-manager-custom-endpoint string Resource Manager API base URL, used in calls to this API | ||
| --runcommand-custom-endpoint string Run Command API base URL, used in calls to this API | ||
| --secrets-manager-custom-endpoint string Secrets Manager API base URL, used in calls to this API | ||
| --serverbackup-custom-endpoint string Server Backup API base URL, used in calls to this API | ||
| --service-account-custom-endpoint string Service Account API base URL, used in calls to this API | ||
| --service-enablement-custom-endpoint string Service Enablement API base URL, used in calls to this API | ||
| --session-time-limit string Maximum time before authentication is required again. After this time, you will be prompted to login again to execute commands that require authentication. Can't be larger than 24h. Requires authentication after being set to take effect. Examples: 3h, 5h30m40s (BETA: currently values greater than 2h have no effect) | ||
| --ske-custom-endpoint string SKE API base URL, used in calls to this API | ||
| --sqlserverflex-custom-endpoint string SQLServer Flex API base URL, used in calls to this API | ||
| --token-custom-endpoint string Custom endpoint for the token API, which is used to request access tokens when the service-account authentication is activated | ||
| --allowed-url-domain string Domain name, used for the verification of the URLs that are given in the custom identity provider endpoint and "STACKIT curl" command | ||
| --authorization-custom-endpoint string Authorization API base URL, used in calls to this API | ||
| --dns-custom-endpoint string DNS API base URL, used in calls to this API | ||
| -h, --help Help for "stackit config set" | ||
| --iaas-custom-endpoint string IaaS API base URL, used in calls to this API | ||
| --identity-provider-custom-client-id string Identity Provider client ID, used for user authentication | ||
| --identity-provider-custom-well-known-configuration string Identity Provider well-known OpenID configuration URL, used for user authentication | ||
| --load-balancer-custom-endpoint string Load Balancer API base URL, used in calls to this API | ||
| --logme-custom-endpoint string LogMe API base URL, used in calls to this API | ||
| --mariadb-custom-endpoint string MariaDB API base URL, used in calls to this API | ||
| --mongodbflex-custom-endpoint string MongoDB Flex API base URL, used in calls to this API | ||
| --object-storage-custom-endpoint string Object Storage API base URL, used in calls to this API | ||
| --observability-custom-endpoint string Observability API base URL, used in calls to this API | ||
| --opensearch-custom-endpoint string OpenSearch API base URL, used in calls to this API | ||
| --postgresflex-custom-endpoint string PostgreSQL Flex API base URL, used in calls to this API | ||
| --rabbitmq-custom-endpoint string RabbitMQ API base URL, used in calls to this API | ||
| --redis-custom-endpoint string Redis API base URL, used in calls to this API | ||
| --resource-manager-custom-endpoint string Resource Manager API base URL, used in calls to this API | ||
| --runcommand-custom-endpoint string Run Command API base URL, used in calls to this API | ||
| --secrets-manager-custom-endpoint string Secrets Manager API base URL, used in calls to this API | ||
| --serverbackup-custom-endpoint string Server Backup API base URL, used in calls to this API | ||
| --service-account-custom-endpoint string Service Account API base URL, used in calls to this API | ||
| --service-enablement-custom-endpoint string Service Enablement API base URL, used in calls to this API | ||
| --session-time-limit string Maximum time before authentication is required again. After this time, you will be prompted to login again to execute commands that require authentication. Can't be larger than 24h. Requires authentication after being set to take effect. Examples: 3h, 5h30m40s (BETA: currently values greater than 2h have no effect) | ||
| --ske-custom-endpoint string SKE API base URL, used in calls to this API | ||
| --sqlserverflex-custom-endpoint string SQLServer Flex API base URL, used in calls to this API | ||
| --token-custom-endpoint string Custom endpoint for the token API, which is used to request access tokens when the service-account authentication is activated | ||
| ``` | ||
@@ -61,0 +61,0 @@ |
@@ -29,33 +29,33 @@ ## stackit config unset | ||
| ``` | ||
| --allowed-url-domain Domain name, used for the verification of the URLs that are given in the IDP endpoint and curl commands. If unset, defaults to stackit.cloud | ||
| --async Configuration option to run commands asynchronously | ||
| --authorization-custom-endpoint Authorization API base URL. If unset, uses the default base URL | ||
| --dns-custom-endpoint DNS API base URL. If unset, uses the default base URL | ||
| -h, --help Help for "stackit config unset" | ||
| --iaas-custom-endpoint IaaS API base URL. If unset, uses the default base URL | ||
| --identity-provider-custom-client-id Identity Provider client ID, used for user authentication | ||
| --identity-provider-custom-endpoint Identity Provider base URL. If unset, uses the default base URL | ||
| --load-balancer-custom-endpoint Load Balancer API base URL. If unset, uses the default base URL | ||
| --logme-custom-endpoint LogMe API base URL. If unset, uses the default base URL | ||
| --mariadb-custom-endpoint MariaDB API base URL. If unset, uses the default base URL | ||
| --mongodbflex-custom-endpoint MongoDB Flex API base URL. If unset, uses the default base URL | ||
| --object-storage-custom-endpoint Object Storage API base URL. If unset, uses the default base URL | ||
| --observability-custom-endpoint Observability API base URL. If unset, uses the default base URL | ||
| --opensearch-custom-endpoint OpenSearch API base URL. If unset, uses the default base URL | ||
| --output-format Output format | ||
| --postgresflex-custom-endpoint PostgreSQL Flex API base URL. If unset, uses the default base URL | ||
| --project-id Project ID | ||
| --rabbitmq-custom-endpoint RabbitMQ API base URL. If unset, uses the default base URL | ||
| --redis-custom-endpoint Redis API base URL. If unset, uses the default base URL | ||
| --resource-manager-custom-endpoint Resource Manager API base URL. If unset, uses the default base URL | ||
| --runcommand-custom-endpoint Server Command base URL. If unset, uses the default base URL | ||
| --secrets-manager-custom-endpoint Secrets Manager API base URL. If unset, uses the default base URL | ||
| --serverbackup-custom-endpoint Server Backup base URL. If unset, uses the default base URL | ||
| --service-account-custom-endpoint Service Account API base URL. If unset, uses the default base URL | ||
| --service-enablement-custom-endpoint Service Enablement API base URL. If unset, uses the default base URL | ||
| --session-time-limit Maximum time before authentication is required again. If unset, defaults to 2h | ||
| --ske-custom-endpoint SKE API base URL. If unset, uses the default base URL | ||
| --sqlserverflex-custom-endpoint SQLServer Flex API base URL. If unset, uses the default base URL | ||
| --token-custom-endpoint Custom endpoint for the token API, which is used to request access tokens when the service-account authentication is activated | ||
| --verbosity Verbosity of the CLI | ||
| --allowed-url-domain Domain name, used for the verification of the URLs that are given in the IDP endpoint and curl commands. If unset, defaults to stackit.cloud | ||
| --async Configuration option to run commands asynchronously | ||
| --authorization-custom-endpoint Authorization API base URL. If unset, uses the default base URL | ||
| --dns-custom-endpoint DNS API base URL. If unset, uses the default base URL | ||
| -h, --help Help for "stackit config unset" | ||
| --iaas-custom-endpoint IaaS API base URL. If unset, uses the default base URL | ||
| --identity-provider-custom-client-id Identity Provider client ID, used for user authentication | ||
| --identity-provider-custom-well-known-configuration Identity Provider well-known OpenID configuration URL. If unset, uses the default identity provider | ||
| --load-balancer-custom-endpoint Load Balancer API base URL. If unset, uses the default base URL | ||
| --logme-custom-endpoint LogMe API base URL. If unset, uses the default base URL | ||
| --mariadb-custom-endpoint MariaDB API base URL. If unset, uses the default base URL | ||
| --mongodbflex-custom-endpoint MongoDB Flex API base URL. If unset, uses the default base URL | ||
| --object-storage-custom-endpoint Object Storage API base URL. If unset, uses the default base URL | ||
| --observability-custom-endpoint Observability API base URL. If unset, uses the default base URL | ||
| --opensearch-custom-endpoint OpenSearch API base URL. If unset, uses the default base URL | ||
| --output-format Output format | ||
| --postgresflex-custom-endpoint PostgreSQL Flex API base URL. If unset, uses the default base URL | ||
| --project-id Project ID | ||
| --rabbitmq-custom-endpoint RabbitMQ API base URL. If unset, uses the default base URL | ||
| --redis-custom-endpoint Redis API base URL. If unset, uses the default base URL | ||
| --resource-manager-custom-endpoint Resource Manager API base URL. If unset, uses the default base URL | ||
| --runcommand-custom-endpoint Server Command base URL. If unset, uses the default base URL | ||
| --secrets-manager-custom-endpoint Secrets Manager API base URL. If unset, uses the default base URL | ||
| --serverbackup-custom-endpoint Server Backup base URL. If unset, uses the default base URL | ||
| --service-account-custom-endpoint Service Account API base URL. If unset, uses the default base URL | ||
| --service-enablement-custom-endpoint Service Enablement API base URL. If unset, uses the default base URL | ||
| --session-time-limit Maximum time before authentication is required again. If unset, defaults to 2h | ||
| --ske-custom-endpoint SKE API base URL. If unset, uses the default base URL | ||
| --sqlserverflex-custom-endpoint SQLServer Flex API base URL. If unset, uses the default base URL | ||
| --token-custom-endpoint Custom endpoint for the token API, which is used to request access tokens when the service-account authentication is activated | ||
| --verbosity Verbosity of the CLI | ||
| ``` | ||
@@ -62,0 +62,0 @@ |
+7
-7
@@ -18,8 +18,8 @@ module github.com/stackitcloud/stackit-cli | ||
| github.com/spf13/viper v1.19.0 | ||
| github.com/stackitcloud/stackit-sdk-go/core v0.12.0 | ||
| github.com/stackitcloud/stackit-sdk-go/core v0.13.0 | ||
| github.com/stackitcloud/stackit-sdk-go/services/authorization v0.3.0 | ||
| github.com/stackitcloud/stackit-sdk-go/services/dns v0.10.0 | ||
| github.com/stackitcloud/stackit-sdk-go/services/iaas v0.8.0 | ||
| github.com/stackitcloud/stackit-sdk-go/services/mongodbflex v0.14.0 | ||
| github.com/stackitcloud/stackit-sdk-go/services/opensearch v0.16.0 | ||
| github.com/stackitcloud/stackit-sdk-go/services/mongodbflex v0.15.0 | ||
| github.com/stackitcloud/stackit-sdk-go/services/opensearch v0.18.0 | ||
| github.com/stackitcloud/stackit-sdk-go/services/postgresflex v0.15.0 | ||
@@ -82,8 +82,8 @@ github.com/stackitcloud/stackit-sdk-go/services/resourcemanager v0.9.0 | ||
| github.com/stackitcloud/stackit-sdk-go/services/loadbalancer v0.14.0 | ||
| github.com/stackitcloud/stackit-sdk-go/services/logme v0.17.0 | ||
| github.com/stackitcloud/stackit-sdk-go/services/mariadb v0.17.0 | ||
| github.com/stackitcloud/stackit-sdk-go/services/logme v0.19.0 | ||
| github.com/stackitcloud/stackit-sdk-go/services/mariadb v0.19.0 | ||
| github.com/stackitcloud/stackit-sdk-go/services/objectstorage v0.10.0 | ||
| github.com/stackitcloud/stackit-sdk-go/services/observability v0.1.0 | ||
| github.com/stackitcloud/stackit-sdk-go/services/rabbitmq v0.17.0 | ||
| github.com/stackitcloud/stackit-sdk-go/services/redis v0.17.0 | ||
| github.com/stackitcloud/stackit-sdk-go/services/rabbitmq v0.19.0 | ||
| github.com/stackitcloud/stackit-sdk-go/services/redis v0.19.0 | ||
| github.com/subosito/gotenv v1.6.0 // indirect | ||
@@ -90,0 +90,0 @@ go.uber.org/multierr v1.11.0 // indirect |
+14
-14
@@ -126,4 +126,4 @@ github.com/alessio/shellescape v1.4.2 h1:MHPfaU+ddJ0/bYWpgIeUnQUqKrlJ1S7BfEYPM4uEoM0= | ||
| github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= | ||
| github.com/stackitcloud/stackit-sdk-go/core v0.12.0 h1:auIzUUNRuydKOScvpICP4MifGgvOajiDQd+ncGmBL0U= | ||
| github.com/stackitcloud/stackit-sdk-go/core v0.12.0/go.mod h1:mDX1mSTsB3mP+tNBGcFNx6gH1mGBN4T+dVt+lcw7nlw= | ||
| github.com/stackitcloud/stackit-sdk-go/core v0.13.0 h1:BtJT2WXqZdexPPQi/HPUIr8g4JUPOCheh6J9dxiCQ4Q= | ||
| github.com/stackitcloud/stackit-sdk-go/core v0.13.0/go.mod h1:mDX1mSTsB3mP+tNBGcFNx6gH1mGBN4T+dVt+lcw7nlw= | ||
| github.com/stackitcloud/stackit-sdk-go/services/authorization v0.3.0 h1:AyzBgcbd0rCm+2+xaWqtfibjWmkKlO+U+7qxqvtKpJ8= | ||
@@ -137,8 +137,8 @@ github.com/stackitcloud/stackit-sdk-go/services/authorization v0.3.0/go.mod h1:1sLuXa7Qvp9f+wKWdRjyNe8B2F8JX7nSTd8fBKadri4= | ||
| github.com/stackitcloud/stackit-sdk-go/services/loadbalancer v0.14.0/go.mod h1:wsO3+vXe1XiKLeCIctWAptaHQZ07Un7kmLTQ+drbj7w= | ||
| github.com/stackitcloud/stackit-sdk-go/services/logme v0.17.0 h1:S8UZYBu2lHmKCPTR17jZetIal8X7cHO1gVRv101UdPw= | ||
| github.com/stackitcloud/stackit-sdk-go/services/logme v0.17.0/go.mod h1:bj9cn1treNSxKTRCEmESwqfENN8vCYn60HUnEA0P83c= | ||
| github.com/stackitcloud/stackit-sdk-go/services/mariadb v0.17.0 h1:+amOO/LW/PfUVU2ptxoB8PuNacawjjX2gGh7bHd45RE= | ||
| github.com/stackitcloud/stackit-sdk-go/services/mariadb v0.17.0/go.mod h1:kPetkX9hNm9HkRyiKQL/tlgdi8frZdMP8afg0mEvQ9s= | ||
| github.com/stackitcloud/stackit-sdk-go/services/mongodbflex v0.14.0 h1:FaJYVfha+atvPfFIf3h3+BFjOjeux9OBHukG1J98kq0= | ||
| github.com/stackitcloud/stackit-sdk-go/services/mongodbflex v0.14.0/go.mod h1:iFerEzGmkg6R13ldFUyHUWHm0ac9cS4ftTDLhP0k/dU= | ||
| github.com/stackitcloud/stackit-sdk-go/services/logme v0.19.0 h1:KcsF549yXOrm8zlqFCNV+lf2L4zvQuh4L2i3kgdWbOE= | ||
| github.com/stackitcloud/stackit-sdk-go/services/logme v0.19.0/go.mod h1:bj9cn1treNSxKTRCEmESwqfENN8vCYn60HUnEA0P83c= | ||
| github.com/stackitcloud/stackit-sdk-go/services/mariadb v0.19.0 h1:tlU/Z1Z8IXqWdkdIQYSHkO/btqYX80rg3oddKBzn430= | ||
| github.com/stackitcloud/stackit-sdk-go/services/mariadb v0.19.0/go.mod h1:kPetkX9hNm9HkRyiKQL/tlgdi8frZdMP8afg0mEvQ9s= | ||
| github.com/stackitcloud/stackit-sdk-go/services/mongodbflex v0.15.0 h1:WjjG2GJ+7fBH7Akil2srDBZhCbqxNpAR8LhYwIoeylo= | ||
| github.com/stackitcloud/stackit-sdk-go/services/mongodbflex v0.15.0/go.mod h1:iFerEzGmkg6R13ldFUyHUWHm0ac9cS4ftTDLhP0k/dU= | ||
| github.com/stackitcloud/stackit-sdk-go/services/objectstorage v0.10.0 h1:tn1MD1nu+gYEbT3lslRI6BrapKwuvHv5Wi2Zw9uVPPc= | ||
@@ -148,10 +148,10 @@ github.com/stackitcloud/stackit-sdk-go/services/objectstorage v0.10.0/go.mod h1:dkVMJI88eJ3Xs0ZV15r4tUpgitUGJXcvrX3RL4Zq2bQ= | ||
| github.com/stackitcloud/stackit-sdk-go/services/observability v0.1.0/go.mod h1:cSnBZGdtx4jnn9HEefkQHDrm8+PuS0NCWvukVfuwP/8= | ||
| github.com/stackitcloud/stackit-sdk-go/services/opensearch v0.16.0 h1:EEjhfIFiC4TsaFKB4mkxz6NFz4InfVs5STmWc+oEjgQ= | ||
| github.com/stackitcloud/stackit-sdk-go/services/opensearch v0.16.0/go.mod h1:ZecMIf9oYj2DGZqWh93l97WdVaRdLl+tW5Fq3YKGwBM= | ||
| github.com/stackitcloud/stackit-sdk-go/services/opensearch v0.18.0 h1:pzHA3sxaAsZzKjsCffMcToAk3ooZsj1PxwZODGRTpoI= | ||
| github.com/stackitcloud/stackit-sdk-go/services/opensearch v0.18.0/go.mod h1:ZecMIf9oYj2DGZqWh93l97WdVaRdLl+tW5Fq3YKGwBM= | ||
| github.com/stackitcloud/stackit-sdk-go/services/postgresflex v0.15.0 h1:05wQYhO37Z4y8xAD+4OTYz6rYu6eJEmwMfCG4tjETEc= | ||
| github.com/stackitcloud/stackit-sdk-go/services/postgresflex v0.15.0/go.mod h1:SdrqGLCkilL6wl1+jcxmLtks2IocgIg+bsyeyYUIzR4= | ||
| github.com/stackitcloud/stackit-sdk-go/services/rabbitmq v0.17.0 h1:k8GIrOQj+COIgkkHNNXw5ciUzvWU/RjL5XD7t5DTrOM= | ||
| github.com/stackitcloud/stackit-sdk-go/services/rabbitmq v0.17.0/go.mod h1:eSgnPBknTJh7t+jVKN+xzeAh+Cg1USOlH3QCyfvG20g= | ||
| github.com/stackitcloud/stackit-sdk-go/services/redis v0.17.0 h1:jnApmhchW5FYNWss1d2hJzH7O3slBOYa2wEseg5pl3o= | ||
| github.com/stackitcloud/stackit-sdk-go/services/redis v0.17.0/go.mod h1:3LhiTR/DMbKR2HuleTzlFHltR1MT1KD0DeW46X6K2GE= | ||
| github.com/stackitcloud/stackit-sdk-go/services/rabbitmq v0.19.0 h1:qZ62GSQKw73JrS7a9WeGILMki26KNyqrMOmD8r41u/A= | ||
| github.com/stackitcloud/stackit-sdk-go/services/rabbitmq v0.19.0/go.mod h1:eSgnPBknTJh7t+jVKN+xzeAh+Cg1USOlH3QCyfvG20g= | ||
| github.com/stackitcloud/stackit-sdk-go/services/redis v0.19.0 h1:/s9GUIpwZTN6I7J4nKmBBmxc6lPJYpCHHxYsC+gDsZs= | ||
| github.com/stackitcloud/stackit-sdk-go/services/redis v0.19.0/go.mod h1:3LhiTR/DMbKR2HuleTzlFHltR1MT1KD0DeW46X6K2GE= | ||
| github.com/stackitcloud/stackit-sdk-go/services/resourcemanager v0.9.0 h1:qCbvGqdG9saRB++UlhXt5ieCCDCITROqL5K2nm38efU= | ||
@@ -158,0 +158,0 @@ github.com/stackitcloud/stackit-sdk-go/services/resourcemanager v0.9.0/go.mod h1:p16qz/pAW8b1gEhqMpIgJfutRPeDPqQLlbVGyCo3f8o= |
+1
-1
@@ -69,3 +69,3 @@ # Installation | ||
| If you can't get latest updates due to an expired key, please go back to Step 1 and execute the commands again to fetch and use the latest key. | ||
| > If you can't install the `stackit` package due to an expired key, please go back to step `1` to import the latest public key. | ||
@@ -72,0 +72,0 @@ #### Any distribution |
@@ -68,2 +68,13 @@ package create | ||
| func fixtureRequiredRequest(mods ...func(request *iaas.ApiCreateNetworkRequest)) iaas.ApiCreateNetworkRequest { | ||
| request := testClient.CreateNetwork(testCtx, testProjectId) | ||
| request = request.CreateNetworkPayload(iaas.CreateNetworkPayload{ | ||
| Name: utils.Ptr("example-network-name"), | ||
| }) | ||
| for _, mod := range mods { | ||
| mod(&request) | ||
| } | ||
| return request | ||
| } | ||
| func fixturePayload(mods ...func(payload *iaas.CreateNetworkPayload)) iaas.CreateNetworkPayload { | ||
@@ -230,2 +241,13 @@ payload := iaas.CreateNetworkPayload{ | ||
| }, | ||
| { | ||
| description: "only name in payload", | ||
| model: &inputModel{ | ||
| GlobalFlagModel: &globalflags.GlobalFlagModel{ | ||
| ProjectId: testProjectId, | ||
| Verbosity: globalflags.VerbosityDefault, | ||
| }, | ||
| Name: utils.Ptr("example-network-name"), | ||
| }, | ||
| expectedRequest: fixtureRequiredRequest(), | ||
| }, | ||
| } | ||
@@ -232,0 +254,0 @@ |
@@ -156,3 +156,3 @@ package create | ||
| if model.IPv6DnsNameServers != nil { | ||
| if model.IPv6DnsNameServers != nil || model.IPv6PrefixLength != nil { | ||
| addressFamily.Ipv6 = &iaas.CreateNetworkIPv6Body{ | ||
@@ -164,3 +164,3 @@ Nameservers: model.IPv6DnsNameServers, | ||
| if model.IPv4DnsNameServers != nil { | ||
| if model.IPv4DnsNameServers != nil || model.IPv4PrefixLength != nil { | ||
| addressFamily.Ipv4 = &iaas.CreateNetworkIPv4Body{ | ||
@@ -173,6 +173,9 @@ Nameservers: model.IPv4DnsNameServers, | ||
| payload := iaas.CreateNetworkPayload{ | ||
| Name: model.Name, | ||
| AddressFamily: addressFamily, | ||
| Name: model.Name, | ||
| } | ||
| if addressFamily.Ipv4 != nil || addressFamily.Ipv6 != nil { | ||
| payload.AddressFamily = addressFamily | ||
| } | ||
| return req.CreateNetworkPayload(payload) | ||
@@ -179,0 +182,0 @@ } |
@@ -37,3 +37,2 @@ package update | ||
| IPv6DnsNameServers *[]string | ||
| IPv6PrefixLength *int64 | ||
| } | ||
@@ -170,7 +169,10 @@ | ||
| payload := iaas.PartialUpdateNetworkPayload{ | ||
| Name: model.Name, | ||
| AddressFamily: addressFamily, | ||
| Name: model.Name, | ||
| } | ||
| if addressFamily.Ipv4 != nil || addressFamily.Ipv6 != nil { | ||
| payload.AddressFamily = addressFamily | ||
| } | ||
| return req.PartialUpdateNetworkPayload(payload) | ||
| } |
@@ -20,6 +20,6 @@ package set | ||
| const ( | ||
| sessionTimeLimitFlag = "session-time-limit" | ||
| identityProviderCustomEndpointFlag = "identity-provider-custom-endpoint" | ||
| identityProviderCustomClientIdFlag = "identity-provider-custom-client-id" | ||
| allowedUrlDomainFlag = "allowed-url-domain" | ||
| sessionTimeLimitFlag = "session-time-limit" | ||
| identityProviderCustomWellKnownConfigurationFlag = "identity-provider-custom-well-known-configuration" | ||
| identityProviderCustomClientIdFlag = "identity-provider-custom-client-id" | ||
| allowedUrlDomainFlag = "allowed-url-domain" | ||
@@ -135,3 +135,3 @@ authorizationCustomEndpointFlag = "authorization-custom-endpoint" | ||
| cmd.Flags().String(sessionTimeLimitFlag, "", "Maximum time before authentication is required again. After this time, you will be prompted to login again to execute commands that require authentication. Can't be larger than 24h. Requires authentication after being set to take effect. Examples: 3h, 5h30m40s (BETA: currently values greater than 2h have no effect)") | ||
| cmd.Flags().String(identityProviderCustomEndpointFlag, "", "Identity Provider base URL, used for user authentication") | ||
| cmd.Flags().String(identityProviderCustomWellKnownConfigurationFlag, "", "Identity Provider well-known OpenID configuration URL, used for user authentication") | ||
| cmd.Flags().String(identityProviderCustomClientIdFlag, "", "Identity Provider client ID, used for user authentication") | ||
@@ -164,3 +164,3 @@ cmd.Flags().String(allowedUrlDomainFlag, "", `Domain name, used for the verification of the URLs that are given in the custom identity provider endpoint and "STACKIT curl" command`) | ||
| cobra.CheckErr(err) | ||
| err = viper.BindPFlag(config.IdentityProviderCustomEndpointKey, cmd.Flags().Lookup(identityProviderCustomEndpointFlag)) | ||
| err = viper.BindPFlag(config.IdentityProviderCustomWellKnownConfigurationKey, cmd.Flags().Lookup(identityProviderCustomWellKnownConfigurationFlag)) | ||
| cobra.CheckErr(err) | ||
@@ -196,3 +196,3 @@ err = viper.BindPFlag(config.IdentityProviderCustomClientIdKey, cmd.Flags().Lookup(identityProviderCustomClientIdFlag)) | ||
| cobra.CheckErr(err) | ||
| err = viper.BindPFlag(config.ResourceManagerEndpointKey, cmd.Flags().Lookup(skeCustomEndpointFlag)) | ||
| err = viper.BindPFlag(config.ResourceManagerEndpointKey, cmd.Flags().Lookup(resourceManagerCustomEndpointFlag)) | ||
| cobra.CheckErr(err) | ||
@@ -199,0 +199,0 @@ err = viper.BindPFlag(config.SecretsManagerCustomEndpointKey, cmd.Flags().Lookup(secretsManagerCustomEndpointFlag)) |
@@ -19,6 +19,6 @@ package unset | ||
| sessionTimeLimitFlag: true, | ||
| identityProviderCustomEndpointFlag: true, | ||
| identityProviderCustomClientIdFlag: true, | ||
| allowedUrlDomainFlag: true, | ||
| sessionTimeLimitFlag: true, | ||
| identityProviderCustomWellKnownConfigurationFlag: true, | ||
| identityProviderCustomClientIdFlag: true, | ||
| allowedUrlDomainFlag: true, | ||
@@ -161,3 +161,3 @@ authorizationCustomEndpointFlag: true, | ||
| flagValues: fixtureFlagValues(func(flagValues map[string]bool) { | ||
| flagValues[identityProviderCustomEndpointFlag] = false | ||
| flagValues[identityProviderCustomWellKnownConfigurationFlag] = false | ||
| }), | ||
@@ -164,0 +164,0 @@ isValid: true, |
@@ -23,6 +23,6 @@ package unset | ||
| sessionTimeLimitFlag = "session-time-limit" | ||
| identityProviderCustomEndpointFlag = "identity-provider-custom-endpoint" | ||
| identityProviderCustomClientIdFlag = "identity-provider-custom-client-id" | ||
| allowedUrlDomainFlag = "allowed-url-domain" | ||
| sessionTimeLimitFlag = "session-time-limit" | ||
| identityProviderCustomWellKnownConfigurationFlag = "identity-provider-custom-well-known-configuration" | ||
| identityProviderCustomClientIdFlag = "identity-provider-custom-client-id" | ||
| allowedUrlDomainFlag = "allowed-url-domain" | ||
@@ -125,3 +125,3 @@ authorizationCustomEndpointFlag = "authorization-custom-endpoint" | ||
| if model.IdentityProviderCustomEndpoint { | ||
| viper.Set(config.IdentityProviderCustomEndpointKey, "") | ||
| viper.Set(config.IdentityProviderCustomWellKnownConfigurationKey, "") | ||
| } | ||
@@ -220,3 +220,3 @@ if model.IdentityProviderCustomClientID { | ||
| cmd.Flags().Bool(sessionTimeLimitFlag, false, fmt.Sprintf("Maximum time before authentication is required again. If unset, defaults to %s", config.SessionTimeLimitDefault)) | ||
| cmd.Flags().Bool(identityProviderCustomEndpointFlag, false, "Identity Provider base URL. If unset, uses the default base URL") | ||
| cmd.Flags().Bool(identityProviderCustomWellKnownConfigurationFlag, false, "Identity Provider well-known OpenID configuration URL. If unset, uses the default identity provider") | ||
| cmd.Flags().Bool(identityProviderCustomClientIdFlag, false, "Identity Provider client ID, used for user authentication") | ||
@@ -257,3 +257,3 @@ cmd.Flags().Bool(allowedUrlDomainFlag, false, fmt.Sprintf("Domain name, used for the verification of the URLs that are given in the IDP endpoint and curl commands. If unset, defaults to %s", config.AllowedUrlDomainDefault)) | ||
| SessionTimeLimit: flags.FlagToBoolValue(p, cmd, sessionTimeLimitFlag), | ||
| IdentityProviderCustomEndpoint: flags.FlagToBoolValue(p, cmd, identityProviderCustomEndpointFlag), | ||
| IdentityProviderCustomEndpoint: flags.FlagToBoolValue(p, cmd, identityProviderCustomWellKnownConfigurationFlag), | ||
| IdentityProviderCustomClientID: flags.FlagToBoolValue(p, cmd, identityProviderCustomClientIdFlag), | ||
@@ -260,0 +260,0 @@ AllowedUrlDomain: flags.FlagToBoolValue(p, cmd, allowedUrlDomainFlag), |
@@ -40,2 +40,3 @@ package auth | ||
| TOKEN_CUSTOM_ENDPOINT authFieldKey = "token_custom_endpoint" | ||
| IDP_TOKEN_ENDPOINT authFieldKey = "idp_token_endpoint" //nolint:gosec // linter false positive | ||
| ) | ||
@@ -61,2 +62,3 @@ | ||
| TOKEN_CUSTOM_ENDPOINT, | ||
| IDP_TOKEN_ENDPOINT, | ||
| authFlowType, | ||
@@ -63,0 +65,0 @@ } |
@@ -26,4 +26,4 @@ package auth | ||
| const ( | ||
| defaultIDPEndpoint = "https://accounts.stackit.cloud/oauth/v2" | ||
| defaultCLIClientID = "stackit-cli-0000-0000-000000000001" | ||
| defaultWellKnownConfig = "https://accounts.stackit.cloud/.well-known/openid-configuration" | ||
| defaultCLIClientID = "stackit-cli-0000-0000-000000000001" | ||
@@ -48,10 +48,14 @@ loginSuccessPath = "/login-successful" | ||
| type apiClient interface { | ||
| Do(req *http.Request) (*http.Response, error) | ||
| } | ||
| // AuthorizeUser implements the PKCE OAuth2 flow. | ||
| func AuthorizeUser(p *print.Printer, isReauthentication bool) error { | ||
| idpEndpoint, err := getIDPEndpoint() | ||
| idpWellKnownConfigURL, err := getIDPWellKnownConfigURL() | ||
| if err != nil { | ||
| return err | ||
| return fmt.Errorf("get IDP well-known configuration: %w", err) | ||
| } | ||
| if idpEndpoint != defaultIDPEndpoint { | ||
| p.Warn("You are using a custom identity provider (%s) for authentication.\n", idpEndpoint) | ||
| if idpWellKnownConfigURL != defaultWellKnownConfig { | ||
| p.Warn("You are using a custom identity provider well-known configuration (%s) for authentication.\n", idpWellKnownConfigURL) | ||
| err := p.PromptForEnter("Press Enter to proceed with the login...") | ||
@@ -63,2 +67,9 @@ if err != nil { | ||
| p.Debug(print.DebugLevel, "get IDP well-known configuration from %s", idpWellKnownConfigURL) | ||
| httpClient := &http.Client{} | ||
| idpWellKnownConfig, err := parseWellKnownConfiguration(httpClient, idpWellKnownConfigURL) | ||
| if err != nil { | ||
| return fmt.Errorf("parse IDP well-known configuration: %w", err) | ||
| } | ||
| idpClientID, err := getIDPClientID() | ||
@@ -106,3 +117,3 @@ if err != nil { | ||
| Endpoint: oauth2.Endpoint{ | ||
| AuthURL: fmt.Sprintf("%s/authorize", idpEndpoint), | ||
| AuthURL: idpWellKnownConfig.AuthorizationEndpoint, | ||
| }, | ||
@@ -154,3 +165,3 @@ Scopes: []string{"openid offline_access email"}, | ||
| // Trade the authorization code and the code verifier for access and refresh tokens | ||
| accessToken, refreshToken, err := getUserAccessAndRefreshTokens(idpEndpoint, idpClientID, codeVerifier, code, redirectURL) | ||
| accessToken, refreshToken, err := getUserAccessAndRefreshTokens(idpWellKnownConfig, idpClientID, codeVerifier, code, redirectURL) | ||
| if err != nil { | ||
@@ -230,3 +241,3 @@ errServer = fmt.Errorf("retrieve tokens: %w", err) | ||
| p.Debug(print.DebugLevel, "opening browser for authentication") | ||
| p.Debug(print.DebugLevel, "using authentication server on %s", idpEndpoint) | ||
| p.Debug(print.DebugLevel, "using authentication server on %s", idpWellKnownConfig.Issuer) | ||
| p.Debug(print.DebugLevel, "using client ID %s for authentication ", idpClientID) | ||
@@ -257,5 +268,4 @@ | ||
| // getUserAccessAndRefreshTokens trades the authorization code retrieved from the first OAuth2 leg for an access token and a refresh token | ||
| func getUserAccessAndRefreshTokens(authDomain, clientID, codeVerifier, authorizationCode, callbackURL string) (accessToken, refreshToken string, err error) { | ||
| // Set the authUrl and form-encoded data for the POST to the access token endpoint | ||
| authUrl := fmt.Sprintf("%s/token", authDomain) | ||
| func getUserAccessAndRefreshTokens(idpWellKnownConfig *wellKnownConfig, clientID, codeVerifier, authorizationCode, callbackURL string) (accessToken, refreshToken string, err error) { | ||
| // Set form-encoded data for the POST to the access token endpoint | ||
| data := fmt.Sprintf( | ||
@@ -270,3 +280,3 @@ "grant_type=authorization_code&client_id=%s"+ | ||
| // Create the request and execute it | ||
| req, _ := http.NewRequest("POST", authUrl, payload) | ||
| req, _ := http.NewRequest("POST", idpWellKnownConfig.TokenEndpoint, payload) | ||
| req.Header.Add("content-type", "application/x-www-form-urlencoded") | ||
@@ -342,1 +352,46 @@ httpClient := &http.Client{} | ||
| } | ||
| // parseWellKnownConfiguration gets the well-known OpenID configuration from the provided URL and returns it as a JSON | ||
| // the method also stores the IDP token endpoint in the authentication storage | ||
| func parseWellKnownConfiguration(httpClient apiClient, wellKnownConfigURL string) (wellKnownConfig *wellKnownConfig, err error) { | ||
| req, _ := http.NewRequest("GET", wellKnownConfigURL, http.NoBody) | ||
| res, err := httpClient.Do(req) | ||
| if err != nil { | ||
| return nil, fmt.Errorf("make the request: %w", err) | ||
| } | ||
| // Process the response | ||
| defer func() { | ||
| closeErr := res.Body.Close() | ||
| if closeErr != nil { | ||
| err = fmt.Errorf("close response body: %w", closeErr) | ||
| } | ||
| }() | ||
| body, err := io.ReadAll(res.Body) | ||
| if err != nil { | ||
| return nil, fmt.Errorf("read response body: %w", err) | ||
| } | ||
| err = json.Unmarshal(body, &wellKnownConfig) | ||
| if err != nil { | ||
| return nil, fmt.Errorf("unmarshal response: %w", err) | ||
| } | ||
| if wellKnownConfig == nil { | ||
| return nil, fmt.Errorf("nil well-known configuration response") | ||
| } | ||
| if wellKnownConfig.Issuer == "" { | ||
| return nil, fmt.Errorf("found no issuer") | ||
| } | ||
| if wellKnownConfig.AuthorizationEndpoint == "" { | ||
| return nil, fmt.Errorf("found no authorization endpoint") | ||
| } | ||
| if wellKnownConfig.TokenEndpoint == "" { | ||
| return nil, fmt.Errorf("found no token endpoint") | ||
| } | ||
| err = SetAuthField(IDP_TOKEN_ENDPOINT, wellKnownConfig.TokenEndpoint) | ||
| if err != nil { | ||
| return nil, fmt.Errorf("set token endpoint in the authentication storage: %w", err) | ||
| } | ||
| return wellKnownConfig, err | ||
| } |
@@ -17,2 +17,6 @@ package auth | ||
| const ( | ||
| testTokenEndpoint = "https://accounts.stackit.cloud/oauth/v2/token" //nolint:gosec // linter false positive | ||
| ) | ||
| type clientTransport struct { | ||
@@ -32,7 +36,3 @@ t *testing.T // May write test errors | ||
| } | ||
| idpEndpoint, err := getIDPEndpoint() | ||
| if err != nil { | ||
| rt.t.Fatalf("get IDP endpoint for test: %v", err) | ||
| } | ||
| if fmt.Sprintf("https://%s", reqURL) == fmt.Sprintf("%s/token", idpEndpoint) { | ||
| if fmt.Sprintf("https://%s", reqURL) == testTokenEndpoint { | ||
| return rt.roundTripRefreshTokens() | ||
@@ -359,4 +359,5 @@ } | ||
| err = SetAuthFieldMap(map[authFieldKey]string{ | ||
| ACCESS_TOKEN: accessToken, | ||
| REFRESH_TOKEN: refreshToken, | ||
| ACCESS_TOKEN: accessToken, | ||
| REFRESH_TOKEN: refreshToken, | ||
| IDP_TOKEN_ENDPOINT: testTokenEndpoint, | ||
| }) | ||
@@ -363,0 +364,0 @@ if err != nil { |
@@ -22,2 +22,3 @@ package auth | ||
| refreshToken string | ||
| tokenEndpoint string | ||
| } | ||
@@ -80,4 +81,5 @@ | ||
| authFields := map[authFieldKey]string{ | ||
| ACCESS_TOKEN: "", | ||
| REFRESH_TOKEN: "", | ||
| ACCESS_TOKEN: "", | ||
| REFRESH_TOKEN: "", | ||
| IDP_TOKEN_ENDPOINT: "", | ||
| } | ||
@@ -92,2 +94,3 @@ err = GetAuthFieldMap(authFields) | ||
| utf.refreshToken = authFields[REFRESH_TOKEN] | ||
| utf.tokenEndpoint = authFields[IDP_TOKEN_ENDPOINT] | ||
| return nil | ||
@@ -162,7 +165,2 @@ } | ||
| func buildRequestToRefreshTokens(utf *userTokenFlow) (*http.Request, error) { | ||
| idpEndpoint, err := getIDPEndpoint() | ||
| if err != nil { | ||
| return nil, err | ||
| } | ||
| idpClientID, err := getIDPClientID() | ||
@@ -175,3 +173,3 @@ if err != nil { | ||
| http.MethodPost, | ||
| fmt.Sprintf("%s/token", idpEndpoint), | ||
| utf.tokenEndpoint, | ||
| http.NoBody, | ||
@@ -178,0 +176,0 @@ ) |
@@ -10,3 +10,3 @@ package auth | ||
| func TestGetIDPEndpoint(t *testing.T) { | ||
| func TestGetWellKnownConfig(t *testing.T) { | ||
| tests := []struct { | ||
@@ -57,3 +57,3 @@ name string | ||
| isValid: true, | ||
| expected: defaultIDPEndpoint, | ||
| expected: defaultWellKnownConfig, | ||
| }, | ||
@@ -64,6 +64,6 @@ } | ||
| viper.Reset() | ||
| viper.Set(config.IdentityProviderCustomEndpointKey, tt.idpCustomEndpoint) | ||
| viper.Set(config.IdentityProviderCustomWellKnownConfigurationKey, tt.idpCustomEndpoint) | ||
| viper.Set(config.AllowedUrlDomainKey, tt.allowedUrlDomain) | ||
| got, err := getIDPEndpoint() | ||
| got, err := getIDPWellKnownConfigURL() | ||
@@ -70,0 +70,0 @@ if tt.isValid && err != nil { |
@@ -11,15 +11,21 @@ package auth | ||
| func getIDPEndpoint() (string, error) { | ||
| idpEndpoint := defaultIDPEndpoint | ||
| type wellKnownConfig struct { | ||
| Issuer string `json:"issuer"` | ||
| AuthorizationEndpoint string `json:"authorization_endpoint"` | ||
| TokenEndpoint string `json:"token_endpoint"` | ||
| } | ||
| customIDPEndpoint := viper.GetString(config.IdentityProviderCustomEndpointKey) | ||
| if customIDPEndpoint != "" { | ||
| idpEndpoint = customIDPEndpoint | ||
| err := utils.ValidateURLDomain(idpEndpoint) | ||
| func getIDPWellKnownConfigURL() (wellKnownConfigURL string, err error) { | ||
| wellKnownConfigURL = defaultWellKnownConfig | ||
| customWellKnownConfig := viper.GetString(config.IdentityProviderCustomWellKnownConfigurationKey) | ||
| if customWellKnownConfig != "" { | ||
| wellKnownConfigURL = customWellKnownConfig | ||
| err := utils.ValidateURLDomain(wellKnownConfigURL) | ||
| if err != nil { | ||
| return "", fmt.Errorf("validate custom identity provider endpoint: %w", err) | ||
| return "", fmt.Errorf("validate custom identity provider well-known configuration: %w", err) | ||
| } | ||
| } | ||
| return idpEndpoint, nil | ||
| return wellKnownConfigURL, nil | ||
| } | ||
@@ -26,0 +32,0 @@ |
@@ -20,5 +20,5 @@ package config | ||
| IdentityProviderCustomEndpointKey = "identity_provider_custom_endpoint" | ||
| IdentityProviderCustomClientIdKey = "identity_provider_custom_client_id" | ||
| AllowedUrlDomainKey = "allowed_url_domain" | ||
| IdentityProviderCustomWellKnownConfigurationKey = "identity_provider_custom_well_known_configuration" | ||
| IdentityProviderCustomClientIdKey = "identity_provider_custom_client_id" | ||
| AllowedUrlDomainKey = "allowed_url_domain" | ||
@@ -75,3 +75,3 @@ AuthorizationCustomEndpointKey = "authorization_custom_endpoint" | ||
| IdentityProviderCustomEndpointKey, | ||
| IdentityProviderCustomWellKnownConfigurationKey, | ||
| IdentityProviderCustomClientIdKey, | ||
@@ -160,3 +160,3 @@ AllowedUrlDomainKey, | ||
| viper.SetDefault(SessionTimeLimitKey, SessionTimeLimitDefault) | ||
| viper.SetDefault(IdentityProviderCustomEndpointKey, "") | ||
| viper.SetDefault(IdentityProviderCustomWellKnownConfigurationKey, "") | ||
| viper.SetDefault(IdentityProviderCustomClientIdKey, "") | ||
@@ -163,0 +163,0 @@ viper.SetDefault(AllowedUrlDomainKey, AllowedUrlDomainDefault) |
+2
-9
@@ -20,3 +20,3 @@ <div align="center"> | ||
| > [!WARNING] | ||
| > On August 26 2024, The STACKIT Argus service was renamed to STACKIT Observability. | ||
| > On August 26 2024, The STACKIT Argus service was renamed to STACKIT Observability. | ||
| > | ||
@@ -27,9 +27,2 @@ > This means that there is a new command group `observability`, which offers the same functionality as the deprecated `argus` command. | ||
| > [!WARNING] | ||
| > On July 9 2024, the new [STACKIT Identity Provider (IDP)](https://docs.stackit.cloud/stackit/en/release-notes-23101442.html#ReleaseNotes-2024-06-21-identity-provider) was released. We are happy to announce that on [v0.9.0](https://github.com/stackitcloud/stackit-cli/releases/tag/v0.9.0), the new IDP was integrated in the STACKIT CLI, where it is used for user authentication. | ||
| > | ||
| > This also means that the **user authentication on STACKIT CLI versions released before July 9 2024 is no longer guaranteed to work for all services**. | ||
| > | ||
| > Please make sure to **update your STACKIT CLI to the latest version after July 9 2024** to ensure that you can continue to use all STACKIT services. | ||
| ## Installation | ||
@@ -78,3 +71,3 @@ | ||
| | Service | CLI Commands | Status | | ||
| |------------------------------------|---------------------------|---------------------------| | ||
| | ---------------------------------- | ------------------------- | ------------------------- | | ||
| | Observability | `observability` | :white_check_mark: | | ||
@@ -81,0 +74,0 @@ | Infrastructure as a Service (IaaS) | `beta network-area` | :white_check_mark: (beta) | |