Ejemplo n.º 1
0
class SliceSerializer(SliceCreateSerializer):
    # Hack to show explicit handled resource (Vlan) - #46-note87
    # FIXME: can be removed when monkey-patch works in resources.serializers
    if is_installed('resources'):
        from resources.serializers import VlanResourceReqSerializer
        resources = VlanResourceReqSerializer(source='*', read_only=True, required=False)
    
    class Meta:
        model = Slice
        read_only_fields = ('group',)
Ejemplo n.º 2
0
 def test_get_modeladmin(self):
     # Try to get every modeladmin from controller's models
     CONTROLLER_APPS = ['communitynetworks', 'firmware', 'gis', 'issues',
         'maintenance', 'monitor', 'nodes', 'notifications', 'pings',
         'resources', 'slices', 'state', 'tinc', 'users']
     for app_name in CONTROLLER_APPS:
         if not is_installed(app_name):
             continue
         app = get_app(app_name)
         for model in get_models(app):
             get_modeladmin(model)
Ejemplo n.º 3
0
class SliverSerializer(serializers.UriHyperlinkedModelSerializer):
    id = serializers.Field(source='api_id')
    interfaces = SliverIfaceSerializer(required=False, many=True, allow_add_remove=True)
    properties = serializers.PropertyField()
    data_uri = FakeFileField(field='data', required=False)
    instance_sn = serializers.IntegerField(read_only=True)
    mgmt_net = serializers.Field()
    
    # FIXME remove when api.aggregate supports nested serializers
    # is only required because SliverDefaultsSerializer imports resources
    # serializers, and breaks api.aggregate functionality based on
    # api._registry (see class SliverDefaultsSerializer)
    if is_installed('resources'):
        from resources.serializers import ResourceReqSerializer
        resources = ResourceReqSerializer(many=True, required=False)
    
    class Meta:
        model = Sliver
        exclude = ('data',)
    
    def to_native(self, obj):
        """ hack for implementing dynamic file_uri's on FakeFile """
        self.__object__ = obj
        return super(SliverSerializer, self).to_native(obj)
    
    def validate(self, attrs):
        """ workaround about nested serialization
            sliverifaces need to be validated with an associated sliver
        """
        super(SliverSerializer, self).validate(attrs)
        ifaces = attrs.get('interfaces', []) or []
        for iface in ifaces:
            Sliver.get_registered_ifaces()[iface.type].clean_model(iface)
        return attrs

    def validate_interfaces(self, attrs, source):
        """Check that one interface of type private has been defined."""
        interfaces = attrs.get(source, [])
        
        # check that mandatory private interface has been defined
        priv_ifaces = 0
        for iface in interfaces:
            if iface.type == 'private':
                priv_ifaces += 1
            if priv_ifaces > 1:
                raise serializers.ValidationError('There can only be one interface of type private.')
        if priv_ifaces == 0:
            raise serializers.ValidationError('There must exist one interface of type private.')
        
        validate_private_iface(interfaces)
        
        for name, iface_cls in Sliver.get_registered_ifaces().items():
            validate_ifaces_nr(name, iface_cls, interfaces)
        return attrs
Ejemplo n.º 4
0
    def test_notify_operators(self):
        self.client.logout()
        self.assertFalse(is_installed('captcha'))
        name = "user" + str(int(round(time.time() * 1000)))
        password = "******"
        data = {
            "name": name,
            "username": name,
            "email": name + "@localhost",
            "password1": password,
            "password2": password,
        }
        response = self.client.post(reverse('registration_register'),
                                    data=data)
        self.assertRedirects(response, reverse('registration_complete'))

        # registration successful sends an email with confirmation URL
        self.assertEquals(len(mail.outbox), 1)
        URL_REGEX = 'http[s]?://\w+/accounts/activate/\w+'
        urls = re.findall(URL_REGEX, mail.outbox[0].body)
        self.assertEquals(len(urls), 1)
        mail.outbox = []

        # Confirm user email
        response = self.client.get(urls[0], follow=True)
        self.assertRedirects(response,
                             reverse('registration_activation_complete'),
                             status_code=301)

        # One email to operators should be sent requesting approvation
        self.assertEquals(len(mail.outbox), 1)
        self.assertTrue(settings.MAIL_REGISTRATION_APPROVE, mail.outbox[0].to)

        # The email contains the user URL
        URL_REGEX = 'http[s]?://\w+/admin/users/user/\d+/'
        urls = re.findall(URL_REGEX, mail.outbox[0].body)
        self.assertEquals(len(urls), 1)
        mail.outbox = []

        # Mark user as active
        user = User.objects.get(name=name)
        user.is_active = True
        user.save()

        # Two emails should be sent: one to user and another to operators
        self.assertEquals(len(mail.outbox), 2)
        self.assertTrue(user.email in mail.outbox[0].to)
        self.assertTrue(settings.MAIL_REGISTRATION_APPROVE, mail.outbox[1].to)

        # Registered user should be able to login
        self.client.login(username=name, password=password)
        response = self.client.get(reverse('admin:index'))
        self.assertEquals(response.status_code, 200)
Ejemplo n.º 5
0
 def test_notify_operators(self):
     self.client.logout()
     self.assertFalse(is_installed('captcha'))
     name = "user" + str(int(round(time.time() * 1000)))
     password = "******"
     data = {
         "name": name,
         "username": name,
         "email": name + "@localhost",
         "password1": password,
         "password2": password,
     }
     response = self.client.post(reverse('registration_register'), data=data)
     self.assertRedirects(response, reverse('registration_complete'))
     
     # registration successful sends an email with confirmation URL
     self.assertEquals(len(mail.outbox), 1)
     URL_REGEX = 'http[s]?://\w+/accounts/activate/\w+'
     urls = re.findall(URL_REGEX, mail.outbox[0].body)
     self.assertEquals(len(urls), 1)
     mail.outbox = []
     
     # Confirm user email
     response = self.client.get(urls[0], follow=True)
     self.assertRedirects(response, reverse('registration_activation_complete'), status_code=301)
     
     # One email to operators should be sent requesting approvation
     self.assertEquals(len(mail.outbox), 1)
     self.assertTrue(settings.MAIL_REGISTRATION_APPROVE, mail.outbox[0].to)
     
     # The email contains the user URL
     URL_REGEX = 'http[s]?://\w+/admin/users/user/\d+/'
     urls = re.findall(URL_REGEX, mail.outbox[0].body)
     self.assertEquals(len(urls), 1)
     mail.outbox = []
     
     # Mark user as active
     user = User.objects.get(name=name)
     user.is_active = True
     user.save()
     
     # Two emails should be sent: one to user and another to operators
     self.assertEquals(len(mail.outbox), 2)
     self.assertTrue(user.email in mail.outbox[0].to)
     self.assertTrue(settings.MAIL_REGISTRATION_APPROVE, mail.outbox[1].to)
     
     # Registered user should be able to login
     self.client.login(username=name, password=password)
     response = self.client.get(reverse('admin:index'))
     self.assertEquals(response.status_code, 200)
Ejemplo n.º 6
0
class SliverDefaultsSerializer(serializers.ModelSerializer):
    instance_sn = serializers.IntegerField(read_only=True)
    data_uri = FakeFileField(field='data', required=False)
    template = serializers.RelHyperlinkedRelatedField(view_name='template-detail')
    # FIXME refactor move to resources app when api.aggregate supports nested serializers
    if is_installed('resources'):
        from resources.serializers import ResourceReqSerializer
        resources = ResourceReqSerializer(source='slice_resources', many=True, required=False)

    class Meta:
        model = SliverDefaults
        exclude = ('id', 'slice', 'data')
    
    def to_native(self, obj):
        """ hack for implementing dynamic file_uri's on FakeFile """
        self.__object__ = obj
        return super(SliverDefaultsSerializer, self).to_native(obj)
Ejemplo n.º 7
0
    def cache_cndb(self, *fields):
        """ fetches fields from cndb and stores it into the database """
        cndb = self.fetch_cndb()

        for field in fields:
            node = self.content_object
            if field == 'gis':
                if not is_installed('gis'):
                    raise ImproperlyConfigured(
                        "'%s' field cannot be cached from CNDB (gis app is not installed)."
                        % field)
                from gis.models import NodeGeolocation
                position = cndb.get('attributes').get('position')
                lat, lon = position.get('lat'), position.get('lon')
                # update the node info
                try:
                    gis = node.gis  # exist related object?
                except NodeGeolocation.DoesNotExist:
                    gis = NodeGeolocation.objects.create(node=node)
                gis.geolocation = "%s,%s" % (lat, lon)
                gis.save()
            else:
                raise NotImplementedError(
                    "'%s' field cannot be cached from CNDB." % field)
                # TODO How to get other info from CNDB API?
                # can be generic? (proposal)
