Compare commits

...

2 Commits

Author SHA1 Message Date
06d1853fb0 url link 저장 및 변경 관리 계정에서 할수 있도록 추가
All checks were successful
Build And Test / build-and-push (push) Successful in 4m8s
2025-01-25 01:30:48 +09:00
sdjo
d34d4f8def landing페이지 수정, 카테고리 리스트 정리
All checks were successful
Build And Test / build-and-push (push) Successful in 5m13s
2025-01-23 14:19:27 +09:00
14 changed files with 451 additions and 79 deletions

View File

@ -0,0 +1,13 @@
{% extends "components/base.html" %}
{% block title %}Landing Page{% endblock %}
{% block main_area %}
<article class="pt-3">
<h2 class="fw-bold pb-2">Welcome!</h2>
<h3>IT Infra 및 DevOps 자원관리 도구</h3>
* IP리스트 관리기능 제공 <br>
* Public NHN Cloud API 기능 일부 제공
<p>계속 기능 구현 중 입니다.</p>
</article>
{% endblock %}

View File

@ -3,11 +3,46 @@
{% block title %}Landing Page{% endblock %}
{% block main_area %}
<article class="pt-3">
<h2 class="fw-bold pb-2">Welcome!</h2>
<h3>IT Infra 및 DevOps 자원관리 도구</h3>
* IP리스트 관리기능 제공 <br>
* Public NHN Cloud API 기능 일부 제공
<p>계속 기능 구현 중 입니다.</p>
</article>
<div class="container mt-5">
<div class="row">
<!-- NoticeBoard Section -->
<div class="col-md-6">
<h2>Latest Notices</h2>
<div class="row">
{% for notice in notices %}
<div class="col-12 mb-3">
<div class="card">
<div class="card-body">
<h5 class="card-title">{{ notice.title }}</h5>
<p class="card-text">{{ notice.content|truncatewords:20 }}</p>
<a href="{% url 'butler:notice_detail' notice.id %}" class="btn btn-primary">View Notice</a>
</div>
</div>
</div>
{% empty %}
<p>No notices available.</p>
{% endfor %}
</div>
</div>
<!-- Blog Posts Section -->
<div class="col-md-6">
<h2>Latest Blog Posts</h2>
<div class="row">
{% for post in blog_posts %}
<div class="col-12 mb-3">
<div class="card">
<div class="card-body">
<h5 class="card-title">{{ post.title }}</h5>
<p class="card-text">{{ post.summary|truncatewords:20 }}</p>
<a href="{% url 'blog:post_detail' post.id %}" class="btn btn-primary">Read More</a>
</div>
</div>
</div>
{% empty %}
<p>No blog posts available.</p>
{% endfor %}
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -4,7 +4,10 @@ from . import views
app_name = 'butler'
urlpatterns = [
path('', views.hello_view, name='landing'), # 루트 경로에서 hello_view 호출
# path('', views.hello_view, name='landing'), # 루트 경로에서 hello_view 호출
# Landing Page
path('', views.LandingPageView.as_view(), name='landing'), # 클래스 기반 뷰(CBV) 호출
path('notice', views.notice_list, name='notice_list'),
path('create_notice/', views.create_notice, name='create_notice'), # 포스트 작성
path('notice/<int:pk>/', views.notice_detail_view, name='notice_detail'),

View File

@ -1,18 +1,23 @@
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.views.generic import TemplateView
from pathlib import Path
import markdown
import os
from .models import NoticeBoard, IPManagementRecord
from blog.models import Post
from .forms import PostForm
from django.db.models import Q
def hello_view(request):
return render(
request,
"butler/landing.html",
)
class LandingPageView(TemplateView):
template_name = "butler/landing.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['blog_posts'] = Post.objects.order_by('-created_at')[:3]
context['notices'] = NoticeBoard.objects.order_by('-created_at')[:3]
return context
# --- notice ---
@login_required

View File

@ -1,40 +1,38 @@
<div class="container-fluid d-flex justify-content-between align-items-center">
<h1 class="d-flex align-items-center fs-4 text-white mb-0">
<a class="navbar-brand" href="/">
<i class="fa-solid fa-dog"></i> DDoCHI</a>
<i class="fa-solid fa-dog"></i>
DDoCHI</a>
</h1>
<!-- 로그인/로그아웃 및 회원가입 버튼 -->
<ul class="navbar-nav flex-row">
{% if user.is_authenticated and user.is_superuser %}
<!-- 관리자 콘솔 버튼 -->
<li class="nav-item me-3">
<a href="/admin" target="_blank" class="btn btn-outline-warning mb-2">ADMIN</a>
</li>
<!-- 관리자 콘솔 버튼 -->
<li class="nav-item me-3">
<a href="/admin" target="_blank" class="btn btn-outline-warning mb-2">ADMIN</a>
</li>
{% endif %}
{% if request.user.is_authenticated %}
<!-- 회원정보 변경 버튼 -->
<li class="nav-item me-3">
<button type="button" class="btn btn-outline-info mb-2" data-bs-toggle="modal"
data-bs-target="#editProfileModal">Edit Profile</button>
</li>
<!-- 로그아웃 버튼 -->
<li class="nav-item">
<form method="post" action="{% url 'custom_auth:logout' %}">
{% csrf_token %}
<button type="submit" class="btn btn-outline-danger w-100">Logout</button>
</form>
</li>
<!-- 회원정보 변경 버튼 -->
<li class="nav-item me-3">
<button type="button" class="btn btn-outline-info mb-2" data-bs-toggle="modal" data-bs-target="#editProfileModal">Edit Profile</button>
</li>
<!-- 로그아웃 버튼 -->
<li class="nav-item">
<form method="post" action="{% url 'custom_auth:logout' %}">
{% csrf_token %}
<button type="submit" class="btn btn-outline-danger w-100">Logout</button>
</form>
</li>
{% else %}
<!-- 로그인 버튼 -->
<li class="nav-item me-3">
<button type="button" class="btn btn-outline-primary mb-2" data-bs-toggle="modal"
data-bs-target="#loginModal">Login</button>
</li>
<!-- 회원가입 버튼 -->
<li class="nav-item me-3">
<button type="button" class="btn btn-outline-success" data-bs-toggle="modal" data-bs-target="#signupModal">Sign
Up</button>
</li>
<!-- 로그인 버튼 -->
<li class="nav-item me-3">
<button type="button" class="btn btn-outline-primary mb-2" data-bs-toggle="modal" data-bs-target="#loginModal">Login</button>
</li>
<!-- 회원가입 버튼 -->
<li class="nav-item me-3">
<button type="button" class="btn btn-outline-success" data-bs-toggle="modal" data-bs-target="#signupModal">Sign Up</button>
</li>
{% endif %}
</ul>
</div>
@ -50,11 +48,11 @@
<div class="modal-body">
<!-- 로그인 실패 메시지 표시 -->
{% if messages %}
{% for message in messages %}
<div class="alert alert-danger" role="alert">
{{ message }}
</div>
{% endfor %}
{% for message in messages %}
<div class="alert alert-danger" role="alert">
{{ message }}
</div>
{% endfor %}
{% endif %}
<!-- 로그인 폼 -->
@ -123,7 +121,7 @@
{% csrf_token %}
<div class="mb-3">
<label for="emailEdit" class="form-label">Email</label>
<input type="email" class="form-control" id="emailEdit" name="email" value="{{ request.user.email }}" required>
<input type="email" class="form-control" id="emailEdit" name="email" value="{{ request.user.email }}" required="required">
</div>
<div class="mb-3">
<label for="nhncIdEdit" class="form-label">NHNC ID</label>
@ -133,6 +131,52 @@
<label for="nhncApiTenantIdEdit" class="form-label">NHNC API Tenant ID</label>
<input type="text" class="form-control" id="nhncApiTenantIdEdit" name="nhnc_api_tenant_id" value="{{ request.user.nhnc_api_tenant_id }}">
</div>
<!-- 추가된 URL 필드 -->
<div class="mb-3">
<label for="urlGiteaEdit" class="form-label">Gitea URL</label>
<input type="url" class="form-control" id="urlGiteaEdit" name="url_gitea" value="{{ request.user.url_gitea }}">
</div>
<div class="mb-3">
<label for="urlHarborEdit" class="form-label">Harbor URL</label>
<input type="url" class="form-control" id="urlHarborEdit" name="url_harbor" value="{{ request.user.url_harbor }}">
</div>
<div class="mb-3">
<label for="urlArgoCDEdit" class="form-label">ArgoCD URL</label>
<input type="url" class="form-control" id="urlArgoCDEdit" name="url_argocd" value="{{ request.user.url_argocd }}">
</div>
<div class="mb-3">
<label for="urlWebIdeEdit" class="form-label">Web IDE URL</label>
<input type="url" class="form-control" id="urlWebIdeEdit" name="url_web_ide" value="{{ request.user.url_web_ide }}">
</div>
<div class="mb-3">
<label for="urlRancherEdit" class="form-label">Rancher URL</label>
<input type="url" class="form-control" id="urlRancherEdit" name="url_rancher" value="{{ request.user.url_rancher }}">
</div>
<div class="mb-3">
<label for="urlGrafanaEdit" class="form-label">Grafana URL</label>
<input type="url" class="form-control" id="urlGrafanaEdit" name="url_grafana" value="{{ request.user.url_grafana }}">
</div>
<div class="mb-3">
<label for="urlPrometheusEdit" class="form-label">Prometheus URL</label>
<input type="url" class="form-control" id="urlPrometheusEdit" name="url_prometheus" value="{{ request.user.url_prometheus }}">
</div>
<div class="mb-3">
<label for="urlOpensearchEdit" class="form-label">OpenSearch URL</label>
<input type="url" class="form-control" id="urlOpensearchEdit" name="url_opensearch" value="{{ request.user.url_opensearch }}">
</div>
<div class="mb-3">
<label for="urlKialiEdit" class="form-label">Kiali URL</label>
<input type="url" class="form-control" id="urlKialiEdit" name="url_kiali" value="{{ request.user.url_kiali }}">
</div>
<div class="mb-3">
<label for="urlNexusEdit" class="form-label">Nexus URL</label>
<input type="url" class="form-control" id="urlNexusEdit" name="url_nexus" value="{{ request.user.url_nexus }}">
</div>
<div class="mb-3">
<label for="urlMattermostEdit" class="form-label">Mattermost URL</label>
<input type="url" class="form-control" id="urlMattermostEdit" name="url_mattermost" value="{{ request.user.url_mattermost }}">
</div>
<!-- 비밀번호 변경 -->
<div class="mb-3">
<label for="passwordEdit" class="form-label">새 비밀번호</label>
<input type="password" class="form-control" id="passwordEdit" name="password">

View File

@ -2,15 +2,16 @@
<nav class="sticky-xl-top small" id="toc">
<ul class="list-unstyled">
<li class="my-2">
<button class="btn d-inline-flex align-items-center collapsed" data-bs-toggle="collapse" aria-expanded="false" data-bs-target="#about-collapse" aria-controls="about-collapse">About</button>
<button class="btn d-inline-flex align-items-center collapsed" data-bs-toggle="collapse" aria-expanded="false" data-bs-target="#about-collapse" aria-controls="about-collapse">About</button>
<ul class="list-unstyled ps-3 collapse" id="about-collapse">
<li>
<a class="d-inline-flex align-items-center rounded" href="/notice">공지사항</a>
</li>
</ul>
</li>
<hr>
<li class="my-2">
<button class="btn d-inline-flex align-items-center collapsed" data-bs-toggle="collapse" aria-expanded="false" data-bs-target="#contents-collapse" aria-controls="contents-collapse">Contents</button>
<button class="btn d-inline-flex align-items-center collapsed" data-bs-toggle="collapse" aria-expanded="false" data-bs-target="#contents-collapse" aria-controls="contents-collapse">Contents</button>
<ul class="list-unstyled ps-3 collapse" id="contents-collapse">
<li>
<a class="d-inline-flex align-items-center rounded" href="/blog">Post</a>
@ -30,9 +31,8 @@
</li>
<hr>
<li class="my-2">
<button class="btn d-inline-flex align-items-center collapsed" data-bs-toggle="collapse" aria-expanded="false" data-bs-target="#nhnc-collapse" aria-controls="nhnc-collapse">NHN Cloud API</button>
<button class="btn d-inline-flex align-items-center collapsed" data-bs-toggle="collapse" aria-expanded="false" data-bs-target="#nhnc-collapse" aria-controls="nhnc-collapse">NHN Cloud API</button>
<ul class="list-unstyled ps-3 collapse" id="nhnc-collapse">
<span>가이드</span>
{% if request.user.is_authenticated and request.user.is_staff %}
<li>
<a class="d-inline-flex align-items-center rounded" href="/nhncloud/test">출력결과 검토</a>
@ -78,56 +78,51 @@
</li>
<hr>
<li class="my-2">
<button class="btn d-inline-flex align-items-center collapsed" data-bs-toggle="collapse" aria-expanded="false" data-bs-target="#components-collapse" aria-controls="components-collapse">DevOpsTools</button>
<button class="btn d-inline-flex align-items-center collapsed" data-bs-toggle="collapse" aria-expanded="false" data-bs-target="#components-collapse" aria-controls="components-collapse">DevOpsTools</button>
<ul class="list-unstyled ps-3 collapse" id="components-collapse">
<span>Dev</span>
<li>
<a class="d-inline-flex align-items-center rounded" href="https://gitea.icurfer.com/icurfer" target="_blank">Repository - Gitea</a>
<a class="d-inline-flex align-items-center rounded" href="{{request.user.url_gitea}}" target="_blank">Repository - Gitea</a>
</li>
<li>
<a class="d-inline-flex align-items-center rounded" href="https://harbor.icurfer.com/" target="_blank">Registry - Harbor</a>
<a class="d-inline-flex align-items-center rounded" href="{{request.user.url_harbor}}" target="_blank">Registry - Harbor</a>
</li>
<li>
<a class="d-inline-flex align-items-center rounded" href="https://argocd.icurfer.com/" target="_blank">Deploy - ArgoCD</a>
<a class="d-inline-flex align-items-center rounded" href="{{request.user.url_argocd}}" target="_blank">Deploy - ArgoCD</a>
</li>
<hr>
<span>Ops</span>
{% if request.user.is_authenticated and request.user.is_staff %}
<li>
<a class="d-inline-flex align-items-center rounded" href="https://code.icurfer.com/" target="_blank">Web VScode - CodeServer</a>
<a class="d-inline-flex align-items-center rounded" href="{{request.user.url_web_ide}}" target="_blank">Web VScode - CodeServer</a>
</li>
{% endif %}
<li>
<a class="d-inline-flex align-items-center rounded" href="https://rancher.icurfer.com/" target="_blank">Cluster Management - Rancher</a>
<a class="d-inline-flex align-items-center rounded" href="{{request.user.url_rancher}}" target="_blank">Cluster Management - Rancher</a>
</li>
<li>
<a class="d-inline-flex align-items-center rounded" href="https://grafana.icurfer.com/" target="_blank">Monitoring - Grafana</a>
<a class="d-inline-flex align-items-center rounded" href="{{request.user.url_grafana}}" target="_blank">Monitoring - Grafana</a>
</li>
<li>
<a class="d-inline-flex align-items-center rounded" href="https://prometheus.icurfer.com/" target="_blank">Metrics - Prometheus</a>
<a class="d-inline-flex align-items-center rounded" href="{{request.user.url_prometheus}}" target="_blank">Metrics - Prometheus</a>
</li>
<li>
<a class="d-inline-flex align-items-center rounded" href="https://os.icurfer.com/" target="_blank">Container Log - OpenSearch</a>
<a class="d-inline-flex align-items-center rounded" href="{{request.user.url_opensearch}}" target="_blank">Container Log - OpenSearch</a>
</li>
<li>
<a class="d-inline-flex align-items-center rounded" href="https://kiali.icurfer.com/" target="_blank">Main Cluster Traffic - Kiali</a>
</li>
</ul>
</li>
<li class="my-2">
<button class="btn d-inline-flex align-items-center collapsed" data-bs-toggle="collapse" aria-expanded="false" data-bs-target="#other-collapse" aria-controls="other-collapse">Other Tools</button>
<ul class="list-unstyled ps-3 collapse" id="other-collapse">
<li>
<a class="d-inline-flex align-items-center rounded" href="https://mm.icurfer.com/" target="_blank">Messenger - Mattermost</a>
<a class="d-inline-flex align-items-center rounded" href="{{request.user.url_kiali}}" target="_blank">Main Cluster Traffic - Kiali</a>
</li>
</ul>
</li>
<hr>
<li class="my-2">
<button class="btn d-inline-flex align-items-center collapsed" data-bs-toggle="collapse" aria-expanded="false" data-bs-target="#forms-collapse" aria-controls="forms-collapse">Documents</button>
<ul class="list-unstyled ps-3 collapse" id="forms-collapse">
<button class="btn d-inline-flex align-items-center collapsed" data-bs-toggle="collapse" aria-expanded="false" data-bs-target="#other-collapse" aria-controls="other-collapse">Other Tools ▽</button>
<ul class="list-unstyled ps-3 collapse" id="other-collapse">
<li>
<a class="d-inline-flex align-items-center rounded" href="#">사용가이드</a>
<a class="d-inline-flex align-items-center rounded" href="{{request.user.url_mattermost}}" target="_blank">Messenger - Mattermost</a>
</li>
<li>
<a class="d-inline-flex align-items-center rounded" href="{{request.user.url_nexus}}" target="_blank">Nexus</a>
</li>
</ul>
</li>

View File

@ -0,0 +1,149 @@
<div class="container-fluid d-flex justify-content-between align-items-center">
<h1 class="d-flex align-items-center fs-4 text-white mb-0">
<a class="navbar-brand" href="/">
<i class="fa-solid fa-dog"></i> DDoCHI</a>
</h1>
<!-- 로그인/로그아웃 및 회원가입 버튼 -->
<ul class="navbar-nav flex-row">
{% if user.is_authenticated and user.is_superuser %}
<!-- 관리자 콘솔 버튼 -->
<li class="nav-item me-3">
<a href="/admin" target="_blank" class="btn btn-outline-warning mb-2">ADMIN</a>
</li>
{% endif %}
{% if request.user.is_authenticated %}
<!-- 회원정보 변경 버튼 -->
<li class="nav-item me-3">
<button type="button" class="btn btn-outline-info mb-2" data-bs-toggle="modal"
data-bs-target="#editProfileModal">Edit Profile</button>
</li>
<!-- 로그아웃 버튼 -->
<li class="nav-item">
<form method="post" action="{% url 'custom_auth:logout' %}">
{% csrf_token %}
<button type="submit" class="btn btn-outline-danger w-100">Logout</button>
</form>
</li>
{% else %}
<!-- 로그인 버튼 -->
<li class="nav-item me-3">
<button type="button" class="btn btn-outline-primary mb-2" data-bs-toggle="modal"
data-bs-target="#loginModal">Login</button>
</li>
<!-- 회원가입 버튼 -->
<li class="nav-item me-3">
<button type="button" class="btn btn-outline-success" data-bs-toggle="modal" data-bs-target="#signupModal">Sign
Up</button>
</li>
{% endif %}
</ul>
</div>
<!-- 로그인 모달 -->
<div class="modal fade" id="loginModal" tabindex="-1" aria-labelledby="loginModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="loginModalLabel">Login</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<!-- 로그인 실패 메시지 표시 -->
{% if messages %}
{% for message in messages %}
<div class="alert alert-danger" role="alert">
{{ message }}
</div>
{% endfor %}
{% endif %}
<!-- 로그인 폼 -->
<form method="post" action="{% url 'custom_auth:login' %}">
{% csrf_token %}
<div class="mb-3">
<label for="username" class="form-label">Username</label>
<input type="text" class="form-control" id="username" name="username" required="required">
</div>
<div class="mb-3">
<label for="password" class="form-label">Password</label>
<input type="password" class="form-control" id="password" name="password" required="required">
</div>
<button type="submit" class="btn btn-primary w-100">Login</button>
</form>
</div>
</div>
</div>
</div>
<!-- 회원가입 모달 -->
<div class="modal fade" id="signupModal" tabindex="-1" aria-labelledby="signupModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="signupModalLabel">Sign Up</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<!-- 회원가입 폼 -->
<form method="post" action="{% url 'custom_auth:signup' %}">
{% csrf_token %}
<div class="mb-3">
<label for="usernameSignup" class="form-label">Username</label>
<input type="text" class="form-control" id="usernameSignup" name="username" required="required">
</div>
<div class="mb-3">
<label for="passwordSignup" class="form-label">Password</label>
<input type="password" class="form-control" id="passwordSignup" name="password1" required="required">
</div>
<div class="mb-3">
<label for="passwordConfirmSignup" class="form-label">Confirm Password</label>
<input type="password" class="form-control" id="passwordConfirmSignup" name="password2" required="required">
</div>
<a href="{% url 'butler:privacy' %}" class="text-dark" target="_blank">개인정보 처리방침</a>
<p class="text-danger">회원 가입후 권한 신청 메일을 보내주세요.</p>
<p class="text-danger">회원 가입시 본 개인정보 처리방침에 동의하는 것으로 간주됩니다.</p>
<button type="submit" class="btn btn-success w-100">Sign Up</button>
</form>
</div>
</div>
</div>
</div>
<!-- 회원정보 변경 모달 -->
<div class="modal fade" id="editProfileModal" tabindex="-1" aria-labelledby="editProfileModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="editProfileModalLabel">Edit Profile</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<!-- 회원정보 변경 폼 -->
<form method="post" action="{% url 'custom_auth:edit_profile' %}">
{% csrf_token %}
<div class="mb-3">
<label for="emailEdit" class="form-label">Email</label>
<input type="email" class="form-control" id="emailEdit" name="email" value="{{ request.user.email }}" required>
</div>
<div class="mb-3">
<label for="nhncIdEdit" class="form-label">NHNC ID</label>
<input type="text" class="form-control" id="nhncIdEdit" name="nhnc_id" value="{{ request.user.nhnc_id }}">
</div>
<div class="mb-3">
<label for="nhncApiTenantIdEdit" class="form-label">NHNC API Tenant ID</label>
<input type="text" class="form-control" id="nhncApiTenantIdEdit" name="nhnc_api_tenant_id" value="{{ request.user.nhnc_api_tenant_id }}">
</div>
<div class="mb-3">
<label for="passwordEdit" class="form-label">새 비밀번호</label>
<input type="password" class="form-control" id="passwordEdit" name="password">
</div>
<div class="mb-3">
<label for="passwordConfirmEdit" class="form-label">비밀번호 확인</label>
<input type="password" class="form-control" id="passwordConfirmEdit" name="password_confirm">
</div>
<button type="submit" class="btn btn-primary w-100">Save Changes</button>
</form>
</div>
</div>
</div>
</div>

View File

@ -12,14 +12,32 @@ class CustomUserAdmin(UserAdmin):
# 사용자 필드 구성
fieldsets = (
(None, {'fields': ('username', 'password')}),
('Personal Info', {'fields': ('email', 'encrypted_private_key')}),
('Personal Info', {
'fields': (
'email',
'encrypted_private_key',
'nhnc_id',
'nhnc_api_tenant_id',
'url_gitea',
'url_harbor',
'url_argocd',
'url_web_ide',
'url_rancher',
'url_grafana',
'url_prometheus',
'url_opensearch',
'url_kiali',
'url_nexus',
'url_mattermost',
)
}),
('Permissions', {'fields': ('is_staff', 'is_active')}),
)
# 읽기 전용 필드 추가
readonly_fields = ('encrypted_private_key',)
search_fields = ('username', 'email')
search_fields = ('username', 'email', 'nhnc_id', 'nhnc_api_tenant_id')
ordering = ('username',)

View File

@ -23,7 +23,22 @@ class CustomUserChangeForm(UserChangeForm):
class Meta:
model = CustomUser
fields = ["email", "nhnc_id", "nhnc_api_tenant_id"]
fields = [
'email',
'nhnc_id',
'nhnc_api_tenant_id',
'url_gitea',
'url_harbor',
'url_argocd',
'url_web_ide',
'url_rancher',
'url_grafana',
'url_prometheus',
'url_opensearch',
'url_kiali',
'url_nexus',
'url_mattermost',
]
def clean(self):
cleaned_data = super().clean()

View File

@ -0,0 +1,58 @@
# Generated by Django 4.2.14 on 2025-01-25 00:49
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('custom_auth', '0005_customuser_encrypted_private_key'),
]
operations = [
migrations.AddField(
model_name='customuser',
name='url_argocd',
field=models.URLField(blank=True, null=True),
),
migrations.AddField(
model_name='customuser',
name='url_gitea',
field=models.URLField(blank=True, null=True),
),
migrations.AddField(
model_name='customuser',
name='url_grafana',
field=models.URLField(blank=True, null=True),
),
migrations.AddField(
model_name='customuser',
name='url_harbor',
field=models.URLField(blank=True, null=True),
),
migrations.AddField(
model_name='customuser',
name='url_kiali',
field=models.URLField(blank=True, null=True),
),
migrations.AddField(
model_name='customuser',
name='url_opensearch',
field=models.URLField(blank=True, null=True),
),
migrations.AddField(
model_name='customuser',
name='url_prometheus',
field=models.URLField(blank=True, null=True),
),
migrations.AddField(
model_name='customuser',
name='url_rancher',
field=models.URLField(blank=True, null=True),
),
migrations.AddField(
model_name='customuser',
name='url_web_ide',
field=models.URLField(blank=True, null=True),
),
]

