SEBA-664 Allow ONU to be manually disabled

Change-Id: Ib23d16eca9a0a9b6c4315791e285f6e52e858e8a
diff --git a/xos/synchronizer/migrations/0007_auto_20190515_1428.py b/xos/synchronizer/migrations/0007_auto_20190515_1428.py
new file mode 100644
index 0000000..8845fc8
--- /dev/null
+++ b/xos/synchronizer/migrations/0007_auto_20190515_1428.py
@@ -0,0 +1,34 @@
+# 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.20 on 2019-05-15 18:28
+from __future__ import unicode_literals
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('volt', '0006_technologyprofile_technologyprofile_decl'),
+    ]
+
+    operations = [
+        migrations.AlterField(
+            model_name='onudevice_decl',
+            name='admin_state',
+            field=models.CharField(blank=True, choices=[(b'DISABLED', b'DISABLED'), (b'ENABLED', b'ENABLED'), (b'ADMIN_DISABLED', b'ADMIN_DISABLED')], default=b'ENABLED', help_text=b'admin state, whether port should be enabled', max_length=32, null=True),
+        ),
+    ]
diff --git a/xos/synchronizer/models/volt.xproto b/xos/synchronizer/models/volt.xproto
index 8856c0f..25fbaf1 100644
--- a/xos/synchronizer/models/volt.xproto
+++ b/xos/synchronizer/models/volt.xproto
@@ -183,7 +183,7 @@
         max_length = 256];
     optional string admin_state = 6 [
         help_text = "admin state, whether port should be enabled",
-        choices = "(('DISABLED', 'DISABLED'), ('ENABLED', 'ENABLED'))",
+        choices = "(('DISABLED', 'DISABLED'), ('ENABLED', 'ENABLED'), ('ADMIN_DISABLED', 'ADMIN_DISABLED'))",
         default = "ENABLED",
         max_length = 32];
     optional string oper_status = 7 [
diff --git a/xos/synchronizer/steps/sync_onu_device.py b/xos/synchronizer/steps/sync_onu_device.py
index 004aa09..ce63ec8 100644
--- a/xos/synchronizer/steps/sync_onu_device.py
+++ b/xos/synchronizer/steps/sync_onu_device.py
@@ -53,7 +53,7 @@
 
     def sync_record(self, o):
 
-        if o.admin_state == "DISABLED":
+        if o.admin_state in ["DISABLED", "ADMIN_DISABLED"]:
             self.disable_onu(o)
         if o.admin_state == "ENABLED":
             self.enable_onu(o)
\ No newline at end of file
diff --git a/xos/synchronizer/steps/test_sync_onu_device.py b/xos/synchronizer/steps/test_sync_onu_device.py
index 612b44f..aba57aa 100644
--- a/xos/synchronizer/steps/test_sync_onu_device.py
+++ b/xos/synchronizer/steps/test_sync_onu_device.py
@@ -82,6 +82,14 @@
         self.assertTrue(m.called)
 
     @requests_mock.Mocker()
+    def test_admin_disabled(self, m):
+        m.post("http://voltha_url:1234/api/v1/devices/test_id/disable")
+
+        self.o.admin_state = "ADMIN_DISABLED"
+        self.sync_step(model_accessor=self.model_accessor).sync_record(self.o)
+        self.assertTrue(m.called)
+
+    @requests_mock.Mocker()
     def test_disable_fail(self, m):
         m.post("http://voltha_url:1234/api/v1/devices/test_id/disable", status_code=500, text="Mock Error")