#                value = cndb.get(CNDB_FIELD_MAP[field])
#                setattr(node, field, value)
#                node.save()
#               # another generalization proposal:
#                CNDB_FIELD_MAP = {
#                    'arch': lambda j: j.get('machine').get('architecture'),
#                    'sliver_pub_ipv4': lambda j: j.get('sliver_pub_ipv4'),
#                    'sliver_pub_ipv4_range': lambda j: '#%d' % len(j.get('ips'))
#                }
#                value = CNDB_FIELD_MAP[field](cndb)

# update last cached time
# use timezone aware datetime
        self.cndb_cached_on = now()
        self.save()
Ejemplo n.º 8
0
    def cache_cndb(self, *fields):
        """ fetches fields from cndb and stores it into the database """
        cndb = self.fetch_cndb()
        
        for field in fields:
            node = self.content_object
            if field == 'gis':
                if not is_installed('gis'):
                    raise ImproperlyConfigured("'%s' field cannot be cached from CNDB (gis app is not installed)." % field)
                from gis.models import NodeGeolocation
                position = cndb.get('attributes').get('position')
                lat, lon = position.get('lat'), position.get('lon')
                # update the node info
                try:
                    gis = node.gis # exist related object?
                except NodeGeolocation.DoesNotExist:
                    gis = NodeGeolocation.objects.create(node=node)
                gis.geolocation = "%s,%s" % (lat, lon)
                gis.save()
            else:
                raise NotImplementedError("'%s' field cannot be cached from CNDB." % field)
                # TODO How to get other info from CNDB API?
                # can be generic? (proposal)
#                value = cndb.get(CNDB_FIELD_MAP[field])
#                setattr(node, field, value)
#                node.save()
#               # another generalization proposal:
#                CNDB_FIELD_MAP = {
#                    'arch': lambda j: j.get('machine').get('architecture'),
#                    'sliver_pub_ipv4': lambda j: j.get('sliver_pub_ipv4'),
#                    'sliver_pub_ipv4_range': lambda j: '#%d' % len(j.get('ips'))
#                }
#                value = CNDB_FIELD_MAP[field](cndb)
        
        # update last cached time
        # use timezone aware datetime
        self.cndb_cached_on = now()
        self.save()
Ejemplo n.º 9
0
    def wrapper(request, obj):
        if request.user.is_anonymous() and "HTTP_AUTHORIZATION" in request.META:
            auth = request.META["HTTP_AUTHORIZATION"].split()
            if len(auth) == 2:
                method, digest = auth
                if method == "Basic":
                    uname, passwd = base64.b64decode(digest).split(":")
                    user = authenticate(username=uname, password=passwd)
                    if user is not None:
                        if user.is_active:
                            login(request, user)
                            request.user = user
                elif method == "Token" and is_installed("rest_framework"):
                    from rest_framework.authentication import TokenAuthentication
                    from rest_framework.exceptions import AuthenticationFailed

                    try:
                        user = TokenAuthentication().authenticate_credentials(digest)[0]
                    except AuthenticationFailed:
                        pass
                    else:
                        request.user = user
        return condition(request, obj)
Ejemplo n.º 10
0
def notify_user_enabled(sender, instance, *args, **kwargs):
    """
    Notify by email user and operators when an account
    is enabled on RESTRICTED mode.
    """
    if kwargs.get('raw', False):
        return # avoid conflicts when loading fixtures
    if settings.USERS_REGISTRATION_MODE != 'RESTRICTED':
        return
    if not is_installed('registration'):
        return
    
    # Only notify if user has been created via registration
    reg_profile = instance.registrationprofile_set.first()
    if reg_profile and instance.pk and instance.is_active:
        old = User.objects.get(pk=instance.pk)
        if not old.is_active:
            send_email_template('registration/account_approved.email', {},
                instance.email)
            send_email_template('registration/account_approved_operators.email',
                {'user': instance}, settings.EMAIL_REGISTRATION_APPROVE)
            
            # remove registration profile to avoid duplicate mails
            reg_profile.delete()
Ejemplo n.º 11
0
 def wrapper(request, obj):
     if request.user.is_anonymous(
     ) and 'HTTP_AUTHORIZATION' in request.META:
         auth = request.META['HTTP_AUTHORIZATION'].split()
         if len(auth) == 2:
             method, digest = auth
             if method == "Basic":
                 uname, passwd = base64.b64decode(digest).split(':')
                 user = authenticate(username=uname, password=passwd)
                 if user is not None:
                     if user.is_active:
                         login(request, user)
                         request.user = user
             elif method == "Token" and is_installed('rest_framework'):
                 from rest_framework.authentication import TokenAuthentication
                 from rest_framework.exceptions import AuthenticationFailed
                 try:
                     user = TokenAuthentication().authenticate_credentials(
                         digest)[0]
                 except AuthenticationFailed:
                     pass
                 else:
                     request.user = user
     return condition(request, obj)
Ejemplo n.º 12
0
from django.conf.urls import patterns, url
from django.views.generic.base import TemplateView

from controller.utils.apps import is_installed
from registration.backends.default.urls import urlpatterns as registration_urlpatterns

from . import BackendFactory

if is_installed('captcha'):
    from .forms import RegistrationCaptchaForm as RegistrationForm
else:
    from .forms import RegistrationFormUniqueEmail as RegistrationForm


backend = BackendFactory.create()
ActivationView = backend.get_activation_view()
RegistrationView = backend.get_registration_view()

urlpatterns = patterns('',
   url(r'^activate/complete/$',
       TemplateView.as_view(template_name='registration/activation_complete.html'),
       name='registration_activation_complete'),
    url(r'^activate/(?P<activation_key>\w+)/$',
       ActivationView.as_view(),
       name='registration_activate'),
    url(r'^register/$',
        RegistrationView.as_view(form_class=RegistrationForm),
        name='registration_register'),
) + registration_urlpatterns
Ejemplo n.º 13
0
                pings = pings.filter(date__gt=ini)
            if pings:
                for __, ping_set in group_by_interval(pings, delta):
                    aggregated, set_size = aggregate(ping_set)
                    result['aggregated'] += aggregated
                    result['total'] += set_size
                    result['created'] += 1 if aggregated else 0
            ini = end
    return "(%(aggregated)s -> %(created)s) / %(total)s" % result


for instance in PING_INSTANCES:
    # get instance settings based on defaults
    settings = Ping.get_instance_settings(instance.get('model'))
    
    # Create periodic tasks
    hour = 2
    if is_installed(instance.get('app')) and settings.get('schedule') > 0:
        name = "pings.%s_ping" % instance.get('app')
        run_every = settings.get('schedule')
        
        @periodic_task(name=name, run_every=run_every, expires=run_every)
        def ping_instance(model=instance.get('model')):
            return ping(model)
        
        name = "pings.%s_downsample" % instance.get('app')
        @periodic_task(name=name, run_every=crontab(minute=0, hour=hour), time_limit=60*60*2)
        def downsample_pings(model=instance.get('model')):
            return downsample(model)
        hour += 1
Ejemplo n.º 14
0
def app_is_installed(app_name):
    return is_installed(app_name)
Ejemplo n.º 15
0
                for __, ping_set in group_by_interval(pings, delta):
                    aggregated, set_size = aggregate(ping_set)
                    result['aggregated'] += aggregated
                    result['total'] += set_size
                    result['created'] += 1 if aggregated else 0
            ini = end
    return "(%(aggregated)s -> %(created)s) / %(total)s" % result


