diff --git a/common/python/rift/mano/sdn/__init__.py b/common/python/rift/mano/sdn/__init__.py
new file mode 100644
index 0000000..8f85832
--- /dev/null
+++ b/common/python/rift/mano/sdn/__init__.py
@@ -0,0 +1,30 @@
+
+# 
+#   Copyright 2017 RIFT.IO Inc
+#
+#   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.
+#
+
+from .accounts import (
+    SDNAccount,
+    SDNAccountCalError,
+    )
+
+from .config import (
+    SDNAccountConfigSubscriber,
+    SDNAccountConfigCallbacks
+    )
+
+from .operdata import (
+     SDNAccountDtsOperdataHandler,
+)
diff --git a/common/python/rift/mano/sdn/accounts.py b/common/python/rift/mano/sdn/accounts.py
new file mode 100644
index 0000000..d539ead
--- /dev/null
+++ b/common/python/rift/mano/sdn/accounts.py
@@ -0,0 +1,157 @@
+
+# 
+#   Copyright 2017 RIFT.IO Inc
+#
+#   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 sys
+import asyncio
+from gi import require_version
+require_version('RwTypes', '1.0')
+require_version('RwsdnalYang', '1.0')
+require_version('RwSdnYang', '1.0')
+
+from gi.repository import (
+        RwTypes,
+        RwsdnalYang,
+        RwSdnYang,
+        )
+import rw_peas
+
+if sys.version_info < (3, 4, 4):
+    asyncio.ensure_future = asyncio.async
+
+
+class PluginLoadingError(Exception):
+    pass
+
+
+class SDNAccountCalError(Exception):
+    pass
+
+
+class SDNAccount(object):
+    def __init__(self, log, rwlog_hdl, account_msg):
+        self._log = log
+        self._account_msg = account_msg.deep_copy()
+
+        self._sdn_plugin = None
+        self._engine = None
+
+        self._sdn = self.plugin.get_interface("Topology")
+        self._sdn.init(rwlog_hdl)
+
+        self._status = RwsdnalYang.SDNAccount_ConnectionStatus(
+                status="unknown",
+                details="Connection status lookup not started"
+                )
+
+        self._validate_task = None
+
+    @property
+    def plugin(self):
+        if self._sdn_plugin is None:
+            try:
+                self._sdn_plugin = rw_peas.PeasPlugin(
+                        getattr(self._account_msg, self.account_type).plugin_name,
+                        'RwSdn-1.0',
+                        )
+
+            except AttributeError as e:
+                raise PluginLoadingError(str(e))
+
+            self._engine, _, _ = self._sdn_plugin()
+
+        return self._sdn_plugin
+
+    def _wrap_status_fn(self, fn, *args, **kwargs):
+        ret = fn(*args, **kwargs)
+        rw_status = ret[0]
+        if rw_status != RwTypes.RwStatus.SUCCESS:
+            msg = "%s returned %s" % (fn.__name__, str(rw_status))
+            self._log.error(msg)
+            raise SDNAccountCalError(msg)
+
+        # If there was only one other return value besides rw_status, then just
+        # return that element.  Otherwise return the rest of the return values
+        # as a list.
+        return ret[1] if len(ret) == 2 else ret[1:]
+
+    @property
+    def sdn(self):
+        return self._sdn
+
+    @property
+    def name(self):
+        return self._account_msg.name
+
+    @property
+    def account_msg(self):
+        return self._account_msg
+
+    @property
+    def sdnal_account_msg(self):
+        return RwsdnalYang.SDNAccount.from_dict(
+                self.account_msg.as_dict(),
+                ignore_missing_keys=True,
+                )
+
+    def sdn_account_msg(self, account_dict):
+        self._account_msg = RwSdnYang.SDNAccount.from_dict(account_dict)
+
+    @property
+    def account_type(self):
+        return self._account_msg.account_type
+
+    @property
+    def connection_status(self):
+        return self._status
+
+    def update_from_cfg(self, cfg):
+        self._log.debug("Updating parent SDN Account to %s", cfg)
+
+        raise NotImplementedError("Update SDN account not yet supported")
+
+
+    @asyncio.coroutine
+    def validate_sdn_account_credentials(self, loop):
+        self._log.debug("Validating SDN Account credentials %s", self._account_msg)
+        self._status = RwSdnYang.SDNAccount_ConnectionStatus(
+                status="validating",
+                details="SDN account connection validation in progress"
+                )
+        rwstatus, status = yield from loop.run_in_executor(
+                None,
+                self._sdn.validate_sdn_creds,
+                self.sdnal_account_msg,
+                )
+        if rwstatus == RwTypes.RwStatus.SUCCESS:
+            self._status = RwSdnYang.SDNAccount_ConnectionStatus.from_dict(status.as_dict())
+        else:
+            self._status = RwSdnYang.SDNAccount_ConnectionStatus(
+                    status="failure",
+                    details="Error when calling SDNAL validate SDN creds"
+                    )
+
+        self._log.info("Got SDN account validation response: %s", self._status)
+
+    def start_validate_credentials(self, loop):
+        if self._validate_task is not None:
+            self._validate_task.cancel()
+            self._validate_task = None
+
+        self._validate_task = asyncio.ensure_future(
+                self.validate_sdn_account_credentials(loop),
+                loop=loop
+                )
diff --git a/common/python/rift/mano/sdn/config.py b/common/python/rift/mano/sdn/config.py
new file mode 100644
index 0000000..a9de01b
--- /dev/null
+++ b/common/python/rift/mano/sdn/config.py
@@ -0,0 +1,240 @@
+
+#
+#   Copyright 2017 RIFT.IO Inc
+#
+#   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 asyncio
+
+import gi
+gi.require_version('RwDts', '1.0')
+import rift.tasklets
+
+from gi.repository import (
+    RwDts as rwdts,
+    ProtobufC,
+    )
+
+from . import accounts
+
+
+class SDNAccountNotFound(Exception):
+    pass
+
+
+class SDNAccountError(Exception):
+    pass
+
+
+def get_add_delete_update_cfgs(dts_member_reg, xact, key_name):
+    # Unforunately, it is currently difficult to figure out what has exactly
+    # changed in this xact without Pbdelta support (RIFT-4916)
+    # As a workaround, we can fetch the pre and post xact elements and
+    # perform a comparison to figure out adds/deletes/updates
+    xact_cfgs = list(dts_member_reg.get_xact_elements(xact))
+    curr_cfgs = list(dts_member_reg.elements)
+
+    xact_key_map = {getattr(cfg, key_name): cfg for cfg in xact_cfgs}
+    curr_key_map = {getattr(cfg, key_name): cfg for cfg in curr_cfgs}
+
+    # Find Adds
+    added_keys = set(xact_key_map) - set(curr_key_map)
+    added_cfgs = [xact_key_map[key] for key in added_keys]
+
+    # Find Deletes
+    deleted_keys = set(curr_key_map) - set(xact_key_map)
+    deleted_cfgs = [curr_key_map[key] for key in deleted_keys]
+
+    # Find Updates
+    updated_keys = set(curr_key_map) & set(xact_key_map)
+    updated_cfgs = [xact_key_map[key] for key in updated_keys if xact_key_map[key] != curr_key_map[key]]
+
+    return added_cfgs, deleted_cfgs, updated_cfgs
+
+
+class SDNAccountConfigCallbacks(object):
+    def __init__(self,
+                 on_add_apply=None, on_add_prepare=None,
+                 on_delete_apply=None, on_delete_prepare=None):
+
+        @asyncio.coroutine
+        def prepare_noop(*args, **kwargs):
+            pass
+
+        def apply_noop(*args, **kwargs):
+            pass
+
+        self.on_add_apply = on_add_apply
+        self.on_add_prepare = on_add_prepare
+        self.on_delete_apply = on_delete_apply
+        self.on_delete_prepare = on_delete_prepare
+
+        for f in ('on_add_apply', 'on_delete_apply'):
+            ref = getattr(self, f)
+            if ref is None:
+                setattr(self, f, apply_noop)
+                continue
+
+            if asyncio.iscoroutinefunction(ref):
+                raise ValueError('%s cannot be a coroutine' % (f,))
+
+        for f in ('on_add_prepare', 'on_delete_prepare'):
+            ref = getattr(self, f)
+            if ref is None:
+                setattr(self, f, prepare_noop)
+                continue
+
+            if not asyncio.iscoroutinefunction(ref):
+                raise ValueError("%s must be a coroutine" % f)
+
+
+class SDNAccountConfigSubscriber(object):
+    XPATH = "C,/rw-sdn:sdn/rw-sdn:account"
+
+    def __init__(self, dts, log, rwlog_hdl, sdn_callbacks, acctstore):
+        self._dts = dts
+        self._log = log
+        self._rwlog_hdl = rwlog_hdl
+        self._reg = None
+
+        self.accounts = acctstore
+
+        self._sdn_callbacks = sdn_callbacks
+
+    def add_account(self, account_msg):
+        self._log.info("adding sdn account: {}".format(account_msg))
+
+        account = accounts.SDNAccount(self._log, self._rwlog_hdl, account_msg)
+        self.accounts[account.name] = account
+
+        self._sdn_callbacks.on_add_apply(account)
+
+    def delete_account(self, account_name):
+        self._log.info("deleting sdn account: {}".format(account_name))
+        del self.accounts[account_name]
+
+        self._sdn_callbacks.on_delete_apply(account_name)
+
+    def update_account(self, account_msg):
+        """ Update an existing sdn account
+
+        In order to simplify update, turn an update into a delete followed by
+        an add.  The drawback to this approach is that we will not support
+        updates of an "in-use" sdn account, but this seems like a
+        reasonable trade-off.
+
+
+        Arguments:
+            account_msg - The sdn account config message
+        """
+        self._log.info("updating sdn account: {}".format(account_msg))
+
+        self.delete_account(account_msg.name)
+        self.add_account(account_msg)
+
+    def register(self):
+        @asyncio.coroutine
+        def apply_config(dts, acg, xact, action, _):
+            self._log.debug("Got sdn account apply config (xact: %s) (action: %s)", xact, action)
+
+            if xact.xact is None:
+                if action == rwdts.AppconfAction.INSTALL:
+                    curr_cfg = self._reg.elements
+                    for cfg in curr_cfg:
+                        self._log.debug("SDN account being re-added after restart.")
+                        if not cfg.has_field('account_type'):
+                            raise SDNAccountError("New SDN account must contain account_type field.")
+                        self.add_account(cfg)
+                else:
+                    # When RIFT first comes up, an INSTALL is called with the current config
+                    # Since confd doesn't actally persist data this never has any data so
+                    # skip this for now.
+                    self._log.debug("No xact handle.  Skipping apply config")
+
+                return
+
+            add_cfgs, delete_cfgs, update_cfgs = get_add_delete_update_cfgs(
+                    dts_member_reg=self._reg,
+                    xact=xact,
+                    key_name="name",
+                    )
+
+            # Handle Deletes
+            for cfg in delete_cfgs:
+                self.delete_account(cfg.name)
+
+            # Handle Adds
+            for cfg in add_cfgs:
+                self.add_account(cfg)
+
+            # Handle Updates
+            for cfg in update_cfgs:
+                self.update_account(cfg)
+
+        @asyncio.coroutine
+        def on_prepare(dts, acg, xact, xact_info, ks_path, msg, scratch):
+            """ Prepare callback from DTS for SDN Account """
+
+            action = xact_info.query_action
+            self._log.debug("SDN account on_prepare config received (action: %s): %s",
+                            xact_info.query_action, msg)
+
+            if action in [rwdts.QueryAction.CREATE, rwdts.QueryAction.UPDATE]:
+                if msg.name in self.accounts:
+                    self._log.debug("SDN account already exists. Invoking update request")
+
+                    # Since updates are handled by a delete followed by an add, invoke the
+                    # delete prepare callbacks to give clients an opportunity to reject.
+                    yield from self._sdn_callbacks.on_delete_prepare(msg.name)
+
+                else:
+                    self._log.debug("SDN account does not already exist. Invoking on_prepare add request")
+                    if not msg.has_field('account_type'):
+                        raise SDNAccountError("New sdn account must contain account_type field.")
+
+                    account = accounts.SDNAccount(self._log, self._rwlog_hdl, msg)
+                    yield from self._sdn_callbacks.on_add_prepare(account)
+
+            elif action == rwdts.QueryAction.DELETE:
+                # Check if the entire SDN account got deleted
+                fref = ProtobufC.FieldReference.alloc()
+                fref.goto_whole_message(msg.to_pbcm())
+                if fref.is_field_deleted():
+                    yield from self._sdn_callbacks.on_delete_prepare(msg.name)
+
+                else:
+                    self._log.error("Deleting individual fields for SDN account not supported")
+                    xact_info.respond_xpath(rwdts.XactRspCode.NACK)
+                    return
+
+            else:
+                self._log.error("Action (%s) NOT SUPPORTED", action)
+                xact_info.respond_xpath(rwdts.XactRspCode.NACK)
+
+            xact_info.respond_xpath(rwdts.XactRspCode.ACK)
+
+        self._log.debug("Registering for SDN Account config using xpath: %s",
+                        SDNAccountConfigSubscriber.XPATH,
+                        )
+
+        acg_handler = rift.tasklets.AppConfGroup.Handler(
+                        on_apply=apply_config,
+                        )
+
+        with self._dts.appconf_group_create(acg_handler) as acg:
+            self._reg = acg.register(
+                    xpath=SDNAccountConfigSubscriber.XPATH,
+                    flags=rwdts.Flag.SUBSCRIBER | rwdts.Flag.DELTA_READY | rwdts.Flag.CACHE,
+                    on_prepare=on_prepare,
+                    )
diff --git a/common/python/rift/mano/sdn/operdata.py b/common/python/rift/mano/sdn/operdata.py
new file mode 100644
index 0000000..b29f100
--- /dev/null
+++ b/common/python/rift/mano/sdn/operdata.py
@@ -0,0 +1,128 @@
+
+#
+#   Copyright 2017 RIFT.IO Inc
+#
+#   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 asyncio
+import rift.tasklets
+
+from gi.repository import(
+        RwSdnYang,
+        RwDts as rwdts,
+        )
+
+
+class SDNAccountNotFound(Exception):
+    pass
+
+
+class SDNAccountDtsOperdataHandler(object):
+    def __init__(self, dts, log, loop):
+        self._dts = dts
+        self._log = log
+        self._loop = loop
+
+        self.sdn_accounts = {}
+
+    def add_sdn_account(self, account):
+        self.sdn_accounts[account.name] = account
+        account.start_validate_credentials(self._loop)
+
+    def delete_sdn_account(self, account_name):
+        del self.sdn_accounts[account_name]
+
+    def get_saved_sdn_accounts(self, sdn_account_name):
+        ''' Get SDN Account corresponding to passed name, or all saved accounts if name is None'''
+        saved_sdn_accounts = []
+
+        if sdn_account_name is None or sdn_account_name == "":
+            sdn_accounts = list(self.sdn_accounts.values())
+            saved_sdn_accounts.extend(sdn_accounts)
+        elif sdn_account_name in self.sdn_accounts:
+            account = self.sdn_accounts[sdn_account_name]
+            saved_sdn_accounts.append(account)
+        else:
+            errstr = "SDN account {} does not exist".format(sdn_account_name)
+            raise KeyError(errstr)
+
+        return saved_sdn_accounts
+
+    def _register_show_status(self):
+        def get_xpath(sdn_name=None):
+            return "D,/rw-sdn:sdn/account{}/connection-status".format(
+                    "[name='%s']" % sdn_name if sdn_name is not None else ''
+                    )
+
+        @asyncio.coroutine
+        def on_prepare(xact_info, action, ks_path, msg):
+            self._log.debug("Got show SDN connection status request: %s", ks_path.create_string())
+            path_entry = RwSdnYang.SDNAccount.schema().keyspec_to_entry(ks_path)
+            sdn_account_name = path_entry.key00.name
+
+            try:
+                saved_accounts = self.get_saved_sdn_accounts(sdn_account_name)
+                for account in saved_accounts:
+                    connection_status = account.connection_status
+                    self._log.debug("Responding to SDN connection status request: %s", connection_status)
+                    xact_info.respond_xpath(
+                            rwdts.XactRspCode.MORE,
+                            xpath=get_xpath(account.name),
+                            msg=account.connection_status,
+                            )
+            except KeyError as e:
+                self._log.warning(str(e))
+                xact_info.respond_xpath(rwdts.XactRspCode.NA)
+                return
+
+            xact_info.respond_xpath(rwdts.XactRspCode.ACK)
+
+        yield from self._dts.register(
+                xpath=get_xpath(),
+                handler=rift.tasklets.DTS.RegistrationHandler(
+                    on_prepare=on_prepare),
+                flags=rwdts.Flag.PUBLISHER,
+                )
+
+    def _register_validate_rpc(self):
+        def get_xpath():
+            return "/rw-sdn:update-sdn-status"
+
+        @asyncio.coroutine
+        def on_prepare(xact_info, action, ks_path, msg):
+            if not msg.has_field("sdn_account"):
+                raise SDNAccountNotFound("SDN account name not provided")
+
+            sdn_account_name = msg.sdn_account
+            try:
+                account = self.sdn_accounts[sdn_account_name]
+            except KeyError:
+                raise SDNAccountNotFound("SDN account name %s not found" % sdn_account_name)
+
+            account.start_validate_credentials(self._loop)
+
+            xact_info.respond_xpath(rwdts.XactRspCode.ACK)
+
+        yield from self._dts.register(
+                xpath=get_xpath(),
+                handler=rift.tasklets.DTS.RegistrationHandler(
+                    on_prepare=on_prepare
+                    ),
+                flags=rwdts.Flag.PUBLISHER,
+                )
+
+    @asyncio.coroutine
+    def register(self):
+        yield from self._register_show_status()
+        yield from self._register_validate_rpc()
