天天看點

從0到1開發自動化運維平台 Day1

作者:CharlesLai89

今天開始抽時間将運維平台怎麼從0到1的實作分享給大家.

後端用的djangorestframework架構,今天先建立一個django項目,實作區域和IDC的管理.

1、建立目錄,初始化虛拟環境,然後安裝drf架構

➜ ~ mkdir ydevops-backend
➜ ~ cd ydevops-backend
➜ ~ python3.9 -m venv venv
➜ ~ source venv/bin/activate
(venv) ➜  pip install djangorestframework
(venv) ➜  pip list
Package             Version
------------------- --------
asgiref             3.6.0
Django              4.1.7
djangorestframework 3.14.0
pip                 22.0.4
pytz                2022.7.1
setuptools          58.1.0
sqlparse            0.4.3
WARNING: You are using pip version 22.0.4; however, version 23.0.1 is available.
You should consider upgrading via the '/home/charles/ydevops-backend/venv/bin/python3.9 -m pip install --upgrade pip' command.           

2、建立工程

(venv) ➜ django-admin startproject devops_backend .  # 注意後面有個點
(venv) ➜ ls
devops_backend  manage.py  venv           

3、建立第一個子產品,cmdb子產品

(venv) ➜  django-admin startapp cmdb
(venv) ➜  ls
cmdb  devops_backend  manage.py  venv           

4、重新梳理下代碼結構

(venv) ➜  mkdir apps
(venv) ➜  mv cmdb apps/           

代碼結構變化後,我們還需要修改下settings.py

import os
import sys
...
sys.path.insert(0, os.path.join(BASE_DIR, 'apps'))           
從0到1開發自動化運維平台 Day1

5、生成資料表及建立使用者

(venv) ➜  python manage.py migrate       
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying auth.0012_alter_user_first_name_max_length... OK
  Applying sessions.0001_initial... OK
(venv) ➜  python manage.py createsuperuser
使用者名 (leave blank to use 'charles'): admin
電子郵件位址: admin@localhost
Password: 
Password (again): 
密碼長度太短。密碼必須包含至少 8 個字元。
這個密碼太常見了。
密碼隻包含數字。
Bypass password validation and create user anyway? [y/N]: y   
Superuser created successfully.           

6、運作項目

(venv) ➜  python manage.py runserver 0.0.0.0:9000           
Watching for file changes with StatReloader
Performing system checks...

System check identified no issues (0 silenced).
March 21, 2023 - 13:43:54
Django version 4.1.7, using settings 'devops_backend.settings'
Starting development server at http://0.0.0.0:9000/
Quit the server with CONTROL-C.           

此時打開浏覽器,應該可以看到首頁,如下圖所示:

從0到1開發自動化運維平台 Day1

7、現在我們開始來編寫區域表Region和IDC表Idc

# 建立模型、視圖和序列化器
(venv) ➜  cd apps/cmdb
(venv) ➜  mkdir model serializer view
(venv) ➜  touch {model,serializer,view}/__init__.py           

公共模型

# model/model_assets.py
from django.db import models


class TimeAbstract(models.Model):
    update_time = models.DateTimeField(
        auto_now=True, null=True, blank=True, verbose_name='更新時間')
    created_time = models.DateTimeField(
        auto_now_add=True, null=True, blank=True, verbose_name='建立時間')

    class ExtMeta:
        related = False
        dashboard = False

    class Meta:
        abstract = True
        ordering = ['-id']           

Region模型

# model/model_assets.py
class Region(TimeAbstract):
    name = models.CharField(max_length=100, unique=True, verbose_name='地域')
    alias = models.CharField(max_length=128, default='', verbose_name='地域别名')
    desc = models.TextField(verbose_name='詳情描述', null=True, blank=True)
    extra = models.JSONField(default=dict, verbose_name='擴充字段')
    # {0: 禁用, 1: 啟用}
    is_enable = models.SmallIntegerField(
        default=1, verbose_name='啟用', help_text='狀态 {0: 禁用, 1: 啟用},預設值為1')

    def __str__(self) -> str:
        return self.alias

    class ExtMeta:
        related = True
        dashboard = True

    class Meta:
        verbose_name = '地域'
        verbose_name_plural = verbose_name + '管理'           

Idc模型

IDC_TYPE = (
    (0, '實體機房'), (1, '公有雲')
)