for instance in PING_INSTANCES:
    # get instance settings based on defaults
    settings = Ping.get_instance_settings(instance.get('model'))

    # Create periodic tasks
    hour = 2
    if is_installed(instance.get('app')) and settings.get('schedule') > 0:
        name = "pings.%s_ping" % instance.get('app')
        run_every = settings.get('schedule')

        @periodic_task(name=name, run_every=run_every, expires=run_every)
        def ping_instance(model=instance.get('model')):
            return ping(model)

        name = "pings.%s_downsample" % instance.get('app')

        @periodic_task(name=name,
                       run_every=crontab(minute=0, hour=hour),
                       time_limit=60 * 60 * 2)
        def downsample_pings(model=instance.get('model')):
            return downsample(model)
Ejemplo n.º 16
0
def app_is_installed(app_name):
    return is_installed(app_name)
Ejemplo n.º 17
0
                self.fields[field_name].required = False
            self.fields[field_name].widget = forms.widgets.Select(choices=choices)

    for field_name in field_names:

        def clean_field(self, field_name=field_name):
            value = self.cleaned_data.get(field_name)
            return value if value != "empty" else ""

        attributes["clean_" + field_name] = clean_field

    attributes["__init__"] = __init__
    return type("VCTLocalFileForm", (base_class,), attributes)


if is_installed("firmware"):
    from firmware.admin import BaseImageInline
    from firmware.models import BaseImage
    from firmware.settings import FIRMWARE_BASE_IMAGE_EXTENSIONS

    if settings.VCT_LOCAL_FILES:
        BaseImageInline.form = local_files_form_factory(BaseImage, "image", extensions=FIRMWARE_BASE_IMAGE_EXTENSIONS)

    # Replace node firmware download for "VM manager"
    if settings.VCT_VM_MANAGEMENT:
        insert_change_view_action(Node, vm_management)
        insertattr(Node, "actions", vm_management)
        node_modeladmin = get_modeladmin(Node)
        old_get_change_view_actions_as_class = node_modeladmin.get_change_view_actions_as_class

        def get_change_view_actions_as_class(self):
Ejemplo n.º 18
0
        roles_qs = Roles.objects.filter(user=uid, group=gid)
        self.assertTrue(roles_qs.exists())
        self.assertTrue(roles_qs.get().is_slice_admin)

    def test_join_request_reject(self):
        uid = 3
        gid = 1
        self._do_action_join_request('reject')

    def test_join_request_ignore(self):
        uid = 3
        gid = 1
        self._do_action_join_request('ignore')


@unittest.skipUnless(is_installed('registration'),
                     "django-registration is required")
class RegistrationTestCase(AuthenticatedTestCase):
    @unittest.skipIf(
        is_installed('captcha'),
        "remove 'captcha' from INSTALLED_APPS for properly run this test.")
    @override_settings(USERS_REGISTRATION_MODE='RESTRICTED',
                       MAIL_REGISTRATION_APPROVE='vct@localhost')
    # Removing captcha doesn't seems to work
    #INSTALLED_APPS = remove_app(settings.INSTALLED_APPS, 'captcha'))
    def test_notify_operators(self):
        self.client.logout()
        self.assertFalse(is_installed('captcha'))
        name = "user" + str(int(round(time.time() * 1000)))
        password = "******"
        data = {
Ejemplo n.º 19
0
from django.conf.urls import patterns, url
from django.views.generic.base import TemplateView

from controller.utils.apps import is_installed
from registration.backends.default.urls import urlpatterns as registration_urlpatterns

from . import BackendFactory

if is_installed('captcha'):
    from .forms import RegistrationCaptchaForm as RegistrationForm
else:
    from .forms import RegistrationFormUniqueEmail as RegistrationForm

backend = BackendFactory.create()
ActivationView = backend.get_activation_view()
RegistrationView = backend.get_registration_view()

urlpatterns = patterns(
    '',
    url(r'^activate/complete/$',
        TemplateView.as_view(
            template_name='registration/activation_complete.html'),
        name='registration_activation_complete'),
    url(r'^activate/(?P<activation_key>\w+)/$',
        ActivationView.as_view(),
        name='registration_activate'),
    url(r'^register/$',
        RegistrationView.as_view(form_class=RegistrationForm),
        name='registration_register'),
) + registration_urlpatterns
Ejemplo n.º 20
0
        return run_instance.AsyncResult(self.task_id)
    
    def revoke(self):
        self.state = self.REVOKED
        self.save()
    
    def kill(self):
        with current_app.default_connection() as connection:
            revoke(self.task_id, connection=connection, terminate=True, signal='KILL')
    
    @property
    def script(self):
        return self.execution.script


@receiver(node_heartbeat, sender=State, dispatch_uid="maintenance.retry_pending_operations")
def retry_pending_operations(sender, node, **kwargs):
    """ runs timeout instances when a node heart beat is received """
    instances = Instance.objects.filter(node=node, state=Instance.TIMEOUT,
            execution__is_active=True, execution__retry_if_offline=True)
    for instance in instances:
        instance.run()


if is_installed('firmware'):
    from firmware.models import construct_safe_locals
    @receiver(construct_safe_locals, dispatch_uid="maintenance.update_safe_locals")
    def update_safe_locals(sender, safe_locals, **kwargs):
        safe_locals.update(dict((setting, getattr(settings, setting))
                for setting in dir(settings) if setting.isupper() ))
Ejemplo n.º 21
0
    url(r'^admin/password_reset/(?P<uidb64>[-\w]+)/(?P<token>[-\w]+)/$',
        'django.contrib.auth.views.password_reset_confirm',
        name='password_reset_confirm'
    ),
    url(r'^admin/password_reset/complete/$',
        'django.contrib.auth.views.password_reset_complete',
        name='password_reset_complete'
    ),
    # Admin
    url(r'^admin/', include(admin.site.urls)),
    url(r'^admin_tools/', include('admin_tools.urls')),
    url(r'^private/', include('privatefiles.urls')),
)


if is_installed('registration'):
    urlpatterns += patterns('',
        url(r'^accounts/', include('users.registration.urls')),)
        
if is_installed('captcha'):
    urlpatterns += patterns('',
        url(r'^captcha/', include('captcha.urls')),
    )

if is_installed('api'):
    from api import api
    api.autodiscover()
    
    urlpatterns += patterns('',
        url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
        url(r'^api-token-auth/', 'rest_framework.authtoken.views.obtain_auth_token', name='api-token-auth'),
Ejemplo n.º 22
0
    url(r'^admin/password_reset/done/$',
        'django.contrib.auth.views.password_reset_done',
        name='password_reset_done'),
    url(r'^admin/password_reset/(?P<uidb64>[-\w]+)/(?P<token>[-\w]+)/$',
        'django.contrib.auth.views.password_reset_confirm',
        name='password_reset_confirm'),
    url(r'^admin/password_reset/complete/$',
        'django.contrib.auth.views.password_reset_complete',
        name='password_reset_complete'),
    # Admin
    url(r'^admin/', include(admin.site.urls)),
    url(r'^admin_tools/', include('admin_tools.urls')),
    url(r'^private/', include('privatefiles.urls')),
)

if is_installed('registration'):
    urlpatterns += patterns(
        '',
        url(r'^accounts/', include('users.registration.urls')),
    )

if is_installed('captcha'):
    urlpatterns += patterns(
        '',
        url(r'^captcha/', include('captcha.urls')),
    )

