728x90

나의 기여 항목은 openstack dns pool show, openstack dns pool list 에 대한 sdk 를 개발하는 것이다.

아 sdk .. 어..어려워...어려워!!

일단 코드를 파헤쳐보자. (어디에 무슨 폴더가 있고 파일이 있는지도 모름 머리아픔)

 


 

일단 dns 폴더는 다음과 같은 위치에 있다. 

 

SDK 는 Resource, Proxy, Connection 구조를 가지고있다. 


Proxy 와 Resource 의 관계

Proxy 란?

- 정의: Proxy는 OpenStack API와 클라이언트 간의 중개 역할을 하는 클래스입니다. 클라이언트가 API 요청을 보내면, Proxy가 이를 처리하여 적절한 리소스에 전달합니다.
- 기능: Proxy는 리소스에 대한 CRUD(Create, Read, Update, Delete) 작업을 수행하는 메서드를 제공합니다. 이를 통해 클라이언트는 복잡한 API 호출을 단순화하여 사용할 수 있습니다.
예: Proxy는 DNS 서비스와 같은 특정 OpenStack 서비스의 API 호출을 추상화하여, 사용자가 직접 API 엔드포인트와 통신하는 대신 Proxy를 통해 간편하게 작업할 수 있게 합니다.

 

Resource란?

- 정의: Resource는 OpenStack의 다양한 엔티티를 표현하는 클래스입니다. 각 Resource는 OpenStack의 특정 리소스를 나타내며, 이러한 리소스는 데이터베이스의 레코드와 유사한 개념입니다.
- 기능: Resource 클래스는 리소스의 속성을 정의하고, 그 리소스에 대한 작업을 수행할 수 있는 메서드를 포함합니다. 예를 들어, Zone, FloatingIP와 같은 클래스가 Resource로 존재합니다.
예: Zone 리소스는 DNS 영역을 나타내며, 이 클래스의 인스턴스를 통해 해당 영역의 속성(예: 이름, 유형 등)을 관리할 수 있습니다.

 

 

스프링으로 생각해보면,, proxy 가 서비스 느낌이고, 리소스는 엔티티느낌?


일단 해보자 

 

API 명세

https://docs.openstack.org/api-ref/dns/dns-api-v2-index.html#list-all-pools

 

DNS v2 API — Designate API Reference documentation

DNS v2 API Zone Zone operations. /v2/zones detail Create a zone Success Code Reason 202 - Accepted Request is accepted, but processing may take some time. Error Code Reason 400 - Bad Request Some content in the request was invalid. 401 - Unauthorized User

docs.openstack.org

 

 

구현이 되어있는 zone.py 를(리소스) 참고해야겠다.

# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

from openstack.dns.v2 import _base
from openstack import exceptions
from openstack import resource
from openstack import utils


class Zone(_base.Resource):
    """DNS ZONE Resource"""

    resources_key = 'zones'
    base_path = '/zones'

    # capabilities - 어떤 API 요청이 가능한지 (CRUD ) 
    allow_create = True
    allow_fetch = True
    allow_commit = True
    allow_delete = True
    allow_list = True

    commit_method = "PATCH"

	# 여기가 request 값 매핑 
    _query_mapping = resource.QueryParameters(
        'name',
        'type',
        'email',
        'status',
        'description',
        'ttl',
        'limit',
        'marker',
    )

	# 여기서부터가 Response 값 매핑 
    #: Properties
    #: current action in progress on the resource
    action = resource.Body('action')
    #: Attributes
    #: Key:Value pairs of information about this zone, and the pool the user
    #: would like to place the zone in. This information can be used by the
    #: scheduler to place zones on the correct pool.
    attributes = resource.Body('attributes', type=dict)
    #: Timestamp when the zone was created
    created_at = resource.Body('created_at')
    #: Zone description
    #: *Type: str*
    description = resource.Body('description')
    #: The administrator email of this zone
    #: *Type: str*
    email = resource.Body('email')
    #: Links contains a `self` pertaining to this zone or a `next` pertaining
    #: to next page
    links = resource.Body('links', type=dict)
    #: The master list for slaver server to fetch DNS
    masters = resource.Body('masters', type=list)
    #: Zone name
    name = resource.Body('name')
    #: The pool which manages the zone, assigned by system
    pool_id = resource.Body('pool_id')
    #: The project id which the zone belongs to
    project_id = resource.Body('project_id')
    #: Serial number in the SOA record set in the zone,
    #: which identifies the change on the primary DNS server
    #: *Type: int*
    serial = resource.Body('serial', type=int)
    #: Zone status
    #: Valid values include `PENDING_CREATE`, `ACTIVE`,
    #: `PENDING_DELETE`, `ERROR`
    status = resource.Body('status')
    #: SOA TTL time, unit is seconds, default 300, TTL range 300-2147483647
    #: *Type: int*
    ttl = resource.Body('ttl', type=int)
    #: Zone type,
    #: Valid values include `PRIMARY`, `SECONDARY`
    #: *Type: str*
    type = resource.Body('type')
    #: Timestamp when the zone was last updated
    updated_at = resource.Body('updated_at')
    #: Whether the zone is shared with other projects
    #: *Type: bool*
    is_shared = resource.Body('shared')

    # Headers for DELETE requests
    #: If true, delete any existing zone shares along with the zone
    delete_shares = resource.Header('x-designate-delete-shares', type=bool)