View File

@ -0,0 +1,23 @@
# Generated by Django 4.2.14 on 2025-01-25 01:20
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('custom_auth', '0006_customuser_url_argocd_customuser_url_gitea_and_more'),
]
operations = [
migrations.AddField(
model_name='customuser',
name='url_mattermost',
field=models.URLField(blank=True, null=True),
),
migrations.AddField(
model_name='customuser',
name='url_nexus',
field=models.URLField(blank=True, null=True),
),
]

View File

@ -5,15 +5,29 @@ from cryptography.fernet import Fernet
class CustomUser(AbstractUser):
"""사용자 모델 - 기존 필드 + SSH Private Key 관리 필드"""
# 기존 필드 유지
# 사용자 모델 - 기존 필드 + SSH Private Key 관리 필드
grade = models.CharField(max_length=50, blank=True, null=True)
nhnc_id = models.CharField(max_length=100, blank=True, null=True)
nhnc_api_tenant_id = models.CharField(max_length=100, blank=True, null=True)
"""사용자 모델 - SSH Private Key 관리 필드"""
# 사용자 모델 - SSH Private Key 관리 필드
encrypted_private_key = models.BinaryField(blank=True, null=True) # 암호화된 SSH 키
# Custom URL 필드 - 2025-01-25
# 여기 추가하면 components/_nav.html 수정
# custom_auth/forms.py 수정, custom_auth/views.py 수정
url_gitea = models.URLField(max_length=200, blank=True, null=True)
url_harbor = models.URLField(max_length=200, blank=True, null=True)
url_argocd = models.URLField(max_length=200, blank=True, null=True)
url_web_ide = models.URLField(max_length=200, blank=True, null=True)
url_rancher = models.URLField(max_length=200, blank=True, null=True)
url_grafana = models.URLField(max_length=200, blank=True, null=True)
url_prometheus = models.URLField(max_length=200, blank=True, null=True)
url_opensearch = models.URLField(max_length=200, blank=True, null=True)
url_kiali = models.URLField(max_length=200, blank=True, null=True)
url_nexus = models.URLField(max_length=200, blank=True, null=True)
url_mattermost = models.URLField(max_length=200, blank=True, null=True)
def encrypt_private_key(self, private_key: str) -> bytes:
"""SSH Private Key 암호화"""

View File

@ -1 +1 @@
dev_0.0.22
dev_0.0.24