# 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')]),
        ),
    ]
