Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
jetconf
jetconf-jukebox
Commits
2bc301d8
Unverified
Commit
2bc301d8
authored
May 31, 2017
by
Pavel Spirek
Browse files
Initial commit
parents
Changes
12
Hide whitespace changes
Inline
Side-by-side
README.rst
0 → 100644
View file @
2bc301d8
.. |date| date::
*******
JetConf example Jukebox backend
*******
:Author: Pavel Špírek <pavel.spirek@nic.cz>
:Date: |date|
jetconf-jukebox/usr_conf_data_handlers.py
0 → 100644
View file @
2bc301d8
from
colorlog
import
info
from
typing
import
List
,
Dict
,
Union
,
Any
from
yangson.instance
import
InstanceRoute
from
.data
import
BaseDatastore
,
DataChange
from
.helpers
import
ErrorHelpers
,
LogHelpers
from
.handler_list
import
CONF_DATA_HANDLES
,
ConfDataObjectHandler
,
ConfDataListHandler
JsonNodeT
=
Union
[
Dict
[
str
,
Any
],
List
]
epretty
=
ErrorHelpers
.
epretty
debug_confh
=
LogHelpers
.
create_module_dbg_logger
(
__name__
)
# ---------- User-defined handlers follow ----------
class
JukeboxExampleConfHandler
(
ConfDataListHandler
):
def
create_item
(
self
,
ii
:
InstanceRoute
,
ch
:
"DataChange"
):
debug_confh
(
self
.
__class__
.
__name__
+
" replace triggered"
)
info
(
"Creating item '/example-jukebox:jukebox/library/artist' in app configuration"
)
def
create_list
(
self
,
ii
:
InstanceRoute
,
ch
:
"DataChange"
):
debug_confh
(
self
.
__class__
.
__name__
+
" replace triggered"
)
info
(
"Creating list '/example-jukebox:jukebox/library/artist' in app configuration"
)
def
replace_item
(
self
,
ii
:
InstanceRoute
,
ch
:
"DataChange"
):
debug_confh
(
self
.
__class__
.
__name__
+
" replace triggered"
)
info
(
"Replacing item '/example-jukebox:jukebox/library/artist' in app configuration"
)
def
replace_list
(
self
,
ii
:
InstanceRoute
,
ch
:
"DataChange"
):
debug_confh
(
self
.
__class__
.
__name__
+
" replace triggered"
)
info
(
"Replacing list '/example-jukebox:jukebox/library/artist' in app configuration"
)
def
delete_item
(
self
,
ii
:
InstanceRoute
,
ch
:
DataChange
):
debug_confh
(
self
.
__class__
.
__name__
+
" delete triggered"
)
info
(
"Deleting item '/example-jukebox:jukebox/library/artist' from app configuration"
)
def
delete_list
(
self
,
ii
:
InstanceRoute
,
ch
:
"DataChange"
):
debug_confh
(
self
.
__class__
.
__name__
+
" delete triggered"
)
info
(
"Deleting list '/example-jukebox:jukebox/library/artist' from app configuration"
)
def
register_conf_handlers
(
ds
:
BaseDatastore
):
CONF_DATA_HANDLES
.
register
(
JukeboxExampleConfHandler
(
ds
,
"/example-jukebox:jukebox/library/artist"
))
jetconf-jukebox/usr_datastore.py
0 → 100644
View file @
2bc301d8
from
yangson.datamodel
import
DataModel
from
.data
import
JsonDatastore
class
UserDatastore
(
JsonDatastore
):
def
__init__
(
self
,
dm
:
DataModel
,
json_file
:
str
,
with_nacm
:
bool
=
False
):
super
().
__init__
(
dm
,
json_file
,
with_nacm
)
self
.
name
=
"Example Data"
# Application-specific init actions can be defined here
jetconf-jukebox/usr_op_handlers.py
0 → 100644
View file @
2bc301d8
from
colorlog
import
info
from
.helpers
import
JsonNodeT
from
.handler_list
import
OP_HANDLERS
from
.data
import
BaseDatastore
# ---------- User-defined handlers follow ----------
class
OpHandlersContainer
:
def
__init__
(
self
,
ds
:
BaseDatastore
):
self
.
ds
=
ds
def
jukebox_play_op
(
self
,
input_args
:
JsonNodeT
,
username
:
str
)
->
JsonNodeT
:
# Structure of RPC's input and output arguments is defined in YANG data model
# Do something
info
(
"Called operation 'jukebox_play_op' by user '{}':"
.
format
(
username
))
info
(
"Playlist name: {}"
.
format
(
input_args
[
"example-jukebox:playlist"
]))
info
(
"Song number: {}"
.
format
(
input_args
[
"example-jukebox:song-number"
]))
def
register_op_handlers
(
ds
:
BaseDatastore
):
op_handlers_obj
=
OpHandlersContainer
(
ds
)
OP_HANDLERS
.
register
(
op_handlers_obj
.
jukebox_play_op
,
"example-jukebox:play"
)
jetconf-jukebox/usr_state_data_handlers.py
0 → 100644
View file @
2bc301d8
from
colorlog
import
error
,
warning
as
warn
,
info
from
yangson.instance
import
InstanceRoute
from
.helpers
import
JsonNodeT
,
PathFormat
from
.handler_list
import
STATE_DATA_HANDLES
,
StateDataContainerHandler
from
.data
import
BaseDatastore
# ---------- User-defined handlers follow ----------
# This handler will generate /example-jukebox:jukebox/library/artist-count node
class
JukeboxExampleStateHandler
(
StateDataContainerHandler
):
def
generate_node
(
self
,
node_ii
:
InstanceRoute
,
username
:
str
,
staging
:
bool
)
->
JsonNodeT
:
info
(
"jukebox_example_handler, ii = {}"
.
format
(
node_ii
))
artist_list_ii
=
self
.
ds
.
parse_ii
(
"/example-jukebox:jukebox/library/artist"
,
PathFormat
.
URL
)
jb_artists
=
self
.
ds
.
get_data_root
().
goto
(
artist_list_ii
).
value
return
len
(
jb_artists
)
# This handler will generate /example-jukebox:jukebox/library/album-count node
class
JukeboxExampleStateHandlerAc
(
StateDataContainerHandler
):
def
generate_node
(
self
,
node_ii
:
InstanceRoute
,
username
:
str
,
staging
:
bool
)
->
JsonNodeT
:
info
(
"jukebox_example_handler_ac, ii = {}"
.
format
(
node_ii
))
artist_list_ii
=
self
.
ds
.
parse_ii
(
"/example-jukebox:jukebox/library/artist"
,
PathFormat
.
URL
)
jb_artists
=
self
.
ds
.
get_data_root
().
goto
(
artist_list_ii
).
value
album_count
=
0
for
artist
in
jb_artists
:
album_list
=
artist
.
get
(
"album"
,
[])
album_count
+=
len
(
album_list
)
return
album_count
# This handler will generate /example-jukebox:jukebox/library/song-count node
class
JukeboxExampleStateHandlerSc
(
StateDataContainerHandler
):
def
generate_node
(
self
,
node_ii
:
InstanceRoute
,
username
:
str
,
staging
:
bool
)
->
JsonNodeT
:
info
(
"jukebox_example_handler_sc, ii = {}"
.
format
(
node_ii
))
artist_list_ii
=
self
.
ds
.
parse_ii
(
"/example-jukebox:jukebox/library/artist"
,
PathFormat
.
URL
)
jb_artists
=
self
.
ds
.
get_data_root
().
goto
(
artist_list_ii
).
value
song_count
=
0
for
artist
in
jb_artists
:
album_list
=
artist
.
get
(
"album"
,
[])
for
album
in
album_list
:
song_list
=
album
.
get
(
"song"
,
[])
song_count
+=
len
(
song_list
)
return
song_count
# Instantiate state data handlers
def
register_state_handlers
(
ds
:
BaseDatastore
):
esh
=
JukeboxExampleStateHandler
(
ds
,
"/example-jukebox:jukebox/library/artist-count"
)
esh_ac
=
JukeboxExampleStateHandlerAc
(
ds
,
"/example-jukebox:jukebox/library/album-count"
)
esh_sc
=
JukeboxExampleStateHandlerSc
(
ds
,
"/example-jukebox:jukebox/library/song-count"
)
STATE_DATA_HANDLES
.
register
(
esh
)
STATE_DATA_HANDLES
.
register
(
esh_ac
)
STATE_DATA_HANDLES
.
register
(
esh_sc
)
setup.py
0 → 100644
View file @
2bc301d8
from
setuptools
import
setup
,
find_packages
import
codecs
import
os
here
=
os
.
path
.
abspath
(
os
.
path
.
dirname
(
__file__
))
with
codecs
.
open
(
os
.
path
.
join
(
here
,
'README.rst'
),
encoding
=
'utf-8'
)
as
readme
:
long_description
=
readme
.
read
()
setup
(
name
=
"jetconf"
,
packages
=
find_packages
(),
use_scm_version
=
True
,
setup_requires
=
[
"setuptools_scm"
],
description
=
"Pure Python implementation of RESTCONF server"
,
long_description
=
long_description
,
url
=
"https://gitlab.labs.nic.cz/labs/jetconf"
,
author
=
"Pavel Spirek"
,
author_email
=
"pavel.spirek@nic.cz"
,
entry_points
=
{
"console_scripts"
:
[
"jetconf=jetconf.__main__:main"
]
},
install_requires
=
[
"yangson"
,
"h2"
,
"colorlog"
,
"pyaml"
,
"pytz"
],
tests_require
=
[
"pytest"
],
keywords
=
[
"RESTCONF"
,
"yang"
,
"data model"
,
"configuration"
,
"json"
],
classifiers
=
[
"Programming Language :: Python"
,
"Programming Language :: Python :: 3.5"
,
"Development Status :: 3 - Alpha"
,
"Intended Audience :: System Administrators"
,
"Intended Audience :: Telecommunications Industry"
,
"License :: OSI Approved :: GNU General Public License v3 (GPLv3)"
,
"Operating System :: OS Independent"
,
"Topic :: System :: Monitoring"
,
"Topic :: System :: Systems Administration"
]
)
yang-data/example-jukebox@2016-08-15.yang
0 → 100644
View file @
2bc301d8
module
example-jukebox
{
namespace
"http://example.com/ns/example-jukebox"
;
prefix
"jbox"
;
organization
"Example, Inc."
;
contact
"support at example.com"
;
description
"Example Jukebox Data Model Module."
;
revision
"2016-08-15"
{
description
"Initial version."
;
reference
"example.com document 1-4673."
;
}
identity
genre
{
description
"Base for all genre types."
;
}
// abbreviated list of genre classifications
identity
alternative
{
base
genre
;
description
"Alternative music."
;
}
identity
blues
{
base
genre
;
description
"Blues music."
;
}
identity
country
{
base
genre
;
description
"Country music."
;
}
identity
jazz
{
base
genre
;
description
"Jazz music."
;
}
identity
pop
{
base
genre
;
description
"Pop music."
;
}
identity
rock
{
base
genre
;
description
"Rock music."
;
}
container
jukebox
{
presence
"An empty container indicates that the jukebox
service is available."
;
description
"Represents a 'jukebox' resource, with a library, playlists,
and a 'play' operation."
;
container
library
{
description
"Represents the 'jukebox' library resource."
;
list
artist
{
key
name
;
description
"Represents one 'artist' resource within the
'jukebox' library resource."
;
leaf
name
{
type
string
{
length
"1 .. max"
;
}
description
"The name of the artist."
;
}
list
album
{
key
name
;
description
"Represents one 'album' resource within one
'artist' resource, within the jukebox library."
;
leaf
name
{
type
string
{
length
"1 .. max"
;
}
description
"The name of the album."
;
}
leaf
genre
{
type
identityref
{
base
genre
;
}
description
"The genre identifying the type of music on
the album."
;
}
leaf
year
{
type
uint16
{
range
"1900 .. max"
;
}
description
"The year the album was released."
;
}
container
admin
{
description
"Administrative information for the album."
;
leaf
label
{
type
string
;
description
"The label that released the album."
;
}
leaf
catalogue-number
{
type
string
;
description
"The album's catalogue number."
;
}
}
list
song
{
key
name
;
description
"Represents one 'song' resource within one
'album' resource, within the jukebox library."
;
leaf
name
{
type
string
{
length
"1 .. max"
;
}
description
"The name of the song."
;
}
leaf
location
{
type
string
;
mandatory
true
;
description
"The file location string of the
media file for the song."
;
}
leaf
format
{
type
string
;
description
"An identifier string for the media type
for the file associated with the
'location' leaf for this entry."
;
}
leaf
length
{
type
uint32
;
units
"seconds"
;
description
"The duration of this song in seconds."
;
}
}
// end list 'song'
}
// end list 'album'
}
// end list 'artist'
leaf
artist-count
{
type
uint32
;
units
"artists"
;
config
false
;
description
"Number of artists in the library."
;
}
leaf
album-count
{
type
uint32
;
units
"albums"
;
config
false
;
description
"Number of albums in the library."
;
}
leaf
song-count
{
type
uint32
;
units
"songs"
;
config
false
;
description
"Number of songs in the library."
;
}
}
// end library
list
playlist
{
key
name
;
description
"Example configuration data resource."
;
leaf
name
{
type
string
;
description
"The name of the playlist."
;
}
leaf
description
{
type
string
;
description
"A comment describing the playlist."
;
}
list
song
{
key
index
;
ordered-by
user
;
description
"Example nested configuration data resource."
;
leaf
index
{
// not really needed
type
uint32
;
description
"An arbitrary integer index for this playlist song."
;
}
leaf
id
{
type
instance-identifier
;
mandatory
true
;
description
"Song identifier. Must identify an instance of
/jukebox/library/artist/album/song/name."
;
}
}
}
container
player
{
description
"Represents the jukebox player resource."
;
leaf
gap
{
type
decimal64
{
fraction-digits
1
;
range
"0.0 .. 2.0"
;
}
units
"tenths of seconds"
;
description
"Time gap between each song."
;
}
}
}
rpc
play
{
description
"Control function for the jukebox player."
;
input
{
leaf
playlist
{
type
string
;
mandatory
true
;
description
"The playlist name."
;
}
leaf
song-number
{
type
uint32
;
mandatory
true
;
description
"Song number in playlist to play."
;
}
}
}
}
yang-data/ietf-inet-types@2013-07-15.yang
0 → 100644
View file @
2bc301d8
module
ietf-inet-types
{
namespace
"urn:ietf:params:xml:ns:yang:ietf-inet-types"
;
prefix
"inet"
;
organization
"IETF NETMOD (NETCONF Data Modeling Language) Working Group"
;
contact
"WG Web: <http://tools.ietf.org/wg/netmod/>
WG List: <mailto:netmod@ietf.org>
WG Chair: David Kessens
<mailto:david.kessens@nsn.com>
WG Chair: Juergen Schoenwaelder
<mailto:j.schoenwaelder@jacobs-university.de>
Editor: Juergen Schoenwaelder
<mailto:j.schoenwaelder@jacobs-university.de>"
;
description
"This module contains a collection of generally useful derived
YANG data types for Internet addresses and related things.
Copyright (c) 2013 IETF Trust and the persons identified as
authors of the code. All rights reserved.
Redistribution and use in source and binary forms, with or
without modification, is permitted pursuant to, and subject
to the license terms contained in, the Simplified BSD License
set forth in Section 4.c of the IETF Trust's Legal Provisions
Relating to IETF Documents
(http://trustee.ietf.org/license-info).
This version of this YANG module is part of RFC 6991; see
the RFC itself for full legal notices."
;
revision
2013-07-15
{
description
"This revision adds the following new data types:
- ip-address-no-zone
- ipv4-address-no-zone
- ipv6-address-no-zone"
;
reference
"RFC 6991: Common YANG Data Types"
;
}
revision
2010-09-24
{
description
"Initial revision."
;
reference
"RFC 6021: Common YANG Data Types"
;
}
/*** collection of types related to protocol fields ***/
typedef
ip-version
{
type
enumeration
{
enum
unknown
{
value
"0"
;
description
"An unknown or unspecified version of the Internet
protocol."
;
}
enum
ipv4
{
value
"1"
;
description
"The IPv4 protocol as defined in RFC 791."
;
}
enum
ipv6
{
value
"2"
;
description
"The IPv6 protocol as defined in RFC 2460."
;
}
}
description
"This value represents the version of the IP protocol.
In the value set and its semantics, this type is equivalent
to the InetVersion textual convention of the SMIv2."
;
reference
"RFC 791: Internet Protocol
RFC 2460: Internet Protocol, Version 6 (IPv6) Specification
RFC 4001: Textual Conventions for Internet Network Addresses"
;
}
typedef
dscp
{
type
uint8
{
range
"0..63"
;
}
description
"The dscp type represents a Differentiated Services Code Point
that may be used for marking packets in a traffic stream.
In the value set and its semantics, this type is equivalent
to the Dscp textual convention of the SMIv2."
;
reference
"RFC 3289: Management Information Base for the Differentiated
Services Architecture
RFC 2474: Definition of the Differentiated Services Field
(DS Field) in the IPv4 and IPv6 Headers
RFC 2780: IANA Allocation Guidelines For Values In
the Internet Protocol and Related Headers"
;
}
typedef
ipv6-flow-label
{
type
uint32
{
range
"0..1048575"
;
}
description
"The ipv6-flow-label type represents the flow identifier or Flow
Label in an IPv6 packet header that may be used to
discriminate traffic flows.
In the value set and its semantics, this type is equivalent
to the IPv6FlowLabel textual convention of the SMIv2."
;
reference
"RFC 3595: Textual Conventions for IPv6 Flow Label
RFC 2460: Internet Protocol, Version 6 (IPv6) Specification"
;
}
typedef
port-number
{
type
uint16
{
range
"0..65535"
;
}
description
"The port-number type represents a 16-bit port number of an
Internet transport-layer protocol such as UDP, TCP, DCCP, or
SCTP. Port numbers are assigned by IANA. A current list of
all assignments is available from <http://www.iana.org/>.
Note that the port number value zero is reserved by IANA. In
situations where the value zero does not make sense, it can
be excluded by subtyping the port-number type.
In the value set and its semantics, this type is equivalent
to the InetPortNumber textual convention of the SMIv2."
;
reference
"RFC 768: User Datagram Protocol
RFC 793: Transmission Control Protocol
RFC 4960: Stream Control Transmission Protocol
RFC 4340: Datagram Congestion Control Protocol (DCCP)
RFC 4001: Textual Conventions for Internet Network Addresses"
;
}
/*** collection of types related to autonomous systems ***/
typedef
as-number
{
type
uint32
;
description
"The as-number type represents autonomous system numbers
which identify an Autonomous System (AS). An AS is a set
of routers under a single technical administration, using
an interior gateway protocol and common metrics to route
packets within the AS, and using an exterior gateway
protocol to route packets to other ASes. IANA maintains
the AS number space and has delegated large parts to the
regional registries.
Autonomous system numbers were originally limited to 16