if is_installed('api'):
    from api import api
    api.autodiscover()
    def handle(self, *args, **options):
        # Warn about deprecated options
        if options.get('local'):
            self.stderr.write(
                "Warning: 'local' option is deprecated and will be ignored.\n")

        version = options.get('version')
        upgrade_notes = []
        if version:
            try:
                major, major2, minor = decode_version(version)
            except ValueError as e:
                raise CommandError(e)
            # Represent version as two digits per number: 1.2.2 -> 10202
            version = int(
                str(major) + "%02d" % int(major2) + "%02d" % int(minor))

            # Pre-upgrade operations (version specific)
            if version < 835:
                # prevent schema migrations from failing
                if is_installed('firmware'):
                    from firmware.models import Build
                    Build.objects.filter(base_image=None).update(base_image='')
            if version <= 902:
                if is_installed('maintenance'):
                    # Apply losed migrations
                    from south.models import MigrationHistory
                    migrated = MigrationHistory.objects.filter(
                        app_name='maintenance').exists()
                    if not migrated:
                        run('python manage.py migrate maintenance 0001 --fake')
            if version < 1002:
                # Update monitor settings (fix typo and add DiskFreeMonitor)
                context = {
                    'settings':
                    run("find . -type f -name 'settings.py'|grep -v 'vct/'")
                }
                # Try automaticate update (making a backup)
                if context['settings']:
                    run("cp %(settings)s %(settings)s.upgrade.bak" % context)
                    # fix NumProcessesMonitor typo
                    run("sed -i 's/NumPocessesMonitor/NumProcessesMonitor/g' "
                        "%(settings)s" % context)
                    # append disk monitor (if needed)
                    # this is a rude check (but runned in a conservative way)
                    if 'DiskFreeMonitor' not in open(
                            context['settings']).read():
                        run("sed -i '/MONITOR_MONITORS = ($/ a\ "
                            "   (\"monitor.monitors.DiskFreeMonitor\",),' "
                            "%(settings)s" % context)
                # warn the user about settings changes
                autoupdate_status = 'OK' if context['settings'] else 'FAIL'
                upgrade_notes.append(
                    'The monitor application has changed and .'
                    'some settings updates are required:\n'
                    ' - Fix typo on NumProcessesMonitor (missing "r")\n'
                    ' - Enable disk monitor\n'
                    ' Please read the monitor app doc (MONITOR_MONITORS setting)\n'
                    'AUTOUPDATE: %s' % autoupdate_status)
            if version <= 1102:
                # Handle InconsistentMigrationHistory on tinc app
                # * v0.11.2 tinc includes 0022, 0028..0030
                # * v0.11.3 tinc adds 0023..0027
                # We can force south to merge migrations because
                # are implemented to be runned without dependencies
                run('python manage.py migrate tinc 0030 --merge --noinput')

        if not options.get('specifics_only'):
            # Common stuff
            development = options.get('development')
            controller_admin = os.path.join(os.path.dirname(__file__),
                                            '../../bin/')
            controller_admin = os.path.join(controller_admin,
                                            'controller-admin.sh')
            run('chmod +x %s' % controller_admin)

            extra = '--development' if development else ''
            if options.get('proxy'):
                extra += ' --proxy %s' % options.get('proxy')
            run("%s install_requirements " % controller_admin + extra)
            run("python manage.py collectstatic --noinput")

            run("python manage.py syncdb --noinput")
            run("python manage.py migrate --noinput")
            if is_installed('firmware'):
                run("python manage.py syncfirmwareplugins")
            if is_installed('notifications'):
                run("python manage.py syncnotifications")
            if is_installed('resources'):
                run("python manage.py syncresources")
            if options.get('restart'):
                run("python manage.py restartservices")

        if not version:
            self.stderr.write(
                '\nNext time you migth want to provide a --from argument '
                'in order to run version specific upgrade operations\n')
            return

        # Post-upgrade operations (version specific)
        if version <= 629:
            # Clean existing sessions because of change on auth backend
            run('echo "delete from django_session;" | python manage.py dbshell'
                )
        if version < 801:
            deprecate_periodic_tasks(('state.ping', ))
        if version < 809:
            # Add PKI directories
            from pki import ca
            from controller.utils.paths import get_site_root
            site_root = get_site_root()
            username = run("stat -c %%U %s" % site_root)
            get_dir = lambda f: os.path.dirname(getattr(ca, f + '_path'))
            for d in set(get_dir(f) for f in ['priv_key', 'pub_key', 'cert']):
                run('mkdir -p %s' % d)
                run('chown %s %s' % (username, d))
            upgrade_notes.append(
                'HTTPS certificate support for the management '
                'network has been introduced in version 0.8.9.\n'
                'In order to use it you sould run:\n'
                '  > python manage.py setuppki\n'
                '  > sudo python manage.py setupapache\n')
        if version < 838:
            # Purge communitynetworks.periodic_cache_node_db
            from djcelery.models import PeriodicTask
            PeriodicTask.objects.filter(
                name='communitynetworks.periodic_cache_node_db').delete()
            run('rabbitmqctl stop_app')
            run('rabbitmqctl reset')
            run('rabbitmqctl start_app')
            run('service celeryd restart')
            upgrade_notes.append(
                'New Celeryd init.d configuration has been '
                'introduced in 0.8.38.\nIt is strongly recommended to upgrade by\n'
                '  > sudo python manage.py setupceleryd\n')
            # Deprecate x86 and amd64 architectures
            from nodes.models import Node
            Node.objects.filter(arch='x86').update(arch='i686')
            Node.objects.filter(arch='amd64').update(arch='x86_64')
            upgrade_notes.append(
                'In order to support Base authentication while downloading '
                'firmwares you should add "WSGIPassAuthorization On" on your apache config.\n'
                'Alternatively you can perform this operation with the following command\n'
                '  > sudo python manage.py setupapache\n'
                '  > /etc/init.d/apache2 reload\n')
        if version < 900:
            upgrade_notes.append(
                'Apache configuration is now placed under '
                '/etc/apache2/conf.d/<project_name>.conf. It is convenient for you '
                'to migrate your current configuration located on /etc/apache2/httpd.conf '
                'to this new location.\n')
            upgrade_notes.append(
                'Celery workers configuration has been updated. '
                'Please update it by running:\n'
                '  > sudo python manage.py setupceleryd\n')
        if version < 905:
            # TODO find the root cause of this
            # maybe is shit imported on settings that import settings like add_app
            # Prevent crazy import erros to appear :S
            from django.utils import translation
            translation.activate('en-us')
            # Change template types for more generic ones
            from slices.models import Template
            from slices.settings import SLICES_TEMPLATE_TYPES
            template_types = [t[0] for t in SLICES_TEMPLATE_TYPES]
            if 'debian' in template_types:
                Template.objects.filter(type='debian6').update(type='debian')
            if 'openwrt' in template_types:
                Template.objects.filter(type='openwrt-backfire').update(
                    type='openwrt')
        if version < 906:
            deprecate_periodic_tasks(('state.nodestate', 'state.sliverstate'))
        if version <= 907:
            # Generate sha256
            from slices.models import Template
            for template in Template.objects.all():
                template.save()
            upgrade_notes.append(
                "It is extremly recommended to update your database "
                "settings to enable atomic request behaviour:\n"
                "  https://docs.djangoproject.com/en/dev/topics/db/transactions/#tying-transactions-to-http-requests\n"
                "Just add:\n"
                "   'ATOMIC_REQUESTS': True,\n"
                "into DATABASES setting within <project_name>/<project_name>/settings.py"
            )
        if version <= 1003:
            # Update firmware configuration after Island refactor (#264)
            from firmware.models import ConfigFile
            try:
                cfg_file = ConfigFile.objects.get(
                    path__contains="node.tinc.connect_to")
            except (ConfigFile.DoesNotExist,
                    ConfigFile.MultipleObjectsReturned):
                # Warn the user that needs to perform manual update
                msg = "Firmware configuration update has failed. "
            else:
                cfg_file.content = cfg_file.content.replace(
                    "node.tinc.island", "node.island")
                cfg_file.save()
                msg = "Firmware configuration updated successfully. Updated ConfigFile ID: %i." % cfg_file.pk
            upgrade_notes.append(
                "%s\nPlease check version 0.10.4 release notes:\n"
                "https://wiki.confine-project.eu/soft:server-release-notes#section0104"
                % msg)
        if version < 1103:
            # Update mgmt network Server APIs certificate
            # perform raw SQL querie because models hasn't been
            # reloaded yet and cannot access e.g. server.api
            from django.db import connection
            from nodes.models import Server
            from pki import ca

            server_id = Server.objects.order_by('id').first().pk
            try:
                cert = ca.get_cert().as_pem()
            except IOError:
                msg = ("Failed to update Server APIs certificate. Missing "
                       "server certificate '%s'.\n"
                       "Run 'python manage.py setuppki --help'" % ca.cert_path)
                upgrade_notes.append(msg)
            else:
                update_sql = ('UPDATE "nodes_serverapi" SET cert = %s '
                              'WHERE "nodes_serverapi"."server_id" = %s')
                cursor = connection.cursor()
                cursor.execute(update_sql, [cert, server_id])
                del cursor
                upgrade_notes.append("Updated Server APIs certificate.")

        if upgrade_notes and options.get('print_upgrade_notes'):
            self.stdout.write('\n\033[1m\n'
                              '    ===================\n'
                              '    ** UPGRADE NOTES **\n'
                              '    ===================\n\n' +
                              '\n'.join(upgrade_notes) + '\033[m\n')
