# 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='NttWorkflowDriverService',
            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': 'NttWorkflowDriver Service',
            },
            bases=('core.service',),
        ),
        migrations.CreateModel(
            name='NttWorkflowDriverServiceInstance',
            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'REQUESTED', b'Requested'), (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 MAC address', 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': 'NttWorkflowDriver Service Instance',
            },
            bases=('core.serviceinstance',),
        ),
        migrations.CreateModel(
            name='NttWorkflowDriverWhiteListEntry',
            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)),
                ('mac_address', models.CharField(blank=True, help_text=b'ONU MAC Address for package A authentication', max_length=256, null=True)),
                ('pon_port_from', models.IntegerField(help_text=b'Start ID of approved PON Port')),
                ('pon_port_to', models.IntegerField(help_text=b'End ID of approved PON Port')),
                ('owner', models.ForeignKey(help_text=b'NttWorkflowDriverService that owns this white list entry', on_delete=django.db.models.deletion.CASCADE, related_name='whitelist_entries', to='ntt-workflow-driver.NttWorkflowDriverService')),
            ],
            options={
                'verbose_name': 'ONU Whitelist',
            },
            bases=(models.Model, core.models.xosbase_header.PlModelMixIn),
        ),
        migrations.AlterUniqueTogether(
            name='nttworkflowdriverwhitelistentry',
            unique_together=set([('owner', 'mac_address')]),
        ),
    ]
