mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-16 22:50:10 +03:00
Merge branch 'master' of https://github.com/OpenNebula/one-ee
This commit is contained in:
commit
7fe69992a4
@ -2269,6 +2269,7 @@ ONEVMDUMP_LIB_RESTORERS_FILES="src/onevmdump/lib/restorers/base.rb"
|
||||
|
||||
ETC_FILES="share/etc/oned.conf \
|
||||
share/etc/defaultrc \
|
||||
share/etc/guacd \
|
||||
src/tm_mad/tmrc \
|
||||
src/scheduler/etc/sched.conf \
|
||||
src/monitor/etc/monitord.conf "
|
||||
|
@ -65,15 +65,14 @@
|
||||
<xs:element name="DOMAIN" type="xs:string"/>
|
||||
<xs:element name="FUNCTION" type="xs:string"/>
|
||||
<xs:element name="NUMA_NODE" type="xs:string"/>
|
||||
<xs:element name="PROFILES" type="xs:string" minOccurs="0"/>
|
||||
<xs:element name="SHORT_ADDRESS" type="xs:string"/>
|
||||
<xs:element name="SLOT" type="xs:string"/>
|
||||
<xs:element name="TYPE" type="xs:string"/>
|
||||
<xs:element name="UUID" type="xs:string" minOccurs="0"/>
|
||||
<xs:element name="VENDOR" type="xs:string"/>
|
||||
<xs:element name="VENDOR_NAME" type="xs:string"/>
|
||||
<xs:element name="VMID" type="xs:integer"/>
|
||||
<xs:element name="UUID" type="xs:string"/>
|
||||
<xs:element name="DEVICE_NAME" type="xs:string"/>
|
||||
<xs:element name="PROFILES" type="xs:string"/>
|
||||
</xs:sequence>
|
||||
</xs:complexType>
|
||||
</xs:element>
|
||||
|
17
share/etc/guacd
Normal file
17
share/etc/guacd
Normal file
@ -0,0 +1,17 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
# Copyright 2002-2022, OpenNebula Project, OpenNebula Systems #
|
||||
# #
|
||||
# Licensed 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. #
|
||||
#--------------------------------------------------------------------------- #
|
||||
|
||||
OPTS="-b 0.0.0.0"
|
@ -559,6 +559,12 @@ Layout/MultilineOperationIndentation:
|
||||
Layout/LineEndStringConcatenationIndentation:
|
||||
Enabled: false
|
||||
|
||||
Layout/LineContinuationSpacing:
|
||||
Enabled: false
|
||||
|
||||
Layout/LineContinuationLeadingSpace:
|
||||
Enabled: false
|
||||
|
||||
#######
|
||||
# STYLE
|
||||
#######
|
||||
@ -914,6 +920,9 @@ Lint/UnmodifiedReduceAccumulator:
|
||||
Lint/AmbiguousOperatorPrecedence:
|
||||
Enabled: false
|
||||
|
||||
Lint/NonAtomicFileOperation:
|
||||
Enabled: false
|
||||
|
||||
#########
|
||||
# METRICS
|
||||
########
|
||||
|
@ -33,6 +33,8 @@ actions:
|
||||
disable: true
|
||||
delete: true
|
||||
edit_labels: true
|
||||
lock: true
|
||||
unlock: true
|
||||
|
||||
# Filters - List of criteria to filter the resources
|
||||
|
||||
|
@ -19,7 +19,12 @@ import {
|
||||
AddCircledOutline,
|
||||
CloudDownload,
|
||||
DownloadCircledOutline,
|
||||
Lock,
|
||||
MoreVert,
|
||||
Group,
|
||||
Trash,
|
||||
} from 'iconoir-react'
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
import { useViews } from 'client/features/Auth'
|
||||
import { useGeneralApi } from 'client/features/General'
|
||||
@ -27,6 +32,12 @@ import { Translate } from 'client/components/HOC'
|
||||
import {
|
||||
useExportAppMutation,
|
||||
useDownloadAppMutation,
|
||||
useLockAppMutation,
|
||||
useUnlockAppMutation,
|
||||
useEnableAppMutation,
|
||||
useDisableAppMutation,
|
||||
useChangeAppOwnershipMutation,
|
||||
useDeleteAppMutation,
|
||||
} from 'client/features/OneApi/marketplaceApp'
|
||||
|
||||
import { ExportForm } from 'client/components/Forms/MarketplaceApp'
|
||||
@ -37,22 +48,37 @@ import {
|
||||
|
||||
import { PATH } from 'client/apps/sunstone/routesOne'
|
||||
import { T, RESOURCE_NAMES, MARKETPLACE_APP_ACTIONS } from 'client/constants'
|
||||
import { ChangeGroupForm, ChangeUserForm } from 'client/components/Forms/Vm'
|
||||
import { Typography } from '@mui/material'
|
||||
|
||||
const MessageToConfirmAction = (rows) => {
|
||||
const ListAppNames = ({ rows = [] }) => {
|
||||
const names = rows?.map?.(({ original }) => original?.NAME)
|
||||
|
||||
return (
|
||||
<>
|
||||
<p>
|
||||
<Translate word={T.Apps} />
|
||||
{`: ${names.join(', ')}`}
|
||||
</p>
|
||||
<p>
|
||||
<Translate word={T.DoYouWantProceed} />
|
||||
</p>
|
||||
</>
|
||||
<Typography variant="inherit" component="span" display="block">
|
||||
<Translate word={T.Apps} />
|
||||
{`: ${names.join(', ')}`}
|
||||
</Typography>
|
||||
)
|
||||
}
|
||||
ListAppNames.propTypes = {
|
||||
rows: PropTypes.arrayOf(
|
||||
PropTypes.shape({
|
||||
original: PropTypes.shape({
|
||||
NAME: PropTypes.string,
|
||||
}),
|
||||
})
|
||||
),
|
||||
}
|
||||
|
||||
const SubHeader = (rows) => <ListAppNames rows={rows} />
|
||||
|
||||
const MessageToConfirmAction = (rows) => (
|
||||
<>
|
||||
<ListAppNames rows={rows} />
|
||||
<Translate word={T.DoYouWantProceed} />
|
||||
</>
|
||||
)
|
||||
|
||||
MessageToConfirmAction.displayName = 'MessageToConfirmAction'
|
||||
|
||||
@ -67,6 +93,12 @@ const Actions = () => {
|
||||
const { enqueueSuccess } = useGeneralApi()
|
||||
const [exportApp] = useExportAppMutation()
|
||||
const [downloadApp] = useDownloadAppMutation()
|
||||
const [lock] = useLockAppMutation()
|
||||
const [unlock] = useUnlockAppMutation()
|
||||
const [enable] = useEnableAppMutation()
|
||||
const [disable] = useDisableAppMutation()
|
||||
const [changeOwnership] = useChangeAppOwnershipMutation()
|
||||
const [deleteApp] = useDeleteAppMutation()
|
||||
|
||||
const marketplaceAppActions = useMemo(
|
||||
() =>
|
||||
@ -117,6 +149,142 @@ const Actions = () => {
|
||||
urls.forEach((url) => window.open(url, '_blank'))
|
||||
},
|
||||
},
|
||||
{
|
||||
tooltip: T.Lock,
|
||||
icon: Lock,
|
||||
selected: true,
|
||||
color: 'secondary',
|
||||
dataCy: 'marketapp-lock',
|
||||
options: [
|
||||
{
|
||||
accessor: MARKETPLACE_APP_ACTIONS.LOCK,
|
||||
name: T.Lock,
|
||||
isConfirmDialog: true,
|
||||
dialogProps: {
|
||||
title: T.Lock,
|
||||
children: MessageToConfirmAction,
|
||||
dataCy: `modal-${MARKETPLACE_APP_ACTIONS.LOCK}`,
|
||||
},
|
||||
onSubmit: (rows) => async () => {
|
||||
const ids = rows?.map?.(({ original }) => original?.ID)
|
||||
await Promise.all(ids.map((id) => lock({ id })))
|
||||
},
|
||||
},
|
||||
{
|
||||
accessor: MARKETPLACE_APP_ACTIONS.UNLOCK,
|
||||
name: T.Unlock,
|
||||
isConfirmDialog: true,
|
||||
dialogProps: {
|
||||
title: T.Unlock,
|
||||
children: MessageToConfirmAction,
|
||||
dataCy: `modal-${MARKETPLACE_APP_ACTIONS.UNLOCK}`,
|
||||
},
|
||||
onSubmit: (rows) => async () => {
|
||||
const ids = rows?.map?.(({ original }) => original?.ID)
|
||||
await Promise.all(ids.map((id) => unlock({ id })))
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
tooltip: T.Enable,
|
||||
icon: MoreVert,
|
||||
selected: true,
|
||||
color: 'secondary',
|
||||
dataCy: 'marketapp-enable',
|
||||
options: [
|
||||
{
|
||||
accessor: MARKETPLACE_APP_ACTIONS.ENABLE,
|
||||
name: T.Enable,
|
||||
isConfirmDialog: true,
|
||||
dialogProps: {
|
||||
title: T.Enable,
|
||||
children: MessageToConfirmAction,
|
||||
dataCy: `modal-${MARKETPLACE_APP_ACTIONS.ENABLE}`,
|
||||
},
|
||||
onSubmit: (rows) => async () => {
|
||||
const ids = rows?.map?.(({ original }) => original?.ID)
|
||||
await Promise.all(ids.map((id) => enable(id)))
|
||||
},
|
||||
},
|
||||
{
|
||||
accessor: MARKETPLACE_APP_ACTIONS.DISABLE,
|
||||
name: T.Disable,
|
||||
isConfirmDialog: true,
|
||||
dialogProps: {
|
||||
title: T.Disable,
|
||||
children: MessageToConfirmAction,
|
||||
dataCy: `modal-${MARKETPLACE_APP_ACTIONS.DISABLE}`,
|
||||
},
|
||||
onSubmit: (rows) => async () => {
|
||||
const ids = rows?.map?.(({ original }) => original?.ID)
|
||||
await Promise.all(ids.map((id) => disable(id)))
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
tooltip: T.Ownership,
|
||||
icon: Group,
|
||||
selected: true,
|
||||
color: 'secondary',
|
||||
dataCy: 'vm-ownership',
|
||||
options: [
|
||||
{
|
||||
accessor: MARKETPLACE_APP_ACTIONS.CHANGE_OWNER,
|
||||
name: T.ChangeOwner,
|
||||
dialogProps: {
|
||||
title: T.ChangeOwner,
|
||||
subheader: SubHeader,
|
||||
dataCy: `modal-${MARKETPLACE_APP_ACTIONS.CHANGE_OWNER}`,
|
||||
},
|
||||
form: ChangeUserForm,
|
||||
onSubmit: (rows) => async (newOwnership) => {
|
||||
const ids = rows?.map?.(({ original }) => original?.ID)
|
||||
await Promise.all(
|
||||
ids.map((id) => changeOwnership({ id, ...newOwnership }))
|
||||
)
|
||||
},
|
||||
},
|
||||
{
|
||||
accessor: MARKETPLACE_APP_ACTIONS.CHANGE_GROUP,
|
||||
name: T.ChangeGroup,
|
||||
dialogProps: {
|
||||
title: T.ChangeGroup,
|
||||
subheader: SubHeader,
|
||||
dataCy: `modal-${MARKETPLACE_APP_ACTIONS.CHANGE_GROUP}`,
|
||||
},
|
||||
form: ChangeGroupForm,
|
||||
onSubmit: (rows) => async (newOwnership) => {
|
||||
const ids = rows?.map?.(({ original }) => original?.ID)
|
||||
await Promise.all(
|
||||
ids.map((id) => changeOwnership({ id, ...newOwnership }))
|
||||
)
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
accessor: MARKETPLACE_APP_ACTIONS.DELETE,
|
||||
tooltip: T.Delete,
|
||||
icon: Trash,
|
||||
color: 'error',
|
||||
selected: { min: 1 },
|
||||
options: [
|
||||
{
|
||||
isConfirmDialog: true,
|
||||
dialogProps: {
|
||||
title: T.Delete,
|
||||
dataCy: `modal-${MARKETPLACE_APP_ACTIONS.DELETE}`,
|
||||
children: MessageToConfirmAction,
|
||||
},
|
||||
onSubmit: (rows) => async () => {
|
||||
const ids = rows?.map?.(({ original }) => original?.ID)
|
||||
await Promise.all(ids.map((id) => deleteApp({ id })))
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}),
|
||||
[view]
|
||||
|
@ -374,7 +374,6 @@ const Actions = () => {
|
||||
form: MigrateForm,
|
||||
dialogProps: {
|
||||
title: T.Deploy,
|
||||
subheader: SubHeader,
|
||||
dataCy: `modal-${VM_ACTIONS.DEPLOY}`,
|
||||
},
|
||||
onSubmit: (rows) => async (formData) => {
|
||||
|
@ -68,7 +68,13 @@ const VmConfigurationTab = ({ tabProps: { actions } = {}, id }) => {
|
||||
|
||||
if (isSupported && hasValue) {
|
||||
const name = idx ? `${idx}.${key}` : key
|
||||
sectionAttributes.push({ name, value, dataCy: name })
|
||||
sectionAttributes.push({
|
||||
name,
|
||||
value,
|
||||
dataCy: name,
|
||||
canCopy: true,
|
||||
showActionsOnHover: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -49,6 +49,8 @@ const Content = ({
|
||||
renderContent: RenderContent,
|
||||
hidden,
|
||||
addBorder = false,
|
||||
setTab,
|
||||
logTabId,
|
||||
}) => (
|
||||
<TabContent
|
||||
key={`tab-${id ?? name}`}
|
||||
@ -59,7 +61,7 @@ const Content = ({
|
||||
<Fade in timeout={400}>
|
||||
<TabContent sx={{ p: '1em .5em' }}>
|
||||
{typeof RenderContent === 'function' ? (
|
||||
<RenderContent />
|
||||
<RenderContent setTab={setTab} logTabId={logTabId} />
|
||||
) : (
|
||||
RenderContent
|
||||
)}
|
||||
@ -129,6 +131,12 @@ const Tabs = ({
|
||||
[tabSelected]
|
||||
)
|
||||
|
||||
const logTabId = tabs
|
||||
.map(function (tabProps) {
|
||||
return tabProps.name
|
||||
})
|
||||
.indexOf('log')
|
||||
|
||||
return (
|
||||
<Stack height={1} overflow="auto">
|
||||
<Fade in timeout={300}>
|
||||
@ -139,7 +147,9 @@ const Tabs = ({
|
||||
) : (
|
||||
<Content
|
||||
addBorder={addBorder}
|
||||
setTab={setTab}
|
||||
{...tabs.find(({ value }, idx) => (value ?? idx) === tabSelected)}
|
||||
logTabId={logTabId}
|
||||
/>
|
||||
)}
|
||||
</Stack>
|
||||
@ -162,6 +172,8 @@ Content.propTypes = {
|
||||
renderContent: PropTypes.oneOfType([PropTypes.object, PropTypes.func]),
|
||||
hidden: PropTypes.bool,
|
||||
addBorder: PropTypes.bool,
|
||||
setTab: PropTypes.func,
|
||||
logTabId: PropTypes.number,
|
||||
}
|
||||
|
||||
export default Tabs
|
||||
|
@ -56,6 +56,8 @@ export const MARKETPLACE_APP_ACTIONS = {
|
||||
DISABLE: 'disable',
|
||||
DELETE: 'delete',
|
||||
EDIT_LABELS: 'edit_labels',
|
||||
LOCK: 'lock',
|
||||
UNLOCK: 'unlock',
|
||||
|
||||
// INFORMATION
|
||||
RENAME: ACTIONS.RENAME,
|
||||
|
@ -305,6 +305,7 @@ module.exports = {
|
||||
LabelAlreadyExists: 'Label already exists',
|
||||
PressToCreateLabel: 'Press enter to create a new label',
|
||||
SavesInTheUserTemplate: "Saved in the User's template",
|
||||
NoLabelsOnList: 'You have not defined any labels, list is empty',
|
||||
|
||||
/* sections - system */
|
||||
User: 'User',
|
||||
|
@ -38,7 +38,7 @@ import { SubmitButton } from 'client/components/FormControl'
|
||||
import { Translate } from 'client/components/HOC'
|
||||
import { T } from 'client/constants'
|
||||
|
||||
const Hosts = memo(({ id }) => {
|
||||
const Hosts = memo(({ id, setTab, logTabId }) => {
|
||||
const [amount, setAmount] = useState(() => 1)
|
||||
const { enqueueInfo } = useGeneralApi()
|
||||
|
||||
@ -113,6 +113,7 @@ const Hosts = memo(({ id }) => {
|
||||
onClick={async () => {
|
||||
configureHost({ provision: id, id: host.ID })
|
||||
enqueueInfo(`Configuring host - ID: ${host.ID}`)
|
||||
setTab(logTabId)
|
||||
}}
|
||||
/>
|
||||
<SubmitButton
|
||||
@ -137,7 +138,11 @@ const Hosts = memo(({ id }) => {
|
||||
)
|
||||
})
|
||||
|
||||
Hosts.propTypes = { id: PropTypes.string.isRequired }
|
||||
Hosts.propTypes = {
|
||||
id: PropTypes.string.isRequired,
|
||||
setTab: PropTypes.func,
|
||||
logTabId: PropTypes.number,
|
||||
}
|
||||
Hosts.displayName = 'Hosts'
|
||||
|
||||
export default Hosts
|
||||
|
@ -63,7 +63,9 @@ const DialogInfo = ({ id }) => {
|
||||
name: 'hosts',
|
||||
label: T.Hosts,
|
||||
icon: HostIcon,
|
||||
renderContent: () => <HostsTab id={id} />,
|
||||
renderContent: ({ setTab, logTabId }) => (
|
||||
<HostsTab id={id} setTab={setTab} logTabId={logTabId} />
|
||||
),
|
||||
},
|
||||
{
|
||||
name: 'log',
|
||||
|
@ -123,7 +123,7 @@ const Settings = () => {
|
||||
<Stack height={1} gap="0.5rem" p="0.5rem" overflow="auto">
|
||||
{labels.length === 0 && (
|
||||
<Typography variant="subtitle2">
|
||||
<Translate word={T.NoLabels} />
|
||||
<Translate word={T.NoLabelsOnList} />
|
||||
</Typography>
|
||||
)}
|
||||
{result?.map((label) => (
|
||||
|
@ -484,6 +484,23 @@ const marketAppApi = oneApi.injectEndpoints({
|
||||
},
|
||||
invalidatesTags: [APP_POOL],
|
||||
}),
|
||||
deleteApp: builder.mutation({
|
||||
/**
|
||||
* Delete Marketplaceapp.
|
||||
*
|
||||
* @param {object} params - Request parameters
|
||||
* @param {string} params.id - Marketplaceapp ID
|
||||
* @returns {number} Marketplace app id
|
||||
* @throws Fails when response isn't code 200
|
||||
*/
|
||||
query: (params) => {
|
||||
const name = Actions.MARKETAPP_DELETE
|
||||
const command = { name, ...Commands[name] }
|
||||
|
||||
return { params, command }
|
||||
},
|
||||
invalidatesTags: (_, __, { id }) => [{ type: APP, id }],
|
||||
}),
|
||||
downloadApp: builder.mutation({
|
||||
/**
|
||||
* Download a MarketPlaceApp.
|
||||
@ -559,6 +576,7 @@ export const {
|
||||
useImportAppMutation,
|
||||
useExportAppMutation,
|
||||
useDownloadAppMutation,
|
||||
useDeleteAppMutation,
|
||||
} = marketAppApi
|
||||
|
||||
export default marketAppApi
|
||||
|
@ -315,7 +315,7 @@ export const getAvailableInfoTabs = (infoTabs = {}, getTabComponent, id) =>
|
||||
|
||||
return (
|
||||
TabContent && {
|
||||
name: camelName,
|
||||
label: camelName,
|
||||
id: tabName,
|
||||
renderContent: () => <TabContent tabProps={tabProps} id={id} />,
|
||||
}
|
||||
|
@ -45,10 +45,6 @@ const {
|
||||
|
||||
const { ok, unauthorized, accepted, internalServerError } = httpCodes
|
||||
|
||||
const appConfig = getFireedgeConfig()
|
||||
|
||||
const namespace = appConfig.namespace || defaultNamespace
|
||||
|
||||
const { GET } = httpMethod
|
||||
|
||||
let user = ''
|
||||
@ -200,6 +196,7 @@ const setRes = (newRes = {}) => {
|
||||
* Set dates.
|
||||
*/
|
||||
const setDates = () => {
|
||||
const appConfig = getFireedgeConfig()
|
||||
limitToken = remember
|
||||
? appConfig.session_remember_expiration || defaultRememberSessionExpiration
|
||||
: appConfig.session_expiration || defaultSessionExpiration
|
||||
@ -314,13 +311,7 @@ const genJWT = (token, informationUser) => {
|
||||
* @returns {object} - user token
|
||||
*/
|
||||
const getCreatedTokenOpennebula = (username = '') => {
|
||||
if (
|
||||
global &&
|
||||
global.users &&
|
||||
username &&
|
||||
global.users[username] &&
|
||||
global.users[username].tokens
|
||||
) {
|
||||
if (username && global?.users?.[username]?.tokens) {
|
||||
let acc = { token: '', time: 0 }
|
||||
global.users[username].tokens.forEach((curr = {}, index = 0) => {
|
||||
const currentTime = parseInt(curr.time, 10)
|
||||
@ -550,6 +541,8 @@ const getServerAdminAndWrapUser = (userData = {}) => {
|
||||
const login = (userData) => {
|
||||
let rtn = false
|
||||
if (userData) {
|
||||
const appConfig = getFireedgeConfig()
|
||||
const namespace = appConfig.namespace || defaultNamespace
|
||||
const findTextError = `[${namespace}.${ActionUsers.USER_INFO}]`
|
||||
if (userData.indexOf && userData.indexOf(findTextError) >= 0) {
|
||||
updaterResponse(httpResponse(unauthorized))
|
||||
|
@ -14,6 +14,7 @@
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
const { env } = require('process')
|
||||
const { DateTime } = require('luxon')
|
||||
const { httpCodes, defaults } = require('server/utils/constants')
|
||||
const { getFireedgeConfig } = require('server/utils/yml')
|
||||
const { defaultWebpackMode, defaultEmptyFunction, defaultOpennebulaZones } =
|
||||
@ -33,16 +34,16 @@ let passOpennebula = ''
|
||||
* @returns {boolean} user valid data
|
||||
*/
|
||||
const userValidation = (user = '', token = '') => {
|
||||
const nowUnix = DateTime.local().toSeconds()
|
||||
let rtn = false
|
||||
if (
|
||||
user &&
|
||||
token &&
|
||||
global &&
|
||||
global.users &&
|
||||
global.users[user] &&
|
||||
global.users[user].tokens &&
|
||||
Array.isArray(global.users[user].tokens) &&
|
||||
global.users[user].tokens.some((x) => x && x.token === token)
|
||||
Array.isArray(global?.users?.[user]?.tokens) &&
|
||||
global?.users?.[user]?.tokens?.some?.(
|
||||
({ token: internalToken, time }) =>
|
||||
time > nowUnix && internalToken === token
|
||||
)
|
||||
) {
|
||||
rtn = true
|
||||
}
|
||||
|
@ -158,11 +158,11 @@ module.exports = {
|
||||
from: resource,
|
||||
default: 0,
|
||||
},
|
||||
userId: {
|
||||
user: {
|
||||
from: postBody,
|
||||
default: -1,
|
||||
},
|
||||
groupId: {
|
||||
group: {
|
||||
from: postBody,
|
||||
default: -1,
|
||||
},
|
||||
|
@ -38,7 +38,7 @@ string HookStateVirtualNetwork::format_message(VirtualNetwork * vn)
|
||||
|
||||
oss << "<HOOK_MESSAGE>"
|
||||
<< "<HOOK_TYPE>STATE</HOOK_TYPE>"
|
||||
<< "<HOOK_OBJECT>VNET</HOOK_OBJECT>"
|
||||
<< "<HOOK_OBJECT>NET</HOOK_OBJECT>"
|
||||
<< "<STATE>" << VirtualNetwork::state_to_str(vn->get_state()) << "</STATE>"
|
||||
<< "<RESOURCE_ID>" << vn->get_oid() << "</RESOURCE_ID>"
|
||||
<< vn->to_xml(vn_xml)
|
||||
|
Loading…
x
Reference in New Issue
Block a user