Differences
This shows you the differences between two versions of the page.
python_wiki:django_configuration [2018/08/03 16:41] billdozor [Django: Jquery] |
python_wiki:django_configuration [2019/05/25 23:50] |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | ====== Django Configuration ====== | ||
- | |||
- | **General Information** | ||
- | |||
- | Configuring the Django Web Framework and its dependencies. | ||
- | |||
- | \\ | ||
- | The **EXAMPLE** sections of code end up building an inventory website. | ||
- | |||
- | \\ | ||
- | **Checklist** | ||
- | * [[python_wiki: | ||
- | |||
- | ---- | ||
- | |||
- | ====== Database: MariaDB ====== | ||
- | |||
- | Configuring the MariaDB Database. | ||
- | |||
- | * Configure MariaDB to listen only on localhost< | ||
- | |||
- | [mysqld] | ||
- | bind-address=127.0.0.1</ | ||
- | |||
- | * Start/ | ||
- | systemctl start mariadb</ | ||
- | |||
- | * Run secure setup< | ||
- | * Prompts for the following: | ||
- | * Set database root password | ||
- | * Remove anonymous users | ||
- | * Disallow root logins remotely | ||
- | * Remove test databases | ||
- | * Reload privilege tables | ||
- | |||
- | * Connect to the database< | ||
- | |||
- | * Create your project' | ||
- | |||
- | * Create a database user that Django will use<code bash> | ||
- | |||
- | * Grant permissions for the app user on your project' | ||
- | |||
- | * Flush privileges< | ||
- | |||
- | ---- | ||
- | |||
- | ====== Django ====== | ||
- | |||
- | Configuring Django. | ||
- | |||
- | * Verify django works< | ||
- | >>> | ||
- | >>> | ||
- | >>> | ||
- | |||
- | ===== Project/App Setup ===== | ||
- | |||
- | * Create a directory to store the project< | ||
- | cd / | ||
- | |||
- | * Create a new Django project< | ||
- | cd / | ||
- | |||
- | * Create a new Django application inside of the project< | ||
- | |||
- | * Edit project settings (/ | ||
- | ALLOWED_HOSTS = [' | ||
- | |||
- | # Application definition (add the application, | ||
- | INSTALLED_APPS = [ | ||
- | # APPNAME.apps.APPCLASSNAME -> see ../ | ||
- | ' | ||
- | ' | ||
- | ' | ||
- | ' | ||
- | ' | ||
- | ' | ||
- | ' | ||
- | ] | ||
- | |||
- | # Static files (CSS, JavaScript, Images) | ||
- | # | ||
- | STATIC_URL = '/ | ||
- | STATIC_ROOT = '/ | ||
- | |||
- | ===== Database Setup ===== | ||
- | |||
- | * Edit project settings (/ | ||
- | # https:// | ||
- | DATABASES = { | ||
- | ' | ||
- | ' | ||
- | ' | ||
- | ' | ||
- | ' | ||
- | ' | ||
- | ' | ||
- | ' | ||
- | ' | ||
- | }, | ||
- | } | ||
- | }</ | ||
- | |||
- | * Run the initial migrate command to create database tables for built in apps that come with Django< | ||
- | python manage.py migrate</ | ||
- | |||
- | * Describe your data models (objects that will be stored in the database) (/ | ||
- | from __future__ import unicode_literals | ||
- | from django.db import models | ||
- | |||
- | # Asset Inventory Example | ||
- | class AssetEntry(models.Model): | ||
- | |||
- | ##-- Tuples for Use in Field Choices --## | ||
- | |||
- | #asset_type choices | ||
- | DEVICE_TYPES = ( | ||
- | (' | ||
- | (' | ||
- | (' | ||
- | (' | ||
- | (' | ||
- | (' | ||
- | ) | ||
- | |||
- | # asset_env choices | ||
- | ENV_NAMES = ( | ||
- | (' | ||
- | (' | ||
- | (' | ||
- | ) | ||
- | |||
- | # Linux OS List | ||
- | OS_NAMES_LINUX = ( | ||
- | (' | ||
- | (' | ||
- | ('RHEL 6', 'Red Hat Enterprise Linux 6' | ||
- | ('RHEL 7', 'Red Hat Enterprise Linux 7' | ||
- | (' | ||
- | (' | ||
- | ) | ||
- | |||
- | # Windows OS List | ||
- | OS_NAMES_WINDOWS = ( | ||
- | ('Win 2008', ' | ||
- | ('Win 2012', ' | ||
- | ('Win 2016', ' | ||
- | ('Win 7', ' | ||
- | ('Win 10', ' | ||
- | ) | ||
- | |||
- | # Other OS List | ||
- | OS_NAMES_OTHER = ( | ||
- | (' | ||
- | (' | ||
- | (' | ||
- | (' | ||
- | (' | ||
- | (' | ||
- | ) | ||
- | |||
- | # Combined OS List - for asset_os choices | ||
- | OS_NAMES = OS_NAMES_LINUX + OS_NAMES_WINDOWS + OS_NAMES_OTHER | ||
- | |||
- | # asset_hardware choices | ||
- | HW_TYPES = ( | ||
- | (' | ||
- | (' | ||
- | ) | ||
- | |||
- | ##-- AssetEntry Fields --## | ||
- | asset_name = models.CharField(' | ||
- | |||
- | asset_type = models.CharField(' | ||
- | |||
- | asset_description = models.CharField(' | ||
- | |||
- | asset_env = models.CharField(' | ||
- | |||
- | asset_os = models.CharField(' | ||
- | |||
- | asset_hardware = models.CharField(' | ||
- | |||
- | # Object representation | ||
- | def __str__(self): | ||
- | return self.asset_name | ||
- | </ | ||
- | |||
- | * Stage changes to the database< | ||
- | python manage.py makemigrations myapphere</ | ||
- | |||
- | * Make changes to the database< | ||
- | python manage.py migrate</ | ||
- | |||
- | ===== Logging Setup ===== | ||
- | |||
- | * Edit project settings (/ | ||
- | LOGGING = { | ||
- | ' | ||
- | ' | ||
- | ' | ||
- | ' | ||
- | ' | ||
- | ' | ||
- | }, | ||
- | ' | ||
- | ' | ||
- | }, | ||
- | }, | ||
- | ' | ||
- | ' | ||
- | ' | ||
- | ' | ||
- | ' | ||
- | ' | ||
- | ' | ||
- | ' | ||
- | }, | ||
- | }, | ||
- | ' | ||
- | ' | ||
- | ' | ||
- | ' | ||
- | ' | ||
- | }, | ||
- | ' | ||
- | ' | ||
- | ' | ||
- | }, | ||
- | }, | ||
- | } | ||
- | ####---- End of Logging Config ----####</ | ||
- | |||
- | * Create logging directory and setup ownership/ | ||
- | chown :apache / | ||
- | chmod g+rwx / | ||
- | |||
- | ===== Admin Interface ===== | ||
- | |||
- | * Create an admin user< | ||
- | |||
- | * Make your models/ | ||
- | from __future__ import unicode_literals | ||
- | |||
- | from django.contrib import admin | ||
- | |||
- | # Register your models here. | ||
- | |||
- | # Make Class Available in Admin Portal (see / | ||
- | from .models import AssetEntry | ||
- | admin.site.register(AssetEntry)</ | ||
- | |||
- | ---- | ||
- | |||
- | ===== URLs/Views ===== | ||
- | |||
- | A URL+View will generate a web page. | ||
- | |||
- | ==== URLs ==== | ||
- | |||
- | **Project Level URLs File** | ||
- | * Edit project URLs (/ | ||
- | from django.conf.urls import url, include | ||
- | from django.contrib import admin | ||
- | |||
- | # URL Regex Patterns - Map URIs to App's url file for additional matching | ||
- | urlpatterns = [ | ||
- | # No URI following site name (default app to use) | ||
- | url(r' | ||
- | # URI for app's name | ||
- | url(r' | ||
- | # Included /admin URI | ||
- | url(r' | ||
- | ]</ | ||
- | |||
- | \\ | ||
- | **App Level URLs File** | ||
- | * Create a new App level URLs file (/ | ||
- | from django.conf.urls import url | ||
- | |||
- | from . import views | ||
- | |||
- | urlpatterns = [ | ||
- | # "/ | ||
- | |||
- | # / | ||
- | url(r' | ||
- | |||
- | # / | ||
- | url(r' | ||
- | |||
- | # / | ||
- | url(r' | ||
- | |||
- | # / | ||
- | url(r' | ||
- | |||
- | # / | ||
- | url(r' | ||
- | |||
- | # / | ||
- | url(r' | ||
- | ]</ | ||
- | |||
- | ==== Views ==== | ||
- | |||
- | * Edit the App Views that are loaded depending upon URL match(/ | ||
- | # -*- coding: utf-8 -*- | ||
- | from __future__ import unicode_literals | ||
- | |||
- | # Render http response+templates | ||
- | from django.shortcuts import render | ||
- | |||
- | # Object or 404 | ||
- | from django.shortcuts import get_object_or_404 | ||
- | |||
- | # HTTP Response | ||
- | from django.http import HttpResponse | ||
- | |||
- | # Logging | ||
- | import logging | ||
- | logger = logging.getLogger(__name__) | ||
- | |||
- | # Your Apps Model | ||
- | from .models import AssetEntry | ||
- | |||
- | # / | ||
- | def index(request): | ||
- | # Get all asset objects | ||
- | all_asset_list = AssetEntry.objects.order_by(' | ||
- | |||
- | # Get number of assets in list | ||
- | number_assets = len(all_asset_list) | ||
- | |||
- | # Map template variable names (1st) to Python variables (2nd) for use in html templates | ||
- | context = { ' | ||
- | |||
- | # Logging | ||
- | logger.info(" | ||
- | |||
- | # Render the http request, using the template, passing the context | ||
- | return render(request, | ||
- | |||
- | |||
- | # / | ||
- | def stats(request): | ||
- | # Get all asset objects | ||
- | all_asset_list = AssetEntry.objects.order_by(' | ||
- | |||
- | # Get all asset device types | ||
- | asset_type_list = [key for key,value in AssetEntry.DEVICE_TYPES] | ||
- | |||
- | # Get all os names, Linux only, Windows only | ||
- | os_list = [key for key,value in AssetEntry.OS_NAMES] | ||
- | os_list_linux = [key for key,value in AssetEntry.OS_NAMES_LINUX] | ||
- | os_list_windows = [key for key,value in AssetEntry.OS_NAMES_WINDOWS] | ||
- | |||
- | # Log for debug purposes | ||
- | #for key in os_list: | ||
- | # logger.info(" | ||
- | |||
- | #- Build Statistics -# | ||
- | # Initialize Stats list (will be a list of dictionaries) | ||
- | stats_list = [] | ||
- | |||
- | ####---- Asset Counts Table: Grand Total Row ----#### | ||
- | sysstats_grand_total = 0 | ||
- | sysstats_grand_physical = 0 | ||
- | sysstats_grand_physical_linux = 0 | ||
- | sysstats_grand_physical_windows = 0 | ||
- | sysstats_grand_physical_other = 0 | ||
- | sysstats_grand_virtual = 0 | ||
- | sysstats_grand_virtual_linux = 0 | ||
- | sysstats_grand_virtual_windows = 0 | ||
- | sysstats_grand_virtual_other = 0 | ||
- | sysstats_grand_vmware = 0 | ||
- | |||
- | # Calculate stats for each type of device | ||
- | for device_type in asset_type_list: | ||
- | # Initialize an empty device stats list | ||
- | device_stats = [] | ||
- | | ||
- | # Add node to the device_stats list if a node from the all_asset_list matches the current device type | ||
- | for node in all_asset_list: | ||
- | if '' | ||
- | device_stats.append(node) | ||
- | |||
- | ####---- Asset Counts Table ----#### | ||
- | # Total Count | ||
- | count_total = len(device_stats) | ||
- | |||
- | #- Add to grand total | ||
- | sysstats_grand_total += count_total | ||
- | |||
- | # Physical and Virtual Counts | ||
- | count_physical = 0 | ||
- | count_physical_linux = 0 | ||
- | count_physical_windows = 0 | ||
- | count_physical_other = 0 | ||
- | count_virtual = 0 | ||
- | count_virtual_linux = 0 | ||
- | count_virtual_windows = 0 | ||
- | count_virtual_other = 0 | ||
- | for node in device_stats: | ||
- | if node.asset_hardware == " | ||
- | count_physical += 1 | ||
- | |||
- | if node.asset_os in os_list_linux: | ||
- | # Physical+Linux Count | ||
- | count_physical_linux += 1 | ||
- | elif node.asset_os in os_list_windows: | ||
- | # Physical+Windows Count | ||
- | count_physical_windows += 1 | ||
- | else: | ||
- | # Physical+Other OS | ||
- | count_physical_other += 1 | ||
- | |||
- | elif node.asset_hardware == " | ||
- | # Virtual Count | ||
- | count_virtual += 1 | ||
- | |||
- | if node.asset_os in os_list_linux: | ||
- | # Virtual+Linux Count | ||
- | count_virtual_linux += 1 | ||
- | elif node.asset_os in os_list_windows: | ||
- | # Virtual+Windows Count | ||
- | count_virtual_windows += 1 | ||
- | else: | ||
- | # Virtual+Other OS | ||
- | count_virtual_other += 1 | ||
- | |||
- | #- Add to grand total physical | ||
- | sysstats_grand_physical += count_physical | ||
- | sysstats_grand_physical_linux += count_physical_linux | ||
- | sysstats_grand_physical_windows += count_physical_windows | ||
- | sysstats_grand_physical_other += count_physical_other | ||
- | |||
- | #- Add to grand total virtual | ||
- | sysstats_grand_virtual += count_virtual | ||
- | sysstats_grand_virtual_linux += count_virtual_linux | ||
- | sysstats_grand_virtual_windows += count_virtual_windows | ||
- | sysstats_grand_virtual_other += count_virtual_other | ||
- | |||
- | ####---- OS Counts Table ----#### | ||
- | # Initialize a new empty OS Counts List | ||
- | os_counts = [] | ||
- | |||
- | # Add all the os names and an initial count of 0 | ||
- | for name in os_list: | ||
- | os_counts.append({ ' | ||
- | |||
- | # Check each node in the devices specific stats | ||
- | for node in device_stats: | ||
- | # Compare node's OS against each os name in the os_counts list and increment count if a match is found | ||
- | for os_entry in os_counts: | ||
- | if os_entry[' | ||
- | # Increment count value on an os name match | ||
- | os_entry[' | ||
- | |||
- | |||
- | ####---- After All Stats Calculations: | ||
- | # Add device statistics to stats_list | ||
- | stats_list.append({ ' | ||
- | |||
- | # Grand Total Only: VMware ESXi Host Count | ||
- | for node in device_stats: | ||
- | if node.asset_os.startswith(" | ||
- | sysstats_grand_vmware += 1 | ||
- | #-- END OF Calculate Device Type Stats loop --# | ||
- | |||
- | ##-- Calculate OS stats grand totals --## | ||
- | |||
- | # Initialize a new empty OS Counts Total List | ||
- | os_counts_total = [] | ||
- | |||
- | # Add all the os names and an initial count of 0 | ||
- | for name in os_list: | ||
- | os_counts_total.append({ ' | ||
- | |||
- | # For each device specific stats entry, add up grand total os counts | ||
- | for device_entry in stats_list: | ||
- | # For each device_entry in the stats_list, go through its os_count_stats value, which is a list of os_names and counts | ||
- | for os_device_entry in device_entry[' | ||
- | # Check each os_count_stats os_name against the os_counts_total os_name list | ||
- | for os_entry_total in os_counts_total: | ||
- | # If we have an os_name match, add the device' | ||
- | if os_entry_total[' | ||
- | os_entry_total[' | ||
- | |||
- | ####---- Add grand totals to stats_list ----#### | ||
- | stats_list.append({ ' | ||
- | |||
- | #- Other Grand Totals: Calculate -# | ||
- | sysstats_grand_linux = sysstats_grand_physical_linux + sysstats_grand_virtual_linux | ||
- | sysstats_grand_windows = sysstats_grand_physical_windows + sysstats_grand_virtual_windows | ||
- | sysstats_grand_other = sysstats_grand_physical_other + sysstats_grand_virtual_other | ||
- | |||
- | # Map template variable names (1st) to the Python variables (2nd) for use in templates | ||
- | context = {' | ||
- | |||
- | # Logging | ||
- | logger.info(" | ||
- | |||
- | # Render the HTTP request, using the template, passing the context | ||
- | return render(request, | ||
- | |||
- | |||
- | # / | ||
- | def env(request, | ||
- | # Get all asset objects | ||
- | all_asset_list = AssetEntry.objects.order_by(' | ||
- | |||
- | # New List for the asset types in the passed environment only | ||
- | new_list = [] | ||
- | |||
- | # Check each asset, add to new list if it matches the requested environment name | ||
- | for node in all_asset_list: | ||
- | if '' | ||
- | new_list.append(node) | ||
- | |||
- | # Get number of assets in list | ||
- | number_assets = len(new_list) | ||
- | |||
- | # Map template variable names (1st) to Python variables (2nd) for use in html templates | ||
- | context = { ' | ||
- | |||
- | # Logging | ||
- | logger.info(" | ||
- | |||
- | # Render the http request, using the template, passing the context | ||
- | return render(request, | ||
- | |||
- | |||
- | # / | ||
- | def asset_type_all_env(request, | ||
- | # Get all asset objects | ||
- | all_asset_list = AssetEntry.objects.order_by(' | ||
- | |||
- | # New List for specific devices only | ||
- | new_list = [] | ||
- | |||
- | # Check each asset, add to new list if it matches the requested device type | ||
- | for node in all_asset_list: | ||
- | if '' | ||
- | new_list.append(node) | ||
- | |||
- | # Get number of assets in list | ||
- | number_assets = len(new_list) | ||
- | |||
- | # Map template variable names (1st) to Python variables (2nd) for use in html templates | ||
- | context = { ' | ||
- | |||
- | # Logging | ||
- | logger.info(" | ||
- | |||
- | # Render the http request, using the template, passing the context | ||
- | return render(request, | ||
- | |||
- | |||
- | # / | ||
- | def type_env(request, | ||
- | # Get all asset objects | ||
- | all_asset_list = AssetEntry.objects.order_by(' | ||
- | |||
- | # New List for specific devices and environment only | ||
- | new_list = [] | ||
- | |||
- | # Check each asset, add to new list if it matches the requested device and environment | ||
- | for node in all_asset_list: | ||
- | if '' | ||
- | if '' | ||
- | new_list.append(node) | ||
- | |||
- | # Get number of assets in list | ||
- | number_assets = len(new_list) | ||
- | |||
- | # Map template variable names (1st) to Python variables (2nd) for use in html templates | ||
- | context = { ' | ||
- | |||
- | # Logging | ||
- | logger.info(" | ||
- | |||
- | # Render the http request, using the template, passing the context | ||
- | return render(request, | ||
- | |||
- | |||
- | # / | ||
- | def asset_hardware(request, | ||
- | # Get all asset objects | ||
- | all_asset_list = AssetEntry.objects.order_by(' | ||
- | |||
- | # New List for asset_hardware (physical or virtual) | ||
- | new_list = [] | ||
- | |||
- | # Check each asset, add to new list if it matches the requested hardware type | ||
- | for node in all_asset_list: | ||
- | if '' | ||
- | new_list.append(node) | ||
- | |||
- | # Get number of assets in list | ||
- | number_assets = len(new_list) | ||
- | |||
- | # Map template variable names (1st) to the Python variables (2nd) for use in templates | ||
- | context = {' | ||
- | |||
- | # Logging | ||
- | logger.info(" | ||
- | |||
- | # Render the HTTP request, using the template, passing the context | ||
- | return render(request, | ||
- | </ | ||
- | |||
- | ---- | ||
- | |||
- | ===== Web Page Templates ===== | ||
- | |||
- | Creating the web page templates. | ||
- | |||
- | * Create directory structure< | ||
- | * Create new pages | ||
- | * templates/ | ||
- | * templates/ | ||
- | |||
- | ==== Page Content: Index ==== | ||
- | |||
- | Example page content for the index.html page. | ||
- | |||
- | / | ||
- | <code html>< | ||
- | < | ||
- | < | ||
- | < | ||
- | </ | ||
- | < | ||
- | {% load static %} | ||
- | <link rel=" | ||
- | |||
- | <!-- Export button jquery (https:// | ||
- | <script type=" | ||
- | <script type=" | ||
- | <script type=" | ||
- | |||
- | <!-- Layout Divide: Left Side Menu for Devices --> | ||
- | <table class=" | ||
- | <tr> | ||
- | <!-- For white gaps in between Device Types and Phys/Virt, this must be larger than stylesheet width --> | ||
- | <!-- Set to style sheet width+25 px --> | ||
- | <td class=" | ||
- | |||
- | <!-- Device Menu: Determine Active Device --> | ||
- | <ul class=" | ||
- | {% if not asset_type %} | ||
- | < | ||
- | {% else %} | ||
- | < | ||
- | {% endif %} | ||
- | |||
- | {% if asset_type == ' | ||
- | < | ||
- | {% else %} | ||
- | < | ||
- | {% endif %} | ||
- | |||
- | {% if asset_type == ' | ||
- | < | ||
- | {% else %} | ||
- | < | ||
- | {% endif %} | ||
- | |||
- | {% if asset_type == ' | ||
- | < | ||
- | {% else %} | ||
- | < | ||
- | {% endif %} | ||
- | |||
- | {% if asset_type == ' | ||
- | < | ||
- | {% else %} | ||
- | < | ||
- | {% endif %} | ||
- | |||
- | {% if asset_type == ' | ||
- | < | ||
- | {% else %} | ||
- | < | ||
- | {% endif %} | ||
- | |||
- | {% if asset_type == ' | ||
- | < | ||
- | {% else %} | ||
- | < | ||
- | {% endif %} | ||
- | |||
- | </ul> | ||
- | </td> | ||
- | <!-- END of Layout Divide: Left Side Menu for Devices --> | ||
- | |||
- | |||
- | <!-- Layout Divide: Right Side Phys and Virt Links --> | ||
- | <!-- For white gaps in between Phys/Virt and Stats, this must be larger than stylesheet width --> | ||
- | <!-- Set to style sheet width+25 px --> | ||
- | <td class=" | ||
- | <!-- Asset Type Menu: Physical and Virtual --> | ||
- | <ul class =" | ||
- | {% if asset_hardware == ' | ||
- | < | ||
- | < | ||
- | {% elif asset_hardware == ' | ||
- | < | ||
- | < | ||
- | {% else %} | ||
- | < | ||
- | < | ||
- | {% endif %} | ||
- | </ul> | ||
- | </td> | ||
- | <!-- END of Layout Divide: Right Side Phys and Virt Links --> | ||
- | |||
- | |||
- | <!-- Layout Divide: Right Side Additional Links --> | ||
- | <td class=" | ||
- | <ul class=" | ||
- | < | ||
- | </ul> | ||
- | </td> | ||
- | <!-- END of Layout Divide: Right Side Additional Links --> | ||
- | |||
- | </tr> | ||
- | |||
- | |||
- | <!-- Layout Divide: Left Side Environment Menu --> | ||
- | <tr> | ||
- | <td class=" | ||
- | |||
- | <!-- Environment Menu: Dynamic Asset Type Links --> | ||
- | <ul class=" | ||
- | {% if env == ' | ||
- | {% if asset_type %} | ||
- | < | ||
- | < | ||
- | < | ||
- | {% else %} | ||
- | < | ||
- | < | ||
- | < | ||
- | {% endif %} | ||
- | {% elif env == ' | ||
- | {% if asset_type %} | ||
- | < | ||
- | < | ||
- | < | ||
- | {% else %} | ||
- | < | ||
- | < | ||
- | < | ||
- | {% endif %} | ||
- | {% elif env == ' | ||
- | {% if asset_type %} | ||
- | < | ||
- | < | ||
- | < | ||
- | {% else %} | ||
- | < | ||
- | < | ||
- | < | ||
- | {% endif %} | ||
- | {% else %} | ||
- | {% if asset_type %} | ||
- | < | ||
- | < | ||
- | < | ||
- | {% else %} | ||
- | < | ||
- | < | ||
- | < | ||
- | {% endif %} | ||
- | {% endif %} | ||
- | </ul> | ||
- | </td> | ||
- | <!-- END of Layout Divide: Left Side Environment Menu --> | ||
- | |||
- | |||
- | <!-- START of Layout Divide: 2nd row for logged in message --> | ||
- | <td class=" | ||
- | {% if user.is_authenticated %} | ||
- | Logged in: {{ user.username }}< | ||
- | <a class=" | ||
- | {% endif %} | ||
- | </ | ||
- | </tr> | ||
- | <!-- END of Layout Divide: 2nd row for logged in message --> | ||
- | |||
- | |||
- | <!-- Layout Divide: Bottom Asset List Table --> | ||
- | <tr> | ||
- | <td class=" | ||
- | |||
- | <!-- Asset List Above Table: Display Device and Environment --> | ||
- | <br> | ||
- | {% if asset_type == ' | ||
- | {% if env == ' | ||
- | < | ||
- | {% elif env == ' | ||
- | < | ||
- | {% elif env == ' | ||
- | < | ||
- | {% else %} | ||
- | < | ||
- | {% endif %} | ||
- | |||
- | {% elif asset_type == ' | ||
- | {% if env == ' | ||
- | < | ||
- | {% elif env == ' | ||
- | < | ||
- | {% elif env == ' | ||
- | < | ||
- | {% else %} | ||
- | < | ||
- | {% endif %} | ||
- | |||
- | {% elif asset_type == ' | ||
- | {% if env == ' | ||
- | < | ||
- | {% elif env == ' | ||
- | < | ||
- | {% elif env == ' | ||
- | < | ||
- | {% else %} | ||
- | < | ||
- | {% endif %} | ||
- | |||
- | {% elif asset_type == ' | ||
- | {% if env == ' | ||
- | < | ||
- | {% elif env == ' | ||
- | < | ||
- | {% elif env == ' | ||
- | < | ||
- | {% else %} | ||
- | < | ||
- | {% endif %} | ||
- | |||
- | {% elif asset_type == ' | ||
- | {% if env == ' | ||
- | < | ||
- | {% elif env == ' | ||
- | < | ||
- | {% elif env == ' | ||
- | < | ||
- | {% else %} | ||
- | < | ||
- | {% endif %} | ||
- | |||
- | {% elif asset_type == ' | ||
- | {% if env == ' | ||
- | < | ||
- | {% elif env == ' | ||
- | < | ||
- | {% elif env == ' | ||
- | < | ||
- | {% else %} | ||
- | < | ||
- | {% endif %} | ||
- | |||
- | {% else %} | ||
- | {% if env == ' | ||
- | < | ||
- | {% elif env == ' | ||
- | < | ||
- | {% elif env == ' | ||
- | < | ||
- | {% else %} | ||
- | < | ||
- | {% endif %} | ||
- | {% endif %} | ||
- | |||
- | <!-- Physical/ | ||
- | {% if asset_hardware %} | ||
- | {% if asset_hardware == ' | ||
- | <b> - Physical -</b> | ||
- | {% elif asset_hardware == ' | ||
- | <b> - Virtual -</b> | ||
- | {% endif %} | ||
- | {% endif %} | ||
- | |||
- | <!-- Assets List Above Table: Number of Assets Displayed --> | ||
- | {% if asset_count %} | ||
- | {% if asset_count == 1 %} | ||
- | <b> ({{ asset_count }} asset)</ | ||
- | {% else %} | ||
- | <b> ({{ asset_count }} assets)</ | ||
- | {% endif %} | ||
- | {% else %} | ||
- | <b> (0 assets)</ | ||
- | {% endif %} | ||
- | |||
- | <!-- Export Buttons --> | ||
- | <a href="#" | ||
- | <a href="#" | ||
- | |||
- | <br> | ||
- | <!-- The Assets List Table --> | ||
- | <table class=" | ||
- | < | ||
- | <tr class=" | ||
- | <th class=" | ||
- | <th class=" | ||
- | <th class=" | ||
- | <th class=" | ||
- | <th class=" | ||
- | <th class=" | ||
- | </tr> | ||
- | </ | ||
- | < | ||
- | {% for name in all_asset_list %} | ||
- | <tr class=" | ||
- | <td class=" | ||
- | <td class=" | ||
- | <td class=" | ||
- | <td class=" | ||
- | <td class=" | ||
- | <td class=" | ||
- | </tr> | ||
- | {% endfor %} | ||
- | </ | ||
- | </ | ||
- | <!-- END of Assets List Table --> | ||
- | |||
- | </td> | ||
- | </tr> | ||
- | </ | ||
- | <!-- END of Layout Divide: Bottom Assets List Table --> | ||
- | |||
- | <br> | ||
- | <hr> | ||
- | <br> | ||
- | |||
- | </ | ||
- | </ | ||
- | </ | ||
- | |||
- | ==== Page Content: Stats ==== | ||
- | |||
- | Example page content for the stats.html page. | ||
- | |||
- | / | ||
- | <code html>< | ||
- | < | ||
- | < | ||
- | < | ||
- | </ | ||
- | < | ||
- | {% load static %} | ||
- | <link rel=" | ||
- | |||
- | <!-- Export button jquery (https:// | ||
- | <script type=" | ||
- | <script type=" | ||
- | <script type=" | ||
- | |||
- | <!-- Layout Divide: Left Side Menu for Devices --> | ||
- | <table class=" | ||
- | <tr> | ||
- | <!-- For white gaps in between Device Types and Phys/Virt, this must be larger than stylesheet width --> | ||
- | <!-- Set to style sheet width+25 px --> | ||
- | <td class=" | ||
- | |||
- | <!-- Device Menu: No Devices Active on Stats Page --> | ||
- | <ul class=" | ||
- | < | ||
- | < | ||
- | < | ||
- | < | ||
- | < | ||
- | < | ||
- | < | ||
- | </ul> | ||
- | </td> | ||
- | <!-- END of Layout Divide: Left Side Menu for Devices --> | ||
- | |||
- | |||
- | <!-- Layout Divide: Right Side Phys and Virt Links --> | ||
- | <!-- For white gaps in between Phys/Virt and Stats, this must be larger than stylesheet width --> | ||
- | <!-- Set to style sheet width+25 px --> | ||
- | <td class=" | ||
- | <!-- Asset Type Menu: Physical and Virtual --> | ||
- | <ul class =" | ||
- | {% if asset_hardware == ' | ||
- | < | ||
- | < | ||
- | {% elif asset_hardware == ' | ||
- | < | ||
- | < | ||
- | {% else %} | ||
- | < | ||
- | < | ||
- | {% endif %} | ||
- | </ul> | ||
- | </td> | ||
- | <!-- END of Layout Divide: Right Side Phys and Virt Links --> | ||
- | |||
- | |||
- | <!-- Layout Divide: Right Side Additional Links --> | ||
- | <td class=" | ||
- | <ul class=" | ||
- | < | ||
- | </ul> | ||
- | </td> | ||
- | <!-- END of Layout Divide: Right Side Additional Links --> | ||
- | |||
- | </tr> | ||
- | |||
- | |||
- | <!-- START of Layout Divide: 2nd row for logged in message --> | ||
- | <tr> | ||
- | <td class=" | ||
- | </td> | ||
- | |||
- | <td class=" | ||
- | {% if user.is_authenticated %} | ||
- | Logged in: {{ user.username }}< | ||
- | <a class=" | ||
- | {% endif %} | ||
- | </td> | ||
- | </tr> | ||
- | <!-- END of Layout Divide: 2nd row for logged in message --> | ||
- | |||
- | |||
- | <!-- Layout Divide: Bottom Stats Table (Asset Counts) --> | ||
- | <tr> | ||
- | <td class=" | ||
- | |||
- | <br> | ||
- | < | ||
- | |||
- | <!-- Export Buttons --> | ||
- | <a href="#" | ||
- | <a href="#" | ||
- | |||
- | <br> | ||
- | <!-- Stats Table (Asset Counts) --> | ||
- | <table class=" | ||
- | < | ||
- | <tr class=" | ||
- | <th class=" | ||
- | <th class=" | ||
- | <th class=" | ||
- | <th class=" | ||
- | <th class=" | ||
- | <th class=" | ||
- | <th class=" | ||
- | <th class=" | ||
- | <th class=" | ||
- | <th class=" | ||
- | </tr> | ||
- | </ | ||
- | < | ||
- | {% for asset in device_stats %} | ||
- | <tr class=" | ||
- | {% if asset.asset_type == ' | ||
- | <td class=" | ||
- | <td class=" | ||
- | <td class=" | ||
- | <td class=" | ||
- | <td class=" | ||
- | <td class=" | ||
- | <td class=" | ||
- | <td class=" | ||
- | <td class=" | ||
- | <td class=" | ||
- | {% else %} | ||
- | <td class=" | ||
- | <td class=" | ||
- | <td class=" | ||
- | <td class=" | ||
- | <td class=" | ||
- | <td class=" | ||
- | <td class=" | ||
- | <td class=" | ||
- | <td class=" | ||
- | <td class=" | ||
- | {% endif %} | ||
- | </tr> | ||
- | {% endfor %} | ||
- | <tr class=" | ||
- | <td class=" | ||
- | <td class=" | ||
- | </tr> | ||
- | <tr class=" | ||
- | <td class=" | ||
- | <td class=" | ||
- | </tr> | ||
- | <tr class=" | ||
- | <td class=" | ||
- | <td class=" | ||
- | </tr> | ||
- | <tr class=" | ||
- | <td class=" | ||
- | <td class=" | ||
- | </tr> | ||
- | </ | ||
- | </ | ||
- | *Physical Virtual Hosts (VMware ESXi) count is included in Physical Linux/Total Linux counts. | ||
- | <!-- END of Stats Table (Asset Counts) --> | ||
- | |||
- | </td> | ||
- | </tr> | ||
- | <!-- END of Layout Divide: Bottom Stats Table (Asset Counts) --> | ||
- | |||
- | <!-- Layout Divide: Bottom Stats Table (OS Counts) --> | ||
- | <tr> | ||
- | <td class=" | ||
- | |||
- | <br> | ||
- | < | ||
- | |||
- | <!-- Export Buttons --> | ||
- | <a href="#" | ||
- | <a href="#" | ||
- | |||
- | <br> | ||
- | <!-- Stats Table (OS Counts) --> | ||
- | <table class=" | ||
- | < | ||
- | <tr class=" | ||
- | <th class=" | ||
- | {% for os_name in os_list %} | ||
- | <th class=" | ||
- | {% endfor %} | ||
- | </tr> | ||
- | </ | ||
- | < | ||
- | {% for asset in device_stats %} | ||
- | <tr class=" | ||
- | {% if asset.asset_type == ' | ||
- | <td class=" | ||
- | {% for name in asset.os_count_stats %} | ||
- | <td class=" | ||
- | {% endfor %} | ||
- | |||
- | {% else %} | ||
- | <td class=" | ||
- | {% for name in asset.os_count_stats %} | ||
- | <td class=" | ||
- | {% endfor %} | ||
- | {% endif %} | ||
- | </tr> | ||
- | |||
- | {% endfor %} | ||
- | </ | ||
- | </ | ||
- | <!-- END of Stats Table (OS Counts) --> | ||
- | |||
- | </td> | ||
- | </tr> | ||
- | </ | ||
- | <!-- END of Layout Divide: Bottom Stats Table (OS Counts) --> | ||
- | |||
- | <br> | ||
- | <hr> | ||
- | <br> | ||
- | |||
- | </ | ||
- | </ | ||
- | </ | ||
- | |||
- | ---- | ||
- | |||
- | ===== Static Files/ | ||
- | |||
- | Configuring stylesheets. | ||
- | |||
- | * Create directory structure< | ||
- | * Create stylesheet (/ | ||
- | |||
- | /* ---- Table Styles ---- */ | ||
- | /* table settings */ | ||
- | table.layout { | ||
- | border-collapse: | ||
- | border-spacing: | ||
- | padding: 0px; | ||
- | } | ||
- | td.layout { | ||
- | border-spacing: | ||
- | padding: 0px; | ||
- | } | ||
- | |||
- | table.myapphere { | ||
- | border-collapse: | ||
- | } | ||
- | |||
- | /* table headers, table definitions */ | ||
- | table.myapphere, | ||
- | border-collapse: | ||
- | border: 1px solid #ddd; | ||
- | padding: 5px; | ||
- | } | ||
- | |||
- | /* th -> table headers */ | ||
- | th.myapphere { | ||
- | background-color: | ||
- | color: white; | ||
- | } | ||
- | |||
- | /* tr -> table rows | ||
- | | ||
- | | ||
- | tr.myapphere: | ||
- | tr.myapphere: | ||
- | |||
- | td.center { | ||
- | text-align: center; | ||
- | } | ||
- | |||
- | td.totals { | ||
- | background-color: | ||
- | font-weight: | ||
- | } | ||
- | |||
- | |||
- | /* ---- Menu Styles ---- */ | ||
- | ul.asset_type { | ||
- | list-style-type: | ||
- | margin: 0; | ||
- | padding: 0; | ||
- | overflow: hidden; | ||
- | background-color: | ||
- | width: 671px; | ||
- | } | ||
- | |||
- | ul.env { | ||
- | list-style-type: | ||
- | margin: 0; | ||
- | padding: 0; | ||
- | overflow: hidden; | ||
- | background-color: | ||
- | width: 163px; | ||
- | } | ||
- | |||
- | ul.stats { | ||
- | list-style-type: | ||
- | margin: 0; | ||
- | padding: 0; | ||
- | overflow: hidden; | ||
- | background-color: | ||
- | width: 60px; | ||
- | } | ||
- | |||
- | ul.asset_hardware { | ||
- | list-style-type: | ||
- | margin: 0; | ||
- | padding: 0; | ||
- | overflow: hidden; | ||
- | background-color: | ||
- | width: 163px; | ||
- | } | ||
- | |||
- | li { | ||
- | float: left; | ||
- | } | ||
- | |||
- | li a { | ||
- | display: block; | ||
- | color: white; | ||
- | text-align: center; | ||
- | padding: 10px 10px; | ||
- | text-decoration: | ||
- | } | ||
- | |||
- | a: | ||
- | background-color: | ||
- | } | ||
- | |||
- | .active { | ||
- | background-color:# | ||
- | } | ||
- | |||
- | |||
- | /* ---- Non-Menu Styles ---- */ | ||
- | a: | ||
- | background-color: | ||
- | } | ||
- | a: | ||
- | background-color: | ||
- | } | ||
- | |||
- | a: | ||
- | background-color: | ||
- | } | ||
- | </ | ||
- | |||
- | ---- | ||
- | |||
- | ====== Apache ====== | ||
- | |||
- | Configuring Apache to pass traffic to the application. | ||
- | |||
- | * Configure Apache' | ||
- | |||
- | # Asset List Django/WSGI Config | ||
- | |||
- | # WSGIScriptAlias: | ||
- | WSGIScriptAlias / / | ||
- | |||
- | # WSGI Daemon Process Config | ||
- | WSGIDaemonProcess myapphere python-path=/ | ||
- | WSGIProcessGroup myapphere | ||
- | |||
- | # Location of Django Application and wsgi.py config | ||
- | < | ||
- | <Files wsgi.py> | ||
- | Require all granted | ||
- | </ | ||
- | </ | ||
- | |||
- | # Static files (admin interface and style sheet) | ||
- | Alias /static/ / | ||
- | < | ||
- | Require all granted | ||
- | </ | ||
- | </ | ||
- | |||
- | * Configure the virtual host (new file)< | ||
- | |||
- | # Virtual Host Config | ||
- | |||
- | # Redirect shortname to fully qualified | ||
- | < | ||
- | ServerName djangoserver | ||
- | Redirect "/" | ||
- | </ | ||
- | |||
- | # Redirect all http to https | ||
- | < | ||
- | ServerName djangoserver.mycorps.domain.org | ||
- | |||
- | < | ||
- | # Redirect all to https | ||
- | RewriteEngine On | ||
- | RewriteCond %{HTTPS} off | ||
- | RewriteRule (.*) https:// | ||
- | </ | ||
- | </ | ||
- | |||
- | |||
- | # Redirect shortname to fully qualified | ||
- | < | ||
- | ServerName djangoserver | ||
- | Redirect "/" | ||
- | </ | ||
- | |||
- | # Django Application lives here at the root /. See: / | ||
- | < | ||
- | # Fully qualified server name | ||
- | ServerName djangoserver.mycorps.domain.org | ||
- | Header always set Strict-Transport-Security " | ||
- | </ | ||
- | |||
- | < | ||
- | # OPTIONAL: CNAME for website - will only work with SSL if using a wildcard certificate | ||
- | ServerName myapphere.mycorps.domain.org | ||
- | Header always set Strict-Transport-Security " | ||
- | </ | ||
- | </ | ||
- | |||
- | * Configure SSL Certificate< | ||
- | |||
- | SSLCertificateFile / | ||
- | SSLCertificateKeyFile / | ||
- | SSLCertificateChainFile / | ||
- | </ | ||
- | * [[linux_wiki: | ||
- | |||
- | * Start and Enable Apache< | ||
- | systemctl enable httpd</ | ||
- | |||
- | ---- | ||
- | |||
- | ====== Django: Authentication ====== | ||
- | |||
- | Adding authentication to Django requires basic auth to be setup first, as LDAP auth builds upon it. | ||
- | |||
- | ===== Basic Authentication ===== | ||
- | |||
- | Basic authentication uses Django local user accounts. | ||
- | |||
- | * Edit Project Settings (/ | ||
- | LOGIN_REDIRECT_URL = '/ | ||
- | |||
- | # Ensure contrib.auth is added to installed apps: | ||
- | # Application definition | ||
- | INSTALLED_APPS = [ | ||
- | ' | ||
- | ' | ||
- | ' | ||
- | ... | ||
- | ]</ | ||
- | |||
- | * Add login and logout URLs to project URLs (/ | ||
- | from django.contrib.auth import views as auth_views | ||
- | |||
- | # URL Patterns - Map to Projects Within Django | ||
- | urlpatterns = [ | ||
- | ... | ||
- | # Login URLs | ||
- | url(r' | ||
- | url(r' | ||
- | ... | ||
- | ]</ | ||
- | |||
- | * Edit the application views (/ | ||
- | from django.contrib.auth.decorators import login_required | ||
- | |||
- | # Put login decorator before every function definition that you want to require login to view: | ||
- | #-> Require login for the view following it <-# | ||
- | @login_required(login_url="/ | ||
- | |||
- | def index(request):</ | ||
- | |||
- | * Create a HTML Login Page (/ | ||
- | < | ||
- | < | ||
- | <meta charset=" | ||
- | < | ||
- | </ | ||
- | |||
- | < | ||
- | < | ||
- | < | ||
- | {% if user.is_authenticated %} | ||
- | Greetings, {{ user.username }}. | ||
- | <a href=" | ||
- | {% endif %} | ||
- | </ | ||
- | |||
- | <hr> | ||
- | < | ||
- | < | ||
- | <form method=" | ||
- | {% csrf_token %} | ||
- | {{ form.as_p }} | ||
- | <button type=" | ||
- | </ | ||
- | </ | ||
- | <hr> | ||
- | |||
- | </ | ||
- | </ | ||
- | |||
- | ===== LDAP Authentication ===== | ||
- | |||
- | Configuring LDAP authentication. | ||
- | |||
- | * Install the python django ldap package< | ||
- | | ||
- | * Edit Project Settings (/ | ||
- | import ldap | ||
- | from django_auth_ldap.config import LDAPSearch | ||
- | from django_auth_ldap.config import GroupOfNamesType | ||
- | from django_auth_ldap.config import LDAPGroupQuery | ||
- | |||
- | # Authentication Backends (LDAP and Django Local) | ||
- | AUTHENTICATION_BACKENDS = ( | ||
- | ' | ||
- | ' | ||
- | ) | ||
- | |||
- | ####- LDAP Server Config -#### | ||
- | AUTH_LDAP_SERVER_URI = " | ||
- | AUTH_LDAP_START_TLS = True | ||
- | |||
- | # Bind Info: Use authenticating user to get user and group info | ||
- | AUTH_LDAP_BIND_AS_AUTHENTICATING_USER = True | ||
- | AUTH_LDAP_USER_DN_TEMPLATE = " | ||
- | |||
- | # Cache LDAP Groups for use with permissions | ||
- | AUTH_LDAP_CACHE_GROUPS = True | ||
- | AUTH_LDAP_GROUP_CACHE_TIMEOUT = 3600 | ||
- | |||
- | # Group Info Gathering | ||
- | AUTH_LDAP_GROUP_SEARCH = LDAPSearch | ||
- | " | ||
- | ldap.SCOPE_SUBTREE, | ||
- | " | ||
- | ) | ||
- | AUTH_LDAP_GROUP_TYPE = GroupOfNamesType() | ||
- | |||
- | # Group restrictions - Who can login via LDAP | ||
- | AUTH_LDAP_REQUIRE_GROUP = ( | ||
- | |||
- | # Allow login for members of the LDAP group " | ||
- | LDAPGroupQuery(" | ||
- | |||
- | # Allow login for members of the LDAP group " | ||
- | LDAPGroupQuery(" | ||
- | ) | ||
- | |||
- | # Use LDAP group membership to calculate group permissions. | ||
- | AUTH_LDAP_FIND_GROUP_PERMS = True | ||
- | |||
- | # Update Django record from LDAP each time user logs in | ||
- | AUTH_LDAP_ALWAYS_UPDATE_USER = True | ||
- | |||
- | # Populate the Django user info from LDAP directory info | ||
- | AUTH_LDAP_USER_ATTR_MAP = { | ||
- | " | ||
- | " | ||
- | " | ||
- | } | ||
- | |||
- | # Set user permission flags by group - set LDAP group " | ||
- | AUTH_LDAP_USER_FLAGS_BY_GROUP = { | ||
- | " | ||
- | } | ||
- | </ | ||
- | |||
- | ---- | ||
- | |||
- | ====== Django: Jquery ====== | ||
- | |||
- | Jquery can be added in order to enable an Export as CSV and/or Excel buttons. | ||
- | |||
- | Reference: Export Jquery Buttons: https:// | ||
- | |||
- | * From the reference link, download: | ||
- | * jquery.base64.js | ||
- | * tableExport.js | ||
- | |||
- | * Search the internet for CSV and XLS icons. Download them. | ||
- | * CSV = save as " | ||
- | * XLS = save as " | ||
- | |||
- | * Save the Javascript files and small pictures (CSV/XLS) into the same directory as the style sheet< | ||
- | |||
- | * Install the Django Jquery integration< | ||
- | |||
- | * Add Jquery to the " | ||
- | INSTALLED_APPS = [ | ||
- | ' | ||
- | |||
- | * Add jquery to HTML templates< | ||
- | <script type=" | ||
- | <script type=" | ||
- | <script type=" | ||
- | |||
- | <!-- Export Buttons --> | ||
- | <a href="#" | ||
- | <a href="#" | ||
- | |||
- | * Collect static files< | ||
- | python manage.py collectstatic</ | ||
- | |||
- | ---- | ||
- | |||
- | ====== DEBUG: TURN OFF ====== | ||
- | |||
- | Lastly, when you are not developing/ | ||
- | |||
- | Edit the project settings< | ||
- | |||
- | DEBUG = False</ | ||
- | |||
- | ---- | ||