Ejemplo n.º 24
0
    def init_with_context(self, context):
        user = context['user']

        self.children += [
            items.MenuItem('Dashboard', reverse('admin:index')),
            items.Bookmarks(),
        ]

        if is_installed('nodes') and user.has_module_perms('nodes'):
            node_items = [
                items.MenuItem('Nodes',
                               reverse('admin:nodes_node_changelist')),
                items.MenuItem('Servers',
                               reverse('admin:nodes_server_changelist')),
                items.MenuItem('Islands',
                               reverse('admin:nodes_island_changelist')),
            ]
            if is_installed('state'):
                node_items.append(
                    items.MenuItem('Summary', reverse('admin:state_report')))
            if is_installed('gis'):
                node_items.insert(
                    1, items.MenuItem('Nodes Map', reverse('gis_map')))
            self.children.append(
                items.MenuItem('Nodes',
                               reverse('admin:nodes_node_changelist'),
                               children=node_items))

        if is_installed('slices') and user.has_module_perms('slices'):
            slice_children = sliver_children = None
            if is_installed('state'):
                slice_children = [
                    items.MenuItem('Status Overview',
                                   reverse('admin:state_slices')),
                ]
                sliver_children = [
                    items.MenuItem('Status Overview',
                                   reverse('admin:state_slivers')),
                ]
            self.children.append(
                items.MenuItem(
                    'Slices',
                    reverse('admin:slices_slice_changelist'),
                    children=[
                        items.MenuItem(
                            'Slices',
                            reverse('admin:slices_slice_changelist'),
                            children=slice_children),
                        items.MenuItem(
                            'Slivers',
                            reverse('admin:slices_sliver_changelist'),
                            children=sliver_children),
                        items.MenuItem(
                            'Templates',
                            reverse('admin:slices_template_changelist')),
                    ]))

        if is_installed('tinc'):
            if user.has_module_perms('tinc'):
                self.children.append(
                    items.MenuItem(
                        'Tinc',
                        reverse('admin:app_list', args=['tinc']),
                        children=[
                            items.MenuItem(
                                'TincAddresses',
                                reverse('admin:tinc_tincaddress_changelist')),
                            items.MenuItem(
                                'Hosts',
                                reverse('admin:tinc_host_changelist')),
                        ]))

        if user.is_superuser:
            administration_models = ()

            if is_installed('djcelery'):
                administration_models += ('djcelery.*', )

            admin_item = items.AppList('Administration',
                                       models=administration_models)

            # Users menu item
            user_items = [
                items.MenuItem('User', reverse('admin:users_user_changelist')),
                items.MenuItem('Group',
                               reverse('admin:users_group_changelist')),
                items.MenuItem('Roles',
                               reverse('admin:users_roles_changelist')),
            ]

            if is_installed('registration'):
                user_items.append(
                    items.MenuItem(
                        'User Registration',
                        reverse(
                            'admin:registration_registrationprofile_changelist'
                        )))

            admin_item.children.append(
                items.MenuItem('Users',
                               reverse('admin:app_list', args=['users']),
                               children=user_items))

            if is_installed('maintenance'):
                maintenance_items = [
                    items.MenuItem(
                        'Operation',
                        reverse('admin:maintenance_operation_changelist')),
                    items.MenuItem(
                        'Instance',
                        reverse('admin:maintenance_instance_changelist'))
                ]
                admin_item.children.append(
                    items.MenuItem('Maintenance',
                                   reverse('admin:app_list',
                                           args=['maintenance']),
                                   children=maintenance_items))

            if is_installed('issues'):
                issues_items = [
                    items.MenuItem('Tickets',
                                   reverse('admin:issues_ticket_changelist')),
                    items.MenuItem('Queues',
                                   reverse('admin:issues_queue_changelist'))
                ]
                admin_item.children.append(
                    items.MenuItem('Issues',
                                   reverse('admin:issues_ticket_changelist'),
                                   children=issues_items))

            if is_installed('firmware'):
                firmware_items = [
                    items.MenuItem('Configuration',
                                   reverse('admin:firmware_config_change')),
                    items.MenuItem('Builds',
                                   reverse('admin:firmware_build_changelist'))
                ]
                admin_item.children.append(
                    items.MenuItem('Firmware',
                                   reverse('admin:app_list',
                                           args=['firmware']),
                                   children=firmware_items))

            if is_installed('notifications'):
                admin_item.children.append(
                    items.MenuItem(
                        'Notifications',
                        reverse(
                            'admin:notifications_notification_changelist')), )

        else:
            admin_items = [
                items.MenuItem('Users',
                               reverse('admin:users_user_changelist')),
                items.MenuItem('Groups',
                               reverse('admin:users_group_changelist')),
            ]
            if is_installed('issues'):
                admin_items.append(
                    items.MenuItem('Tickets',
                                   reverse('admin:issues_ticket_changelist')))
            admin_item = items.MenuItem('Administration', children=admin_items)

        self.children.append(admin_item)

        if is_installed('api'):
            self.children.append(items.MenuItem('API', api_link(context)))

        self.children.append(
            items.MenuItem('Documentation',
                           'http://wiki.confine-project.eu/soft:server'))
Ejemplo n.º 25
0
class RegistrationTestCase(AuthenticatedTestCase):
    @unittest.skipIf(
        is_installed('captcha'),
        "remove 'captcha' from INSTALLED_APPS for properly run this test.")
    @override_settings(USERS_REGISTRATION_MODE='RESTRICTED',
                       MAIL_REGISTRATION_APPROVE='vct@localhost')
    # Removing captcha doesn't seems to work
    #INSTALLED_APPS = remove_app(settings.INSTALLED_APPS, 'captcha'))
    def test_notify_operators(self):
        self.client.logout()
        self.assertFalse(is_installed('captcha'))
        name = "user" + str(int(round(time.time() * 1000)))
        password = "******"
        data = {
            "name": name,
            "username": name,
            "email": name + "@localhost",
            "password1": password,
            "password2": password,
        }
        response = self.client.post(reverse('registration_register'),
                                    data=data)
        self.assertRedirects(response, reverse('registration_complete'))

        # registration successful sends an email with confirmation URL
        self.assertEquals(len(mail.outbox), 1)
        URL_REGEX = 'http[s]?://\w+/accounts/activate/\w+'
        urls = re.findall(URL_REGEX, mail.outbox[0].body)
        self.assertEquals(len(urls), 1)
        mail.outbox = []

        # Confirm user email
        response = self.client.get(urls[0], follow=True)
        self.assertRedirects(response,
                             reverse('registration_activation_complete'),
                             status_code=301)

        # One email to operators should be sent requesting approvation
        self.assertEquals(len(mail.outbox), 1)
        self.assertTrue(settings.MAIL_REGISTRATION_APPROVE, mail.outbox[0].to)

        # The email contains the user URL
        URL_REGEX = 'http[s]?://\w+/admin/users/user/\d+/'
        urls = re.findall(URL_REGEX, mail.outbox[0].body)
        self.assertEquals(len(urls), 1)
        mail.outbox = []

        # Mark user as active
        user = User.objects.get(name=name)
        user.is_active = True
        user.save()

        # Two emails should be sent: one to user and another to operators
        self.assertEquals(len(mail.outbox), 2)
        self.assertTrue(user.email in mail.outbox[0].to)
        self.assertTrue(settings.MAIL_REGISTRATION_APPROVE, mail.outbox[1].to)

        # Registered user should be able to login
        self.client.login(username=name, password=password)
        response = self.client.get(reverse('admin:index'))
        self.assertEquals(response.status_code, 200)

    def test_registration_form(self):
        """Test registration form validation."""
        # Create user to validate duplicated username, name, email
        User.objects.create(name='Frank',
                            email='frank@localhost',
                            username='******')

        # Define valid data for user registration
        data = {
            'name': 'Name Lastname',
            'username': '******',
            'email': 'name.lastname@localhost',
            'password1': 's3cr3t',
            'password2': 's3cr3t',
        }

        # check form with valid data
        form = RegistrationForm(data=data)
        self.assertTrue(form.is_valid())

        # check form with valid but uncommon e-mail address
        data_test = data.copy()
        data_test[
            'email'] = 'name.lastname+suffix@localhost'  # a plus sign is valid!
        form = RegistrationForm(data=data_test)
        self.assertTrue(form.is_valid())

        # doesn't validate with invalid username
        data_test = data.copy()
        data_test['username'] = '******'  # spaces not accepted
        form = RegistrationForm(data=data_test)
        self.assertFalse(form.is_valid(),
                         "Invalid username shouldn't validate.")

        # check invalid email validation
        data_test = data.copy()
        data_test['email'] = 'invalid-email'
        form = RegistrationForm(data=data_test)
        self.assertFalse(form.is_valid(), "Invalid email shouldn't validate.")

        # check duplicated username
        data_test = data.copy()
        data_test['username'] = '******'
        form = RegistrationForm(data=data_test)
        self.assertFalse(form.is_valid(),
                         "Duplicated username shouldn't validate.")

        # check duplicated name
        data_test = data.copy()
        data_test['name'] = 'Frank'
        form = RegistrationForm(data=data_test)
        self.assertFalse(form.is_valid(),
                         "Duplicated name shouldn't validate.")

        # check duplicated email
        data_test = data.copy()
        data_test['email'] = 'frank@localhost'
        form = RegistrationForm(data=data_test)
        self.assertFalse(form.is_valid(),
                         "Duplicated email shouldn't validate.")

        # check not matching passwords
        data_test = data.copy()
        data_test['password2'] = 'pass-not-matchs!'
        form = RegistrationForm(data=data_test)
        self.assertFalse(form.is_valid(),
                         "Different passwords shouldn't validate.")

    def test_registration_admin_search(self):
        """
        Test registration profile admin search with custom
        user model (#518).
        """
        self._login(superuser=True)
        url = reverse('admin:registration_registrationprofile_changelist')
        resp = self.client.get(url, {'q': 'foo'})
        self.assertEquals(resp.status_code, 200)
