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
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
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
Sebastian Schrader
Kea
Commits
c029dc26
Commit
c029dc26
authored
Oct 17, 2018
by
Francis Dupont
Browse files
Options
Browse Files
Download
Plain Diff
[65-libyang-host_rebased] Rebased before merging
parents
f0eb96b9
06ed2a4d
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
711 additions
and
0 deletions
+711
-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_host_unittests.cc
src/lib/yang/tests/translator_host_unittests.cc
+225
-0
src/lib/yang/translator_host.cc
src/lib/yang/translator_host.cc
+278
-0
src/lib/yang/translator_host.h
src/lib/yang/translator_host.h
+205
-0
No files found.
src/lib/yang/Makefile.am
View file @
c029dc26
...
@@ -16,6 +16,7 @@ libkea_yang_la_SOURCES += translator_option_data.h
...
@@ -16,6 +16,7 @@ libkea_yang_la_SOURCES += translator_option_data.h
libkea_yang_la_SOURCES
+=
translator_option_def.cc
libkea_yang_la_SOURCES
+=
translator_option_def.cc
libkea_yang_la_SOURCES
+=
translator_option_def.h
libkea_yang_la_SOURCES
+=
translator_option_def.h
libkea_yang_la_SOURCES
+=
translator_pool.cc translator_pool.h
libkea_yang_la_SOURCES
+=
translator_pool.cc translator_pool.h
libkea_yang_la_SOURCES
+=
translator_host.cc translator_host.h
libkea_yang_la_SOURCES
+=
yang_models.h
libkea_yang_la_SOURCES
+=
yang_models.h
...
@@ -37,6 +38,7 @@ libkea_yang_include_HEADERS = \
...
@@ -37,6 +38,7 @@ libkea_yang_include_HEADERS = \
translator.h
\
translator.h
\
translator_control_socket.h
\
translator_control_socket.h
\
translator_database.h
\
translator_database.h
\
translator_host.h
\
translator_option_data.h
\
translator_option_data.h
\
translator_option_def.h
\
translator_option_def.h
\
translator_pool.h
\
translator_pool.h
\
...
...
src/lib/yang/tests/Makefile.am
View file @
c029dc26
...
@@ -25,6 +25,7 @@ run_unittests_SOURCES += translator_database_unittests.cc
...
@@ -25,6 +25,7 @@ run_unittests_SOURCES += translator_database_unittests.cc
run_unittests_SOURCES
+=
translator_option_data_unittests.cc
run_unittests_SOURCES
+=
translator_option_data_unittests.cc
run_unittests_SOURCES
+=
translator_option_def_unittests.cc
run_unittests_SOURCES
+=
translator_option_def_unittests.cc
run_unittests_SOURCES
+=
translator_pool_unittests.cc
run_unittests_SOURCES
+=
translator_pool_unittests.cc
run_unittests_SOURCES
+=
translator_host_unittests.cc
run_unittests_SOURCES
+=
run_unittests.cc
run_unittests_SOURCES
+=
run_unittests.cc
run_unittests_CPPFLAGS
=
$(AM_CPPFLAGS)
$(GTEST_INCLUDES)
run_unittests_CPPFLAGS
=
$(AM_CPPFLAGS)
$(GTEST_INCLUDES)
run_unittests_LDFLAGS
=
$(AM_LDFLAGS)
$(GTEST_LDFLAGS)
run_unittests_LDFLAGS
=
$(AM_LDFLAGS)
$(GTEST_LDFLAGS)
...
...
src/lib/yang/tests/translator_host_unittests.cc
0 → 100644
View file @
c029dc26
// 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_host.h>
#include <yang/yang_models.h>
#include <yang/tests/sysrepo_setup.h>
#include <gtest/gtest.h>
#include <sstream>
using
namespace
std
;
using
namespace
isc
;
using
namespace
isc
::
data
;
using
namespace
isc
::
yang
;
using
namespace
isc
::
yang
::
test
;
namespace
{
/// @brief Translator name.
extern
char
const
host_reservations
[]
=
"host reservations"
;
/// @brief Test fixture class for @ref TranslatorHosts.
class
TranslatorHostsTest
:
public
GenericTranslatorTest
<
host_reservations
,
TranslatorHosts
>
{
public:
/// Constructor.
TranslatorHostsTest
()
{
}
/// Destructor (does nothing).
virtual
~
TranslatorHostsTest
()
{
}
};
// This test verifies that an empty host reservation list can be properly
// translated from YANG to JSON.
TEST_F
(
TranslatorHostsTest
,
getEmpty
)
{
useModel
(
KEA_DHCP6_SERVER
);
// Get the host reservation list and checks it is empty.
const
string
&
xpath
=
"/kea-dhcp6-server:config/subnet6/subnet6[id='111']/reservations"
;
ConstElementPtr
hosts
;
EXPECT_NO_THROW
(
hosts
=
t_obj_
->
getHosts
(
xpath
));
ASSERT_TRUE
(
hosts
);
ASSERT_EQ
(
Element
::
list
,
hosts
->
getType
());
EXPECT_EQ
(
0
,
hosts
->
size
());
}
// This test verifies that one host reservation can be properly
// translated from YANG to JSON.
TEST_F
(
TranslatorHostsTest
,
get
)
{
useModel
(
KEA_DHCP6_SERVER
);
// Create the subnet 2001:db8::/48 #111.
const
string
&
subnet
=
"/kea-dhcp6-server:config/subnet6/subnet6[id='111']"
;
S_Val
v_subnet
(
new
Val
(
"2001:db8::/48"
,
SR_STRING_T
));
const
string
&
xsubnet
=
subnet
+
"/subnet"
;
EXPECT_NO_THROW
(
sess_
->
set_item
(
xsubnet
.
c_str
(),
v_subnet
));
// Create the host reservation for 2001:db8::1.
const
string
&
xpath
=
subnet
+
"/reservations"
;
ostringstream
shost
;
shost
<<
xpath
+
"/host[identifier-type='hw-address']"
<<
"[identifier='00:01:02:03:04:05']"
;
const
string
&
xaddr
=
shost
.
str
()
+
"/ip-addresses"
;
S_Val
s_addr
(
new
Val
(
"2001:db8::1"
));
EXPECT_NO_THROW
(
sess_
->
set_item
(
xaddr
.
c_str
(),
s_addr
));
// Get the host.
ConstElementPtr
host
;
EXPECT_NO_THROW
(
host
=
t_obj_
->
getHost
(
shost
.
str
()));
ASSERT_TRUE
(
host
);
ElementPtr
expected
=
Element
::
createMap
();
ElementPtr
addresses
=
Element
::
createList
();
addresses
->
add
(
Element
::
create
(
string
(
"2001:db8::1"
)));
expected
->
set
(
"hw-address"
,
Element
::
create
(
string
(
"00:01:02:03:04:05"
)));
expected
->
set
(
"ip-addresses"
,
addresses
);
EXPECT_TRUE
(
expected
->
equals
(
*
host
));
// Get the host reservation list and checks the host reservation is in it.
ConstElementPtr
hosts
;
EXPECT_NO_THROW
(
hosts
=
t_obj_
->
getHosts
(
xpath
));
ASSERT_TRUE
(
hosts
);
ASSERT_EQ
(
Element
::
list
,
hosts
->
getType
());
ASSERT_EQ
(
1
,
hosts
->
size
());
EXPECT_TRUE
(
host
->
equals
(
*
hosts
->
get
(
0
)));
}
// This test verifies that an empty host reservation list can be properly
// translated from JSON to YANG.
TEST_F
(
TranslatorHostsTest
,
setEmpty
)
{
useModel
(
KEA_DHCP6_SERVER
);
// Create the subnet 2001:db8::/48 #111.
const
string
&
subnet
=
"/kea-dhcp6-server:config/subnet6/subnet6[id='111']"
;
S_Val
v_subnet
(
new
Val
(
"2001:db8::/48"
,
SR_STRING_T
));
const
string
&
xsubnet
=
subnet
+
"/subnet"
;
EXPECT_NO_THROW
(
sess_
->
set_item
(
xsubnet
.
c_str
(),
v_subnet
));
// Set empty list.
const
string
&
xpath
=
subnet
+
"/reservations"
;
ConstElementPtr
hosts
=
Element
::
createList
();
EXPECT_NO_THROW
(
t_obj_
->
setHosts
(
xpath
,
hosts
));
// Get it back.
hosts
.
reset
();
EXPECT_NO_THROW
(
hosts
=
t_obj_
->
getHosts
(
xpath
));
ASSERT_TRUE
(
hosts
);
ASSERT_EQ
(
Element
::
list
,
hosts
->
getType
());
EXPECT_EQ
(
0
,
hosts
->
size
());
}
// This test verifies that one host reservation can be properly
// translated from JSON to YANG.
TEST_F
(
TranslatorHostsTest
,
set
)
{
useModel
(
KEA_DHCP4_SERVER
);
// Create the subnet 10.0.0.0/14 #111.
const
string
&
subnet
=
"/kea-dhcp4-server:config/subnet4/subnet4[id='111']"
;
S_Val
v_subnet
(
new
Val
(
"10.0.0.0/24"
,
SR_STRING_T
));
const
string
&
xsubnet
=
subnet
+
"/subnet"
;
EXPECT_NO_THROW
(
sess_
->
set_item
(
xsubnet
.
c_str
(),
v_subnet
));
// Set one host.
const
string
&
xpath
=
subnet
+
"/reservations"
;
ElementPtr
hosts
=
Element
::
createList
();
ElementPtr
host
=
Element
::
createMap
();
host
->
set
(
"flex-id"
,
Element
::
create
(
string
(
"00:ff"
)));
host
->
set
(
"ip-address"
,
Element
::
create
(
string
(
"10.0.0.1"
)));
host
->
set
(
"hostname"
,
Element
::
create
(
string
(
"foo"
)));
hosts
->
add
(
host
);
EXPECT_NO_THROW
(
t_obj_
->
setHosts
(
xpath
,
hosts
));
// Get it back.
hosts
.
reset
();
EXPECT_NO_THROW
(
hosts
=
t_obj_
->
getHosts
(
xpath
));
ASSERT_TRUE
(
hosts
);
ASSERT_EQ
(
Element
::
list
,
hosts
->
getType
());
ASSERT_EQ
(
1
,
hosts
->
size
());
EXPECT_TRUE
(
host
->
equals
(
*
hosts
->
get
(
0
)));
// Check the tree representation.
S_Tree
tree
;
EXPECT_NO_THROW
(
tree
=
sess_
->
get_subtree
(
"/kea-dhcp4-server:config"
));
ASSERT_TRUE
(
tree
);
string
expected
=
"kea-dhcp4-server:config (container)
\n
"
" |
\n
"
" -- subnet4 (container)
\n
"
" |
\n
"
" -- subnet4 (list instance)
\n
"
" |
\n
"
" -- id = 111
\n
"
" |
\n
"
" -- subnet = 10.0.0.0/24
\n
"
" |
\n
"
" -- reservations (container)
\n
"
" |
\n
"
" -- host (list instance)
\n
"
" |
\n
"
" -- identifier-type = flex-id
\n
"
" |
\n
"
" -- identifier = 00:ff
\n
"
" |
\n
"
" -- hostname = foo
\n
"
" |
\n
"
" -- ip-address = 10.0.0.1
\n
"
;
EXPECT_EQ
(
expected
,
tree
->
to_string
(
100
));
// Check it validates.
EXPECT_NO_THROW
(
sess_
->
validate
());
}
// This test verifies that several host reservations can be properly
// translated from YANG to JSON.
TEST_F
(
TranslatorHostsTest
,
getMany
)
{
useModel
(
KEA_DHCP6_SERVER
);
// Create the subnet 2001:db8::/48 #111.
const
string
&
subnet
=
"/kea-dhcp6-server:config/subnet6/subnet6[id='111']"
;
S_Val
v_subnet
(
new
Val
(
"2001:db8::/48"
,
SR_STRING_T
));
const
string
&
xsubnet
=
subnet
+
"/subnet"
;
EXPECT_NO_THROW
(
sess_
->
set_item
(
xsubnet
.
c_str
(),
v_subnet
));
// Create the host reservation for 2001:db8::1.
const
string
&
xpath
=
subnet
+
"/reservations"
;
ostringstream
shost
;
shost
<<
xpath
+
"/host[identifier-type='hw-address']"
<<
"[identifier='00:01:02:03:04:05']"
;
const
string
&
xaddr
=
shost
.
str
()
+
"/ip-addresses"
;
S_Val
s_addr
(
new
Val
(
"2001:db8::1"
));
EXPECT_NO_THROW
(
sess_
->
set_item
(
xaddr
.
c_str
(),
s_addr
));
// Create another reservation for 2001:db8::2
const
string
xpath2
=
subnet
+
"/reservations"
;
ostringstream
shost2
;
shost2
<<
xpath
+
"/host[identifier-type='hw-address']"
<<
"[identifier='00:01:0a:0b:0c:0d']"
;
const
string
xaddr2
=
shost2
.
str
()
+
"/ip-addresses"
;
S_Val
s_addr2
(
new
Val
(
"2001:db8::2"
));
EXPECT_NO_THROW
(
sess_
->
set_item
(
xaddr2
.
c_str
(),
s_addr2
));
// Get the host.
ConstElementPtr
hosts
;
string
hosts_path
=
subnet
+
"/reservations"
;
EXPECT_NO_THROW
(
hosts
=
t_obj_
->
getHosts
(
hosts_path
));
ASSERT_TRUE
(
hosts
);
EXPECT_EQ
(
hosts
->
str
(),
"[ {
\"
hw-address
\"
:
\"
00:01:02:03:04:05
\"
, "
"
\"
ip-addresses
\"
: [
\"
2001:db8::1
\"
] }, "
"{
\"
hw-address
\"
:
\"
00:01:0a:0b:0c:0d
\"
, "
"
\"
ip-addresses
\"
: [
\"
2001:db8::2
\"
] } ]"
);
}
};
// end of anonymous namespace
src/lib/yang/translator_host.cc
0 → 100644
View file @
c029dc26
// 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_host.h>
#include <yang/adaptor.h>
#include <yang/yang_models.h>
#include <sstream>
using
namespace
std
;
using
namespace
isc
::
data
;
namespace
isc
{
namespace
yang
{
TranslatorHost
::
TranslatorHost
(
S_Session
session
,
const
string
&
model
)
:
TranslatorBasic
(
session
),
TranslatorOptionData
(
session
,
model
),
TranslatorOptionDataList
(
session
,
model
),
model_
(
model
)
{
}
TranslatorHost
::~
TranslatorHost
()
{
}
ElementPtr
TranslatorHost
::
getHost
(
const
string
&
xpath
)
{
try
{
if
((
model_
==
KEA_DHCP4_SERVER
)
||
(
model_
==
KEA_DHCP6_SERVER
))
{
return
(
getHostKea
(
xpath
));
}
}
catch
(
const
sysrepo_exception
&
ex
)
{
isc_throw
(
SysrepoError
,
"sysrepo error getting host reservation at '"
<<
xpath
<<
"': "
<<
ex
.
what
());
}
isc_throw
(
NotImplemented
,
"getHost not implemented for the model: "
<<
model_
);
}
ElementPtr
TranslatorHost
::
getHostKea
(
const
string
&
xpath
)
{
ConstElementPtr
id_type
=
getItem
(
xpath
+
"/identifier-type"
);
ConstElementPtr
id
=
getItem
(
xpath
+
"/identifier"
);
if
(
!
id_type
||
!
id
)
{
isc_throw
(
Unexpected
,
"getHostKea requires both identifier and "
"identifier-type"
);
}
ElementPtr
result
=
Element
::
createMap
();
result
->
set
(
id_type
->
stringValue
(),
id
);
ConstElementPtr
hostname
=
getItem
(
xpath
+
"/hostname"
);
if
(
hostname
)
{
result
->
set
(
"hostname"
,
hostname
);
}
if
(
model_
==
KEA_DHCP4_SERVER
)
{
ConstElementPtr
address
=
getItem
(
xpath
+
"/ip-address"
);
if
(
address
)
{
result
->
set
(
"ip-address"
,
address
);
}
}
else
{
ConstElementPtr
addresses
=
getItems
(
xpath
+
"/ip-addresses"
);
if
(
addresses
&&
(
addresses
->
size
()
>
0
))
{
result
->
set
(
"ip-addresses"
,
addresses
);
}
ConstElementPtr
prefixes
=
getItems
(
xpath
+
"/prefixes"
);
if
(
prefixes
&&
(
prefixes
->
size
()
>
0
))
{
result
->
set
(
"prefixes"
,
prefixes
);
}
}
ConstElementPtr
options
=
getOptionDataList
(
xpath
+
"/option-data-list"
);
if
(
options
&&
(
options
->
size
()
>
0
))
{
result
->
set
(
"option-data"
,
options
);
}
ConstElementPtr
classes
=
getItems
(
xpath
+
"/client-classes"
);
if
(
classes
)
{
result
->
set
(
"client-classes"
,
classes
);
}
if
(
model_
==
KEA_DHCP4_SERVER
)
{
ConstElementPtr
next
=
getItem
(
xpath
+
"/next-server"
);
if
(
next
)
{
result
->
set
(
"next-server"
,
next
);
}
ConstElementPtr
hostname
=
getItem
(
xpath
+
"/server-hostname"
);
if
(
hostname
)
{
result
->
set
(
"server-hostname"
,
hostname
);
}
ConstElementPtr
boot
=
getItem
(
xpath
+
"/boot-file-name"
);
if
(
boot
)
{
result
->
set
(
"boot-file-name"
,
boot
);
}
}
ConstElementPtr
context
=
getItem
(
xpath
+
"/user-context"
);
if
(
context
)
{
result
->
set
(
"user-context"
,
Element
::
fromJSON
(
context
->
stringValue
()));
}
return
(
result
);
}
void
TranslatorHost
::
setHost
(
const
string
&
xpath
,
ConstElementPtr
elem
)
{
try
{
if
((
model_
==
KEA_DHCP4_SERVER
)
||
(
model_
==
KEA_DHCP6_SERVER
))
{
setHostKea
(
xpath
,
elem
);
}
else
{
isc_throw
(
NotImplemented
,
"setHost not implemented for the model: "
<<
model_
);
}
}
catch
(
const
sysrepo_exception
&
ex
)
{
isc_throw
(
SysrepoError
,
"sysrepo error setting host reservation '"
<<
elem
->
str
()
<<
"' at '"
<<
xpath
<<
"': "
<<
ex
.
what
());
}
}
void
TranslatorHost
::
setHostKea
(
const
string
&
xpath
,
ConstElementPtr
elem
)
{
ConstElementPtr
hostname
=
elem
->
get
(
"hostname"
);
// Skip identifier and identifier type as they are keys.
if
(
hostname
)
{
setItem
(
xpath
+
"/hostname"
,
hostname
,
SR_STRING_T
);
}
if
(
model_
==
KEA_DHCP4_SERVER
)
{
ConstElementPtr
address
=
elem
->
get
(
"ip-address"
);
if
(
address
)
{
setItem
(
xpath
+
"/ip-address"
,
address
,
SR_STRING_T
);
}
}
else
{
ConstElementPtr
addresses
=
elem
->
get
(
"ip-addresses"
);
if
(
addresses
&&
(
addresses
->
size
()
>
0
))
{
for
(
ConstElementPtr
address
:
addresses
->
listValue
())
{
setItem
(
xpath
+
"/ip-addresses"
,
address
,
SR_STRING_T
);
}
}
ConstElementPtr
prefixes
=
elem
->
get
(
"prefixes"
);
if
(
prefixes
&&
(
prefixes
->
size
()
>
0
))
{
for
(
ConstElementPtr
prefix
:
prefixes
->
listValue
())
{
setItem
(
xpath
+
"/prefixes"
,
prefix
,
SR_STRING_T
);
}
}
}
ConstElementPtr
options
=
elem
->
get
(
"option-data"
);
if
(
options
&&
(
options
->
size
()
>
0
))
{
setOptionDataList
(
xpath
+
"/option-data-list"
,
options
);
}
ConstElementPtr
classes
=
elem
->
get
(
"client-classes"
);
if
(
classes
&&
(
classes
->
size
()
>
0
))
{
for
(
ConstElementPtr
cclass
:
classes
->
listValue
())
{
setItem
(
xpath
+
"/client-classes"
,
cclass
,
SR_STRING_T
);
}
}
// These are DHCPv4-specific parameters.
if
(
model_
==
KEA_DHCP4_SERVER
)
{
ConstElementPtr
next
=
elem
->
get
(
"next-server"
);
if
(
next
)
{
setItem
(
xpath
+
"/next-server"
,
next
,
SR_STRING_T
);
}
ConstElementPtr
hostname
=
elem
->
get
(
"server-hostname"
);
if
(
hostname
)
{
setItem
(
xpath
+
"/server-hostname"
,
hostname
,
SR_STRING_T
);
}
ConstElementPtr
boot
=
elem
->
get
(
"boot-file-name"
);
if
(
boot
)
{
setItem
(
xpath
+
"/boot-file-name"
,
boot
,
SR_STRING_T
);
}
}
// User context is supported in both kea-dhcp4-server and kea-dhcp6-server.
ConstElementPtr
context
=
Adaptor
::
getContext
(
elem
);
if
(
context
)
{
setItem
(
xpath
+
"/user-context"
,
Element
::
create
(
context
->
str
()),
SR_STRING_T
);
}
}
TranslatorHosts
::
TranslatorHosts
(
S_Session
session
,
const
string
&
model
)
:
TranslatorBasic
(
session
),
TranslatorOptionData
(
session
,
model
),
TranslatorOptionDataList
(
session
,
model
),
TranslatorHost
(
session
,
model
),
model_
(
model
)
{
}
TranslatorHosts
::~
TranslatorHosts
()
{
}
ElementPtr
TranslatorHosts
::
getHosts
(
const
string
&
xpath
)
{
try
{
ElementPtr
result
=
Element
::
createList
();
S_Iter_Value
iter
=
getIter
(
xpath
+
"/*"
);
if
(
!
iter
)
{
// Can't happen.
isc_throw
(
Unexpected
,
"getHosts can't get iterator: "
<<
xpath
);
}
for
(;;)
{
const
string
&
host
=
getNext
(
iter
);
if
(
host
.
empty
())
{
break
;
}
result
->
add
(
getHost
(
host
));
}
return
(
result
);
}
catch
(
const
sysrepo_exception
&
ex
)
{
isc_throw
(
SysrepoError
,
"sysrepo error getting host reservations at '"
<<
xpath
<<
"': "
<<
ex
.
what
());
}
}
void
TranslatorHosts
::
setHosts
(
const
string
&
xpath
,
ConstElementPtr
elem
)
{
try
{
if
((
model_
==
KEA_DHCP4_SERVER
)
||
(
model_
==
KEA_DHCP6_SERVER
))
{
setHostsKea
(
xpath
,
elem
);
}
else
{
isc_throw
(
NotImplemented
,
"setHosts not implemented for the model: "
<<
model_
);
}
}
catch
(
const
sysrepo_exception
&
ex
)
{
isc_throw
(
SysrepoError
,
"sysrepo error setting host reservations '"
<<
elem
->
str
()
<<
"' at '"
<<
xpath
<<
"': "
<<
ex
.
what
());
}
}
void
TranslatorHosts
::
setHostsKea
(
const
string
&
xpath
,
ConstElementPtr
elem
)
{
for
(
size_t
i
=
0
;
i
<
elem
->
size
();
++
i
)
{
string
id_type
=
"unknown"
;
ConstElementPtr
host
=
elem
->
get
(
i
);
ConstElementPtr
id
=
host
->
get
(
"hw-address"
);
if
(
id
)
{
id_type
=
"hw-address"
;
goto
found
;
}
id
=
host
->
get
(
"duid"
);
if
(
id
)
{
id_type
=
"duid"
;
goto
found
;
}
if
(
model_
==
KEA_DHCP4_SERVER
)
{
id
=
host
->
get
(
"circuit-id"
);
if
(
id
)
{
id_type
=
"circuit-id"
;
goto
found
;
}
id
=
host
->
get
(
"client-id"
);
if
(
id
)
{
id_type
=
"client-id"
;
goto
found
;
}
}
id
=
host
->
get
(
"flex-id"
);
if
(
id
)
{
id_type
=
"flex-id"
;
goto
found
;
}
found:
if
(
id_type
==
"unknown"
)
{
isc_throw
(
BadValue
,
"getHosts: can't find the identifier type in "
<<
host
->
str
());
}
ostringstream
key
;
key
<<
xpath
<<
"/host[identifier-type='"
<<
id_type
<<
"'][identifier='"
<<
id
->
stringValue
()
<<
"']"
;
setHost
(
key
.
str
(),
host
);
}
}
};
// end of namespace isc::yang
};
// end of namespace isc
src/lib/yang/translator_host.h
0 → 100644
View file @
c029dc26
// 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_HOST_H
#define ISC_TRANSLATOR_HOST_H 1
#include <yang/translator_option_data.h>
#include <list>
namespace
isc
{
namespace
yang
{
/// Translation between YANG and JSON for a single host reservation.
///
/// JSON syntax for kea-dhcp4 is:
/// @code
/// {
/// "hw-address": <hardware address>,
/// "duid": <duid>,
/// "circuit-id": <circuit id>,
/// "client-id": <client id>,
/// "flex-id": <flex id>,
/// "ip-address": <ipv4 reserved address>,
/// "hostname": <hostname>,
/// "next-server": "<next server>",
/// "server-hostname": "<server hostname>",
/// "boot-file-name": "<boot file name>",
/// "client-classes": "<client class names>",
/// "option-data": [ <list of option data> ],
/// "user-context": { <json map> },
/// "comment": "<comment>"
/// }
/// @endcode
///
/// JSON syntax for kea-dhcp6 is:
/// @code
/// {
/// "hw-address": <hardware address>,
/// "duid": <duid>,
/// "flex-id": <flex id>,
/// "ip-addresses": <ipv6 reserved addresses>,
/// "prefixes": <ipv6 reserved prefixes>,
/// "hostname": <hostname>,
/// "client-classes": "<client class names>",
/// "option-data": [ <list of option data> ],
/// "user-context": { <json map> },
/// "comment": "<comment>"
/// }
/// @endcode
///
/// YANG syntax for kea-dhcp[46] is with identifier-type and identifier
/// as the list keys:
/// @code
/// +--rw identifier-type enumeration
/// +--rw identifier string
/// +--rw hostname? string
/// +--rw option-data-list option-data*
/// +--rw client-classes* string
/// +--rw user-context? string
/// (DHCPv4 only)
/// +--rw ip-address? inet:ipv4-address
/// +--rw next-server? inet:ipv4-address
/// +--rw server-hostname? string
/// +--rw boot-file-name? string
/// (DHCPv6 only)
/// +--rw ip-addresses* inet:ipv6-address
/// +--rw prefixes* inet:ipv6-prefix
/// @endcode
///
/// An example in JSON and YANG formats:
/// @code
/// [
/// {
/// "flex-id": "00:ff",
/// "ip-address": "10.0.0.1",
/// "hostname": "foo"
/// }
/// ]
/// @endcode
/// @code
/// /kea-dhcp4-server:config (container)
/// /kea-dhcp4-server:config/subnet4 (container)
/// /kea-dhcp4-server:config/subnet4/subnet4[id='111'] (list instance)
/// /kea-dhcp4-server:config/subnet4/subnet4[id='111']/id = 111
/// /kea-dhcp4-server:config/subnet4/subnet4[id='111']/subnet = 10.0.0.0/24
/// /kea-dhcp4-server:config/subnet4/subnet4[id='111']/
/// reservations (container)
/// /kea-dhcp4-server:config/subnet4/subnet4[id='111']/reservations/
/// host[identifier-type='flex-id'][identifier='00:ff'] (list instance)
/// /kea-dhcp4-server:config/subnet4/subnet4[id='111']/reservations/
/// host[identifier-type='flex-id'][identifier='00:ff']/
/// identifier-type = flex-id
/// /kea-dhcp4-server:config/subnet4/subnet4[id='111']/reservations/
/// host[identifier-type='flex-id'][identifier='00:ff']/