Initial DT workflow

Sample PPPoE-based workflow.
Track the subscriber PPPoE protocols state, authentication and IP address assignement are done via PPPoE protocols (PAP, CHAP, IPCP...).
Work with BNG app running on ONOS that generates events in the bng.pppoe Kafka topic.

Change-Id: Iae57395dcc90d027932c790c1c36d7b3e3f3e19b
diff --git a/xos/synchronizer/migrations/0001_initial.py b/xos/synchronizer/migrations/0001_initial.py
new file mode 100644
index 0000000..a3c4808
--- /dev/null
+++ b/xos/synchronizer/migrations/0001_initial.py
@@ -0,0 +1,106 @@
+# Copyright 2017-present Open Networking Foundation
+#
+# 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.
+
+# -*- coding: utf-8 -*-
+# Generated by Django 1.11.27 on 2020-01-14 19:25
+from __future__ import unicode_literals
+
+import core.models.xosbase_header
+from django.db import migrations, models
+import django.db.models.deletion
+import django.utils.timezone
+
+
+class Migration(migrations.Migration):
+
+    initial = True
+
+    dependencies = [
+        ('core', '0012_backupoperation_decl_uuid'),
+    ]
+
+    operations = [
+        migrations.CreateModel(
+            name='DtWorkflowDriverService',
+            fields=[
+                ('service_decl_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='core.Service_decl')),
+            ],
+            options={
+                'verbose_name': 'DtWorkflowDriver Service',
+            },
+            bases=('core.service',),
+        ),
+        migrations.CreateModel(
+            name='DtWorkflowDriverServiceInstance',
+            fields=[
+                ('serviceinstance_decl_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='core.ServiceInstance_decl')),
+                ('serial_number', models.CharField(help_text=b'Serial number of ONU', max_length=256, unique=True)),
+                ('authentication_state', models.CharField(choices=[(b'AWAITING', b'Awaiting'), (b'STARTED', b'Started'), (b'APPROVED', b'Approved'), (b'DENIED', b'Denied')], default=b'AWAITING', help_text=b'Subscriber authentication state', max_length=50)),
+                ('of_dpid', models.CharField(help_text=b'OLT Openflow ID', max_length=256)),
+                ('uni_port_id', models.IntegerField(help_text=b'ONU UNI port ID')),
+                ('admin_onu_state', models.CharField(choices=[(b'AWAITING', b'Awaiting'), (b'ENABLED', b'Enabled'), (b'DISABLED', b'Disabled')], default=b'AWAITING', help_text=b'ONU administrative state', max_length=256)),
+                ('status_message', models.CharField(blank=True, default=b'', help_text=b'Status text of current state machine state', max_length=256, null=True)),
+                ('pppoe_state', models.CharField(choices=[(b'AWAITING', b'Awaiting'), (b'INITIATED', b'Initiated'), (b'CONNECTED', b'Connected'), (b'DISCONNECTED', b'Disconnected')], default=b'AWAITING', help_text=b'State of the subscriber PPPoE session', max_length=256)),
+                ('pppoe_session_id', models.CharField(blank=True, help_text=b'Subscriber PPPoE session ID', max_length=20, null=True)),
+                ('ipcp_state', models.CharField(choices=[(b'AWAITING', b'Awaiting'), (b'CONF_ACK', b'Ack'), (b'CONF_REQUEST', b'Requested')], default=b'AWAITING', help_text=b'State of the IPCP protocol for IP address assignment', max_length=256)),
+                ('ip_address', models.CharField(blank=True, help_text=b'Subscriber IP address, learned from IPCP', max_length=20, null=True)),
+                ('mac_address', models.CharField(blank=True, help_text=b'Subscriber MAC address', max_length=20, null=True)),
+                ('oper_onu_status', models.CharField(choices=[(b'AWAITING', b'Awaiting'), (b'ENABLED', b'Enabled'), (b'DISABLED', b'Disabled')], default=b'AWAITING', help_text=b'ONU operational state', max_length=256)),
+            ],
+            options={
+                'verbose_name': 'DtWorkflowDriver Service Instance',
+            },
+            bases=('core.serviceinstance',),
+        ),
+        migrations.CreateModel(
+            name='DtWorkflowDriverWhiteListEntry',
+            fields=[
+                ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
+                ('created', models.DateTimeField(auto_now_add=True, help_text=b'Time this model was created')),
+                ('updated', models.DateTimeField(default=django.utils.timezone.now, help_text=b'Time this model was changed by a non-synchronizer')),
+                ('enacted', models.DateTimeField(blank=True, default=None, help_text=b'When synced, set to the timestamp of the data that was synced', null=True)),
+                ('policed', models.DateTimeField(blank=True, default=None, help_text=b'When policed, set to the timestamp of the data that was policed', null=True)),
+                ('backend_register', models.CharField(blank=True, default=b'{}', max_length=1024, null=True)),
+                ('backend_need_delete', models.BooleanField(default=False)),
+                ('backend_need_reap', models.BooleanField(default=False)),
+                ('backend_status', models.CharField(default=b'Provisioning in progress', max_length=1024)),
+                ('backend_code', models.IntegerField(default=0)),
+                ('deleted', models.BooleanField(default=False)),
+                ('write_protect', models.BooleanField(default=False)),
+                ('lazy_blocked', models.BooleanField(default=False)),
+                ('no_sync', models.BooleanField(default=False)),
+                ('no_policy', models.BooleanField(default=False)),
+                ('policy_status', models.CharField(blank=True, default=b'Policy in process', max_length=1024, null=True)),
+                ('policy_code', models.IntegerField(blank=True, default=0, null=True)),
+                ('leaf_model_name', models.CharField(help_text=b'The most specialized model in this chain of inheritance, often defined by a service developer', max_length=1024)),
+                ('backend_need_delete_policy', models.BooleanField(default=False, help_text=b'True if delete model_policy must be run before object can be reaped')),
+                ('xos_managed', models.BooleanField(default=True, help_text=b'True if xos is responsible for creating/deleting this object')),
+                ('backend_handle', models.CharField(blank=True, help_text=b'Handle used by the backend to track this object', max_length=1024, null=True)),
+                ('changed_by_step', models.DateTimeField(blank=True, default=None, help_text=b'Time this model was changed by a sync step', null=True)),
+                ('changed_by_policy', models.DateTimeField(blank=True, default=None, help_text=b'Time this model was changed by a model policy', null=True)),
+                ('serial_number', models.CharField(help_text=b'ONU Serial Number', max_length=256)),
+                ('pon_port_id', models.IntegerField(help_text=b'PON Port on which this ONU is expected to show up')),
+                ('device_id', models.CharField(help_text=b'OLT Device (logical device id) on which this ONU is expected to show up', max_length=54)),
+                ('owner', models.ForeignKey(help_text=b'DtWorkflowDriverService that owns this white list entry', on_delete=django.db.models.deletion.CASCADE, related_name='whitelist_entries', to='dt-workflow-driver.DtWorkflowDriverService')),
+            ],
+            options={
+                'verbose_name': 'ONU Whitelist',
+            },
+            bases=(models.Model, core.models.xosbase_header.PlModelMixIn),
+        ),
+        migrations.AlterUniqueTogether(
+            name='dtworkflowdriverwhitelistentry',
+            unique_together=set([('owner', 'serial_number')]),
+        ),
+    ]
diff --git a/xos/synchronizer/migrations/__init__.py b/xos/synchronizer/migrations/__init__.py
new file mode 100755
index 0000000..dd67de8
--- /dev/null
+++ b/xos/synchronizer/migrations/__init__.py
@@ -0,0 +1,13 @@
+# Copyright 2020-present Open Networking Foundation
+#
+# 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.
\ No newline at end of file