Ejemplo n.º 26
0
        roles_qs = Roles.objects.filter(user=uid, group=gid)
        self.assertTrue(roles_qs.exists())
        self.assertTrue(roles_qs.get().is_slice_admin)

    def test_join_request_reject(self):
        uid = 3
        gid = 1
        self._do_action_join_request('reject')
        
    def test_join_request_ignore(self):
        uid = 3
        gid = 1
        self._do_action_join_request('ignore')


@unittest.skipUnless(is_installed('registration'), "django-registration is required")
class RegistrationTestCase(AuthenticatedTestCase):
    
    @unittest.skipIf(is_installed('captcha'), "remove 'captcha' from INSTALLED_APPS for properly run this test.")
    @override_settings(USERS_REGISTRATION_MODE = 'RESTRICTED',
        MAIL_REGISTRATION_APPROVE = 'vct@localhost')
        # Removing captcha doesn't seems to work
        #INSTALLED_APPS = remove_app(settings.INSTALLED_APPS, 'captcha'))
    def test_notify_operators(self):
        self.client.logout()
        self.assertFalse(is_installed('captcha'))
        name = "user" + str(int(round(time.time() * 1000)))
        password = "******"
        data = {
            "name": name,
            "username": name,
Ejemplo n.º 27
0
FIRMWARE_BUILD_IMAGE_STORAGE = getattr(settings, 'FIRMWARE_BUILD_IMAGE_STORAGE',
    FileSystemStorage(location=settings.PRIVATE_MEDIA_ROOT))


FIRMWARE_BUILD_IMAGE_PATH = getattr(settings, 'FIRMWARE_BUILD_IMAGE_PATH', 'firmwares')


FIRMWARE_BASE_IMAGE_EXTENSIONS = getattr(settings, 'FIRMWARE_BASE_IMAGE_EXTENSIONS', ('.img.gz',))


FIRMWARE_PLUGINS_USB_IMAGE = getattr(settings, 'FIRMWARE_PLUGINS_USB_IMAGE',
    '%(site_root)s/confine-install.img.gz')


# FIRMWARE DEFAULT PASSWORD REMOVED
if hasattr(settings, 'FIRMWARE_PLUGINS_PASSWORD_DEFAULT'):
    import warnings
    warnings.warn("FIRMWARE_PLUGINS_PASSWORD_DEFAULT setting has been deprecated "
                  "and is currently unused. You can safely remove it.")


auth_keys_path = ''
if is_installed('maintenance'):
    from maintenance.settings import MAINTENANCE_PUB_KEY_PATH
    auth_keys_path = MAINTENANCE_PUB_KEY_PATH

FIRMWARE_PLUGINS_INITIAL_AUTH_KEYS_PATH = getattr(settings,
    'FIRMWARE_PLUGINS_INITIAL_AUTH_KEYS_PATH', auth_keys_path)
del auth_keys_path
Ejemplo n.º 28
0
        for k,v in filters.items():
            if getattr(obj, k) != v:
                return addr
        obj = getattr(obj, field, obj)
        ct = ContentType.objects.get_for_model(type(obj))
        url = reverse('admin:pings_ping_list', args=(ct.pk, obj.pk))
        state = Ping.get_state(obj)
        color = STATES_COLORS.get(state, "black")
        context = {
            'color': color,
            'title': state,
            'url': url,
            'addr': addr }
        colored = '<b><a style="color: %(color)s;" title="%(title)s" href="%(url)s">%(addr)s</a></b>' % context
        return mark_safe(colored)
    colored_address.short_description = getattr(old_method, 'short_description', old_method.__name__)
    return colored_address


for instance in PING_INSTANCES:
    if is_installed(instance.get('app')):
        context = {'app': instance.get('app')}
        for admin_class, field_name, field, __ in instance.get('admin_classes'):
            context['admin'] = admin_class
            exec('from %(app)s.admin import %(admin)s as admin' % context)
            model_field = lambda self, obj: getattr(obj, field_name)
            model_field.short_description = field_name
            old_method = getattr(admin, field_name, model_field)
            filters = instance.get('filter', {})
            setattr(admin, field_name, make_colored_address(old_method, field=field, filters=filters))
Ejemplo n.º 29
0
         return value or None


class PEMCertificateField(models.TextField):
    """X.509 PEM-encoded certificate."""
    default_validators = [validate_cert]
    
    def get_db_prep_value(self, value, connection=None, prepared=False):
        """Remove carriage return to avoid problems on API representation."""
        return value.replace('\r\n', '\n').strip() if value else None


class TrimmedCharField(models.CharField):
    """ Remove trailing spaces """
    __metaclass__ = models.SubfieldBase

    def to_python(self, value):
        if value: value = value.strip()
        return super(TrimmedCharField, self).to_python(value)

if is_installed('south'):
    from south.modelsinspector import add_introspection_rules
    add_introspection_rules([], ["^controller\.models\.fields\.MultiSelectField"])
    add_introspection_rules([], ["^controller\.models\.fields\.RSAPublicKeyField"])
    add_introspection_rules([], ["^controller\.models\.fields\.URIField"])
    add_introspection_rules([], ["^controller\.models\.fields\.NullableCharField"])
    add_introspection_rules([], ["^controller\.models\.fields\.NullableTextField"])
    add_introspection_rules([], ["^controller\.models\.fields\.PEMCertificateField"])
    add_introspection_rules([], ["^controller\.models\.fields\.TrimmedCharField"])

Ejemplo n.º 30
0
from time import time

from django.contrib.contenttypes import generic
from django.contrib.contenttypes.models import ContentType
from django.db import models

from controller.utils.apps import is_installed
from controller.utils.time import heartbeat_expires

from .settings import PING_DEFAULT_INSTANCE, PING_INSTANCES, PING_COUNT


for instance in PING_INSTANCES:
    # This has to be before Ping class in order to avoid import problems
    if is_installed(instance.get('app')):
        context = {
            'app': instance.get('app'),
            'model': instance.get('model').split('.')[1] }
        exec('from %(app)s.models import %(model)s as model' % context)
        model.add_to_class('pings', generic.GenericRelation('pings.Ping'))


class Ping(models.Model):
    ONLINE = 'ONLINE'
    OFFLINE = 'OFFLINE'
    NODATA = 'NODATA'
    
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    samples = models.PositiveIntegerField(default=PING_COUNT)
 def handle(self, *args, **options):
     # Warn about deprecated options
     if options.get('local'):
         self.stderr.write("Warning: 'local' option is deprecated and will be ignored.\n")
     
     version = options.get('version')
     upgrade_notes = []
     if version:
         try:
             major, major2, minor = decode_version(version)
         except ValueError as e:
             raise CommandError(e)
         # Represent version as two digits per number: 1.2.2 -> 10202
         version = int(str(major) + "%02d" % int(major2) + "%02d" % int(minor))
         
         # Pre-upgrade operations (version specific)
         if version < 835:
             # prevent schema migrations from failing
             if is_installed('firmware'):
                 from firmware.models import Build
                 Build.objects.filter(base_image=None).update(base_image='')
         if version <= 902:
             if is_installed('maintenance'):
                 # Apply losed migrations
                 from south.models import MigrationHistory
                 migrated = MigrationHistory.objects.filter(app_name='maintenance').exists()
                 if not migrated:
                     run('python manage.py migrate maintenance 0001 --fake')
         if version < 1002:
             # Update monitor settings (fix typo and add DiskFreeMonitor)
             context = {
                 'settings': run("find . -type f -name 'settings.py'|grep -v 'vct/'")
             }
             # Try automaticate update (making a backup)
             if context['settings']:
                 run("cp %(settings)s %(settings)s.upgrade.bak" % context)
                 # fix NumProcessesMonitor typo
                 run("sed -i 's/NumPocessesMonitor/NumProcessesMonitor/g' "
                     "%(settings)s" % context)
                 # append disk monitor (if needed)
                 # this is a rude check (but runned in a conservative way)
                 if 'DiskFreeMonitor' not in open(context['settings']).read():
                     run("sed -i '/MONITOR_MONITORS = ($/ a\ "
                         "   (\"monitor.monitors.DiskFreeMonitor\",),' "
                         "%(settings)s" % context)
             # warn the user about settings changes
             autoupdate_status = 'OK' if context['settings'] else 'FAIL'
             upgrade_notes.append('The monitor application has changed and .'
                 'some settings updates are required:\n'
                 ' - Fix typo on NumProcessesMonitor (missing "r")\n'
                 ' - Enable disk monitor\n'
                 ' Please read the monitor app doc (MONITOR_MONITORS setting)\n'
                 'AUTOUPDATE: %s' % autoupdate_status)
         if version <= 1102:
             # Handle InconsistentMigrationHistory on tinc app
             # * v0.11.2 tinc includes 0022, 0028..0030
             # * v0.11.3 tinc adds 0023..0027
             # We can force south to merge migrations because
             # are implemented to be runned without dependencies
             run('python manage.py migrate tinc 0030 --merge --noinput')
     
     if not options.get('specifics_only'):
         # Common stuff
         development = options.get('development')
         controller_admin = os.path.join(os.path.dirname(__file__), '../../bin/')
         controller_admin = os.path.join(controller_admin, 'controller-admin.sh')
         run('chmod +x %s' % controller_admin)
         
         extra = '--development' if development else ''
         if options.get('proxy'):
             extra += ' --proxy %s' % options.get('proxy')
         run("%s install_requirements " % controller_admin + extra)
         run("python manage.py collectstatic --noinput")
         
         run("python manage.py syncdb --noinput")
         run("python manage.py migrate --noinput")
         if is_installed('firmware'):
             run("python manage.py syncfirmwareplugins")
         if is_installed('notifications'):
             run("python manage.py syncnotifications")
         if is_installed('resources'):
             run("python manage.py syncresources")
         if options.get('restart'):
             run("python manage.py restartservices")
     
     if not version:
         self.stderr.write('\nNext time you migth want to provide a --from argument '
                           'in order to run version specific upgrade operations\n')
         return
     
     # Post-upgrade operations (version specific)
     if version <= 629:
         # Clean existing sessions because of change on auth backend
         run('echo "delete from django_session;" | python manage.py dbshell')
     if version < 801:
         deprecate_periodic_tasks(('state.ping',))
     if version < 809:
         # Add PKI directories
         from pki import ca
         from controller.utils.paths import get_site_root
         site_root = get_site_root()
         username = run("stat -c %%U %s" % site_root)
         get_dir = lambda f: os.path.dirname(getattr(ca, f+'_path'))
         for d in set( get_dir(f) for f in ['priv_key', 'pub_key', 'cert'] ):
             run('mkdir -p %s' % d)
             run('chown %s %s' % (username, d))
         upgrade_notes.append('HTTPS certificate support for the management '
             'network has been introduced in version 0.8.9.\n'
             'In order to use it you sould run:\n'
             '  > python manage.py setuppki\n'
             '  > sudo python manage.py setupapache\n')
     if version < 838:
         # Purge communitynetworks.periodic_cache_node_db
         from djcelery.models import PeriodicTask
         PeriodicTask.objects.filter(name='communitynetworks.periodic_cache_node_db').delete()
         run('rabbitmqctl stop_app')
         run('rabbitmqctl reset')
         run('rabbitmqctl start_app')
         run('service celeryd restart')
         upgrade_notes.append('New Celeryd init.d configuration has been '
             'introduced in 0.8.38.\nIt is strongly recommended to upgrade by\n'
             '  > sudo python manage.py setupceleryd\n')
         # Deprecate x86 and amd64 architectures
         from nodes.models import Node
         Node.objects.filter(arch='x86').update(arch='i686')
         Node.objects.filter(arch='amd64').update(arch='x86_64')
         upgrade_notes.append('In order to support Base authentication while downloading '
             'firmwares you should add "WSGIPassAuthorization On" on your apache config.\n'
             'Alternatively you can perform this operation with the following command\n'
             '  > sudo python manage.py setupapache\n'
             '  > /etc/init.d/apache2 reload\n')
     if version < 900:
         upgrade_notes.append('Apache configuration is now placed under '
             '/etc/apache2/conf.d/<project_name>.conf. It is convenient for you '
             'to migrate your current configuration located on /etc/apache2/httpd.conf '
             'to this new location.\n')
         upgrade_notes.append('Celery workers configuration has been updated. '
             'Please update it by running:\n'
             '  > sudo python manage.py setupceleryd\n')
     if version < 905:
         # TODO find the root cause of this
         # maybe is shit imported on settings that import settings like add_app
         # Prevent crazy import erros to appear :S
         from django.utils import translation
         translation.activate('en-us')
         # Change template types for more generic ones
         from slices.models import Template
         from slices.settings import SLICES_TEMPLATE_TYPES
         template_types = [ t[0] for t in SLICES_TEMPLATE_TYPES ]
         if 'debian' in template_types:
             Template.objects.filter(type='debian6').update(type='debian')
         if 'openwrt' in template_types:
             Template.objects.filter(type='openwrt-backfire').update(type='openwrt')
     if version < 906:
         deprecate_periodic_tasks(('state.nodestate', 'state.sliverstate'))
     if version <= 907:
         # Generate sha256
         from slices.models import Template
         for template in Template.objects.all():
             template.save()
         upgrade_notes.append("It is extremly recommended to update your database "
             "settings to enable atomic request behaviour:\n"
             "  https://docs.djangoproject.com/en/dev/topics/db/transactions/#tying-transactions-to-http-requests\n"
             "Just add:\n"
             "   'ATOMIC_REQUESTS': True,\n"
             "into DATABASES setting within <project_name>/<project_name>/settings.py")
     if version <= 1003:
         # Update firmware configuration after Island refactor (#264)
         from firmware.models import ConfigFile
         try:
             cfg_file = ConfigFile.objects.get(path__contains="node.tinc.connect_to")
         except (ConfigFile.DoesNotExist, ConfigFile.MultipleObjectsReturned):
             # Warn the user that needs to perform manual update
             msg = "Firmware configuration update has failed. "
         else:
             cfg_file.content = cfg_file.content.replace("node.tinc.island", "node.island")
             cfg_file.save()
             msg = "Firmware configuration updated successfully. Updated ConfigFile ID: %i." % cfg_file.pk
         upgrade_notes.append("%s\nPlease check version 0.10.4 release notes:\n"
             "https://wiki.confine-project.eu/soft:server-release-notes#section0104" % msg)
     if version < 1103:
         # Update mgmt network Server APIs certificate
         # perform raw SQL querie because models hasn't been
         # reloaded yet and cannot access e.g. server.api
         from django.db import connection
         from nodes.models import Server
         from pki import ca
         
         server_id = Server.objects.order_by('id').first().pk
         try:
             cert = ca.get_cert().as_pem()
         except IOError:
             msg = ("Failed to update Server APIs certificate. Missing "
                    "server certificate '%s'.\n"
                    "Run 'python manage.py setuppki --help'" % ca.cert_path)
             upgrade_notes.append(msg)
         else:
             update_sql = ('UPDATE "nodes_serverapi" SET cert = %s '
                           'WHERE "nodes_serverapi"."server_id" = %s')
             cursor = connection.cursor()
             cursor.execute(update_sql, [cert, server_id])
             del cursor
             upgrade_notes.append("Updated Server APIs certificate.")
     
     if upgrade_notes and options.get('print_upgrade_notes'):
         self.stdout.write('\n\033[1m\n'
             '    ===================\n'
             '    ** UPGRADE NOTES **\n'
             '    ===================\n\n' +
             '\n'.join(upgrade_notes) + '\033[m\n')
Ejemplo n.º 32
0
from django.core.urlresolvers import reverse, resolve
from django.db import models
from django.utils.safestring import mark_safe

from controller.admin import ChangeViewActions, SortableTabularInline
from controller.admin.utils import get_admin_link
from controller.utils.apps import is_installed
from permissions.admin import PermissionModelAdmin, PermissionTabularInline

from .actions import join_request, enable_account, send_email
from .filters import MyGroupsListFilter
from .forms import (UserCreationForm, UserChangeForm, GroupRolesFormSet,
    UserRolesForm, JoinRequestForm, GroupAdminForm, GroupRolesInlineForm)
from .models import User, AuthToken, Roles, Group, JoinRequest, ResourceRequest

if is_installed('registration'):
    from .registration import admin as reg_admin # overrides registration.admin


class AuthTokenInline(PermissionTabularInline):
    model = AuthToken
    extra = 0
    
    class Media:
        css = {
             'all': ('users/monospace-authtoken.css',)
        }
    
    def formfield_for_dbfield(self, db_field, **kwargs):
        """ Use monospace font style in script textarea """
        if db_field.name == 'data':
Ejemplo n.º 33
0
 def init_with_context(self, context):
     user = context['user']
     
     self.children += [
         items.MenuItem('Dashboard', reverse('admin:index')),
         items.Bookmarks(),]
     
     if is_installed('nodes') and user.has_module_perms('nodes'):
         node_items = [
             items.MenuItem('Nodes',
                 reverse('admin:nodes_node_changelist')),
             items.MenuItem('Servers',
                 reverse('admin:nodes_server_changelist')),
             items.MenuItem('Islands',
                 reverse('admin:nodes_island_changelist')),
         ]
         if is_installed('state'):
             node_items.append(
                 items.MenuItem('Summary', reverse('admin:state_report'))
             )
         if is_installed('gis'):
             node_items.insert(
                 1,
                 items.MenuItem('Nodes Map', reverse('gis_map'))
             )
         self.children.append(
             items.MenuItem('Nodes',
                 reverse('admin:nodes_node_changelist'),
                 children=node_items))
     
     if is_installed('slices') and user.has_module_perms('slices'):
         slice_children = sliver_children = None
         if is_installed('state'):
             slice_children = [
                 items.MenuItem('Status Overview',
                     reverse('admin:state_slices')),
             ]
             sliver_children = [
                 items.MenuItem('Status Overview',
                     reverse('admin:state_slivers')),
             ]
         self.children.append(items.MenuItem('Slices',
             reverse('admin:slices_slice_changelist'),
             children=[
                 items.MenuItem('Slices',
                     reverse('admin:slices_slice_changelist'),
                     children=slice_children),
                 items.MenuItem('Slivers',
                     reverse('admin:slices_sliver_changelist'),
                     children=sliver_children),
                 items.MenuItem('Templates',
                     reverse('admin:slices_template_changelist')),
             ]))
     
     if is_installed('tinc'):
         if user.has_module_perms('tinc'):
             self.children.append(items.MenuItem('Tinc',
                 reverse('admin:app_list', args=['tinc']),
                 children=[
                     items.MenuItem('TincAddresses',
                         reverse('admin:tinc_tincaddress_changelist')),
                     items.MenuItem('Hosts',
                         reverse('admin:tinc_host_changelist')),
                 ]))
     
     if user.is_superuser:
         administration_models = ()
         
         if is_installed('djcelery'):
             administration_models += ('djcelery.*',)
         
         admin_item = items.AppList('Administration', models=administration_models)
         
         # Users menu item
         user_items = [
             items.MenuItem('User',
                 reverse('admin:users_user_changelist')),
             items.MenuItem('Group',
                 reverse('admin:users_group_changelist')),
             items.MenuItem('Roles',
                 reverse('admin:users_roles_changelist')),
         ]
         
         if is_installed('registration'):
             user_items.append(
                 items.MenuItem('User Registration',
                     reverse('admin:registration_registrationprofile_changelist')))
         
         admin_item.children.append(
             items.MenuItem('Users',
                 reverse('admin:app_list', args=['users']),
                 children=user_items)
         )
         
         if is_installed('maintenance'):
             maintenance_items = [
                 items.MenuItem('Operation',
                     reverse('admin:maintenance_operation_changelist')),
                 items.MenuItem('Instance',
                     reverse('admin:maintenance_instance_changelist'))
             ]
             admin_item.children.append(
                 items.MenuItem('Maintenance',
                     reverse('admin:app_list', args=['maintenance']),
                     children=maintenance_items)
                 )
         
         if is_installed('issues'):
             issues_items = [
                 items.MenuItem('Tickets',
                     reverse('admin:issues_ticket_changelist')),
                 items.MenuItem('Queues',
                     reverse('admin:issues_queue_changelist'))
             ]
             admin_item.children.append(
                 items.MenuItem('Issues',
                     reverse('admin:issues_ticket_changelist'),
                     children=issues_items)
                 )
         
         if is_installed('firmware'):
             firmware_items = [
                 items.MenuItem('Configuration',
                     reverse('admin:firmware_config_change')),
                 items.MenuItem('Builds',
                     reverse('admin:firmware_build_changelist'))
             ]
             admin_item.children.append(
                 items.MenuItem('Firmware',
                     reverse('admin:app_list', args=['firmware']),
                     children=firmware_items)
                 )
         
         if is_installed('notifications'):
             admin_item.children.append(
                 items.MenuItem('Notifications',
                     reverse('admin:notifications_notification_changelist')),
             )
     
     else:
         admin_items = [
             items.MenuItem('Users',
                 reverse('admin:users_user_changelist')),
             items.MenuItem('Groups',
                 reverse('admin:users_group_changelist')),
             ]
         if is_installed('issues'):
             admin_items.append(
                 items.MenuItem('Tickets',
                     reverse('admin:issues_ticket_changelist'))
                 )
         admin_item = items.MenuItem('Administration',
             children=admin_items)
     
     self.children.append(admin_item)
     
     if is_installed('api'):
         self.children.append(items.MenuItem('API', api_link(context)))
     
     self.children.append(items.MenuItem('Documentation',
         'http://wiki.confine-project.eu/soft:server'))
Ejemplo n.º 34
0
from django.db import models
from django.utils.safestring import mark_safe

from controller.admin import ChangeViewActions, SortableTabularInline
from controller.admin.utils import get_admin_link
from controller.utils.apps import is_installed
from permissions.admin import PermissionModelAdmin, PermissionTabularInline

from .actions import join_request, enable_account, send_email
from .filters import MyGroupsListFilter
from .forms import (UserCreationForm, UserChangeForm, GroupRolesFormSet,
                    UserRolesForm, JoinRequestForm, GroupAdminForm,
                    GroupRolesInlineForm)
from .models import User, AuthToken, Roles, Group, JoinRequest, ResourceRequest

if is_installed('registration'):
    from .registration import admin as reg_admin  # overrides registration.admin


class AuthTokenInline(PermissionTabularInline):
    model = AuthToken
    extra = 0

    class Media:
        css = {'all': ('users/monospace-authtoken.css', )}

    def formfield_for_dbfield(self, db_field, **kwargs):
        """ Use monospace font style in script textarea """
        if db_field.name == 'data':
            kwargs['widget'] = forms.Textarea(attrs={'cols': 130, 'rows': '6'})
        return super(AuthTokenInline,
Ejemplo n.º 35
0
 def post_save(self, obj, created=False):
     if created and is_installed('resources'):
         management.call_command('syncresources')