class Idc(TimeAbstract):
    """
    Idc模型
    """
    name = models.CharField(max_length=100, unique=True, verbose_name='名稱')
    alias = models.CharField(max_length=128, unique=True, verbose_name='别名')
    region = models.ForeignKey(
        Region, blank=True, null=True, on_delete=models.PROTECT, verbose_name='區域')
    type = models.SmallIntegerField(default=0, choices=IDC_TYPE, verbose_name='機房類型',
                                    help_text=f"可選: {IDC_TYPE}")
    supplier = models.CharField(
        max_length=128, default=None, null=True, blank=True, verbose_name='服務商')
    config = models.JSONField(default=dict, verbose_name='配置資訊',
                              help_text='阿裡雲:{"key":"key","secret":"secret","region":["cn-south-1"],"project":[]}\n華為雲:{"domain":"domain","user":"user","password":password","project":[{"region":"region","project_id":"project_id"}]}')
    forward = models.BooleanField(default=False, verbose_name='是否中轉')
    ops = models.CharField(max_length=100, blank=True,
                           null=True, verbose_name='運維機器')
    repo = models.SmallIntegerField(default=0, verbose_name='鏡像倉庫')
    contact = models.JSONField(default=list, verbose_name='聯系人')
    desc = models.TextField(default='', null=True,
                            blank=True, verbose_name='備注')

    def __str__(self):
        return self.name

    class ExtMeta:
        related = True
        dashboard = True
        icon = 'international'

    class Meta:
        verbose_name = 'IDC機房'
        verbose_name_plural = verbose_name + '管理'           

8、建立區域和IDC表

(venv) ➜ cd ../..
(venv) ➜ python manage.py makemigrations
Migrations for 'cmdb':
  apps/cmdb/migrations/0001_initial.py
    - Create model Region
    - Create model Idc
(venv) ➜ python manage.py migrate       
Operations to perform:
  Apply all migrations: admin, auth, cmdb, contenttypes, sessions
Running migrations:
  Applying cmdb.0001_initial... OK           

9、編寫序列化器

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@author  :   Charles Lai
@file    :   serializer_assets.py
@time    :   2023/03/21 22:18
@contact :   [email protected]
'''

# here put the import lib
from rest_framework import serializers

from cmdb.models import Region, Idc


class RegionSerializers(serializers.ModelSerializer):

    class Meta:
        model = Region
        fields = '__all__'


class IdcSerializers(serializers.ModelSerializer):

    class Meta:
        model = Idc
        fields = '__all__'
           

10、編寫視圖

#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@author  :   Charles Lai
@file    :   view_assets.py
@time    :   2023/03/21 22:21
@contact :   [email protected]
'''

# here put the import lib
from rest_framework import viewsets

from cmdb.models import Region, Idc
from cmdb.serializer import RegionSerializers, IdcSerializers


class RegionViewSet(viewsets.ModelViewSet):
    """
    區域視圖

    ### 區域權限
        {'*': ('env_all', '區域環境管理')},
        {'get': ('env_list', '檢視區域環境')},
        {'post': ('env_create', '建立區域環境')},
        {'put': ('env_edit', '編輯區域環境')},
        {'patch': ('env_edit', '編輯區域環境')},
        {'delete': ('env_delete', '删除區域環境')}
    """
    perms_map = (
        {'*': ('admin', '管理者')},
        {'*': ('env_all', '區域環境管理')},
        {'get': ('env_list', '檢視區域環境')},
        {'post': ('env_create', '建立區域環境')},
        {'put': ('env_edit', '編輯區域環境')},
        {'patch': ('env_edit', '編輯區域環境')},
        {'delete': ('env_delete', '删除區域環境')}
    )
    queryset = Region.objects.all()
    serializer_class = RegionSerializers


class IdcViewSet(viewsets.ModelViewSet):
    """
    IT資産 - IDC視圖

    ### IDC權限
        {'*': ('itasset_all', 'IT資産管理')},
        {'get': ('itasset_list', '檢視IT資産')},
        {'post': ('itasset_create', '建立IT資産')},
        {'put': ('itasset_edit', '編輯IT資産')},
        {'delete': ('itasset_delete', '删除IT資産')}
    """
    perms_map = (
        {'*': ('admin', '管理者')},
        {'*': ('itasset_all', 'IT資産管理')},
        {'get': ('itasset_list', '檢視IT資産')},
        {'post': ('itasset_create', '建立IT資産')},
        {'put': ('itasset_edit', '編輯IT資産')},
        {'delete': ('itasset_delete', '删除IT資産')}
    )
    queryset = Idc.objects.all()
    serializer_class = IdcSerializers
           

11、添加路由,修改devops_backend/urls.py

"""devops_backend URL Configuration
"""
from django.contrib import admin
from django.urls import path, include

from rest_framework.routers import DefaultRouter

from cmdb.views import RegionViewSet, IdcViewSet

router = DefaultRouter()
router.register('region', RegionViewSet)
router.register('asset/idc', IdcViewSet)

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include(router.urls)),
]           

12、這樣我們就實作了區域和IDC的管理了,此時打開http://localhost:9000/api/?format=api,應看到下圖所示:

從0到1開發自動化運維平台 Day1

點選進入每個路由都可以進行get和post請求操作.

好了,今天就實作region和idc的管理接口,暫時先這樣吧

繼續閱讀