Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Kea
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
450
Issues
450
List
Boards
Labels
Service Desk
Milestones
Merge Requests
75
Merge Requests
75
Operations
Operations
Incidents
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
ISC Open Source Projects
Kea
Commits
63d5e666
Commit
63d5e666
authored
Sep 13, 2018
by
Francis Dupont
Committed by
Tomek Mrugalski
Sep 21, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[65-libyang-option-data] Filled files, waiting for adaptor merge
parent
a388c647
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
493 additions
and
0 deletions
+493
-0
src/lib/yang/Makefile.am
src/lib/yang/Makefile.am
+2
-0
src/lib/yang/tests/Makefile.am
src/lib/yang/tests/Makefile.am
+1
-0
src/lib/yang/tests/translator_option_data_unittests.cc
src/lib/yang/tests/translator_option_data_unittests.cc
+157
-0
src/lib/yang/translator_option_data.cc
src/lib/yang/translator_option_data.cc
+197
-0
src/lib/yang/translator_option_data.h
src/lib/yang/translator_option_data.h
+136
-0
No files found.
src/lib/yang/Makefile.am
View file @
63d5e666
...
...
@@ -8,6 +8,8 @@ lib_LTLIBRARIES = libkea-yang.la
libkea_yang_la_SOURCES
=
adaptor.cc adaptor.h
libkea_yang_la_SOURCES
+=
sysrepo_error.h
libkea_yang_la_SOURCES
+=
translator.cc translator.h
libkea_yang_la_SOURCES
+=
translator_option_data.cc
libkea_yang_la_SOURCES
+=
translator_option_data.h
libkea_yang_la_LIBADD
=
$(top_builddir)
/src/lib/asiolink/libkea-asiolink.la
libkea_yang_la_LIBADD
+=
$(top_builddir)
/src/lib/cc/libkea-cc.la
...
...
src/lib/yang/tests/Makefile.am
View file @
63d5e666
...
...
@@ -19,6 +19,7 @@ if HAVE_GTEST
TESTS
+=
run_unittests
run_unittests_SOURCES
=
adaptor_unittests.cc
run_unittests_SOURCES
+=
translator_unittests.cc
run_unittests_SOURCES
+=
translator_option_data_unittests.cc
run_unittests_SOURCES
+=
run_unittests.cc
run_unittests_CPPFLAGS
=
$(AM_CPPFLAGS)
$(GTEST_INCLUDES)
run_unittests_LDFLAGS
=
$(AM_LDFLAGS)
$(GTEST_LDFLAGS)
...
...
src/lib/yang/tests/translator_option_data_unittests.cc
0 → 100644
View file @
63d5e666
// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <config.h>
#include <yang/translator_option_data.h>
#include <boost/scoped_ptr.hpp>
#include <gtest/gtest.h>
#include <sstream>
using
namespace
std
;
using
namespace
isc
;
using
namespace
isc
::
data
;
using
namespace
isc
::
yang
;
namespace
{
// Test get empty option data list.
TEST
(
TranslatorOptionDataListTest
,
getEmpty
)
{
// Get a translator option data list object to play with.
S_Connection
conn
(
new
Connection
(
"translator option data list unittests"
));
S_Session
sess
(
new
Session
(
conn
,
SR_DS_CANDIDATE
));
boost
::
scoped_ptr
<
TranslatorOptionDataList
>
todl_obj
;
// Use the ad hoc model.
const
string
&
model
=
"kea-dhcp4"
;
EXPECT_NO_THROW
(
todl_obj
.
reset
(
new
TranslatorOptionDataList
(
sess
,
model
)));
// Get the option data list and checks it is empty.
const
string
&
xpath
=
"/kea-dhcp4:config/option-data-list"
;
ConstElementPtr
options
;
EXPECT_NO_THROW
(
options
=
todl_obj
->
getOptionDataList
(
xpath
));
ASSERT_TRUE
(
options
);
ASSERT_EQ
(
Element
::
list
,
options
->
getType
());
EXPECT_EQ
(
0
,
options
->
size
());
}
// Test get one option data.
TEST
(
TranslatorOptionDataListTest
,
get
)
{
// Get a translator option data list object to play with.
S_Connection
conn
(
new
Connection
(
"translator option data list unittests"
));
S_Session
sess
(
new
Session
(
conn
,
SR_DS_CANDIDATE
));
boost
::
scoped_ptr
<
TranslatorOptionDataList
>
todl_obj
;
// Use the ad hoc model.
const
string
&
model
=
"kea-dhcp6"
;
EXPECT_NO_THROW
(
todl_obj
.
reset
(
new
TranslatorOptionDataList
(
sess
,
model
)));
// Create the option code 100.
const
string
&
xpath
=
"/kea-dhcp6:config/option-data-list"
;
const
string
&
xoption
=
xpath
+
"/option-data[code='100'][space='dns']"
;
const
string
&
xformat
=
xoption
+
"/csv-format"
;
const
string
&
xdata
=
xoption
+
"/data"
;
const
string
&
xsend
=
xoption
+
"/always-send"
;
S_Val
s_false
(
new
Val
(
false
));
ASSERT_NO_THROW
(
sess
->
set_item
(
xformat
.
c_str
(),
s_false
));
S_Val
s_data
(
new
Val
(
"12121212"
));
ASSERT_NO_THROW
(
sess
->
set_item
(
xdata
.
c_str
(),
s_data
));
ASSERT_NO_THROW
(
sess
->
set_item
(
xsend
.
c_str
(),
s_false
));
// Get the option data.
ConstElementPtr
option
;
EXPECT_NO_THROW
(
option
=
todl_obj
->
getOptionData
(
xoption
));
ASSERT_TRUE
(
option
);
EXPECT_EQ
(
"{
\"
always-send
\"
: false,
\"
code
\"
: 100,
\"
csv-format
\"
: false,
\"
data
\"
:
\"
12121212
\"
,
\"
space
\"
:
\"
dns
\"
}"
,
option
->
str
());
// Get the option data list.
ConstElementPtr
options
;
EXPECT_NO_THROW
(
options
=
todl_obj
->
getOptionDataList
(
xpath
));
ASSERT_TRUE
(
options
);
ASSERT_EQ
(
Element
::
list
,
options
->
getType
());
EXPECT_EQ
(
1
,
options
->
size
());
EXPECT_TRUE
(
option
->
equals
(
*
options
->
get
(
0
)));
}
// Test set empty option data list.
TEST
(
TranslatorOptionDataListTest
,
setEmpty
)
{
// Get a translator option data list object to play with.
S_Connection
conn
(
new
Connection
(
"translator option data list unittests"
));
S_Session
sess
(
new
Session
(
conn
,
SR_DS_CANDIDATE
));
boost
::
scoped_ptr
<
TranslatorOptionDataList
>
todl_obj
;
// Use the ad hoc model.
const
string
&
model
=
"kea-dhcp4"
;
EXPECT_NO_THROW
(
todl_obj
.
reset
(
new
TranslatorOptionDataList
(
sess
,
model
)));
// Set empty list.
const
string
&
xpath
=
"/kea-dhcp4:config/option-data-list"
;
ConstElementPtr
options
=
Element
::
createList
();
EXPECT_NO_THROW
(
todl_obj
->
setOptionDataList
(
xpath
,
options
));
// Get it back.
options
.
reset
();
EXPECT_NO_THROW
(
options
=
todl_obj
->
getOptionDataList
(
xpath
));
ASSERT_TRUE
(
options
);
EXPECT_EQ
(
0
,
options
->
size
());
}
// Test set an option data.
TEST
(
TranslatorOptionDataListTest
,
set
)
{
// Get a translator option data list object to play with.
S_Connection
conn
(
new
Connection
(
"translator option data list unittests"
));
S_Session
sess
(
new
Session
(
conn
,
SR_DS_CANDIDATE
));
boost
::
scoped_ptr
<
TranslatorOptionDataList
>
todl_obj
;
// Use the ad hoc model.
const
string
&
model
=
"kea-dhcp6"
;
EXPECT_NO_THROW
(
todl_obj
.
reset
(
new
TranslatorOptionDataList
(
sess
,
model
)));
// Set one option data.
const
string
&
xpath
=
"/kea-dhcp6:config/option-data-list"
;
ElementPtr
options
=
Element
::
createList
();
ElementPtr
option
=
Element
::
createMap
();
option
->
set
(
"code"
,
Element
::
create
(
100
));
option
->
set
(
"space"
,
Element
::
create
(
string
(
"dns"
)));
option
->
set
(
"csv-format"
,
Element
::
create
(
false
));
option
->
set
(
"data"
,
Element
::
create
(
string
(
"12121212"
)));
option
->
set
(
"always-send"
,
Element
::
create
(
false
));
options
->
add
(
option
);
EXPECT_NO_THROW
(
todl_obj
->
setOptionDataList
(
xpath
,
options
));
// Get it back.
ConstElementPtr
got
;
EXPECT_NO_THROW
(
got
=
todl_obj
->
getOptionDataList
(
xpath
));
ASSERT_TRUE
(
got
);
ASSERT_EQ
(
1
,
got
->
size
());
EXPECT_TRUE
(
option
->
equals
(
*
got
->
get
(
0
)));
// Check the tree representation.
S_Tree
tree
;
EXPECT_NO_THROW
(
tree
=
sess
->
get_subtree
(
"/kea-dhcp6:config"
));
ASSERT_TRUE
(
tree
);
string
expected
=
"kea-dhcp6:config (container)
\n
"
" |
\n
"
" -- option-data-list (container)
\n
"
" |
\n
"
" -- option-data (list instance)
\n
"
" |
\n
"
" -- code = 100
\n
"
" |
\n
"
" -- space = dns
\n
"
" |
\n
"
" -- data = 12121212
\n
"
" |
\n
"
" -- csv-format = false
\n
"
" |
\n
"
" -- always-send = false
\n
"
;
EXPECT_EQ
(
expected
,
tree
->
to_string
(
100
));
}
};
// end of anonymous namespace
src/lib/yang/translator_option_data.cc
0 → 100644
View file @
63d5e666
// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include <yang/translator_option_data.h>
#include <yang/adaptor.h>
#include <sstream>
using
namespace
std
;
using
namespace
isc
::
data
;
namespace
isc
{
namespace
yang
{
TranslatorOptionData
::
TranslatorOptionData
(
S_Session
session
,
const
string
&
model
)
:
TranslatorBasic
(
session
),
model_
(
model
)
{
}
TranslatorOptionData
::~
TranslatorOptionData
()
{
}
ElementPtr
TranslatorOptionData
::
getOptionData
(
const
string
&
xpath
)
{
try
{
if
((
model_
==
"kea-dhcp4"
)
||
(
model_
==
"kea-dhcp6"
))
{
return
(
getOptionDataKea
(
xpath
));
}
}
catch
(
const
sysrepo_exception
&
ex
)
{
isc_throw
(
SysrepoError
,
"sysrepo error getting option data at '"
<<
xpath
<<
"': "
<<
ex
.
what
());
}
isc_throw
(
NotImplemented
,
"getOptionData not implemented for the model: "
<<
model_
);
}
ElementPtr
TranslatorOptionData
::
getOptionDataKea
(
const
string
&
xpath
)
{
ConstElementPtr
code
=
getItem
(
xpath
+
"/code"
);
ConstElementPtr
space
=
getItem
(
xpath
+
"/space"
);
if
(
!
code
||
!
space
)
{
return
(
ElementPtr
());
}
ElementPtr
result
=
Element
::
createMap
();
result
->
set
(
"code"
,
code
);
result
->
set
(
"space"
,
space
);
ConstElementPtr
name
=
getItem
(
xpath
+
"/name"
);
if
(
name
)
{
result
->
set
(
"name"
,
name
);
}
ConstElementPtr
data
=
getItem
(
xpath
+
"/data"
);
if
(
data
)
{
result
->
set
(
"data"
,
data
);
}
ConstElementPtr
format
=
getItem
(
xpath
+
"/csv-format"
);
if
(
format
)
{
result
->
set
(
"csv-format"
,
format
);
}
ConstElementPtr
send
=
getItem
(
xpath
+
"/always-send"
);
if
(
send
)
{
result
->
set
(
"always-send"
,
send
);
}
ConstElementPtr
context
=
getItem
(
xpath
+
"/user-context"
);
if
(
context
)
{
result
->
set
(
"user-context"
,
Element
::
fromJSON
(
context
->
stringValue
()));
}
return
(
result
);
}
void
TranslatorOptionData
::
setOptionData
(
const
string
&
xpath
,
ConstElementPtr
elem
)
{
try
{
if
((
model_
==
"kea-dhcp4"
)
||
(
model_
==
"kea-dhcp6"
))
{
setOptionDataKea
(
xpath
,
elem
);
}
else
{
isc_throw
(
NotImplemented
,
"setOptionData not implemented for the model: "
<<
model_
);
}
}
catch
(
const
sysrepo_exception
&
ex
)
{
isc_throw
(
SysrepoError
,
"sysrepo error setting option data '"
<<
elem
->
str
()
<<
"' at '"
<<
xpath
<<
"': "
<<
ex
.
what
());
}
}
void
TranslatorOptionData
::
setOptionDataKea
(
const
string
&
xpath
,
ConstElementPtr
elem
)
{
ConstElementPtr
name
=
elem
->
get
(
"name"
);
if
(
name
)
{
setItem
(
xpath
+
"/name"
,
name
,
SR_STRING_T
);
}
ConstElementPtr
data
=
elem
->
get
(
"data"
);
if
(
data
)
{
setItem
(
xpath
+
"/data"
,
data
,
SR_STRING_T
);
}
ConstElementPtr
format
=
elem
->
get
(
"csv-format"
);
if
(
format
)
{
setItem
(
xpath
+
"/csv-format"
,
format
,
SR_BOOL_T
);
}
ConstElementPtr
send
=
elem
->
get
(
"always-send"
);
if
(
send
)
{
setItem
(
xpath
+
"/always-send"
,
send
,
SR_BOOL_T
);
}
ConstElementPtr
context
=
Adaptor
::
getContext
(
elem
);
if
(
context
)
{
setItem
(
xpath
+
"/user-context"
,
Element
::
create
(
context
->
str
()),
SR_STRING_T
);
}
}
TranslatorOptionDataList
::
TranslatorOptionDataList
(
S_Session
session
,
const
string
&
model
)
:
TranslatorBasic
(
session
),
TranslatorOptionData
(
session
,
model
),
model_
(
model
)
{
}
TranslatorOptionDataList
::~
TranslatorOptionDataList
()
{
}
ConstElementPtr
TranslatorOptionDataList
::
getOptionDataList
(
const
string
&
xpath
)
{
try
{
if
((
model_
==
"kea-dhcp4"
)
||
(
model_
==
"kea-dhcp6"
))
{
return
(
getOptionDataListKea
(
xpath
));
}
}
catch
(
const
sysrepo_exception
&
ex
)
{
isc_throw
(
SysrepoError
,
"sysrepo error getting option data list at '"
<<
xpath
<<
"': "
<<
ex
.
what
());
}
isc_throw
(
NotImplemented
,
"getOptionDataList not implemented for the model: "
<<
model_
);
}
ConstElementPtr
TranslatorOptionDataList
::
getOptionDataListKea
(
const
string
&
xpath
)
{
ElementPtr
result
=
Element
::
createList
();
S_Iter_Value
iter
=
getIter
(
xpath
+
"/*"
);
if
(
!
iter
)
{
return
(
ConstElementPtr
());
}
for
(;;)
{
const
string
&
option
=
getNext
(
iter
);
if
(
option
.
empty
())
{
break
;
}
result
->
add
(
getOptionData
(
option
));
}
return
(
result
);
}
void
TranslatorOptionDataList
::
setOptionDataList
(
const
string
&
xpath
,
ConstElementPtr
elem
)
{
try
{
if
((
model_
==
"kea-dhcp4"
)
||
(
model_
==
"kea-dhcp6"
))
{
setOptionDataListKea
(
xpath
,
elem
);
}
else
{
isc_throw
(
NotImplemented
,
"setOptionDataList not implemented for the model: "
<<
model_
);
}
}
catch
(
const
sysrepo_exception
&
ex
)
{
isc_throw
(
SysrepoError
,
"sysrepo error setting option data list '"
<<
elem
->
str
()
<<
"' at '"
<<
xpath
<<
"': "
<<
ex
.
what
());
}
}
void
TranslatorOptionDataList
::
setOptionDataListKea
(
const
string
&
xpath
,
ConstElementPtr
elem
)
{
for
(
size_t
i
=
0
;
i
<
elem
->
size
();
++
i
)
{
ConstElementPtr
option
=
elem
->
get
(
i
);
if
(
!
option
->
contains
(
"code"
))
{
isc_throw
(
BadValue
,
"option data without code: "
<<
option
->
str
());
}
unsigned
code
=
static_cast
<
unsigned
>
(
option
->
get
(
"code"
)
->
intValue
());
if
(
!
option
->
contains
(
"space"
))
{
isc_throw
(
BadValue
,
"option data without space: "
<<
option
->
str
());
}
string
space
=
option
->
get
(
"space"
)
->
stringValue
();
ostringstream
keys
;
keys
<<
xpath
<<
"/option-data[code='"
<<
code
<<
"'][space='"
<<
space
<<
"']"
;
setOptionData
(
keys
.
str
(),
option
);
}
}
};
// end of namespace isc::yang
};
// end of namespace isc
src/lib/yang/translator_option_data.h
0 → 100644
View file @
63d5e666
// Copyright (C) 2018 Internet Systems Consortium, Inc. ("ISC")
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
#ifndef ISC_TRANSLATOR_OPTION_DATA_H
#define ISC_TRANSLATOR_OPTION_DATA_H 1
#include <yang/translator.h>
#include <list>
namespace
isc
{
namespace
yang
{
// @brief Between Yang and JSON translator class for the option data.
class
TranslatorOptionData
:
virtual
public
TranslatorBasic
{
public:
/// @brief Constructor.
///
/// @param session Sysrepo session.
/// @param model Model name.
TranslatorOptionData
(
S_Session
session
,
const
std
::
string
&
model
);
/// @brief Destructor.
virtual
~
TranslatorOptionData
();
/// @brief Get and translate an option data from Yang to JSON.
///
/// JSON syntax for Kea DHCP with command channel is:
/// @code
/// {
/// "code": <code>,
/// "name": <name>,
/// "space": <space>,
/// "csv-format": <csv format flag>,
/// "data": <value>,
/// "always-send": <always send flag>,
/// "user-context": { <json map> },
/// "comment": "<comment>"
/// }
/// @endcode
///
/// @param xpath The xpath of the option data.
/// @return JSON representation of the option data.
/// @throw SysrepoError when sysrepo raises an error.
isc
::
data
::
ElementPtr
getOptionData
(
const
std
::
string
&
xpath
);
/// @brief Translate and set option data from JSON to Yang.
///
/// @param xpath The xpath of the option data.
/// @param elem The JSON element.
void
setOptionData
(
const
std
::
string
&
xpath
,
isc
::
data
::
ConstElementPtr
elem
);
protected:
/// @brief getOptionData JSON for kea-dhcp[46].
///
/// @param xpath The xpath of the option data.
/// @return JSON representation of the option data.
/// @throw SysrepoError when sysrepo raises an error.
isc
::
data
::
ElementPtr
getOptionDataKea
(
const
std
::
string
&
xpath
);
/// @brief setOptionData for kea-dhcp[46].
///
/// Yang syntax for kea-dhcp[46] with code and space as keys is:
/// @code
/// +--rw name? string
/// +--rw data? string
/// +--rw code uint8 / uint16
/// +--rw space string
/// +--rw csv-format? string
/// +--rw always-send? boolean
/// +--rw user-context? string
/// @endcode
///
/// @param xpath The xpath of the option data.
/// @param elem The JSON element.
void
setOptionDataKea
(
const
std
::
string
&
xpath
,
isc
::
data
::
ConstElementPtr
elem
);
/// @brief The model.
std
::
string
model_
;
};
// @brief Between Yang and JSON translator class for option data list.
class
TranslatorOptionDataList
:
virtual
public
TranslatorOptionData
{
public:
/// @brief Constructor.
///
/// @param session Sysrepo session.
/// @param model Model name.
TranslatorOptionDataList
(
S_Session
session
,
const
std
::
string
&
model
);
/// @brief Destructor.
virtual
~
TranslatorOptionDataList
();
/// @brief Get and translate option data list from Yang to JSON.
///
/// @param xpath The xpath of the option data list.
/// @throw SysrepoError when sysrepo raises an error.
isc
::
data
::
ConstElementPtr
getOptionDataList
(
const
std
::
string
&
xpath
);
/// @brief Translate and set option data list from JSON to Yang.
///
/// @param xpath The xpath of the option data list.
/// @param elem The JSON element.
void
setOptionDataList
(
const
std
::
string
&
xpath
,
isc
::
data
::
ConstElementPtr
elem
);
protected:
/// @brief getOptionDataList for kea-dhcp[46].
///
/// @param xpath The xpath of the option data list.
/// @throw SysrepoError when sysrepo raises an error.
isc
::
data
::
ConstElementPtr
getOptionDataListKea
(
const
std
::
string
&
xpath
);
/// @brief setOptionDataList for kea-dhcp[46].
///
/// Yang syntax is a option-data list keyed by code and space.
///
/// @param xpath The xpath of the option data list.
/// @param elem The JSON element.
void
setOptionDataListKea
(
const
std
::
string
&
xpath
,
isc
::
data
::
ConstElementPtr
elem
);
/// @brief The model.
std
::
string
model_
;
};
};
// end of namespace isc::yang
};
// end of namespace isc
#endif // ISC_TRANSLATOR_OPTION_DATA_H
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment