Skip to content
GitLab
Explore
Sign in
Show whitespace changes
Inline
Side-by-side
Some changes are not shown.
For a faster browsing experience, only
20 of 384+
files are shown.
src/context/service/database/Device.py
View file @
8c03968b
...
...
@@ -21,7 +21,9 @@ from typing import Dict, List, Optional, Set, Tuple
from
common.method_wrappers.ServiceExceptions
import
InvalidArgumentException
,
NotFoundException
from
common.message_broker.MessageBroker
import
MessageBroker
from
common.proto.context_pb2
import
(
Device
,
DeviceFilter
,
DeviceId
,
DeviceIdList
,
DeviceList
,
Empty
,
EventTypeEnum
,
TopologyId
)
Device
,
DeviceDriverEnum
,
DeviceFilter
,
DeviceId
,
DeviceIdList
,
DeviceList
,
Empty
,
EventTypeEnum
,
TopologyId
)
from
common.tools.grpc.Tools
import
grpc_message_to_json_string
from
common.tools.object_factory.Device
import
json_device_id
from
context.service.database.uuids.Topology
import
topology_get_uuid
...
...
@@ -103,10 +105,12 @@ def device_set(db_engine : Engine, messagebroker : MessageBroker, request : Devi
})
topology_uuids
.
add
(
topology_uuid
)
is_oc_driver
=
DeviceDriverEnum
.
DEVICEDRIVER_OC
in
set
(
request
.
device_drivers
)
endpoints_data
:
List
[
Dict
]
=
list
()
for
i
,
endpoint
in
enumerate
(
request
.
device_endpoints
):
endpoint_device_uuid
=
endpoint
.
endpoint_id
.
device_id
.
device_uuid
.
uuid
if
len
(
endpoint_device_uuid
)
==
0
:
endpoint_device_uuid
=
device_uuid
if
len
(
endpoint_device_uuid
)
==
0
or
is_oc_driver
:
endpoint_device_uuid
=
device_uuid
if
endpoint_device_uuid
not
in
{
raw_device_uuid
,
device_uuid
}:
raise
InvalidArgumentException
(
'
request.device_endpoints[{:d}].device_id.device_uuid.uuid
'
.
format
(
i
),
endpoint_device_uuid
,
...
...
@@ -132,6 +136,7 @@ def device_set(db_engine : Engine, messagebroker : MessageBroker, request : Devi
'
created_at
'
:
now
,
'
updated_at
'
:
now
,
})
LOGGER
.
info
(
f
"
endpoint data
{
endpoints_data
}
"
)
if
endpoint_topology_uuid
not
in
topology_uuids
:
related_topologies
.
append
({
...
...
@@ -199,15 +204,15 @@ def device_set(db_engine : Engine, messagebroker : MessageBroker, request : Devi
stmt
=
stmt
.
returning
(
TopologyDeviceModel
.
topology_uuid
)
topology_uuids
=
session
.
execute
(
stmt
).
fetchall
()
LOGGER
.
warning
(
'
RAW topology_uuids={:s}
'
.
format
(
str
(
topology_uuids
)))
#
LOGGER.warning('RAW topology_uuids={:s}'.format(str(topology_uuids)))
if
len
(
topology_uuids
)
>
0
:
topology_uuids
=
[
topology_uuid
[
0
]
for
topology_uuid
in
topology_uuids
]
LOGGER
.
warning
(
'
NEW topology_uuids={:s}
'
.
format
(
str
(
topology_uuids
)))
#
LOGGER.warning('NEW topology_uuids={:s}'.format(str(topology_uuids)))
query
=
session
.
query
(
TopologyModel
)
query
=
query
.
filter
(
TopologyModel
.
topology_uuid
.
in_
(
topology_uuids
))
device_topologies
:
List
[
TopologyModel
]
=
query
.
all
()
device_topology_ids
=
[
obj
.
dump_id
()
for
obj
in
device_topologies
]
LOGGER
.
warning
(
'
device_topology_ids={:s}
'
.
format
(
str
(
device_topology_ids
)))
#
LOGGER.warning('device_topology_ids={:s}'.format(str(device_topology_ids)))
updated_components
=
False
...
...
@@ -229,7 +234,7 @@ def device_set(db_engine : Engine, messagebroker : MessageBroker, request : Devi
changed_config_rules
=
upsert_config_rules
(
session
,
config_rules
,
device_uuid
=
device_uuid
)
return
updated
or
updated_endpoints
or
changed_config_rules
,
device_topology_ids
return
updated
or
updated_endpoints
or
updated_components
or
changed_config_rules
,
device_topology_ids
updated
,
device_topology_ids
=
run_transaction
(
sessionmaker
(
bind
=
db_engine
),
callback
)
device_id
=
json_device_id
(
device_uuid
)
...
...
src/context/service/database/Events.py
View file @
8c03968b
...
...
@@ -17,7 +17,8 @@ from typing import Dict, Iterator, Set
from
common.message_broker.Message
import
Message
from
common.message_broker.MessageBroker
import
MessageBroker
from
common.proto.context_pb2
import
(
ConnectionEvent
,
ContextEvent
,
DeviceEvent
,
EventTypeEnum
,
LinkEvent
,
ServiceEvent
,
SliceEvent
,
TopologyEvent
)
ConnectionEvent
,
ContextEvent
,
DeviceEvent
,
EventTypeEnum
,
LinkEvent
,
ServiceEvent
,
SliceEvent
,
TopologyEvent
,
OpticalConfigEvent
)
class
EventTopicEnum
(
enum
.
Enum
):
CONNECTION
=
'
connection
'
...
...
@@ -28,6 +29,8 @@ class EventTopicEnum(enum.Enum):
SERVICE
=
'
service
'
SLICE
=
'
slice
'
TOPOLOGY
=
'
topology
'
OPTICALCONFIG
=
'
optical-config
'
TOPIC_TO_EVENTCLASS
=
{
EventTopicEnum
.
CONNECTION
.
value
:
ConnectionEvent
,
...
...
@@ -38,6 +41,8 @@ TOPIC_TO_EVENTCLASS = {
EventTopicEnum
.
SERVICE
.
value
:
ServiceEvent
,
EventTopicEnum
.
SLICE
.
value
:
SliceEvent
,
EventTopicEnum
.
TOPOLOGY
.
value
:
TopologyEvent
,
EventTopicEnum
.
OPTICALCONFIG
.
value
:
OpticalConfigEvent
}
CONSUME_TIMEOUT
=
0.5
# seconds
...
...
@@ -61,6 +66,10 @@ def notify_event_topology(messagebroker : MessageBroker, event_type : EventTypeE
def
notify_event_device
(
messagebroker
:
MessageBroker
,
event_type
:
EventTypeEnum
,
device_id
:
Dict
)
->
None
:
notify_event
(
messagebroker
,
EventTopicEnum
.
DEVICE
,
event_type
,
{
'
device_id
'
:
device_id
})
def
notify_event_opticalconfig
(
messagebroker
:
MessageBroker
,
event_type
:
EventTypeEnum
,
opticalconfig_id
:
Dict
)
->
None
:
notify_event
(
messagebroker
,
EventTopicEnum
.
DEVICE
,
event_type
,
{
'
opticalconfig_id
'
:
opticalconfig_id
})
def
notify_event_link
(
messagebroker
:
MessageBroker
,
event_type
:
EventTypeEnum
,
link_id
:
Dict
)
->
None
:
notify_event
(
messagebroker
,
EventTopicEnum
.
LINK
,
event_type
,
{
'
link_id
'
:
link_id
})
...
...
src/context/service/database/Link.py
View file @
8c03968b
...
...
@@ -159,15 +159,15 @@ def link_set(db_engine : Engine, messagebroker : MessageBroker, request : Link)
stmt
=
stmt
.
returning
(
TopologyLinkModel
.
topology_uuid
)
topology_uuids
=
session
.
execute
(
stmt
).
fetchall
()
LOGGER
.
warning
(
'
RAW topology_uuids={:s}
'
.
format
(
str
(
topology_uuids
)))
#
LOGGER.warning('RAW topology_uuids={:s}'.format(str(topology_uuids)))
if
len
(
topology_uuids
)
>
0
:
topology_uuids
=
[
topology_uuid
[
0
]
for
topology_uuid
in
topology_uuids
]
LOGGER
.
warning
(
'
NEW topology_uuids={:s}
'
.
format
(
str
(
topology_uuids
)))
#
LOGGER.warning('NEW topology_uuids={:s}'.format(str(topology_uuids)))
query
=
session
.
query
(
TopologyModel
)
query
=
query
.
filter
(
TopologyModel
.
topology_uuid
.
in_
(
topology_uuids
))
link_topologies
:
List
[
TopologyModel
]
=
query
.
all
()
link_topology_ids
=
[
obj
.
dump_id
()
for
obj
in
link_topologies
]
LOGGER
.
warning
(
'
link_topology_ids={:s}
'
.
format
(
str
(
link_topology_ids
)))
#
LOGGER.warning('link_topology_ids={:s}'.format(str(link_topology_ids)))
return
updated
or
updated_endpoints
,
link_topology_ids
...
...
src/context/service/database/OpticalConfig.py
0 → 100644
View file @
8c03968b
# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
#
# 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.
import
json
,
logging
from
sqlalchemy.dialects.postgresql
import
insert
from
common.message_broker.MessageBroker
import
MessageBroker
from
sqlalchemy.engine
import
Engine
from
sqlalchemy.orm
import
Session
,
sessionmaker
from
sqlalchemy_cockroachdb
import
run_transaction
from
common.proto.context_pb2
import
OpticalConfig
,
OpticalConfigId
,
Empty
,
EventTypeEnum
from
.models.OpticalConfigModel
import
OpticalConfigModel
,
OpticalChannelModel
from
context.service.database.uuids.OpticalConfig
import
channel_get_uuid
from
.Events
import
notify_event_opticalconfig
LOGGER
=
logging
.
getLogger
(
__name__
)
def
get_opticalconfig
(
db_engine
:
Engine
):
def
callback
(
session
:
Session
):
optical_configs
=
list
()
results
=
session
.
query
(
OpticalConfigModel
).
all
()
for
obj
in
results
:
LOGGER
.
info
(
f
"
opticaln config obj from context
{
obj
.
dump
()
}
"
)
optical_config
=
OpticalConfig
()
optical_config
.
config
=
json
.
dumps
(
obj
.
dump
())
optical_config
.
opticalconfig_id
.
opticalconfig_uuid
=
obj
.
dump_id
()[
"
opticalconfig_uuid
"
]
optical_configs
.
append
(
optical_config
)
return
optical_configs
obj
=
run_transaction
(
sessionmaker
(
bind
=
db_engine
),
callback
)
return
obj
def
set_opticalconfig
(
db_engine
:
Engine
,
request
:
OpticalConfig
):
LOGGER
.
info
(
f
"
request
{
request
}
"
)
opticalconfig_id
=
OpticalConfigId
()
opticalconfig_id
.
opticalconfig_uuid
=
request
.
opticalconfig_id
.
opticalconfig_uuid
OpticalConfig_data
=
[]
if
request
.
config
:
channels
=
[]
transceivers
=
[]
config
=
json
.
loads
(
request
.
config
)
if
'
transceivers
'
in
config
and
len
(
config
[
'
transceivers
'
][
'
transceiver
'
])
>
0
:
transceivers
=
[
transceiver
for
transceiver
in
config
[
'
transceivers
'
][
'
transceiver
'
]]
if
'
channels
'
in
config
and
len
(
config
[
'
channels
'
])
>
0
:
#channels = [channel['name']['index'] for channel in config['channels']]
for
channel_params
in
config
[
'
channels
'
]:
channels
.
append
(
{
"
channel_uuid
"
:
channel_get_uuid
(
channel_params
[
'
name
'
][
'
index
'
]),
"
opticalconfig_uuid
"
:
request
.
opticalconfig_id
.
opticalconfig_uuid
,
"
channel_name
"
:
channel_params
[
'
name
'
][
'
index
'
],
"
frequency
"
:
int
(
channel_params
[
"
frequency
"
])
if
"
frequency
"
in
channel_params
else
0
,
"
operational_mode
"
:
int
(
channel_params
[
"
operational-mode
"
])
if
"
operational-mode
"
in
channel_params
else
0
,
"
target_output_power
"
:
channel_params
[
"
target-output-power
"
]
if
"
target-output-power
"
in
channel_params
else
''
,
}
)
OpticalConfig_data
.
append
(
{
"
opticalconfig_uuid
"
:
request
.
opticalconfig_id
.
opticalconfig_uuid
,
"
transcievers
"
:
transceivers
,
"
interfaces
"
:
json
.
dumps
(
config
[
"
interfaces
"
][
"
interface
"
]),
"
channel_namespace
"
:
config
[
"
channel_namespace
"
],
"
endpoints
"
:
[
json
.
dumps
(
endpoint
)
for
endpoint
in
config
[
"
endpoints
"
]],}
)
LOGGER
.
info
(
f
"
optical config to set
{
OpticalConfig_data
}
"
)
LOGGER
.
info
(
f
"
channels
{
channels
}
"
)
def
callback
(
session
:
Session
)
->
bool
:
stmt
=
insert
(
OpticalConfigModel
).
values
(
OpticalConfig_data
)
stmt
=
stmt
.
on_conflict_do_update
(
index_elements
=
[
OpticalConfigModel
.
opticalconfig_uuid
],
set_
=
dict
(
channel_namespace
=
stmt
.
excluded
.
channel_namespace
)
)
stmt
=
stmt
.
returning
(
OpticalConfigModel
.
opticalconfig_uuid
)
opticalconfig_id
=
session
.
execute
(
stmt
).
fetchone
()
if
(
len
(
channels
)
>
0
)
:
stmt
=
insert
(
OpticalChannelModel
).
values
(
channels
)
stmt
=
stmt
.
on_conflict_do_update
(
index_elements
=
[
OpticalChannelModel
.
channel_uuid
,
OpticalConfigModel
.
opticalconfig_uuid
],
set_
=
dict
(
channel_name
=
stmt
.
excluded
.
channel_name
,
frequency
=
stmt
.
excluded
.
frequency
,
operational_mode
=
stmt
.
excluded
.
operational_mode
,
target_output_power
=
stmt
.
excluded
.
target_output_power
,
)
)
stmt
=
stmt
.
returning
(
OpticalChannelModel
.
channel_uuid
)
opticalChannel_id
=
session
.
execute
(
stmt
).
fetchone
()
LOGGER
.
info
(
f
"
new optical channel config
{
opticalChannel_id
}
"
)
opticalconfig_id
=
run_transaction
(
sessionmaker
(
bind
=
db_engine
),
callback
)
return
{
'
opticalconfig_uuid
'
:
opticalconfig_id
}
def
select_opticalconfig
(
db_engine
:
Engine
,
request
:
OpticalConfigId
):
def
callback
(
session
:
Session
)
->
OpticalConfig
:
result
=
OpticalConfig
()
stmt
=
session
.
query
(
OpticalConfigModel
)
stmt
=
stmt
.
filter_by
(
opticalconfig_uuid
=
request
.
opticalconfig_uuid
)
obj
=
stmt
.
first
()
if
obj
is
not
None
:
result
.
config
=
json
.
dumps
(
obj
.
dump
())
result
.
opticalconfig_id
.
opticalconfig_uuid
=
obj
.
opticalconfig_uuid
return
result
return
run_transaction
(
sessionmaker
(
bind
=
db_engine
,
expire_on_commit
=
False
),
callback
)
def
delete_opticalconfig
(
db_engine
:
Engine
,
messagebroker
:
MessageBroker
,
request
:
OpticalConfigId
):
opticalconfig_uuid
=
request
.
opticalconfig_uuid
def
callback
(
session
:
Session
):
query
=
session
.
query
(
OpticalConfigModel
)
num_deleted
=
session
.
query
(
OpticalConfigModel
).
filter_by
(
opticalconfig_uuid
=
opticalconfig_uuid
).
delete
()
return
num_deleted
>
0
deleted
=
run_transaction
(
sessionmaker
(
bind
=
db_engine
),
callback
)
if
deleted
:
notify_event_opticalconfig
(
messagebroker
,
EventTypeEnum
.
EVENTTYPE_REMOVE
,
opticalconfig_uuid
)
return
Empty
()
src/context/service/database/Service.py
View file @
8c03968b
...
...
@@ -20,7 +20,9 @@ from sqlalchemy.orm import Session, selectinload, sessionmaker
from
sqlalchemy_cockroachdb
import
run_transaction
from
typing
import
Dict
,
List
,
Optional
,
Set
from
common.proto.context_pb2
import
(
ContextId
,
Empty
,
EventTypeEnum
,
Service
,
ServiceFilter
,
ServiceId
,
ServiceIdList
,
ServiceList
)
ContextId
,
Empty
,
EventTypeEnum
,
Service
,
ServiceFilter
,
ServiceId
,
ServiceIdList
,
ServiceList
,
ServiceTypeEnum
)
from
common.message_broker.MessageBroker
import
MessageBroker
from
common.method_wrappers.ServiceExceptions
import
InvalidArgumentException
,
NotFoundException
from
common.tools.object_factory.Context
import
json_context_id
...
...
@@ -84,6 +86,9 @@ def service_set(db_engine : Engine, messagebroker : MessageBroker, request : Ser
context_uuid
,
service_uuid
=
service_get_uuid
(
request
.
service_id
,
service_name
=
service_name
,
allow_random
=
True
)
service_type
=
grpc_to_enum__service_type
(
request
.
service_type
)
if
service_type
is
None
and
request
.
service_type
==
ServiceTypeEnum
.
SERVICETYPE_OPTICAL_CONNECTIVITY
:
service_type
=
"
OPTICAL_CONNECTIVITY
"
service_status
=
grpc_to_enum__service_status
(
request
.
service_status
.
service_status
)
now
=
datetime
.
datetime
.
utcnow
()
...
...
src/context/service/database/models/OpticalConfigModel.py
0 → 100644
View file @
8c03968b
# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
#
# 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.
import
json
from
sqlalchemy
import
Column
,
String
,
Integer
,
ForeignKey
from
sqlalchemy.dialects.postgresql
import
ARRAY
from
sqlalchemy.orm
import
relationship
from
._Base
import
_Base
class
OpticalConfigModel
(
_Base
):
__tablename__
=
'
optical_config
'
opticalconfig_uuid
=
Column
(
String
,
primary_key
=
True
)
transcievers
=
Column
(
ARRAY
(
String
),
nullable
=
True
)
interfaces
=
Column
(
String
,
nullable
=
True
)
channel_namespace
=
Column
(
String
,
nullable
=
True
)
endpoints
=
Column
(
ARRAY
(
String
),
nullable
=
True
)
channels
=
relationship
(
"
OpticalChannelModel
"
)
def
dump_id
(
self
):
return
{
"
opticalconfig_uuid
"
:
self
.
opticalconfig_uuid
}
def
dump
(
self
):
return
{
"
channels
"
:
[
channel
.
dump
()
for
channel
in
self
.
channels
],
"
transceivers
"
:
{
"
transceiver
"
:
[
transciever
for
transciever
in
self
.
transcievers
]},
"
interfaces
"
:
{
"
interface
"
:
json
.
loads
(
self
.
interfaces
)},
"
channel_namespace
"
:
self
.
channel_namespace
,
"
endpoints
"
:
[
json
.
loads
(
endpoint
)
for
endpoint
in
self
.
endpoints
],
}
class
OpticalChannelModel
(
_Base
):
__tablename__
=
'
optical_channel
'
channel_uuid
=
Column
(
String
,
primary_key
=
True
)
channel_name
=
Column
(
String
,
nullable
=
True
)
frequency
=
Column
(
Integer
,
nullable
=
True
)
operational_mode
=
Column
(
Integer
,
nullable
=
True
)
target_output_power
=
Column
(
String
,
nullable
=
True
)
opticalconfig_uuid
=
Column
(
ForeignKey
(
'
optical_config.opticalconfig_uuid
'
,
ondelete
=
'
CASCADE
'
),
primary_key
=
True
)
opticalconfig
=
relationship
(
'
OpticalConfigModel
'
,
back_populates
=
'
channels
'
)
def
dump_id
(
self
):
return
{
"
channel_uuid
"
:
self
.
channel_uuid
}
def
dump
(
self
):
return
{
"
name
"
:{
'
index
'
:
self
.
channel_name
},
"
frequency
"
:
self
.
frequency
,
"
target-output-power
"
:
self
.
target_output_power
,
"
operational-mode
"
:
self
.
operational_mode
,
}
src/context/service/database/models/OpticalLinkModel.py
0 → 100644
View file @
8c03968b
import
operator
from
sqlalchemy
import
CheckConstraint
,
Column
,
DateTime
,
Float
,
ForeignKey
,
Integer
,
String
,
Boolean
from
sqlalchemy.dialects.postgresql
import
UUID
from
sqlalchemy.types
import
ARRAY
from
sqlalchemy.orm
import
relationship
from
typing
import
Dict
from
._Base
import
_Base
class
OpticalLinkModel
(
_Base
):
__tablename__
=
'
opticallink
'
optical_link_uuid
=
Column
(
UUID
(
as_uuid
=
False
),
primary_key
=
True
)
optical_link_name
=
Column
(
String
,
nullable
=
False
)
length
=
Column
(
Integer
,
nullable
=
True
)
source
=
Column
(
String
,
nullable
=
True
)
target
=
Column
(
String
,
nullable
=
True
)
optical_link_fiber
=
relationship
(
"
FiberModel
"
)
created_at
=
Column
(
DateTime
,
nullable
=
False
)
updated_at
=
Column
(
DateTime
,
nullable
=
False
)
def
dump_id
(
self
)
->
Dict
:
return
{
'
optical_link_uuid
'
:
{
'
uuid
'
:
self
.
link_uuid
}}
def
dump
(
self
)
->
Dict
:
result
=
{
'
optical_link_id
'
:
self
.
dump_id
(),
'
name
'
:
self
.
optical_link_name
,
'
details
'
:
{
"
length
"
:
self
.
length
,
'
source
'
:
self
.
source
,
"
target
"
:
self
.
target
,
'
fibers
'
:
[
fiber
.
dump
()
for
fiber
in
self
.
optical_link_fiber
]
}
}
return
result
class
FiberModel
(
_Base
):
__tablename__
=
'
fiber
'
fiber_uuid
=
Column
(
UUID
(
as_uuid
=
False
),
primary_key
=
True
)
fiber_length
=
Column
(
Integer
,
nullable
=
True
)
source_port
=
Column
(
String
,
nullable
=
True
)
destination_port
=
Column
(
String
,
nullable
=
True
)
local_peer_port
=
Column
(
String
,
nullable
=
True
)
remote_peer_port
=
Column
(
String
,
nullable
=
True
)
used
=
Column
(
Boolean
,
nullable
=
true
)
c_slots
=
Column
(
ARRAY
(
Integer
),
nullable
=
True
)
l_slots
=
Column
(
ARRAY
(
Integer
),
nullable
=
True
)
s_slots
=
Column
(
ARRAY
(
Integer
),
nullable
=
True
)
optical_link_uuid
=
Column
(
ForeignKey
(
'
opticallink.optical_link_uuid
'
,
ondelete
=
'
CASCADE
'
),
primary_key
=
True
)
optical_link
=
relationship
(
'
OpticalLinkModel
'
,
back_populates
=
'
optical_link_fibers
'
)
def
dump_id
(
self
)
->
Dict
:
return
{
'
fiber_uuid
'
:
{
'
uuid
'
:
self
.
fiber_uuid
}}
def
dump
(
self
)
->
Dict
:
result
=
{
'
ID
'
:
self
.
dump_id
(),
'
length
'
:
self
.
fiber_length
,
"
src_port
"
:
self
.
source_port
,
"
dst_port
"
:
self
.
destination_port
,
"
local_peer_port
"
:
self
.
local_peer_port
,
"
remote_peer_port
"
:
self
.
remote_peer_port
,
"
used
"
:
self
.
used
,
"
c_slots
"
:
self
.
c_slots
,
"
l_slots
"
:
self
.
l_slots
,
"
s_slots
"
:
self
.
s_slots
}
return
result
\ No newline at end of file
src/context/service/database/models/enums/DeviceDriver.py
View file @
8c03968b
...
...
@@ -33,6 +33,7 @@ class ORM_DeviceDriverEnum(enum.Enum):
GNMI_OPENCONFIG
=
DeviceDriverEnum
.
DEVICEDRIVER_GNMI_OPENCONFIG
FLEXSCALE
=
DeviceDriverEnum
.
DEVICEDRIVER_FLEXSCALE
IETF_ACTN
=
DeviceDriverEnum
.
DEVICEDRIVER_IETF_ACTN
OC
=
DeviceDriverEnum
.
DEVICEDRIVER_OC
grpc_to_enum__device_driver
=
functools
.
partial
(
grpc_to_enum
,
DeviceDriverEnum
,
ORM_DeviceDriverEnum
)
src/context/service/database/models/enums/ServiceType.py
View file @
8c03968b
...
...
@@ -28,6 +28,7 @@ class ORM_ServiceTypeEnum(enum.Enum):
TAPI_CONNECTIVITY_SERVICE
=
ServiceTypeEnum
.
SERVICETYPE_TAPI_CONNECTIVITY_SERVICE
TE
=
ServiceTypeEnum
.
SERVICETYPE_TE
E2E
=
ServiceTypeEnum
.
SERVICETYPE_E2E
OPTICAL_CONNECTIVITY
=
ServiceTypeEnum
.
SERVICETYPE_OPTICAL_CONNECTIVITY
grpc_to_enum__service_type
=
functools
.
partial
(
grpc_to_enum
,
ServiceTypeEnum
,
ORM_ServiceTypeEnum
)
src/context/service/database/models/enums/_GrpcToEnum.py
View file @
8c03968b
...
...
@@ -14,16 +14,21 @@
import
re
from
enum
import
Enum
from
typing
import
Optional
from
typing
import
Any
,
Optional
# Enumeration classes are redundant with gRPC classes, but gRPC does not provide a programmatical method to retrieve
# the values it expects from strings containing the desired value symbol or its integer value, so a kind of mapping is
# required. Besides, ORM Models expect Enum classes in EnumeratedFields; we create specific and conveniently defined
# Enum classes to serve both purposes.
def
grpc_to_enum
(
grpc_enum_class
,
orm_enum_class
:
Enum
,
grpc_enum_value
,
grpc_enum_prefix
:
Optional
[
str
]
=
None
):
def
grpc_to_enum
(
grpc_enum_class
,
orm_enum_class
:
Enum
,
grpc_enum_value
,
grpc_enum_prefix
:
Optional
[
str
]
=
None
,
fail_if_not_found
:
bool
=
False
)
->
Optional
[
Any
]:
enum_name
=
grpc_enum_class
.
Name
(
grpc_enum_value
)
_orig_enum_name
=
enum_name
_orig_grpc_enum_prefix
=
grpc_enum_prefix
if
grpc_enum_prefix
is
None
:
grpc_enum_prefix
=
orm_enum_class
.
__name__
.
upper
()
#grpc_enum_prefix = re.sub(r'^ORM_(.+)$', r'\1', grpc_enum_prefix)
...
...
@@ -35,4 +40,7 @@ def grpc_to_enum(grpc_enum_class, orm_enum_class : Enum, grpc_enum_value, grpc_e
enum_name
=
enum_name
.
replace
(
grpc_enum_prefix
,
''
)
orm_enum_value
=
orm_enum_class
.
_member_map_
.
get
(
enum_name
)
if
orm_enum_value
is
None
and
fail_if_not_found
:
MSG
=
'
Unable to map gRPC Enum Value ({:s} / {:s}) to ORM Enum Value; grpc_enum_prefix={:s}
'
raise
Exception
(
MSG
.
format
(
str
(
grpc_enum_value
),
str
(
_orig_enum_name
),
str
(
_orig_grpc_enum_prefix
)))
return
orm_enum_value
src/context/service/database/uuids/OpticalConfig.py
0 → 100644
View file @
8c03968b
from
common.method_wrappers.ServiceExceptions
import
InvalidArgumentsException
from
._Builder
import
get_uuid_from_string
,
get_uuid_random
def
channel_get_uuid
(
channel_name
:
str
,
allow_random
:
bool
=
False
)
->
str
:
if
len
(
channel_name
)
>
0
:
return
get_uuid_from_string
(
channel_name
)
if
allow_random
:
return
get_uuid_random
()
raise
InvalidArgumentsException
([
(
'
channel uuid
'
,
channel_name
),
],
extra_details
=
[
'
Channel name is required to produce a channel UUID
'
])
src/dbscanserving/.gitlab-ci.yml
View file @
8c03968b
...
...
@@ -21,7 +21,7 @@ build dbscanserving:
before_script
:
-
docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
script
:
-
docker build -t "$IMAGE_NAME:$IMAGE_TAG" -f ./src/$IMAGE_NAME/Dockerfile .
-
docker
buildx
build -t "$IMAGE_NAME:$IMAGE_TAG" -f ./src/$IMAGE_NAME/Dockerfile .
-
docker tag "$IMAGE_NAME:$IMAGE_TAG" "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG"
-
docker push "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG"
after_script
:
...
...
src/device/.gitlab-ci.yml
View file @
8c03968b
...
...
@@ -21,7 +21,7 @@ build device:
before_script
:
-
docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
script
:
-
docker build -t "$IMAGE_NAME:$IMAGE_TAG" -f ./src/$IMAGE_NAME/Dockerfile .
-
docker
buildx
build -t "$IMAGE_NAME:$IMAGE_TAG" -f ./src/$IMAGE_NAME/Dockerfile .
-
docker tag "$IMAGE_NAME:$IMAGE_TAG" "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG"
-
docker push "$CI_REGISTRY_IMAGE/$IMAGE_NAME:$IMAGE_TAG"
after_script
:
...
...
src/device/Config.py
View file @
8c03968b
...
...
@@ -12,3 +12,9 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import
os
TRUE_VALUES
=
{
'
T
'
,
'
TRUE
'
,
'
YES
'
,
'
1
'
}
DEVICE_EMULATED_ONLY
=
os
.
environ
.
get
(
'
DEVICE_EMULATED_ONLY
'
)
LOAD_ALL_DEVICE_DRIVERS
=
(
DEVICE_EMULATED_ONLY
is
None
)
or
(
DEVICE_EMULATED_ONLY
.
upper
()
not
in
TRUE_VALUES
)
src/device/Dockerfile
View file @
8c03968b
...
...
@@ -62,9 +62,11 @@ RUN python3 -m pip install -r requirements.txt
# Add component files into working directory
WORKDIR
/var/teraflow
COPY
src/context/. context/
COPY
src/context/__init__.py context/__init__.py
COPY
src/context/client/. context/client/
COPY
src/monitoring/__init__.py monitoring/__init__.py
COPY
src/monitoring/client/. monitoring/client/
COPY
src/device/. device/
COPY
src/monitoring/. monitoring/
RUN
mkdir
-p
tests/tools/mock_ietf_actn_sdn_ctrl
RUN
touch
tests/__init__.py
...
...
src/device/client/DeviceClient.py
View file @
8c03968b
...
...
@@ -15,12 +15,12 @@
import
grpc
,
logging
from
common.Constants
import
ServiceNameEnum
from
common.Settings
import
get_service_host
,
get_service_port_grpc
from
common.proto.context_pb2
import
Device
,
DeviceConfig
,
DeviceId
,
Empty
from
common.proto.context_pb2
import
Device
,
DeviceConfig
,
DeviceId
,
Empty
,
OpticalConfig
,
OpticalConfigId
from
common.proto.device_pb2
import
MonitoringSettings
from
common.proto.device_pb2_grpc
import
DeviceServiceStub
from
common.tools.client.RetryDecorator
import
retry
,
delay_exponential
from
common.tools.grpc.Tools
import
grpc_message_to_json_string
from
common.proto.openconfig_device_pb2_grpc
import
OpenConfigServiceStub
LOGGER
=
logging
.
getLogger
(
__name__
)
MAX_RETRIES
=
15
DELAY_FUNCTION
=
delay_exponential
(
initial
=
0.01
,
increment
=
2.0
,
maximum
=
5.0
)
...
...
@@ -34,12 +34,14 @@ class DeviceClient:
LOGGER
.
debug
(
'
Creating channel to {:s}...
'
.
format
(
str
(
self
.
endpoint
)))
self
.
channel
=
None
self
.
stub
=
None
self
.
openconfig_stub
=
None
self
.
connect
()
LOGGER
.
debug
(
'
Channel created
'
)
def
connect
(
self
):
self
.
channel
=
grpc
.
insecure_channel
(
self
.
endpoint
)
self
.
stub
=
DeviceServiceStub
(
self
.
channel
)
self
.
openconfig_stub
=
OpenConfigServiceStub
(
self
.
channel
)
def
close
(
self
):
if
self
.
channel
is
not
None
:
self
.
channel
.
close
()
...
...
@@ -80,3 +82,8 @@ class DeviceClient:
response
=
self
.
stub
.
MonitorDeviceKpi
(
request
)
LOGGER
.
debug
(
'
MonitorDeviceKpi result: {:s}
'
.
format
(
grpc_message_to_json_string
(
response
)))
return
response
def
ConfigureOpticalDevice
(
self
,
request
:
OpticalConfig
)
->
OpticalConfigId
:
LOGGER
.
debug
(
'
ConfigureOpticalDevice request: {:s}
'
.
format
(
grpc_message_to_json_string
(
request
)))
response
=
self
.
openconfig_stub
.
ConfigureOpticalDevice
(
request
)
LOGGER
.
debug
(
'
ConfigureOpticalDevice result: {:s}
'
.
format
(
grpc_message_to_json_string
(
response
)))
return
response
src/device/service/DeviceService.py
View file @
8c03968b
...
...
@@ -12,13 +12,17 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import
os
from
common.Constants
import
ServiceNameEnum
from
common.Settings
import
get_service_port_grpc
from
common.proto.device_pb2_grpc
import
add_DeviceServiceServicer_to_server
from
common.proto.openconfig_device_pb2_grpc
import
add_OpenConfigServiceServicer_to_server
from
common.tools.service.GenericGrpcService
import
GenericGrpcService
from
device.Config
import
LOAD_ALL_DEVICE_DRIVERS
from
.driver_api.DriverInstanceCache
import
DriverInstanceCache
from
.DeviceServiceServicerImpl
import
DeviceServiceServicerImpl
from
.monitoring.MonitoringLoops
import
MonitoringLoops
from
.OpenConfigServicer
import
OpenConfigServicer
# Custom gRPC settings
# Multiple clients might keep connections alive waiting for RPC methods to be executed.
...
...
@@ -31,10 +35,14 @@ class DeviceService(GenericGrpcService):
super
().
__init__
(
port
,
max_workers
=
GRPC_MAX_WORKERS
,
cls_name
=
cls_name
)
self
.
monitoring_loops
=
MonitoringLoops
()
self
.
device_servicer
=
DeviceServiceServicerImpl
(
driver_instance_cache
,
self
.
monitoring_loops
)
if
LOAD_ALL_DEVICE_DRIVERS
:
self
.
openconfig_device_servicer
=
OpenConfigServicer
(
driver_instance_cache
,
self
.
monitoring_loops
)
def
install_servicers
(
self
):
self
.
monitoring_loops
.
start
()
add_DeviceServiceServicer_to_server
(
self
.
device_servicer
,
self
.
server
)
if
LOAD_ALL_DEVICE_DRIVERS
:
add_OpenConfigServiceServicer_to_server
(
self
.
openconfig_device_servicer
,
self
.
server
)
def
stop
(
self
):
super
().
stop
()
...
...
src/device/service/DeviceServiceServicerImpl.py
View file @
8c03968b
...
...
@@ -20,7 +20,9 @@ from common.Settings import ENVVAR_SUFIX_SERVICE_HOST, get_env_var_name
from
common.method_wrappers.Decorator
import
MetricTypeEnum
,
MetricsPool
,
safe_and_metered_rpc_method
from
common.method_wrappers.ServiceExceptions
import
NotFoundException
,
OperationFailedException
from
common.proto.context_pb2
import
(
Device
,
DeviceConfig
,
DeviceDriverEnum
,
DeviceId
,
DeviceOperationalStatusEnum
,
Empty
,
Link
)
Device
,
DeviceConfig
,
DeviceDriverEnum
,
DeviceId
,
DeviceOperationalStatusEnum
,
Empty
,
Link
,
OpticalConfig
,
OpticalConfigId
)
from
common.proto.device_pb2
import
MonitoringSettings
from
common.proto.device_pb2_grpc
import
DeviceServiceServicer
from
common.tools.context_queries.Device
import
get_device
...
...
@@ -58,6 +60,7 @@ class DeviceServiceServicerImpl(DeviceServiceServicer):
device_uuid
=
request
.
device_id
.
device_uuid
.
uuid
connection_config_rules
=
check_connect_rules
(
request
.
device_config
)
if
request
.
device_drivers
[
0
]
!=
DeviceDriverEnum
.
DEVICEDRIVER_OC
:
check_no_endpoints
(
request
.
device_endpoints
)
t1
=
time
.
time
()
...
...
@@ -85,9 +88,11 @@ class DeviceServiceServicerImpl(DeviceServiceServicer):
# update device_uuid to honor UUID provided by Context
device_uuid
=
device
.
device_id
.
device_uuid
.
uuid
device_name
=
device
.
name
t2
=
time
.
time
()
self
.
mutex_queues
.
add_alias
(
device_uuid
,
device_name
)
self
.
mutex_queues
.
wait_my_turn
(
device_uuid
)
t3
=
time
.
time
()
try
:
...
...
@@ -139,6 +144,13 @@ class DeviceServiceServicerImpl(DeviceServiceServicer):
# ZTP is not deployed; assume the device is ready while onboarding and set them as enabled.
device
.
device_operational_status
=
DeviceOperationalStatusEnum
.
DEVICEOPERATIONALSTATUS_ENABLED
# temporary line
if
request
.
device_drivers
[
0
]
==
DeviceDriverEnum
.
DEVICEDRIVER_OC
and
len
(
request
.
device_endpoints
)
>
0
:
#for endpoint in request.device_endpoints:
# #endpoint.endpoint_id.device_id.CopyFrom(device.device_id)
# pass
device
.
device_endpoints
.
extend
(
request
.
device_endpoints
)
device_id
=
context_client
.
SetDevice
(
device
)
t10
=
time
.
time
()
...
...
src/device/service/OpenConfigServicer.py
0 → 100644
View file @
8c03968b
# Copyright 2022-2023 ETSI TeraFlowSDN - TFS OSG (https://tfs.etsi.org/)
#
# 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.
import
grpc
,
logging
,
json
from
common.method_wrappers.Decorator
import
MetricsPool
,
safe_and_metered_rpc_method
from
common.method_wrappers.ServiceExceptions
import
NotFoundException
from
common.proto.context_pb2
import
(
Device
,
DeviceId
,
DeviceOperationalStatusEnum
,
Empty
,
OpticalConfig
,
OpticalConfig
)
from
common.proto.device_pb2_grpc
import
DeviceServiceServicer
from
common.tools.context_queries.Device
import
get_device
from
common.tools.mutex_queues.MutexQueues
import
MutexQueues
from
context.client.ContextClient
import
ContextClient
from
.driver_api._Driver
import
_Driver
from
.driver_api.DriverInstanceCache
import
DriverInstanceCache
,
get_driver
from
.monitoring.MonitoringLoops
import
MonitoringLoops
from
.Tools
import
extract_resources
from
.Tools
import
check_no_endpoints
LOGGER
=
logging
.
getLogger
(
__name__
)
METRICS_POOL
=
MetricsPool
(
'
Device
'
,
'
RPC
'
)
METRICS_POOL_DETAILS
=
MetricsPool
(
'
Device
'
,
'
execution
'
,
labels
=
{
'
driver
'
:
''
,
'
operation
'
:
''
,
'
step
'
:
''
,
})
class
OpenConfigServicer
(
DeviceServiceServicer
):
def
__init__
(
self
,
driver_instance_cache
:
DriverInstanceCache
,
monitoring_loops
:
MonitoringLoops
)
->
None
:
LOGGER
.
debug
(
'
Creating Servicer...
'
)
self
.
driver_instance_cache
=
driver_instance_cache
self
.
monitoring_loops
=
monitoring_loops
self
.
mutex_queues
=
MutexQueues
()
LOGGER
.
debug
(
'
Servicer Created
'
)
@safe_and_metered_rpc_method
(
METRICS_POOL
,
LOGGER
)
def
AddOpenConfigDevice
(
self
,
request
:
OpticalConfig
,
context
:
grpc
.
ServicerContext
)
->
DeviceId
:
device_uuid
=
request
.
device_id
.
device_uuid
.
uuid
check_no_endpoints
(
request
.
device_endpoints
)
context_client
=
ContextClient
()
device
=
get_device
(
context_client
,
device_uuid
,
rw_copy
=
True
)
if
device
is
None
:
# not in context, create blank one to get UUID, and populate it below
device
=
Device
()
device
.
device_id
.
CopyFrom
(
request
.
device_id
)
# pylint: disable=no-member
device
.
name
=
request
.
name
device
.
device_type
=
request
.
device_type
device
.
device_operational_status
=
DeviceOperationalStatusEnum
.
DEVICEOPERATIONALSTATUS_UNDEFINED
device
.
device_drivers
.
extend
(
request
.
device_drivers
)
# pylint: disable=no-member
device
.
device_config
.
CopyFrom
(
request
.
device_config
)
device
.
device_endpoints
.
extend
(
request
.
device_endpoints
)
# pylint: disable=no-member
device_id
=
context_client
.
SetDevice
(
device
)
device
=
get_device
(
context_client
,
device_id
.
device_uuid
.
uuid
,
rw_copy
=
True
)
# update device_uuid to honor UUID provided by Context
device_uuid
=
device
.
device_id
.
device_uuid
.
uuid
self
.
mutex_queues
.
wait_my_turn
(
device_uuid
)
try
:
device_id
=
context_client
.
SetDevice
(
device
)
except
Exception
as
error
:
LOGGER
.
debug
(
"
error %s
"
,
error
)
@safe_and_metered_rpc_method
(
METRICS_POOL
,
LOGGER
)
def
ConfigureOpticalDevice
(
self
,
request
:
OpticalConfig
,
context
:
grpc
.
ServicerContext
)
->
Empty
:
device_uuid
=
request
.
opticalconfig_id
.
opticalconfig_uuid
resources
=
[]
is_all_good
=
True
config
=
json
.
loads
(
request
.
config
)
LOGGER
.
info
(
f
"
config from openconfigservicer
{
config
}
"
)
try
:
context_client
=
ContextClient
()
device
=
get_device
(
context_client
,
device_uuid
,
rw_copy
=
True
,
include_endpoints
=
True
,
include_components
=
False
,
include_config_rules
=
False
)
LOGGER
.
info
(
f
"
device is
{
device
}
"
)
if
device
is
None
:
raise
NotFoundException
(
'
Device
'
,
device_uuid
,
extra_details
=
'
loading in ConfigureDevice
'
)
resources
,
conditions
=
extract_resources
(
config
=
config
,
device
=
device
)
LOGGER
.
info
(
f
"
from openconfigservicer
{
resources
}
and conditions
{
conditions
}
"
)
driver
:
_Driver
=
get_driver
(
self
.
driver_instance_cache
,
device
)
results
=
driver
.
SetConfig
(
resources
=
resources
,
conditions
=
conditions
)
for
result
in
results
:
if
not
result
:
is_all_good
=
False
LOGGER
.
info
(
f
"
resluts
{
results
}
and is_all_good
{
is_all_good
}
"
)
if
is_all_good
:
driver
.
GetConfig
(
resource_keys
=
[])
#TODO: add a control with the NETCONF get
#driver.GetConfig(resource_keys=filter_fields)
except
Exception
as
e
:
LOGGER
.
info
(
"
error in configuring %s
"
,
e
)
return
Empty
()
src/device/service/Tools.py
View file @
8c03968b
...
...
@@ -15,12 +15,14 @@
import
json
,
logging
from
typing
import
Any
,
Dict
,
List
,
Optional
,
Tuple
,
Union
from
common.Constants
import
DEFAULT_CONTEXT_NAME
,
DEFAULT_TOPOLOGY_NAME
from
common.method_wrappers.ServiceExceptions
import
InvalidArgumentException
from
common.proto.context_pb2
import
ConfigActionEnum
,
ConfigRule_ACL
,
Device
,
DeviceConfig
,
Link
,
Location
from
common.DeviceTypes
import
DeviceTypeEnum
from
common.method_wrappers.ServiceExceptions
import
InvalidArgumentException
,
NotFoundException
from
common.proto.context_pb2
import
ConfigActionEnum
,
ConfigRule_ACL
,
Device
,
DeviceConfig
,
EndPoint
,
Link
,
Location
from
common.proto.device_pb2
import
MonitoringSettings
from
common.proto.kpi_sample_types_pb2
import
KpiSampleType
from
common.tools.grpc.ConfigRules
import
update_config_rule_custom
from
common.tools.grpc.Tools
import
grpc_message_to_json
from
common.type_checkers.Checkers
import
chk_length
,
chk_type
from
.driver_api._Driver
import
_Driver
,
RESOURCE_ENDPOINTS
from
.monitoring.MonitoringLoops
import
MonitoringLoops
from
.ErrorMessages
import
(
...
...
@@ -30,6 +32,21 @@ from .ErrorMessages import (
LOGGER
=
logging
.
getLogger
(
__name__
)
def
get_endpoint_matching
(
device
:
Device
,
endpoint_uuid_or_name
:
str
)
->
EndPoint
:
for
endpoint
in
device
.
device_endpoints
:
choices
=
{
endpoint
.
endpoint_id
.
endpoint_uuid
.
uuid
,
endpoint
.
name
}
if
endpoint_uuid_or_name
in
choices
:
return
endpoint
device_uuid
=
device
.
device_id
.
device_uuid
.
uuid
extra_details
=
'
Device({:s})
'
.
format
(
str
(
device_uuid
))
raise
NotFoundException
(
'
Endpoint
'
,
endpoint_uuid_or_name
,
extra_details
=
extra_details
)
def
get_device_endpoint_uuids
(
endpoint
:
Tuple
[
str
,
str
,
Optional
[
str
]])
->
Tuple
[
str
,
str
]:
chk_type
(
'
endpoint
'
,
endpoint
,
(
tuple
,
list
))
chk_length
(
'
endpoint
'
,
endpoint
,
min_length
=
2
,
max_length
=
3
)
device_uuid
,
endpoint_uuid
=
endpoint
[
0
:
2
]
# ignore topology_uuid by now
return
device_uuid
,
endpoint_uuid
def
check_connect_rules
(
device_config
:
DeviceConfig
)
->
Dict
[
str
,
Any
]:
connection_config_rules
=
dict
()
unexpected_config_rules
=
list
()
...
...
@@ -97,6 +114,7 @@ def populate_endpoints(
resources_to_get
=
[
RESOURCE_ENDPOINTS
]
results_getconfig
=
driver
.
GetConfig
(
resources_to_get
)
LOGGER
.
debug
(
'
results_getconfig = {:s}
'
.
format
(
str
(
results_getconfig
)))
LOGGER
.
info
(
'
results_getconfig = {:s}
'
.
format
(
str
(
results_getconfig
)))
# first quick pass to identify need of mgmt endpoints and links
add_mgmt_port
=
False
...
...
@@ -434,3 +452,74 @@ def update_endpoints(src_device : Device, dst_device : Device) -> None:
dst_topology_id
=
dst_endpoint_id
.
topology_id
if
len
(
src_topology_uuid
)
>
0
:
dst_topology_id
.
topology_uuid
.
uuid
=
src_topology_uuid
if
len
(
src_context_uuid
)
>
0
:
dst_topology_id
.
context_id
.
context_uuid
.
uuid
=
src_context_uuid
def
get_edit_target
(
device
:
Device
,
is_opticalband
:
bool
)
->
str
:
if
is_opticalband
:
return
'
optical-band
'
if
device
.
device_type
==
DeviceTypeEnum
.
OPTICAL_ROADM
:
return
'
media-channel
'
return
'
optical-channel
'
def
is_key_existed
(
key
:
str
,
keys_dic
=
dict
,
key_name_to_use
=
None
)
->
dict
:
dic
=
{}
dic
[
'
resource_key
'
]
=
key
if
key_name_to_use
is
not
None
:
dic
[
'
resource_key
'
]
=
key_name_to_use
if
key
in
keys_dic
:
dic
[
'
value
'
]
=
keys_dic
[
key
]
else
:
dic
[
'
value
'
]
=
None
return
dic
def
extract_resources
(
config
:
dict
,
device
:
Device
)
->
list
:
conditions
=
{}
resources
=
[]
resources
.
append
(
is_key_existed
(
'
channel_namespace
'
,
config
))
resources
.
append
(
is_key_existed
(
'
add_transceiver
'
,
config
))
is_opticalband
=
config
.
get
(
'
is_opticalband
'
,
False
)
conditions
[
'
is_opticalband
'
]
=
is_opticalband
conditions
[
'
edit_type
'
]
=
get_edit_target
(
device
,
is_opticalband
)
if
'
flow
'
in
config
:
#for tuple_value in config['flow'][device.name]:
source_vals
=
[]
dest_vals
=
[]
for
tuple_value
in
config
[
'
flow
'
]:
source_port
=
None
destination_port
=
None
source_port_uuid
,
destination_port_uuid
=
tuple_value
if
source_port_uuid
!=
'
0
'
:
src_endpoint_obj
=
get_endpoint_matching
(
device
,
source_port_uuid
)
source_port
=
src_endpoint_obj
.
name
source_vals
.
append
(
source_port
)
if
destination_port_uuid
!=
'
0
'
:
dst_endpoint_obj
=
get_endpoint_matching
(
device
,
destination_port_uuid
)
destination_port
=
dst_endpoint_obj
.
name
dest_vals
.
append
(
destination_port
)
resources
.
append
({
'
resource_key
'
:
'
source_port
'
,
'
value
'
:
source_vals
})
resources
.
append
({
'
resource_key
'
:
'
destination_port
'
,
'
value
'
:
dest_vals
})
if
'
new_config
'
in
config
:
lower_frequency
=
None
upper_frequency
=
None
resources
.
append
(
is_key_existed
(
'
target-output-power
'
,
keys_dic
=
config
[
'
new_config
'
]))
resources
.
append
(
is_key_existed
(
'
frequency
'
,
keys_dic
=
config
[
'
new_config
'
]))
resources
.
append
(
is_key_existed
(
'
operational-mode
'
,
keys_dic
=
config
[
'
new_config
'
]))
resources
.
append
(
is_key_existed
(
'
line-port
'
,
keys_dic
=
config
[
'
new_config
'
]))
resources
.
append
(
is_key_existed
(
'
band_type
'
,
keys_dic
=
config
[
'
new_config
'
],
key_name_to_use
=
'
name
'
))
resources
.
append
(
is_key_existed
(
'
ob_id
'
,
keys_dic
=
config
[
'
new_config
'
],
key_name_to_use
=
'
optical-band-parent
'
))
resources
.
append
(
is_key_existed
(
'
name
'
,
keys_dic
=
config
[
'
new_config
'
],
key_name_to_use
=
'
channel_name
'
))
if
not
is_opticalband
:
if
'
frequency
'
in
config
[
'
new_config
'
]
and
'
band
'
in
config
[
'
new_config
'
]
and
conditions
[
'
edit_type
'
]
==
'
media-channel
'
:
lower_frequency
=
int
(
int
(
config
[
'
new_config
'
][
'
frequency
'
])
-
(
int
(
config
[
'
new_config
'
][
'
band
'
])
/
2
))
upper_frequency
=
int
(
int
(
config
[
'
new_config
'
][
'
frequency
'
])
+
(
int
(
config
[
'
new_config
'
][
'
band
'
])
/
2
))
#lower_frequency = (config['new_config']['frequency'] - config['new_config']['band'])/2
#upper_frequency = (config['new_config']['frequency'] + config['new_config']['band'])/2
resources
.
append
(
is_key_existed
(
'
flow_id
'
,
keys_dic
=
config
[
'
new_config
'
],
key_name_to_use
=
'
index
'
))
#resources.append({'resource_key':'index','value':config['new_config']['flow_id'] if 'flow_id' in config['new_config'] else None})
else
:
lower_frequency
=
config
[
'
new_config
'
][
'
low-freq
'
]
if
'
low-freq
'
in
config
[
'
new_config
'
]
else
None
upper_frequency
=
config
[
'
new_config
'
][
'
up-freq
'
]
if
'
up-freq
'
in
config
[
'
new_config
'
]
else
None
resources
.
append
(
is_key_existed
(
'
ob_id
'
,
keys_dic
=
config
[
'
new_config
'
],
key_name_to_use
=
'
index
'
))
#resources.append({'resource_key':'index','value':config['new_config']['ob_id'] if 'ob_id' in config['new_config'] else None})
resources
.
append
({
'
resource_key
'
:
'
lower-frequency
'
,
'
value
'
:
lower_frequency
})
resources
.
append
({
'
resource_key
'
:
'
upper-frequency
'
,
'
value
'
:
upper_frequency
})
return
[
resources
,
conditions
]
Prev
1
…
9
10
11
12
13
14
15
16
17
…
20
Next