# 이 action 함수는 리소스의 상태를 변경하거나, 특정 기능을 수행하기 위해서라고 함 ( 근데도 모호해서 뭔소린지 모르겠음. 물어봐야겠다.)
# action 매개변수 - 특정 작업의 이름, body : 해당 작업에 필요한 추가 데이터를 포함함 
    def _action(self, session, action, body):
        """Preform actions given the message body."""
        url = utils.urljoin(self.base_path, self.id, 'tasks', action)
        response = session.post(url, json=body)
        exceptions.raise_from_response(response)
        return response

    def abandon(self, session):
        self._action(session, 'abandon', None)

    def xfr(self, session):
        self._action(session, 'xfr', None)

 

어쨌든 request, response 에 따른 값 설정은 알겠는데

action 에 대한 이해가 좀 안되는것같다.

왜 있는거지? api 요청은 다 proxy 가 하는게 아닌건가?

 

 

gpt 에 따르면,,,

으음..그런가

 

그럼 일단 pool 리소스를 작성해보자.


Request

NameInTypeDescription

여기서 헤더는 Con 에 담기는 것 같다. (추측)

x-auth-token (Optional) header string Token used to identify the user from keystone
x-auth-all-projects (Optional) header bool If enabled this will show results from all projects in Designate
x-auth-sudo-project-id (Optional) header string This allows a user to impersonate another project

 

Response Parameters

NameInTypeDescription

x-openstack-request-id header string ID of the request
description body string Description for the resource. Only shown in API / Horizon
id body uuid ID for this pool
attributes body object Key:Value pairs of information about this pool. This information can be used by the scheduler to place zones on the correct pools
project_id body uuid ID for the project that owns the resource
ns_records body string Name Servers for this pool. Any zones hosted by this pool should be delegated to these DNS servers
name body string Name for this pool
created_at body datestamp Date / Time when resource was created.
updated_at body datestamp Date / Time when resource last updated.
links body object Links to the resource, and other related reso

urces. When a response has been broken into pages, we will include a next link that should be followed to retrieve all results
metadata body object Returns the total_count of resources matching this filter

 

 

from openstack.dns.v2 import _base
from openstack import exceptions
from openstack import resource
from openstack import utils
class Pool(_base.Resource):
    """DNS Pool Resource"""

    resources_key = 'pools'
    base_path = '/v2/pools'

    # capabilities
    allow_list = True
    commit_method = "GET"

    #: Properties

    description = resource.Body('description')
    id = resource.Body('id')
    project_id = resource.Body('project_id')
    created_at = resource.Body('created_at')
    updated_at = resource.Body('updated_at')
    name = resource.Body('name')
    attributes = resource.Body('attributes')
    ns_records = resource.Body('ns_records', type=list)
    links = resource.Body('links',type=dict)

    # Adding additional attributes based on response
    total_count = resource.Body('total_count', type=int, alias='metadata.total_count')
    self = resource.Body('self', alias='links.self')

일단 여기까지는 선언해뒀는데, 뭔가...

metadata를 저런식으로 하는게 아닌것같은느낌

Response Example

{
  "metadata": {
    "total_count": 2
  },
  "links": {
    "self": "http://127.0.0.1:9001/v2/pools"
  },
  "pools": [
    {
      "description": null,
      "id": "794ccc2c-d751-44fe-b57f-8894c9f5c842",
      "project_id": null,
      "created_at": "2015-02-18T22:18:58.000000",
      "attributes": null,
      "ns_records": [
        {
          "hostname": "ns1.example.org.",
          "priority": 1
        }
      ],
      "links": {
        "self": "http://127.0.0.1:9001/v2/pools/794ccc2c-d751-44fe-b57f-8894c9f5c842"
      },
      "name": "default",
      "updated_at": "2015-02-19T15:59:44.000000"
    },
    {
      "description": null,
      "id": "d1716333-8c16-490f-85ee-29af36907605",
      "project_id": "noauth-project",
      "created_at": "2015-02-23T21:56:33.000000",
      "attributes": null,
      "ns_records": [
        {
          "hostname": "ns2.example.org.",
          "priority": 1
        }
      ],
      "links": {
        "self": "http://127.0.0.1:9001/v2/pools/d1716333-8c16-490f-85ee-29af36907605"
      },
      "name": "example_pool",
      "updated_at": null
    }
  ]
}

 

 

 

의문점 

1. pools 자체가 리스트 인데, 그걸 선언해야하지않을까

2. metadata 와 links 는 왜 따로 뽑는거지? self 의 link 와 뭐가다른거며,, 

3. 이 코드에도 action 을 넣어야하는건가? 

 

일단 이번주는 여기까지

 

다음주차에 이어서 봐야할 것 

- server.py 를 예시로 들어서 어떤식으로 선언했는지 참고해서 리소스 고치기 

728x90
리촬리