You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by da...@apache.org on 2023/11/03 10:55:42 UTC
(cloudstack) 01/01: Merge remote-tracking branch 'apache/4.18' into main
This is an automated email from the ASF dual-hosted git repository.
dahn pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cloudstack.git
commit a15cb81c85d15f91c6e1dee569dc7a55066ceb7d
Merge: 78213da8286 e6f048bc2e8
Author: Daan Hoogland <da...@onecht.net>
AuthorDate: Fri Nov 3 11:55:26 2023 +0100
Merge remote-tracking branch 'apache/4.18' into main
agent/src/main/java/com/cloud/agent/Agent.java | 4 +
.../main/java/com/cloud/agent/api/PingAnswer.java | 13 +-
.../com/cloud/agent/manager/AgentManagerImpl.java | 148 +++++++++++++--------
.../kvm/resource/LibvirtComputingResource.java | 4 +-
.../kvm/resource/LibvirtDomainXMLParser.java | 25 +++-
test/integration/smoke/test_host_ping.py | 102 ++++++++++++++
ui/src/components/view/ListView.vue | 30 +++--
7 files changed, 250 insertions(+), 76 deletions(-)
diff --cc agent/src/main/java/com/cloud/agent/Agent.java
index b1ec592b9fe,e8558931cbf..9e0ee746c03
--- a/agent/src/main/java/com/cloud/agent/Agent.java
+++ b/agent/src/main/java/com/cloud/agent/Agent.java
@@@ -40,8 -40,7 +40,9 @@@ import java.util.concurrent.atomic.Atom
import javax.naming.ConfigurationException;
+import com.cloud.resource.AgentStatusUpdater;
+import com.cloud.resource.ResourceStatusUpdater;
+ import com.cloud.agent.api.PingAnswer;
import com.cloud.utils.NumbersUtil;
import org.apache.cloudstack.agent.lb.SetupMSListAnswer;
import org.apache.cloudstack.agent.lb.SetupMSListCommand;
diff --cc ui/src/components/view/ListView.vue
index cafed924e4c,286d9d16d2a..6d0f4121425
--- a/ui/src/components/view/ListView.vue
+++ b/ui/src/components/view/ListView.vue
@@@ -113,95 -82,138 +113,99 @@@
style="margin-left: 5px"
:actions="actions"
:resource="record"
- :enabled="quickViewEnabled() && actions.length > 0 && columns && columns[0].dataIndex === 'name' "
+ :enabled="quickViewEnabled() && actions.length > 0 && columns && columns[0].dataIndex === 'displayname' "
@exec-action="$parent.execAction"/>
- <span v-if="$route.path.startsWith('/project')" style="margin-right: 5px">
- <tooltip-button type="dashed" size="small" icon="LoginOutlined" @onClick="changeProject(record)" />
- </span>
- <span v-if="$showIcon() && !['vm'].includes($route.path.split('/')[1])" style="margin-right: 5px">
+ <router-link :to="{ path: $route.path + '/' + record.id }">{{ text }}</router-link>
+ </template>
+ <template v-if="column.key === 'username'">
+ <span v-if="$showIcon() && !['vm', 'vnfapp'].includes($route.path.split('/')[1])" style="margin-right: 5px">
<resource-icon v-if="$showIcon() && record.icon && record.icon.base64image" :image="record.icon.base64image" size="2x"/>
- <os-logo v-else-if="record.ostypename" :osName="record.ostypename" size="2x" />
- <render-icon v-else-if="typeof $route.meta.icon ==='string'" style="font-size: 16px;" :icon="$route.meta.icon"/>
- <render-icon v-else style="font-size: 16px;" :svgIcon="$route.meta.icon" />
+ <user-outlined v-else style="font-size: 16px;" />
</span>
- <span v-else :style="{ 'margin-right': record.ostypename ? '5px' : '0' }">
- <os-logo v-if="record.ostypename" :osName="record.ostypename" size="1x" />
+ <router-link :to="{ path: $route.path + '/' + record.id }" v-if="['/accountuser', '/vpnuser'].includes($route.path)">{{ text }}</router-link>
+ <router-link :to="{ path: '/accountuser', query: { username: record.username, domainid: record.domainid } }" v-else-if="$store.getters.userInfo.roletype !== 'User'">{{ text }}</router-link>
+ <span v-else>{{ text }}</span>
+ </template>
+ <template v-if="column.key === 'entityid'">
+ <router-link :to="{ path: generateCommentsPath(record), query: { tab: 'comments' } }">{{ record.entityname }}</router-link>
+ </template>
+ <template v-if="column.key === 'entitytype'">
+ {{ generateHumanReadableEntityType(record) }}
+ </template>
+ <template v-if="column.key === 'adminsonly' && ['Admin'].includes($store.getters.userInfo.roletype)">
+ <a-checkbox :checked="record.adminsonly" :value="record.id" v-if="record.userid === $store.getters.userInfo.id" @change="e => updateAdminsOnly(e)" />
+ <a-checkbox :checked="record.adminsonly" disabled v-else />
+ </template>
+ <template v-if="column.key === 'ipaddress'" href="javascript:;">
+ <router-link v-if="['/publicip', '/privategw'].includes($route.path)" :to="{ path: $route.path + '/' + record.id }">{{ text }}</router-link>
+ <span v-else>
+ <copy-label :label="text" />
</span>
-
- <span v-if="record.hasannotations">
- <span v-if="record.id">
- <router-link :to="{ path: $route.path + '/' + record.id }">{{ text }}</router-link>
- <router-link :to="{ path: $route.path + '/' + record.id, query: { tab: 'comments' } }"><message-filled style="padding-left: 10px" size="small"/></router-link>
- </span>
- <router-link v-else :to="{ path: $route.path + '/' + record.name }" >{{ text }}</router-link>
+ <span v-if="record.issourcenat">
+
+ <a-tag>source-nat</a-tag>
</span>
- <span v-else-if="$route.path.startsWith('/globalsetting')">{{ text }}</span>
- <span v-else-if="$route.path.startsWith('/preferences')">{{ text }}</span>
- <span v-else-if="$route.path.startsWith('/alert')">
- <router-link :to="{ path: $route.path + '/' + record.id }" v-if="record.id">{{ $t(text.toLowerCase()) }}</router-link>
- <router-link :to="{ path: $route.path + '/' + record.name }" v-else>{{ $t(text.toLowerCase()) }}</router-link>
+ <span v-if="record.isstaticnat">
+
+ <a-tag>static-nat</a-tag>
</span>
- <span v-else-if="$route.path.startsWith('/tungstenfabric')">
- <router-link :to="{ path: $route.path + '/' + record.id }" v-if="record.id">{{ $t(text.toLowerCase()) }}</router-link>
- <router-link :to="{ path: $route.path + '/' + record.name }" v-else>{{ $t(text.toLowerCase()) }}</router-link>
+ </template>
+ <template v-if="column.key === 'ip6address'" href="javascript:;">
+ <span>{{ ipV6Address(text, record) }}</span>
+ </template>
+ <template v-if="column.key === 'publicip'">
+ <router-link v-if="['/autoscalevmgroup'].includes($route.path)" :to="{ path: '/publicip' + '/' + record.publicipid }">{{ text }}</router-link>
+ <router-link v-else :to="{ path: $route.path + '/' + record.id }">{{ text }}</router-link>
+ </template>
+ <template v-if="column.key === 'traffictype'">
+ {{ text }}
+ </template>
+ <template v-if="column.key === 'vmname'">
+ <router-link :to="{ path: createPathBasedOnVmType(record.vmtype, record.virtualmachineid) }">{{ text }}</router-link>
+ </template>
+ <template v-if="column.key === 'virtualmachinename'">
+ <router-link :to="{ path: getVmRouteUsingType(record) + record.virtualmachineid }">{{ text }}</router-link>
+ </template>
+ <template v-if="column.key === 'volumename'">
+ <router-link :to="{ path: '/volume/' + record.volumeid }">{{ text }}</router-link>
+ </template>
+ <template v-if="column.key === 'size'">
- <span v-if="text">
++ <span v-if="text && $route.path === '/kubernetes'">
++ {{ text }}
+ </span>
- <span v-else-if="isTungstenPath()">
- <router-link :to="{ path: $route.path + '/' + record.uuid, query: { zoneid: record.zoneid } }" v-if="record.uuid && record.zoneid">{{ $t(text.toLowerCase()) }}</router-link>
- <router-link :to="{ path: $route.path + '/' + record.uuid, query: { zoneid: $route.query.zoneid } }" v-else-if="record.uuid && $route.query.zoneid">{{ $t(text.toLowerCase()) }}</router-link>
- <router-link :to="{ path: $route.path }" v-else>{{ $t(text.toLowerCase()) }}</router-link>
++ <span v-else-if="text">
+ {{ parseFloat(parseFloat(text) / 1024.0 / 1024.0 / 1024.0).toFixed(2) }} GiB
</span>
- <span v-else>
- <router-link :to="{ path: $route.path + '/' + record.id }" v-if="record.id">{{ text }}</router-link>
- <router-link :to="{ path: $route.path + '/' + record.name }" v-else>{{ text }}</router-link>
+ </template>
+ <template v-if="column.key === 'physicalsize'">
+ <span v-if="text">
+ {{ isNaN(text) ? text : (parseFloat(parseFloat(text) / 1024.0 / 1024.0 / 1024.0).toFixed(2) + ' GiB') }}
</span>
- </span>
- </template>
- <template #templatetype="{ text, record }">
- <router-link :to="{ path: $route.path + '/' + record.templatetype }">{{ text }}</router-link>
- </template>
- <template #type="{ text }">
- <span v-if="['USER.LOGIN', 'USER.LOGOUT', 'ROUTER.HEALTH.CHECKS', 'FIREWALL.CLOSE', 'ALERT.SERVICE.DOMAINROUTER'].includes(text)">{{ $t(text.toLowerCase()) }}</span>
- <span v-else>{{ text }}</span>
- </template>
- <template #displayname="{text, record}">
- <QuickView
- style="margin-left: 5px"
- :actions="actions"
- :resource="record"
- :enabled="quickViewEnabled() && actions.length > 0 && columns && columns[0].dataIndex === 'displayname' "
- @exec-action="$parent.execAction"/>
- <router-link :to="{ path: $route.path + '/' + record.id }">{{ text }}</router-link>
- </template>
- <template #username="{text, record}">
- <span v-if="$showIcon() && !['vm'].includes($route.path.split('/')[1])" style="margin-right: 5px">
- <resource-icon v-if="$showIcon() && record.icon && record.icon.base64image" :image="record.icon.base64image" size="2x"/>
- <user-outlined v-else style="font-size: 16px;" />
- </span>
- <router-link :to="{ path: $route.path + '/' + record.id }" v-if="['/accountuser', '/vpnuser'].includes($route.path)">{{ text }}</router-link>
- <router-link :to="{ path: '/accountuser', query: { username: record.username, domainid: record.domainid } }" v-else-if="$store.getters.userInfo.roletype !== 'User'">{{ text }}</router-link>
+ </template>
+ <template v-if="column.key === 'physicalnetworkname'">
+ <router-link :to="{ path: '/physicalnetwork/' + record.physicalnetworkid }">{{ text }}</router-link>
+ </template>
+ <template v-if="column.key === 'serviceofferingname'">
+ <router-link :to="{ path: '/computeoffering/' + record.serviceofferingid }">{{ text }}</router-link>
+ </template>
+ <template v-if="column.key === 'hypervisor'">
+ <span v-if="$route.name === 'hypervisorcapability'">
- <router-link :to="{ path: $route.path + '/' + record.id }">{{ text }}</router-link>
- </span>
- <span v-else-if="$route.name === 'guestoshypervisormapping'">
- <QuickView
- style="margin-left: 5px"
- :actions="actions"
- :resource="record"
- :enabled="quickViewEnabled() && actions.length > 0 && columns && columns[0].dataIndex === 'hypervisor' "
- @exec-action="$parent.execAction"/>
- <router-link :to="{ path: $route.path + '/' + record.id }">{{ text }}</router-link>
- </span>
++ <router-link :to="{ path: $route.path + '/' + record.id }">{{ text }}</router-link>
++ </span>
++ <span v-else-if="$route.name === 'guestoshypervisormapping'">
++ <QuickView
++ style="margin-left: 5px"
++ :actions="actions"
++ :resource="record"
++ :enabled="quickViewEnabled() && actions.length > 0 && columns && columns[0].dataIndex === 'hypervisor' "
++ @exec-action="$parent.execAction"/>
++ <router-link :to="{ path: $route.path + '/' + record.id }">{{ text }}</router-link>
++ </span>
++ </template>
<span v-else>{{ text }}</span>
</template>
- <template #entityid="{ record }" href="javascript:;">
- <router-link :to="{ path: generateCommentsPath(record), query: { tab: 'comments' } }">{{ record.entityname }}</router-link>
- </template>
- <template #entitytype="{ record }" href="javascript:;">
- {{ generateHumanReadableEntityType(record) }}
- </template>
- <template #adminsonly="{ record }" v-if="['Admin'].includes($store.getters.userInfo.roletype)" href="javascript:;">
- <a-checkbox :checked="record.adminsonly" :value="record.id" v-if="record.userid === $store.getters.userInfo.id" @change="e => updateAdminsOnly(e)" />
- <a-checkbox :checked="record.adminsonly" disabled v-else />
- </template>
- <template #ipaddress="{ text, record }" href="javascript:;">
- <router-link v-if="['/publicip', '/privategw'].includes($route.path)" :to="{ path: $route.path + '/' + record.id }">{{ text }}</router-link>
- <span v-else>
- <copy-label :label="text" />
- </span>
- <span v-if="record.issourcenat">
-
- <a-tag>source-nat</a-tag>
- </span>
- <span v-if="record.isstaticnat">
-
- <a-tag>static-nat</a-tag>
- </span>
- </template>
- <template #ip6address="{ text, record }" href="javascript:;">
- <span>{{ ipV6Address(text, record) }}</span>
- </template>
- <template #publicip="{ text, record }">
- <router-link v-if="['/autoscalevmgroup'].includes($route.path)" :to="{ path: '/publicip' + '/' + record.publicipid }">{{ text }}</router-link>
- <router-link v-else :to="{ path: $route.path + '/' + record.id }">{{ text }}</router-link>
- </template>
- <template #traffictype="{ text }" href="javascript:;">
- {{ text }}
- </template>
- <template #vmname="{ text, record }">
- <router-link :to="{ path: createPathBasedOnVmType(record.vmtype, record.virtualmachineid) }">{{ text }}</router-link>
- </template>
- <template #virtualmachinename="{ text, record }">
- <router-link :to="{ path: '/vm/' + record.virtualmachineid }">{{ text }}</router-link>
- </template>
- <template #volumename="{ text, record }">
- <router-link :to="{ path: '/volume/' + record.volumeid }">{{ text }}</router-link>
- </template>
- <template #size="{ text }">
- <span v-if="text && $route.path === '/kubernetes'">
- {{ text }}
- </span>
- <span v-else-if="text">
- {{ parseFloat(parseFloat(text) / 1024.0 / 1024.0 / 1024.0).toFixed(2) }} GiB
- </span>
- </template>
- <template #physicalsize="{ text }">
- <span v-if="text">
- {{ isNaN(text) ? text : (parseFloat(parseFloat(text) / 1024.0 / 1024.0 / 1024.0).toFixed(2) + ' GiB') }}
- </span>
- </template>
- <template #physicalnetworkname="{ text, record }">
- <router-link :to="{ path: '/physicalnetwork/' + record.physicalnetworkid }">{{ text }}</router-link>
- </template>
- <template #serviceofferingname="{ text, record }">
- <router-link :to="{ path: '/computeoffering/' + record.serviceofferingid }">{{ text }}</router-link>
- </template>
- <template #hypervisor="{ text, record }">
- <span v-if="$route.name === 'hypervisorcapability'">
+ <template v-if="column.key === 'osname'">
+ <span v-if="$route.name === 'guestos'">
<router-link :to="{ path: $route.path + '/' + record.id }">{{ text }}</router-link>
</span>
<span v-else>{{ text }}</span>
@@@ -254,214 -263,193 +258,212 @@@
<router-link v-if="record.storageid" :to="{ path: '/storagepool/' + record.storageid }">{{ text }}</router-link>
<span v-else>{{ text }}</span>
</template>
-
- <template
- v-for="(value, name) in thresholdMapping"
- :key="name"
- #[name]="{ text, record }"
- href="javascript:;">
- <span>
- <span v-if="record[value.disable]" class="alert-disable-threshold">
- {{ text }}
- </span>
- <span v-else-if="record[value.notification]" class="alert-notification-threshold">
- {{ text }}
- </span>
- <span style="padding: 10%;" v-else>
- {{ text }}
+ <template v-for="(value, name) in thresholdMapping" :key="name">
+ <template v-if="column.key === name">
+ <span>
+ <span v-if="record[value.disable]" class="alert-disable-threshold">
+ {{ text }}
+ </span>
+ <span v-else-if="record[value.notification]" class="alert-notification-threshold">
+ {{ text }}
+ </span>
+ <span style="padding: 10%;" v-else>
+ {{ text }}
+ </span>
</span>
- </span>
- </template>
-
- <template #level="{ text, record }">
- <router-link :to="{ path: '/event/' + record.id }">{{ text }}</router-link>
- </template>
+ </template>
- </template>
-
+ <template v-if="column.key === 'level'">
+ <router-link :to="{ path: '/event/' + record.id }">{{ text }}</router-link>
+ </template>
- <template #clustername="{ text, record }">
- <router-link :to="{ path: '/cluster/' + record.clusterid }">{{ text }}</router-link>
- </template>
- <template #podname="{ text, record }">
- <router-link :to="{ path: '/pod/' + record.podid }">{{ text }}</router-link>
- </template>
- <template #account="{ text, record }">
- <template v-if="record.owner">
- <template v-for="(item, idx) in record.owner" :key="idx">
- <span style="margin-right:5px">
- <span v-if="$store.getters.userInfo.roletype !== 'User'">
- <router-link v-if="'user' in item" :to="{ path: '/accountuser', query: { username: item.user, domainid: record.domainid }}">{{ item.account + '(' + item.user + ')' }}</router-link>
- <router-link v-else :to="{ path: '/account', query: { name: item.account, domainid: record.domainid, dataView: true } }">{{ item.account }}</router-link>
+ <template v-if="column.key === 'clustername'">
+ <router-link :to="{ path: '/cluster/' + record.clusterid }">{{ text }}</router-link>
+ </template>
+ <template v-if="column.key === 'podname'">
+ <router-link :to="{ path: '/pod/' + record.podid }">{{ text }}</router-link>
+ </template>
+ <template v-if="column.key === 'account'">
+ <template v-if="record.owner">
+ <template v-for="(item, idx) in record.owner" :key="idx">
+ <span style="margin-right:5px">
+ <span v-if="$store.getters.userInfo.roletype !== 'User'">
+ <router-link v-if="'user' in item" :to="{ path: '/accountuser', query: { username: item.user, domainid: record.domainid }}">{{ item.account + '(' + item.user + ')' }}</router-link>
+ <router-link v-else :to="{ path: '/account', query: { name: item.account, domainid: record.domainid, dataView: true } }">{{ item.account }}</router-link>
+ </span>
+ <span v-else>{{ item.user ? item.account + '(' + item.user + ')' : item.account }}</span>
</span>
- <span v-else>{{ item.user ? item.account + '(' + item.user + ')' : item.account }}</span>
- </span>
+ </template>
+ </template>
+ <template v-if="text && !text.startsWith('PrjAcct-')">
+ <router-link
+ v-if="'quota' in record && $router.resolve(`${$route.path}/${record.account}`).matched[0].redirect !== '/exception/404'"
+ :to="{ path: `${$route.path}/${record.account}`, query: { account: record.account, domainid: record.domainid, quota: true } }">{{ text }}</router-link>
+ <router-link :to="{ path: '/account/' + record.accountid }" v-else-if="record.accountid">{{ text }}</router-link>
+ <router-link :to="{ path: '/account', query: { name: record.account, domainid: record.domainid, dataView: true } }" v-else-if="$store.getters.userInfo.roletype !== 'User'">{{ text }}</router-link>
+ <span v-else>{{ text }}</span>
</template>
</template>
- <template v-if="text && !text.startsWith('PrjAcct-')">
- <router-link
- v-if="'quota' in record && $router.resolve(`${$route.path}/${record.account}`).matched[0].redirect !== '/exception/404'"
- :to="{ path: `${$route.path}/${record.account}`, query: { account: record.account, domainid: record.domainid, quota: true } }">{{ text }}</router-link>
- <router-link :to="{ path: '/account/' + record.accountid }" v-else-if="record.accountid">{{ text }}</router-link>
- <router-link :to="{ path: '/account', query: { name: record.account, domainid: record.domainid, dataView: true } }" v-else-if="$store.getters.userInfo.roletype !== 'User'">{{ text }}</router-link>
+ <template v-if="column.key === 'resource'">
+ <resource-label :resourceType="record.resourcetype" :resourceId="record.resourceid" :resourceName="record.resourcename" />
+ </template>
+ <template v-if="column.key === 'domain'">
+ <router-link v-if="record.domainid && !record.domainid.toString().includes(',') && $store.getters.userInfo.roletype !== 'User'" :to="{ path: '/domain/' + record.domainid, query: { tab: 'details' } }">{{ text }}</router-link>
<span v-else>{{ text }}</span>
</template>
- </template>
- <template #resource="{ record }">
- <resource-label :resourceType="record.resourcetype" :resourceId="record.resourceid" :resourceName="record.resourcename" />
- </template>
- <template #domain="{ text, record }">
- <router-link v-if="record.domainid && !record.domainid.toString().includes(',') && $store.getters.userInfo.roletype !== 'User'" :to="{ path: '/domain/' + record.domainid, query: { tab: 'details' } }">{{ text }}</router-link>
- <span v-else>{{ text }}</span>
- </template>
- <template #domainpath="{ text, record }">
- <router-link v-if="record.domainid && !record.domainid.includes(',') && $router.resolve('/domain/' + record.domainid).matched[0].redirect !== '/exception/404'" :to="{ path: '/domain/' + record.domainid, query: { tab: 'details' } }">{{ text }}</router-link>
- <span v-else>{{ text }}</span>
- </template>
- <template #zone="{ text, record }">
- <router-link v-if="record.zoneid && !record.zoneid.includes(',') && $router.resolve('/zone/' + record.zoneid).matched[0].redirect !== '/exception/404'" :to="{ path: '/zone/' + record.zoneid }">{{ text }}</router-link>
- <span v-else>{{ text }}</span>
- </template>
- <template #zonename="{ text, record }">
- <router-link v-if="$router.resolve('/zone/' + record.zoneid).matched[0].redirect !== '/exception/404'" :to="{ path: '/zone/' + record.zoneid }">{{ text }}</router-link>
- <router-link v-else-if="$router.resolve('/zones/' + record.zoneid).matched[0].redirect !== '/exception/404'" :to="{ path: '/zones/' + record.zoneid }">{{ text }}</router-link>
- <span v-else>{{ text }}</span>
- </template>
- <template #rolename="{ text, record }">
- <router-link v-if="record.roleid && $router.resolve('/role/' + record.roleid).matched[0].redirect !== '/exception/404'" :to="{ path: '/role/' + record.roleid }">{{ text }}</router-link>
- <span v-else>{{ text }}</span>
- </template>
- <template #templateversion="{ record }">
- <span> {{ record.version }} </span>
- </template>
- <template #softwareversion="{ record }">
- <span> {{ record.softwareversion ? record.softwareversion : 'N/A' }} </span>
- </template>
- <template #access="{ record }">
- <status :text="record.readonly ? 'ReadOnly' : 'ReadWrite'" displayText />
- </template>
- <template #requiresupgrade="{ record }">
- <status :text="record.requiresupgrade ? 'warning' : ''" />
- {{ record.requiresupgrade ? 'Yes' : 'No' }}
- </template>
- <template #loadbalancerrule="{ record }">
- <span> {{ record.loadbalancerrule }} </span>
- </template>
- <template #autoscalingenabled="{ record }">
- <status :text="record.autoscalingenabled ? 'Enabled' : 'Disabled'" />
- {{ record.autoscalingenabled ? 'Enabled' : 'Disabled' }}
- </template>
- <template #current="{record}">
- <status :text="record.current ? record.current.toString() : 'false'" />
- </template>
- <template #created="{ text }">
- {{ $toLocaleDate(text) }}
- </template>
- <template #sent="{ text }">
- {{ $toLocaleDate(text) }}
- </template>
- <template #order="{ text, record }">
- <div class="shift-btns">
- <a-tooltip :name="text" placement="top">
- <template #title>{{ $t('label.move.to.top') }}</template>
- <a-button
- shape="round"
- @click="moveItemTop(record)"
- class="shift-btn">
- <DoubleLeftOutlined class="shift-btn shift-btn--rotated" />
- </a-button>
- </a-tooltip>
- <a-tooltip placement="top">
- <template #title>{{ $t('label.move.to.bottom') }}</template>
- <a-button
- shape="round"
- @click="moveItemBottom(record)"
- class="shift-btn">
- <DoubleRightOutlined class="shift-btn shift-btn--rotated" />
- </a-button>
- </a-tooltip>
- <a-tooltip placement="top">
- <template #title>{{ $t('label.move.up.row') }}</template>
- <a-button shape="round" @click="moveItemUp(record)" class="shift-btn">
- <CaretUpOutlined class="shift-btn" />
- </a-button>
- </a-tooltip>
- <a-tooltip placement="top">
- <template #title>{{ $t('label.move.down.row') }}</template>
- <a-button shape="round" @click="moveItemDown(record)" class="shift-btn">
- <CaretDownOutlined class="shift-btn" />
- </a-button>
- </a-tooltip>
- </div>
- </template>
+ <template v-if="column.key === 'domainpath'">
+ <router-link v-if="record.domainid && !record.domainid.includes(',') && $router.resolve('/domain/' + record.domainid).matched[0].redirect !== '/exception/404'" :to="{ path: '/domain/' + record.domainid, query: { tab: 'details' } }">{{ text }}</router-link>
+ <span v-else>{{ text }}</span>
+ </template>
+ <template v-if="column.key === 'zone'">
+ <router-link v-if="record.zoneid && !record.zoneid.includes(',') && $router.resolve('/zone/' + record.zoneid).matched[0].redirect !== '/exception/404'" :to="{ path: '/zone/' + record.zoneid }">{{ text }}</router-link>
+ <span v-else>{{ text }}</span>
+ </template>
+ <template v-if="column.key === 'zonename'">
+ <router-link v-if="$router.resolve('/zone/' + record.zoneid).matched[0].redirect !== '/exception/404'" :to="{ path: '/zone/' + record.zoneid }">{{ text }}</router-link>
+ <router-link v-else-if="$router.resolve('/zones/' + record.zoneid).matched[0].redirect !== '/exception/404'" :to="{ path: '/zones/' + record.zoneid }">{{ text }}</router-link>
+ <span v-else>{{ text }}</span>
+ </template>
+ <template v-if="column.key === 'rolename'">
+ <router-link v-if="record.roleid && $router.resolve('/role/' + record.roleid).matched[0].redirect !== '/exception/404'" :to="{ path: '/role/' + record.roleid }">{{ text }}</router-link>
+ <span v-else>{{ text }}</span>
+ </template>
+ <template v-if="column.key === 'templateversion'">
+ <span> {{ record.version }} </span>
+ </template>
+ <template v-if="column.key === 'softwareversion'">
+ <span> {{ record.softwareversion ? record.softwareversion : 'N/A' }} </span>
+ </template>
+ <template v-if="column.key === 'access'">
+ <status :text="record.readonly ? 'ReadOnly' : 'ReadWrite'" displayText />
+ </template>
+ <template v-if="column.key === 'requiresupgrade'">
+ <status :text="record.requiresupgrade ? 'warning' : ''" />
+ {{ record.requiresupgrade ? 'Yes' : 'No' }}
+ </template>
+ <template v-if="column.key === 'loadbalancerrule'">
+ <span> {{ record.loadbalancerrule }} </span>
+ </template>
+ <template v-if="column.key === 'autoscalingenabled'">
+ <status :text="record.autoscalingenabled ? 'Enabled' : 'Disabled'" />
+ {{ record.autoscalingenabled ? 'Enabled' : 'Disabled' }}
+ </template>
+ <template v-if="column.key === 'current'">
+ <status :text="record.current ? record.current.toString() : 'false'" />
+ </template>
+ <template v-if="column.key === 'enabled'">
+ <status :text="record.enabled ? record.enabled.toString() : 'false'" />
+ {{ record.enabled ? 'Enabled' : 'Disabled' }}
+ </template>
+ <template v-if="['created', 'sent'].includes(column.key)">
+ {{ $toLocaleDate(text) }}
+ </template>
+ <template v-if="['startdate', 'enddate'].includes(column.key) && ['vm', 'vnfapp'].includes($route.path.split('/')[1])">
+ {{ getDateAtTimeZone(text, record.timezone) }}
+ </template>
+ <template v-if="column.key === 'order'">
+ <div class="shift-btns">
+ <a-tooltip :name="text" placement="top">
+ <template #title>{{ $t('label.move.to.top') }}</template>
+ <a-button
+ shape="round"
+ @click="moveItemTop(record)"
+ class="shift-btn">
+ <DoubleLeftOutlined class="shift-btn shift-btn--rotated" />
+ </a-button>
+ </a-tooltip>
+ <a-tooltip placement="top">
+ <template #title>{{ $t('label.move.to.bottom') }}</template>
+ <a-button
+ shape="round"
+ @click="moveItemBottom(record)"
+ class="shift-btn">
+ <DoubleRightOutlined class="shift-btn shift-btn--rotated" />
+ </a-button>
+ </a-tooltip>
+ <a-tooltip placement="top">
+ <template #title>{{ $t('label.move.up.row') }}</template>
+ <a-button shape="round" @click="moveItemUp(record)" class="shift-btn">
+ <CaretUpOutlined class="shift-btn" />
+ </a-button>
+ </a-tooltip>
+ <a-tooltip placement="top">
+ <template #title>{{ $t('label.move.down.row') }}</template>
+ <a-button shape="round" @click="moveItemDown(record)" class="shift-btn">
+ <CaretDownOutlined class="shift-btn" />
+ </a-button>
+ </a-tooltip>
+ </div>
+ </template>
- <template #value="{ text, record }">
- <a-input
- v-if="editableValueKey === record.key"
- v-focus="true"
- :defaultValue="record.value"
- :disabled="!('updateConfiguration' in $store.getters.apis)"
- v-model:value="editableValue"
- @keydown.esc="editableValueKey = null"
- @pressEnter="saveValue(record)">
- </a-input>
- <div v-else style="width: 200px; word-break: break-all">
- {{ text }}
- </div>
- </template>
- <template #actions="{ record }">
- <tooltip-button
- :tooltip="$t('label.edit')"
- :disabled="!('updateConfiguration' in $store.getters.apis)"
- v-if="editableValueKey !== record.key"
- icon="edit-outlined"
- @onClick="editValue(record)" />
- <tooltip-button
- :tooltip="$t('label.cancel')"
- @onClick="editableValueKey = null"
- v-if="editableValueKey === record.key"
- iconType="CloseCircleTwoTone"
- iconTwoToneColor="#f5222d" />
- <tooltip-button
- :tooltip="$t('label.ok')"
- :disabled="!('updateConfiguration' in $store.getters.apis)"
- @onClick="saveValue(record)"
- v-if="editableValueKey === record.key"
- iconType="CheckCircleTwoTone"
- iconTwoToneColor="#52c41a" />
- <tooltip-button
- :tooltip="$t('label.reset.config.value')"
- @onClick="resetConfig(record)"
- v-if="editableValueKey !== record.key"
- icon="reload-outlined"
- :disabled="!('updateConfiguration' in $store.getters.apis)" />
+ <template v-if="column.key === 'value'">
+ <a-input
+ v-if="editableValueKey === record.key"
+ v-focus="true"
+ :defaultValue="record.value"
+ :disabled="!('updateConfiguration' in $store.getters.apis)"
+ v-model:value="editableValue"
+ @keydown.esc="editableValueKey = null"
+ @pressEnter="saveValue(record)">
+ </a-input>
+ <div v-else style="width: 200px; word-break: break-all">
+ {{ text }}
+ </div>
+ </template>
+ <template v-if="column.key === 'actions'">
+ <tooltip-button
+ :tooltip="$t('label.edit')"
+ :disabled="!('updateConfiguration' in $store.getters.apis)"
+ v-if="editableValueKey !== record.key"
+ icon="edit-outlined"
+ @onClick="editValue(record)" />
+ <tooltip-button
+ :tooltip="$t('label.cancel')"
+ @onClick="editableValueKey = null"
+ v-if="editableValueKey === record.key"
+ iconType="CloseCircleTwoTone"
+ iconTwoToneColor="#f5222d" />
+ <tooltip-button
+ :tooltip="$t('label.ok')"
+ :disabled="!('updateConfiguration' in $store.getters.apis)"
+ @onClick="saveValue(record)"
+ v-if="editableValueKey === record.key"
+ iconType="CheckCircleTwoTone"
+ iconTwoToneColor="#52c41a" />
+ <tooltip-button
+ :tooltip="$t('label.reset.config.value')"
+ @onClick="resetConfig(record)"
+ v-if="editableValueKey !== record.key"
+ icon="reload-outlined"
+ :disabled="!('updateConfiguration' in $store.getters.apis)" />
+ </template>
+ <template v-if="column.key === 'tariffActions'">
+ <tooltip-button
+ :tooltip="$t('label.edit')"
+ v-if="editableValueKey !== record.key"
+ :disabled="!('quotaTariffUpdate' in $store.getters.apis)"
+ icon="edit-outlined"
+ @onClick="editTariffValue(record)" />
+ <slot></slot>
+ </template>
+ <template v-if="column.key === 'vmScheduleActions'">
+ <tooltip-button
+ :tooltip="$t('label.edit')"
+ :disabled="!('updateVMSchedule' in $store.getters.apis)"
+ icon="edit-outlined"
+ @onClick="updateVMSchedule(record)" />
+ <tooltip-button
+ :tooltip="$t('label.remove')"
+ :disabled="!('deleteVMSchedule' in $store.getters.apis)"
+ icon="delete-outlined"
+ :danger="true"
+ type="primary"
+ @onClick="removeVMSchedule(record)" />
+ </template>
</template>
- <template #tariffActions="{ record }">
- <tooltip-button
- :tooltip="$t('label.edit')"
- v-if="editableValueKey !== record.key"
- :disabled="!('quotaTariffUpdate' in $store.getters.apis)"
- icon="edit-outlined"
- @onClick="editTariffValue(record)" />
- <slot></slot>
+ <template #footer>
+ <span v-if="hasSelected">
+ {{ `Selected ${selectedRowKeys.length} items` }}
+ </span>
</template>
</a-table>
</template>