33
44
55class ViewSQL :
6- """Class to manage the "records" View which represents all configured DNS
7- records bases on the serveradmin data."""
6+ """Class to manage the "powerdns_records" View which represents all configured DNS
7+ records bases on the serveradmin data.
8+ The view contains ALL DNS related records in a powerdns-like schema and the "object_ids" which are responsible
9+ for tis record, like vm-server or related domain names
10+ """
811
912 @classmethod
1013 def update_view_schema (cls ):
@@ -20,33 +23,31 @@ def get_record_view_sql(cls):
2023 # - todo: check materialized view with proper indexes
2124 # - todo if view schema is safe, remove it and only REPLACE VIEW
2225 sql = 'DROP VIEW IF EXISTS powerdns_records;'
23- sql += "CREATE OR REPLACE VIEW powerdns_records (object_id , name, type, content, domain, ttl) AS ("
26+ sql += "CREATE OR REPLACE VIEW powerdns_records (object_ids , name, type, content, domain, ttl) AS ("
2427 sub_queries = []
2528 for record_setting in RecordSetting .objects .all ():
29+ object_ids_expression = cls .get_object_ids_expression (record_setting )
2630 name_expression = cls .get_name_expression (record_setting )
2731 type_expression = cls .get_record_type_expression (record_setting )
28- content_expression = cls .get_content_expression (record_setting )
32+ content_expression = cls .get_content_expression (record_setting , True )
2933 domain_expression = cls .get_domain_expression (record_setting )
3034 attribute_join = cls .get_attribute_join (record_setting )
3135 domain_join = cls .get_domain_join (record_setting )
32- if record_setting .record_type == 'PTR' :
33- content_expression = 's.hostname'
36+ where_condition = cls .get_where_condition (record_setting )
3437
3538 sub_queries .append (
3639 f"""
3740 SELECT
38- s.server_id as object_id ,
41+ { object_ids_expression } as object_ids ,
3942 { name_expression } as name,
4043 { type_expression } as type,
4144 { content_expression } as content,
4245 { domain_expression } as domain,
4346 { record_setting .ttl } as ttl
44- FROM
45- server s
47+ FROM server s
4648 { attribute_join }
4749 { domain_join }
48- WHERE
49- s.servertype_id = '{ record_setting .servertype } '
50+ { where_condition }
5051 """
5152 )
5253 sql += " UNION ALL " .join (sub_queries )
@@ -55,8 +56,16 @@ def get_record_view_sql(cls):
5556 return sql
5657
5758 @staticmethod
58- def get_content_expression (record_setting ):
59+ def get_content_expression (record_setting , main : bool = False ):
60+ if record_setting .record_type == 'PTR' and main :
61+ # todo check if we can simplify PTRs a bit, as we have to reverse a bunch of logic
62+ if record_setting .domain :
63+ return f"domain_name.hostname"
64+ else :
65+ return 's.hostname'
66+
5967 if record_setting .source_value_special :
68+ # the content is in the "server table already"
6069 attribute = Attribute .specials [record_setting .source_value_special ]
6170 if attribute .type == 'inet' :
6271 # get plain IP address from inet (which also contains the netmask)
@@ -73,6 +82,7 @@ def get_content_expression(record_setting):
7382
7483 @staticmethod
7584 def get_attribute_join (record_setting ):
85+ """if the record content is in an non-special attribute, we need to JOIN the attribute table(s)"""
7686 if record_setting .source_value_special :
7787 # the needed attribute is already in the server table
7888 attribute_join = ""
@@ -103,6 +113,7 @@ def get_record_type_expression(cls, record_setting):
103113
104114 @classmethod
105115 def get_name_expression (cls , record_setting ):
116+ """get the "name" field for the record"""
106117 if record_setting .record_type == 'PTR' :
107118 content = cls .get_content_expression (record_setting )
108119 return f"public.ptr({ content } ::inet)"
@@ -123,6 +134,7 @@ def get_domain_expression(cls, record_setting):
123134
124135 @classmethod
125136 def get_domain_join (cls , record_setting ):
137+ """Get the JOIN for the domain, if needed"""
126138 if record_setting .domain :
127139 return f"""
128140 JOIN server_relation_attribute domain
@@ -131,3 +143,22 @@ def get_domain_join(cls, record_setting):
131143 JOIN server domain_name
132144 ON domain_name.server_id = domain.value"""
133145 return ""
146+
147+ @classmethod
148+ def get_where_condition (cls , record_setting ):
149+ """Add special WHERE conditions to the query, if needed"""
150+ if record_setting .servertype :
151+ return f"WHERE s.servertype_id = '{ record_setting .servertype } '"
152+ return ''
153+
154+ @classmethod
155+ def get_object_ids_expression (cls , record_setting ):
156+ """Get the expression to get the object_ids for the record
157+ This are the object_ids of the server and the object_ids of the domain.
158+ So all objects which are kinda touching this record
159+ """
160+ ids = ['s.server_id' ]
161+ if record_setting .domain :
162+ ids .append ('domain_name.server_id' )
163+
164+ return f"ARRAY[{ ',' .join (ids )} ]::integer[]"
0 commit comments