From 33e91bd1d08829345939eaa4a4c041b7016f9486 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bernardo=20De=20Marco=20Gon=C3=A7alves?= Date: Fri, 22 May 2026 16:13:58 -0300 Subject: [PATCH] UI for API Key Pair Management --- .../admin/user/RegisterUserKeysCmd.java | 5 +- .../apache/cloudstack/acl/ApiKeyPairVO.java | 2 +- .../META-INF/db/schema-42210to42300.sql | 8 +- ui/public/locales/en.json | 25 +- ui/public/locales/pt_BR.json | 19 + ui/src/components/view/ApiKeyPairsTab.vue | 455 +++++++++++++++ ui/src/components/view/DetailsTab.vue | 4 +- ui/src/components/view/InfoCard.vue | 104 ++-- ui/src/components/view/ListView.vue | 2 +- ui/src/config/router.js | 2 + ui/src/config/section/keypair.js | 69 +++ ui/src/config/section/user.js | 6 + ui/src/views/AutogenView.vue | 6 +- .../views/iam/ApiKeyPairPermissionTable.vue | 522 ++++++++++++++++++ ui/src/views/iam/GenerateApiKeyPair.vue | 229 ++++++++ 15 files changed, 1397 insertions(+), 61 deletions(-) create mode 100644 ui/src/components/view/ApiKeyPairsTab.vue create mode 100644 ui/src/config/section/keypair.js create mode 100644 ui/src/views/iam/ApiKeyPairPermissionTable.vue create mode 100644 ui/src/views/iam/GenerateApiKeyPair.vue diff --git a/api/src/main/java/org/apache/cloudstack/api/command/admin/user/RegisterUserKeysCmd.java b/api/src/main/java/org/apache/cloudstack/api/command/admin/user/RegisterUserKeysCmd.java index 11d7c1d2ffab..cd7200035bbf 100644 --- a/api/src/main/java/org/apache/cloudstack/api/command/admin/user/RegisterUserKeysCmd.java +++ b/api/src/main/java/org/apache/cloudstack/api/command/admin/user/RegisterUserKeysCmd.java @@ -50,7 +50,7 @@ public class RegisterUserKeysCmd extends BaseAsyncCmd { @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, description = "API key pair name.") private String name; - @Parameter(name = ApiConstants.DESCRIPTION, type = CommandType.STRING, description = "API key pair description.") + @Parameter(name = ApiConstants.DESCRIPTION, type = CommandType.STRING, description = "API key pair description.", length = 1024) private String description; @Parameter(name = ApiConstants.START_DATE, type = CommandType.DATE, description = "Start date of the API key pair. " + @@ -138,6 +138,9 @@ public List> getRules() { String description = detail.get(ApiConstants.DESCRIPTION); if (StringUtils.isNotEmpty(description)) { + if (permission.length() > 255) { + throw new ServerApiException(ApiErrorCode.PARAM_ERROR, "Description cannot be longer than 255 characters."); + } ruleDetails.put(ApiConstants.DESCRIPTION, description); } diff --git a/engine/schema/src/main/java/org/apache/cloudstack/acl/ApiKeyPairVO.java b/engine/schema/src/main/java/org/apache/cloudstack/acl/ApiKeyPairVO.java index eb38b08f6151..7a6bd7a3b140 100644 --- a/engine/schema/src/main/java/org/apache/cloudstack/acl/ApiKeyPairVO.java +++ b/engine/schema/src/main/java/org/apache/cloudstack/acl/ApiKeyPairVO.java @@ -70,7 +70,7 @@ public class ApiKeyPairVO implements ApiKeyPair { @Temporal(value = TemporalType.TIMESTAMP) private Date created = Date.from(Instant.now()); - @Column(name = "description") + @Column(name = "description", length = 1024) private String description = ""; @Column(name = "api_key", nullable = false) diff --git a/engine/schema/src/main/resources/META-INF/db/schema-42210to42300.sql b/engine/schema/src/main/resources/META-INF/db/schema-42210to42300.sql index c99f798d3d56..b328ac3b4b84 100644 --- a/engine/schema/src/main/resources/META-INF/db/schema-42210to42300.sql +++ b/engine/schema/src/main/resources/META-INF/db/schema-42210to42300.sql @@ -73,7 +73,7 @@ CREATE TABLE IF NOT EXISTS `cloud`.`api_keypair` ( `user_id` bigint(20) unsigned NOT NULL, `start_date` datetime, `end_date` datetime, - `description` varchar(100), + `description` varchar(1024), `api_key` varchar(255) NOT NULL, `secret_key` varchar(255) NOT NULL, `created` datetime NOT NULL, @@ -107,11 +107,15 @@ WHERE user.api_key IS NOT NULL AND user.secret_key IS NOT NULL; -- Drop API keys from user table ALTER TABLE `cloud`.`user` DROP COLUMN api_key, DROP COLUMN secret_key; --- Grant access to the "deleteUserKeys" API to the "User", "Domain Admin" and "Resource Admin" roles, similarly to the "registerUserKeys" API +-- Grant access to the "deleteUserKeys" and "listUserKeyRules" APIs to the "User", "Domain Admin" and "Resource Admin" roles, similarly to the "registerUserKeys" API CALL `cloud`.`IDEMPOTENT_UPDATE_API_PERMISSION`('User', 'deleteUserKeys', 'ALLOW'); CALL `cloud`.`IDEMPOTENT_UPDATE_API_PERMISSION`('Domain Admin', 'deleteUserKeys', 'ALLOW'); CALL `cloud`.`IDEMPOTENT_UPDATE_API_PERMISSION`('Resource Admin', 'deleteUserKeys', 'ALLOW'); +CALL `cloud`.`IDEMPOTENT_UPDATE_API_PERMISSION`('User', 'listUserKeyRules', 'ALLOW'); +CALL `cloud`.`IDEMPOTENT_UPDATE_API_PERMISSION`('Domain Admin', 'listUserKeyRules', 'ALLOW'); +CALL `cloud`.`IDEMPOTENT_UPDATE_API_PERMISSION`('Resource Admin', 'listUserKeyRules', 'ALLOW'); + -- Add conserve mode for VPC offerings CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.vpc_offerings','conserve_mode', 'tinyint(1) unsigned NULL DEFAULT 0 COMMENT ''True if the VPC offering is IP conserve mode enabled, allowing public IP services to be used across multiple VPC tiers'' '); diff --git a/ui/public/locales/en.json b/ui/public/locales/en.json index 1187b3e62b40..d373db8fa3af 100644 --- a/ui/public/locales/en.json +++ b/ui/public/locales/en.json @@ -62,6 +62,7 @@ "label.action.attach.disk": "Attach Disk", "label.action.attach.iso": "Attach ISO", "label.action.attach.to.instance": "Attach to Instance", +"label.action.bulk.delete.api.keys": "Bulk delete API key pairs", "label.action.bulk.delete.egress.firewall.rules": "Bulk delete egress firewall rules", "label.action.bulk.delete.firewall.rules": "Bulk delete firewall rules", "label.action.bulk.delete.ip.v6.firewall.rules": "Bulk remove IPv6 firewall rules", @@ -82,6 +83,7 @@ "label.action.copy.iso": "Copy ISO", "label.action.copy.snapshot": "Copy Snapshot", "label.action.copy.template": "Copy Template", +"label.action.create.api.key": "Create API key pair for user", "label.action.create.backup.schedule": "Create Backup Schedule", "label.action.create.recurring.snapshot": "Create Recurring Snapshot", "label.action.create.snapshot.from.vmsnapshot": "Create Snapshot from Instance Snapshot", @@ -116,6 +118,7 @@ "label.action.delete.snapshot": "Delete Snapshot", "label.action.delete.template": "Delete Template", "label.action.delete.tungsten.router.table": "Remove Tungsten Fabric route table from Network", +"label.action.delete.keypair": "Delete API key pair", "label.action.delete.user": "Delete User", "label.action.delete.vgpu.profile": "Delete vGPU profile", "label.action.delete.volume": "Delete Volume", @@ -409,6 +412,11 @@ "label.api.docs.count": "APIs available for your account", "label.api.version": "API version", "label.apikey": "API key", +"label.apikeypairs": "API Key Pairs", +"label.apikeypair.description": "Description of the API key pair", +"label.apikeypair.name": "Name of the API key pair", +"label.apikeypair.startdate": "API key pair starting validation date", +"label.apikeypair.enddate": "API key pair expiration date", "label.app.cookie": "AppCookie", "label.app.name": "CloudStack", "label.application.policy.set": "Application Policy Set", @@ -624,6 +632,7 @@ "label.configure.ldap": "Configure LDAP", "label.configure.ovs": "Configure Ovs", "label.configure.sticky.policy": "Configure sticky policy", +"label.confirm.delete.api.keys": "Please confirm you wish to delete the selected API key pairs", "label.confirm.delete.egress.firewall.rules": "Please confirm you wish to delete the selected egress firewall rules.", "label.confirm.delete.firewall.rules": "Please confirm you wish to delete the selected firewall rules.", "label.confirm.delete.ip.v6.firewall.rules": "Please confirm you wish to delete the selected IPv6 firewall rules", @@ -786,6 +795,7 @@ "label.delete.alerts": "Delete alerts", "label.delete.asnrange": "Delete AS Range", "label.delete.autoscale.vmgroup": "Delete AutoScaling Group", +"label.delete.all.rules": "Delete all API key pair rules", "label.delete.backup": "Delete backup", "label.delete.backup.schedule": "Delete backup schedule", "label.delete.bgp.peer": "Delete BGP peer", @@ -843,6 +853,7 @@ "label.deleting": "Deleting", "label.deleting.failed": "Deleting failed", "label.deleting.iso": "Deleting ISO", +"label.deleting.keypair": "Deleting API key pair", "label.deleting.snapshot": "Deleting Snapshot", "label.deleting.template": "Deleting Template", "label.deleteprotection": "Delete protection", @@ -1641,6 +1652,7 @@ "message.memory.usage.info.hypervisor.additionals": "The data shown may not reflect the actual memory usage if the Instance does not have the additional hypervisor tools installed", "message.memory.usage.info.negative.value": "If the Instance's memory usage cannot be obtained from the hypervisor, the lines for free memory in the raw data graph and memory usage in the percentage graph will be disabled", "message.migrate.volume.tooltip": "Volume can be migrated to any suitable storage pool. Admin has to choose the appropriate disk offering to replace, that supports the new storage pool", +"message.register.keypair.failed": "Failed to register API key pair", "label.migrate.with.storage": "Migrate with storage", "label.migrating": "Migrating", "label.migrating.data": "Migrating data", @@ -2080,12 +2092,14 @@ "label.redundantvpcrouter": "Redundant VPC", "label.refresh": "Refresh", "label.region": "Region", +"label.register.api.key": "Register API key pair", "label.register.extension": "Register Extension", "label.register.oauth": "Register OAuth", "label.register.template": "Register Template", "label.register.user.data": "Register User Data", "label.register.cni.config": "Register CNI Configuration", "label.register.user.data.details": "Enter the User Data in plain text or in Base64 encoding. Up to 32KB of Base64 encoded User Data can be sent by default. The setting vm.userdata.max.length can be used to increase the limit to upto 1MB.", +"label.registering.keypair": "Registering API key pair", "label.reinstall.vm": "Reinstall Instance", "label.reject": "Reject", "label.related": "Related", @@ -2172,6 +2186,7 @@ "label.restore.volume.attach": "Restore volume and attach", "label.use.backup.ip.address": "Use IP Addresses from Backup", "label.use.backup.ip.address.tooltip": "Use the same IP/MAC addresses as stored in the backup metadata. The command will error out if the IP/MAC addresses are not available", +"label.userapikey": "API Key", "label.review": "Review", "label.role": "Role", "label.roleid": "Role", @@ -2399,6 +2414,7 @@ "label.unregister.extension": "Unregister Extension", "label.usediops": "IOPS used", "label.userdata": "User Data", +"label.user.api.key.rules": "API key pair rules", "label.user.data.id": "User Data ID", "label.user.data.name": "User Data name", "label.user.data.details": "User Data details", @@ -2932,7 +2948,7 @@ "label.versioning": "Versioning", "label.objectlocking": "Object Lock", "label.bucket.policy": "Bucket Policy", -"label.usersecretkey": "Secret Key", +"label.usersecretkey": "API Secret Key", "label.create.bucket": "Create Bucket", "label.cniconfiguration": "CNI Configuration", "label.cniconfigname": "Associated CNI Configuration", @@ -3345,6 +3361,8 @@ "message.delete.failed": "Delete fail", "message.delete.gateway": "Please confirm you want to delete the gateway.", "message.delete.ip.v6.prefix.processing": "Deleting IPv6 prefix...", +"message.delete.keypair": "Please confirm that you would like to delete this API key pair.", +"message.delete.keypair.failed": "Failed to delete API key pair", "message.delete.port.forward.processing": "Deleting port forwarding rule...", "message.delete.project": "Are you sure you want to delete this project?", "message.delete.rule.processing": "Deleting rule...", @@ -3751,6 +3769,8 @@ "message.new.version.available": "A new version of CloudStack is available. Click here to check the details", "message.no.data.to.show.for.period": "No data to show for the selected period.", "message.no.description": "No description entered.", +"message.note.about.keypair.permissions.title": "Note about API key pair rule permissions", +"message.note.about.keypair.permissions.body": "During the creation of API key pairs, it is possible to define a corresponding set of rule permissions. If a rule set is defined, the API key pair will only have access to APIs for which access has been explicitly granted (i.e., APIs whose corresponding rules are marked as allowed). On the other hand, if no rule set is specified, the API key pair permissions will follow and adapt to the permission set of the user's account role.", "message.offering.internet.protocol.warning": "WARNING: IPv6 supported Networks use static routing and will require upstream routes to be configured manually.", "message.offering.ipv6.warning": "Please refer documentation for creating IPv6 enabled Network/VPC offering IPv6 support in CloudStack - Isolated Networks and VPC Network Tiers", "message.oobm.configured": "Successfully configured out-of-band management for host", @@ -3943,6 +3963,7 @@ "message.success.create.keypair": "Successfully created SSH key pair", "message.success.create.kubernetes.cluster": "Successfully created Kubernetes Cluster", "message.success.create.l2.network": "Successfully created L2 Network", +"message.success.create.password": "Successfully created API key pair for user", "message.success.create.snapshot.from.vmsnapshot": "Successfully created Snapshot from Instance Snapshot", "message.success.create.template": "Successfully created Template", "message.success.create.user": "Successfully created User", @@ -3959,6 +3980,7 @@ "message.success.delete.gpu.devices": "Successfully deleted GPU device(s)", "message.success.delete.icon": "Successfully deleted icon of", "message.success.delete.interface.static.route": "Successfully removed interface Static Route", +"message.success.delete.keypair": "Success deleting API key pair", "message.success.delete.ipv4.subnet": "Successfully removed IPv4 subnet", "message.success.delete.network.static.route": "Successfully removed Network Static Route", "message.success.delete.node": "Successfully deleted node", @@ -3990,6 +4012,7 @@ "message.success.register.keypair": "Successfully registered SSH key pair", "message.success.register.template": "Successfully registered Template", "message.success.register.user.data": "Successfully registered User Data", +"message.success.register.user.keypair": "Success registering API key pair", "message.success.release.ip": "Successfully released IP", "message.success.release.dedicated.bgp.peer": "Successfully released dedicated BGP peer", "message.success.release.dedicated.ipv4.subnet": "Successfully released dedicated IPv4 subnet", diff --git a/ui/public/locales/pt_BR.json b/ui/public/locales/pt_BR.json index 4b446eccff32..c607155cd350 100644 --- a/ui/public/locales/pt_BR.json +++ b/ui/public/locales/pt_BR.json @@ -51,6 +51,7 @@ "label.action": "A\u00e7\u00e3o", "label.action.attach.disk": "Anexar disco", "label.action.attach.iso": "Anexar ISO", +"label.action.bulk.delete.api.keys": "Apagar em massa as chaves de acesso \u00e0 API.", "label.action.bulk.delete.egress.firewall.rules": "Apagar em massa as regras de sa\u00edda do firewall.", "label.action.bulk.delete.firewall.rules": "Apagar em massa as regras do firewall.", "label.action.bulk.delete.ip.v6.firewall.rules": "Apagar em massa as regras de firewall IPv6.", @@ -70,6 +71,7 @@ "label.action.copy.iso": "Copiar ISO", "label.action.copy.snapshot": "Copiar Snapshot", "label.action.copy.template": "Copiar template", +"label.action.create.api.key": "Criar um par de chaves de API para usu\u00e1rio", "label.action.create.snapshot.from.vmsnapshot": "Criar snapshot a partir de uma snapshot de VM", "label.action.create.template.from.volume": "Criar template a partir do disco", "label.action.create.volume": "Criar disco", @@ -86,6 +88,7 @@ "label.action.delete.interface.static.route": "Remover rota est\u00e1tica da interface Tungsten Fabric", "label.action.delete.ip.range": "Remover intervalo de IPs", "label.action.delete.iso": "Remover ISO", +"label.action.delete.keypair": "Remover par de chaves", "label.action.delete.load.balancer": "Remover regra do balanceador de carga", "label.action.delete.network": "Remover rede", "label.action.delete.network.permission": "Excluir permiss\u00e3o de Rede", @@ -379,6 +382,11 @@ "label.api.docs.count": "APIs dispon\u00edveis para sua conta", "label.api.version": "Vers\u00e3o da API", "label.apikey": "Chave da API", +"label.apikeypairs": "Par de chaves de API", +"label.apikeypair.description": "Descri\u00e7\u00e3o do par de chaves de API", +"label.apikeypair.name": "Nome do par de chaves de API", +"label.apikeypair.startdate": "Data de in\u00edcio de valida\u00e7\u00e3o par de chaves de API", +"label.apikeypair.enddate": "Data de expira\u00e7\u00e3o do par de chaves de API", "label.app.cookie": "AppCookie", "label.app.name": "CloudStack", "label.application.policy.set": "Conjunto de Pol\u00edticas de Aplica\u00e7\u00e3o", @@ -564,6 +572,7 @@ "label.configure.ldap": "Configurar LDAP", "label.configure.ovs": "Configure Ovs", "label.configure.sticky.policy": "Configurar sticky policy", +"label.confirm.delete.api.keys": "Por favor, confirme se deseja apagar as chaves de acesso \u00e0 API selecionadas", "label.confirm.delete.egress.firewall.rules": "Por favor, confirme se deseja apagar as regras de firewall de sa\u00edda selecionadas", "label.confirm.delete.firewall.rules": "Por favor, confirme se deseja apagar as regras de firewall selecionadas", "label.confirm.delete.ip.v6.firewall.rules": "Por favor, confirme que deseja excluir as regras de firewall IPv6 selecionadas", @@ -709,6 +718,7 @@ "label.delete.acl": "Apagar lista ACL", "label.delete.affinity.group": "Apagar grupo de afinidade", "label.delete.alerts": "Remover alertas", +"label.delete.all.rules": "Apagar todas as regras", "label.delete.asnrange": "Excluir Faixa AS", "label.delete.autoscale.vmgroup": "Excluir grupo de auto escalonamento horizontal", "label.delete.backup": "Apagar backup", @@ -763,6 +773,7 @@ "label.deleteconfirm": "Por favor, confirme que voc\u00ea deseja apagar isto", "label.deleting": "Removendo", "label.deleting.failed": "Falha ao remover", +"label.deleting.keypair": "Deletando uma chave de API", "label.deleting.iso": "Removendo ISO", "label.deleting.template": "Remover template", "label.deleting.snapshot": "Excluindo Snapshot", @@ -1887,6 +1898,7 @@ "label.register.oauth": "Registrar OAuth", "label.register.user.data": "Registrar dados de usu\u00e1rio", "label.register.template": "Registrar template", +"label.registering.keypair": "Registrando par de chaves de API", "label.reinstall.vm": "Reinstalar VM", "label.reject": "Rejeitar", "label.related": "Relacionado", @@ -2046,6 +2058,7 @@ "label.secondarystoragelimit": "Limites do armazenamento secund\u00e1rio (GiB)", "label.secretkey": "Chave secreta", "label.secret.key": "Chave secreta", +"label.apikeyaccess": "Accesso a pares de chaves de API", "label.secured": "Protegido", "label.security.groups": "Grupos de seguran\u00e7a", "label.securitygroup": "Grupo de seguran\u00e7a", @@ -2462,10 +2475,13 @@ "label.usenewdiskoffering": "Substituir a oferta de disco?", "label.user": "Usu\u00e1rio", "label.user.conflict": "Conflito", +"label.userapikey": "Chave de API", +"label.usersecretkey": "Chave Secreta de API", "label.user.data": "Dados de usu\u00e1rio", "label.username": "Nome de usu\u00e1rio", "label.users": "Usu\u00e1rios", "label.usersource": "Tipo de usu\u00e1rio", +"label.user.api.key.rules": "Regras", "label.using.cli": "Usando CLI", "label.utilization": "Utiliza\u00e7\u00e3o", "label.uuid": "ID", @@ -3362,6 +3378,8 @@ "message.nfs.mount.options.description": "Lista separada por v\u00edrgulas de op\u00e7\u00f5es de montagem NFS para hosts KVM. Op\u00e7\u00f5es suportadas : vers=[3,4.0,4.1,4.2], nconnect=[1...16]", "message.no.data.to.show.for.period": "Nenhum dado para mostrar no per\u00edodo selecionado.", "message.no.description": "Nenhuma descri\u00e7\u00e3o inserida.", +"message.note.about.keypair.permissions.title": "Observa\u00e7\u00e3o sobre as permiss\u00f5es de regras de pares de chaves de API", +"message.note.about.keypair.permissions.body": "Durante a cria\u00e7\u00e3o de pares de chaves de API, é possível definir um conjunto correspondente de permiss\u00f5es de regras. Se um conjunto de regras for definido, o par de chaves de API terá acesso apenas às APIs para as quais o acesso foi explicitamente concedido (ou seja, APIs cujas regras correspondentes estejam marcadas como permitidas). Por outro lado, se nenhum conjunto de regras for especificado, as permiss\u00f5es do par de chaves de API seguir\u00e3o e se adaptar\u00e3o ao conjunto de permiss\u00f5es da role da conta do usu\u00e1rio.", "message.offering.internet.protocol.warning": "AVISO: Redes suportadas por IPv6 usam roteamento est\u00e1tico e exigir\u00e3o que rotas upstream sejam configuradas manualmente.", "message.offering.ipv6.warning": "Por favor, consulte a documenta\u00e7\u00e3o para criar oferta de Rede/VPC habilitada para IPv6 Suporte IPv6 no CloudStack - Redes Isoladas e Camadas de VPC", "message.ovf.configurations": "H\u00e1 propriedades OVF dispon\u00edveis para a personaliza\u00e7\u00e3o do aparelho selecionado. Por favor, edite os valores de forma apropriada.As ofertas incompat\u00edveis de computa\u00e7\u00e3o ser\u00e3o desativadas.", @@ -3388,6 +3406,7 @@ "message.read.accept.license.agreements": "Leia e aceite os termos dos contratos de licen\u00e7a.", "message.read.admin.guide.scaling.up": "Por favor leia a sess\u00e3o sobre escalonamento din\u00e2mico no guia do administrador antes de escalonar.", "message.recover.vm": "Por favor, confirme a recupera\u00e7\u00e3o desta VM.", +"message.register.keypair.failed": "Falha ao registrar par de chave de API", "message.reinstall.vm": "NOTA: proceda com cuidado. Isso far\u00e1 com que a m\u00e1quina virtual seja re-instalada a partir do template. Todos os dados do disco root ser\u00e3o perdidos. Se houver volumes de dados adicionais, eles n\u00e3o ser\u00e3o alterados.", "message.release.ip.failed": "Falha ao liberar IP", "message.releasing.dedicated.cluster": "Liberando cluster dedicado...", diff --git a/ui/src/components/view/ApiKeyPairsTab.vue b/ui/src/components/view/ApiKeyPairsTab.vue new file mode 100644 index 000000000000..8605fe831b9b --- /dev/null +++ b/ui/src/components/view/ApiKeyPairsTab.vue @@ -0,0 +1,455 @@ +// Licensed to the Apache Software Foundation (ASF) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The ASF licenses this file +// to you under the Apache License, Version 2.0 (the +// "License"); you may not use this file except in compliance +// with the License. You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, +// software distributed under the License is distributed on an +// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. See the License for the +// specific language governing permissions and limitations +// under the License. + + + + + diff --git a/ui/src/components/view/DetailsTab.vue b/ui/src/components/view/DetailsTab.vue index 4145eeb9be6d..ecff34b2949d 100644 --- a/ui/src/components/view/DetailsTab.vue +++ b/ui/src/components/view/DetailsTab.vue @@ -97,7 +97,7 @@ {{ $t(dataResource[item].toLowerCase()) }} {{ dataResource[item] }} -
+
{{ $toLocaleDate(dataResource[item]) }}
{{ dataResource[item] }}
@@ -168,7 +168,7 @@
{{ dataResource[item] }}
- +
{{ $t('label.' + item.replace('date', '.date.and.time'))}}
diff --git a/ui/src/components/view/InfoCard.vue b/ui/src/components/view/InfoCard.vue index 996e30ead3b5..ab821a19d62d 100644 --- a/ui/src/components/view/InfoCard.vue +++ b/ui/src/components/view/InfoCard.vue @@ -120,12 +120,18 @@ -
+
{{ $t('label.status') }}
+
+
{{ $t('label.apikeyaccess') }}
+
+ +
+
{{ $t('label.allocationstate') }}
@@ -159,6 +165,42 @@
+
+
+ + + {{ $t('label.apikey') }} + + +
+ {{ resource.apikey.substring(0, 20) }}... +
+

+
+ + + {{ $t('label.secretkey') }} + + +
+ {{ resource.secretkey.substring(0, 20) }}... +
+
+
{{ $t('label.ostypename') }}
@@ -794,6 +836,14 @@ {{ resource.account }}
+
+
{{ $t('label.user') }}
+
+ + {{ resource.username }} + {{ resource.username }} +
+
{{ $t('label.role') }}
@@ -881,54 +931,6 @@ :osCategoryId="osCategoryId" />
- - - -