",
14 | "license": "BSD-2-Clause",
15 | "repository": {
16 | "type": "git",
17 | "url": "https://github.com/MarioUhrik/external-dns-ui"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/app/static/prism.css:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2020 SIGHUP s.r.l All rights reserved.
3 | * Use of this source code is governed by a BSD-style
4 | * license that can be found in the LICENSE file.
5 | */
6 |
7 | /* PrismJS 1.21.0
8 | https://prismjs.com/download.html#themes=prism-tomorrow&languages=clike+ruby+yaml&plugins=line-numbers */
9 | /**
10 | * prism.js tomorrow night eighties for JavaScript, CoffeeScript, CSS and HTML
11 | * Based on https://github.com/chriskempson/tomorrow-theme
12 | * @author Rose Pritchard
13 | */
14 |
15 | code[class*="language-"],
16 | pre[class*="language-"] {
17 | color: #ccc;
18 | background: none;
19 | /* font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
20 | font-size: 1em; */
21 | text-align: left;
22 | white-space: pre;
23 | word-spacing: normal;
24 | word-break: normal;
25 | word-wrap: normal;
26 | line-height: 1.5;
27 |
28 | -moz-tab-size: 4;
29 | -o-tab-size: 4;
30 | tab-size: 4;
31 |
32 | -webkit-hyphens: none;
33 | -moz-hyphens: none;
34 | -ms-hyphens: none;
35 | hyphens: none;
36 |
37 | }
38 |
39 | /* Code blocks */
40 | pre[class*="language-"] {
41 | padding: 1em;
42 | margin: .5em 0;
43 | overflow: auto;
44 | }
45 |
46 | :not(pre) > code[class*="language-"],
47 | pre[class*="language-"] {
48 | background: #2d2d2d;
49 | }
50 |
51 | /* Inline code */
52 | :not(pre) > code[class*="language-"] {
53 | padding: .1em;
54 | border-radius: .3em;
55 | white-space: normal;
56 | }
57 |
58 | .token.comment,
59 | .token.block-comment,
60 | .token.prolog,
61 | .token.doctype,
62 | .token.cdata {
63 | color: #999;
64 | }
65 |
66 | .token.punctuation {
67 | color: #ccc;
68 | }
69 |
70 | .token.tag,
71 | .token.attr-name,
72 | .token.namespace,
73 | .token.deleted {
74 | color: #e2777a;
75 | }
76 |
77 | .token.function-name {
78 | color: #6196cc;
79 | }
80 |
81 | .token.boolean,
82 | .token.number,
83 | .token.function {
84 | color: #f08d49;
85 | }
86 |
87 | .token.property,
88 | .token.class-name,
89 | .token.constant,
90 | .token.symbol {
91 | color: #f8c555;
92 | }
93 |
94 | .token.selector,
95 | .token.important,
96 | .token.atrule,
97 | .token.keyword,
98 | .token.builtin {
99 | color: #cc99cd;
100 | }
101 |
102 | .token.string,
103 | .token.char,
104 | .token.attr-value,
105 | .token.regex,
106 | .token.variable {
107 | color: #7ec699;
108 | }
109 |
110 | .token.operator,
111 | .token.entity,
112 | .token.url {
113 | color: #67cdcc;
114 | }
115 |
116 | .token.important,
117 | .token.bold {
118 | font-weight: bold;
119 | }
120 | .token.italic {
121 | font-style: italic;
122 | }
123 |
124 | .token.entity {
125 | cursor: help;
126 | }
127 |
128 | .token.inserted {
129 | color: green;
130 | }
131 |
132 | pre[class*="language-"].line-numbers {
133 | position: relative;
134 | padding-left: 3.8em;
135 | counter-reset: linenumber;
136 | }
137 |
138 | pre[class*="language-"].line-numbers > code {
139 | position: relative;
140 | white-space: inherit;
141 | }
142 |
143 | .line-numbers .line-numbers-rows {
144 | position: absolute;
145 | pointer-events: none;
146 | top: 0;
147 | font-size: 100%;
148 | left: -3.8em;
149 | width: 3em; /* works for line-numbers below 1000 lines */
150 | letter-spacing: -1px;
151 | border-right: 1px solid #999;
152 |
153 | -webkit-user-select: none;
154 | -moz-user-select: none;
155 | -ms-user-select: none;
156 | user-select: none;
157 |
158 | }
159 |
160 | .line-numbers-rows > span {
161 | display: block;
162 | counter-increment: linenumber;
163 | }
164 |
165 | .line-numbers-rows > span:before {
166 | content: counter(linenumber);
167 | color: #999;
168 | display: block;
169 | padding-right: 0.8em;
170 | text-align: right;
171 | }
172 |
--------------------------------------------------------------------------------
/app/static/prism.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (c) 2020 SIGHUP s.r.l All rights reserved.
3 | * Use of this source code is governed by a BSD-style
4 | * license that can be found in the LICENSE file.
5 | */
6 |
7 | /* PrismJS 1.21.0
8 | https://prismjs.com/download.html#themes=prism-tomorrow&languages=clike+ruby+yaml&plugins=line-numbers */
9 | var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(u){var c=/\blang(?:uage)?-([\w-]+)\b/i,n=0,M={manual:u.Prism&&u.Prism.manual,disableWorkerMessageHandler:u.Prism&&u.Prism.disableWorkerMessageHandler,util:{encode:function e(n){return n instanceof W?new W(n.type,e(n.content),n.alias):Array.isArray(n)?n.map(e):n.replace(/&/g,"&").replace(/=l.reach);k+=y.value.length,y=y.next){var b=y.value;if(t.length>n.length)return;if(!(b instanceof W)){var x=1;if(h&&y!=t.tail.prev){m.lastIndex=k;var w=m.exec(n);if(!w)break;var A=w.index+(f&&w[1]?w[1].length:0),P=w.index+w[0].length,S=k;for(S+=y.value.length;S<=A;)y=y.next,S+=y.value.length;if(S-=y.value.length,k=S,y.value instanceof W)continue;for(var E=y;E!==t.tail&&(Sl.reach&&(l.reach=j);var C=y.prev;L&&(C=I(t,C,L),k+=L.length),z(t,C,x);var _=new W(o,g?M.tokenize(O,g):O,v,O);y=I(t,C,_),N&&I(t,y,N),1"+a.content+""+a.tag+">"},!u.document)return u.addEventListener&&(M.disableWorkerMessageHandler||u.addEventListener("message",function(e){var n=JSON.parse(e.data),t=n.language,r=n.code,a=n.immediateClose;u.postMessage(M.highlight(r,M.languages[t],t)),a&&u.close()},!1)),M;var e=M.util.currentScript();function t(){M.manual||M.highlightAll()}if(e&&(M.filename=e.src,e.hasAttribute("data-manual")&&(M.manual=!0)),!M.manual){var r=document.readyState;"loading"===r||"interactive"===r&&e&&e.defer?document.addEventListener("DOMContentLoaded",t):window.requestAnimationFrame?window.requestAnimationFrame(t):window.setTimeout(t,16)}return M}(_self);"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism);
10 | Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|interface|extends|implements|trait|instanceof|new)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,boolean:/\b(?:true|false)\b/,function:/\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+\.?\d*|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/};
11 | !function(e){e.languages.ruby=e.languages.extend("clike",{comment:[/#.*/,{pattern:/^=begin\s[\s\S]*?^=end/m,greedy:!0}],"class-name":{pattern:/(\b(?:class)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:alias|and|BEGIN|begin|break|case|class|def|define_method|defined|do|each|else|elsif|END|end|ensure|extend|for|if|in|include|module|new|next|nil|not|or|prepend|protected|private|public|raise|redo|require|rescue|retry|return|self|super|then|throw|undef|unless|until|when|while|yield)\b/});var n={pattern:/#\{[^}]+\}/,inside:{delimiter:{pattern:/^#\{|\}$/,alias:"tag"},rest:e.languages.ruby}};delete e.languages.ruby.function,e.languages.insertBefore("ruby","keyword",{regex:[{pattern:RegExp("%r(?:"+["([^a-zA-Z0-9\\s{(\\[<])(?:(?!\\1)[^\\\\]|\\\\[^])*\\1[gim]{0,3}","\\((?:[^()\\\\]|\\\\[^])*\\)[gim]{0,3}","\\{(?:[^#{}\\\\]|#(?:\\{[^}]+\\})?|\\\\[^])*\\}[gim]{0,3}","\\[(?:[^\\[\\]\\\\]|\\\\[^])*\\][gim]{0,3}","<(?:[^<>\\\\]|\\\\[^])*>[gim]{0,3}"].join("|")+")"),greedy:!0,inside:{interpolation:n}},{pattern:/(^|[^/])\/(?!\/)(?:\[[^\r\n\]]+\]|\\.|[^[/\\\r\n])+\/[gim]{0,3}(?=\s*(?:$|[\r\n,.;})]))/,lookbehind:!0,greedy:!0}],variable:/[@$]+[a-zA-Z_]\w*(?:[?!]|\b)/,symbol:{pattern:/(^|[^:]):[a-zA-Z_]\w*(?:[?!]|\b)/,lookbehind:!0},"method-definition":{pattern:/(\bdef\s+)[\w.]+/,lookbehind:!0,inside:{function:/\w+$/,rest:e.languages.ruby}}}),e.languages.insertBefore("ruby","number",{builtin:/\b(?:Array|Bignum|Binding|Class|Continuation|Dir|Exception|FalseClass|File|Stat|Fixnum|Float|Hash|Integer|IO|MatchData|Method|Module|NilClass|Numeric|Object|Proc|Range|Regexp|String|Struct|TMS|Symbol|ThreadGroup|Thread|Time|TrueClass)\b/,constant:/\b[A-Z]\w*(?:[?!]|\b)/}),e.languages.ruby.string=[{pattern:RegExp("%[qQiIwWxs]?(?:"+["([^a-zA-Z0-9\\s{(\\[<])(?:(?!\\1)[^\\\\]|\\\\[^])*\\1","\\((?:[^()\\\\]|\\\\[^])*\\)","\\{(?:[^#{}\\\\]|#(?:\\{[^}]+\\})?|\\\\[^])*\\}","\\[(?:[^\\[\\]\\\\]|\\\\[^])*\\]","<(?:[^<>\\\\]|\\\\[^])*>"].join("|")+")"),greedy:!0,inside:{interpolation:n}},{pattern:/("|')(?:#\{[^}]+\}|\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0,inside:{interpolation:n}}],e.languages.rb=e.languages.ruby}(Prism);
12 | !function(n){var t=/[*&][^\s[\]{},]+/,e=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,r="(?:"+e.source+"(?:[ \t]+"+t.source+")?|"+t.source+"(?:[ \t]+"+e.source+")?)";function a(n,t){t=(t||"").replace(/m/g,"")+"m";var e="([:\\-,[{]\\s*(?:\\s<>[ \t]+)?)(?:<>)(?=[ \t]*(?:$|,|]|}|\\s*#))".replace(/<>/g,function(){return r}).replace(/<>/g,function(){return n});return RegExp(e,t)}n.languages.yaml={scalar:{pattern:RegExp("([\\-:]\\s*(?:\\s<>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)[^\r\n]+(?:\\2[^\r\n]+)*)".replace(/<>/g,function(){return r})),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp("((?:^|[:\\-,[{\r\n?])[ \t]*(?:<>[ \t]+)?)[^\r\n{[\\]},#\\s]+?(?=\\s*:\\s)".replace(/<>/g,function(){return r})),lookbehind:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:a("\\d{4}-\\d\\d?-\\d\\d?(?:[tT]|[ \t]+)\\d\\d?:\\d{2}:\\d{2}(?:\\.\\d*)?[ \t]*(?:Z|[-+]\\d\\d?(?::\\d{2})?)?|\\d{4}-\\d{2}-\\d{2}|\\d\\d?:\\d{2}(?::\\d{2}(?:\\.\\d*)?)?"),lookbehind:!0,alias:"number"},boolean:{pattern:a("true|false","i"),lookbehind:!0,alias:"important"},null:{pattern:a("null|~","i"),lookbehind:!0,alias:"important"},string:{pattern:a("(\"|')(?:(?!\\2)[^\\\\\r\n]|\\\\.)*\\2"),lookbehind:!0,greedy:!0},number:{pattern:a("[+-]?(?:0x[\\da-f]+|0o[0-7]+|(?:\\d+\\.?\\d*|\\.?\\d+)(?:e[+-]?\\d+)?|\\.inf|\\.nan)","i"),lookbehind:!0},tag:e,important:t,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},n.languages.yml=n.languages.yaml}(Prism);
13 | !function(){if("undefined"!=typeof self&&self.Prism&&self.document){var o="line-numbers",a=/\n(?!$)/g,e=Prism.plugins.lineNumbers={getLine:function(e,n){if("PRE"===e.tagName&&e.classList.contains(o)){var t=e.querySelector(".line-numbers-rows"),i=parseInt(e.getAttribute("data-start"),10)||1,r=i+(t.children.length-1);n");(i=document.createElement("span")).setAttribute("aria-hidden","true"),i.className="line-numbers-rows",i.innerHTML=l,t.hasAttribute("data-start")&&(t.style.counterReset="linenumber "+(parseInt(t.getAttribute("data-start"),10)-1)),e.element.appendChild(i),u([t]),Prism.hooks.run("line-numbers",e)}}}),Prism.hooks.add("line-numbers",function(e){e.plugins=e.plugins||{},e.plugins.lineNumbers=!0})}function u(e){if(0!=(e=e.filter(function(e){var n=t(e)["white-space"];return"pre-wrap"===n||"pre-line"===n})).length){var n=e.map(function(e){var n=e.querySelector("code"),t=e.querySelector(".line-numbers-rows");if(n&&t){var i=e.querySelector(".line-numbers-sizer"),r=n.textContent.split(a);i||((i=document.createElement("span")).className="line-numbers-sizer",n.appendChild(i)),i.innerHTML="0",i.style.display="block";var s=i.getBoundingClientRect().height;return i.innerHTML="",{element:e,lines:r,lineHeights:[],oneLinerHeight:s,sizer:i}}}).filter(Boolean);n.forEach(function(e){var i=e.sizer,n=e.lines,r=e.lineHeights,s=e.oneLinerHeight;r[n.length-1]=void 0,n.forEach(function(e,n){if(e&&1
2 |
6 |
--------------------------------------------------------------------------------
/app/templates/base.html:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 | external-dns-ui {{ title }}
12 |
13 |
14 |
15 |
21 |
22 |
23 |
24 |
30 |
31 | {% if hide_sidebar == true %}
32 | {% else %}
33 |
34 |
37 |
38 | {% endif %}
39 |
40 |
41 | {% block content %}{% endblock %}
42 |
43 |
44 |
45 | {% include 'footer.html' %}
46 |
47 |
48 |
49 |
50 |
51 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/app/templates/footer.html:
--------------------------------------------------------------------------------
1 |
6 |
7 |
14 |
--------------------------------------------------------------------------------
/app/templates/hostnames.html:
--------------------------------------------------------------------------------
1 |
6 |
7 | {% extends "base.html" %}
8 | {% block sidebar %}
9 | Ingress reachability status:
10 | {% for hostname in hostname_statuses %}
11 |
12 | {% if hostname_statuses[hostname] == false %} unreachable {%else%} reachable {% endif %}
13 | {{ hostname }}
14 |
15 | {% endfor %}
16 | {% endblock %}
17 | {% block content %}
18 | Status of external-dns:
19 | {% if up_to_date == false %} Out of sync {%else%} In Sync {% endif %}
20 | {% endblock %}
21 |
--------------------------------------------------------------------------------
/app/templates/message.html:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 |
10 |
11 | external-dns-ui - {{ title }}
12 |
13 |
14 |
107 |
108 |
109 |
110 |
111 |
112 |
133 |
134 | {% include 'footer.html' %}
135 |
136 |
137 |
138 |
139 |
--------------------------------------------------------------------------------
/app/uwsgi.ini:
--------------------------------------------------------------------------------
1 | [uwsgi]
2 | module = app
3 | callable = app
4 | master = true
5 | buffer-size = 65535
6 |
--------------------------------------------------------------------------------
/manifests/deployment.yaml:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2020 SIGHUP s.r.l All rights reserved.
2 | # Use of this source code is governed by a BSD-style
3 | # license that can be found in the LICENSE file.
4 |
5 | apiVersion: apps/v1
6 | kind: Deployment
7 | metadata:
8 | name: external-dns-ui
9 | spec:
10 | selector:
11 | matchLabels:
12 | app: external-dns-ui
13 | template:
14 | metadata:
15 | labels:
16 | app: external-dns-ui
17 | spec:
18 | serviceAccountName: external-dns-ui
19 | containers:
20 | - name: external-dns-ui
21 | image: mariouhrik/external-dns-ui
22 | imagePullPolicy: Always
23 | env:
24 | - name: EDUI_NAMESPACE
25 | valueFrom:
26 | fieldRef:
27 | fieldPath: metadata.namespace
28 | resources:
29 | requests:
30 | memory: "256Mi"
31 | cpu: "100m"
32 | limits:
33 | memory: "512Mi"
34 | cpu: "500m"
35 | livenessProbe:
36 | httpGet:
37 | path: /health
38 | port: http
39 | readinessProbe:
40 | httpGet:
41 | path: /health
42 | port: http
43 | ports:
44 | - containerPort: 8080
45 | name: http
46 | securityContext:
47 | privileged: false
48 |
--------------------------------------------------------------------------------
/manifests/ingress.yaml:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2020 SIGHUP s.r.l All rights reserved.
2 | # Use of this source code is governed by a BSD-style
3 | # license that can be found in the LICENSE file.
4 |
5 | apiVersion: networking.k8s.io/v1beta1
6 | kind: Ingress
7 | metadata:
8 | name: external-dns-ui
9 | spec:
10 | rules:
11 | # Set the HOST accordingly
12 | - host: edui.internal.mycompany.com
13 | http:
14 | paths:
15 | - path: /
16 | backend:
17 | serviceName: external-dns-ui
18 | servicePort: http
19 |
--------------------------------------------------------------------------------
/manifests/kustomization.yaml:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2020 SIGHUP s.r.l All rights reserved.
2 | # Use of this source code is governed by a BSD-style
3 | # license that can be found in the LICENSE file.
4 |
5 | namespace: external-dns # please specify - should be the same as the namespace with external-dns in it
6 |
7 | resources:
8 | - rbac.yaml
9 | - deployment.yaml
10 | - service.yaml
11 | # Uncomment the following line to create an ingress if you want to expose the
12 | # the app to the outside. Remember to edit the file and set the host accordingly.
13 | # - ingress.yaml
14 |
15 | images:
16 | - name: mariouhrik/external-dns-ui
17 | newTag: latest
18 |
--------------------------------------------------------------------------------
/manifests/rbac.yaml:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2020 SIGHUP s.r.l All rights reserved.
2 | # Use of this source code is governed by a BSD-style
3 | # license that can be found in the LICENSE file.
4 |
5 | apiVersion: v1
6 | kind: ServiceAccount
7 | metadata:
8 | name: external-dns-ui
9 | ---
10 | apiVersion: rbac.authorization.k8s.io/v1
11 | kind: ClusterRole
12 | metadata:
13 | name: external-dns-ui
14 | rules:
15 | - apiGroups:
16 | - extensions
17 | resources:
18 | - ingresses
19 | verbs:
20 | - get
21 | - list
22 | - watch
23 | ---
24 | apiVersion: rbac.authorization.k8s.io/v1
25 | kind: Role
26 | metadata:
27 | name: external-dns-ui
28 | rules:
29 | - apiGroups:
30 | - extensions
31 | - ""
32 | resources:
33 | - deployments
34 | - pods
35 | - pods/log
36 | verbs:
37 | - get
38 | - list
39 | - watch
40 | ---
41 | apiVersion: rbac.authorization.k8s.io/v1
42 | kind: ClusterRoleBinding
43 | metadata:
44 | name: external-dns-ui
45 | roleRef:
46 | apiGroup: rbac.authorization.k8s.io
47 | kind: ClusterRole
48 | name: external-dns-ui
49 | subjects:
50 | - kind: ServiceAccount
51 | name: external-dns-ui
52 | namespace: external-dns # please specify - should be the same as the namespace with external-dns in it
53 | ---
54 | apiVersion: rbac.authorization.k8s.io/v1
55 | kind: RoleBinding
56 | metadata:
57 | name: external-dns-ui
58 | roleRef:
59 | apiGroup: rbac.authorization.k8s.io
60 | kind: Role
61 | name: external-dns-ui
62 | subjects:
63 | - kind: ServiceAccount
64 | name: external-dns-ui
65 | namespace: external-dns # please specify - should be the same as the namespace with external-dns in it
66 |
--------------------------------------------------------------------------------
/manifests/service.yaml:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2020 SIGHUP s.r.l All rights reserved.
2 | # Use of this source code is governed by a BSD-style
3 | # license that can be found in the LICENSE file.
4 |
5 |
6 | apiVersion: v1
7 | kind: Service
8 | metadata:
9 | name: external-dns-ui
10 | spec:
11 | selector:
12 | app: external-dns-ui
13 | ports:
14 | - port: 80
15 | targetPort: http
16 |
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "config:base"
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/screenshots/external-dns-ui_1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/MarioUhrik/external-dns-ui/3d5025fada1abcbd695d218e23e88a587bb6f523/screenshots/external-dns-ui_1.jpg
--------------------------------------------------------------------------------
/test/kustomization.yaml:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2020 SIGHUP s.r.l All rights reserved.
2 | # Use of this source code is governed by a BSD-style
3 | # license that can be found in the LICENSE file.
4 |
5 | namespace: external-dns
6 |
7 | bases:
8 | - ../manifests
9 |
10 | resources:
11 | - test_ingresses.yaml
12 | - test_external-dns.yaml
13 |
14 | patches:
15 | - patch_external-dns-ui.yaml
16 |
--------------------------------------------------------------------------------
/test/patch_external-dns-ui.yaml:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2020 SIGHUP s.r.l All rights reserved.
2 | # Use of this source code is governed by a BSD-style
3 | # license that can be found in the LICENSE file.
4 |
5 | apiVersion: apps/v1
6 | kind: Deployment
7 | metadata:
8 | name: external-dns-ui
9 | spec:
10 | template:
11 | spec:
12 | containers:
13 | - name: external-dns-ui
14 | env:
15 | - name: EDUI_LOG_LEVEL
16 | value: DEBUG
17 |
--------------------------------------------------------------------------------
/test/setup_test_environment.sh:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2020 SIGHUP s.r.l All rights reserved.
2 | # Use of this source code is governed by a BSD-style
3 | # license that can be found in the LICENSE file.
4 |
5 | # Build & push Docker image
6 | cd ..
7 | docker build . -t mariouhrik/external-dns-ui:latest
8 | docker push mariouhrik/external-dns-ui:latest
9 | cd -
10 |
11 | # Deploy a Minikube test environment
12 | if minikube status | grep -ri running; then minikube status; else echo "Please start minikube via minikube start" && exit 1; fi
13 | if minikube addons list | grep ingress | grep enabled; then echo "Minikube ingress addon is enabled"; else echo "Please enable Ingress addon for minikube via minikube addons enable ingress" && exit 2; fi
14 | kubectl -n external-dns delete deployment external-dns-ui external-dns
15 | kubectl -n external-dns delete pod -l app=external-dns-ui
16 | kustomize build | kubectl apply -f -
17 | kubectl apply -f test_ingresses.yaml -n testns
18 | echo "Waiting for the external-dns-ui pod to get Ready..."
19 | sleep 8
20 | kubectl -n external-dns wait --for=condition=Ready pod -l app=external-dns-ui
21 | EXTERNAL_DNS_POD_NAME=$(kubectl -n external-dns get pod -l app=external-dns-ui -o custom-columns=:metadata.name --no-headers=true)
22 | kubectl -n external-dns exec -it $EXTERNAL_DNS_POD_NAME -- sh -c "echo \"10.0.2.15 testdomain.com\" >> /etc/hosts"
23 | kubectl -n external-dns exec -it $EXTERNAL_DNS_POD_NAME -- sh -c "echo \"10.0.2.15 gatekeeper2.testdomain.com\" >> /etc/hosts"
24 |
25 | # Setup port-forward, so that you can view the web app at localhost:8000
26 | echo "-----------------------TEST ENVIRONMENT SETUP COMPLETED SUCCESSFULLY----------------------------"
27 | echo "Please, use the following command:"
28 | echo ""
29 | echo " kubectl -n external-dns port-forward svc/external-dns-ui 8000:80"
30 | echo ""
31 | echo "Afterwards, you can use your web browser and visit the web app at localhost:8000"
32 |
--------------------------------------------------------------------------------
/test/test_external-dns.yaml:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2020 SIGHUP s.r.l All rights reserved.
2 | # Use of this source code is governed by a BSD-style
3 | # license that can be found in the LICENSE file.
4 |
5 | apiVersion: v1
6 | kind: Namespace
7 | metadata:
8 | name: external-dns
9 | ---
10 | apiVersion: apps/v1
11 | kind: Deployment #Incorrectly configured dummy deployment of external-dns
12 | metadata:
13 | name: external-dns
14 | spec:
15 | replicas: 1
16 | selector:
17 | matchLabels:
18 | app: external-dns
19 | template:
20 | metadata:
21 | labels:
22 | app: external-dns
23 | spec:
24 | serviceAccountName: external-dns
25 | containers:
26 | - name: external-dns
27 | image: k8s.gcr.io/external-dns/external-dns:v0.7.4
28 | args:
29 | - --source=service
30 | - --source=ingress
31 | - --domain-filter=testdomain.com
32 | - --registry=txt
33 | ports:
34 | - name: metrics
35 | containerPort: 7979
36 | resources:
37 | requests:
38 | cpu: 50m
39 | memory: 50Mi
40 | limits:
41 | cpu: 250m
42 | memory: 250Mi
43 | readinessProbe:
44 | httpGet:
45 | path: /healthz
46 | port: metrics
47 | livenessProbe:
48 | failureThreshold: 2
49 | httpGet:
50 | path: /healthz
51 | port: metrics
52 | securityContext:
53 | runAsNonRoot: true
54 | runAsUser: 65534
55 | readOnlyRootFilesystem: true
56 | capabilities:
57 | drop:
58 | - "ALL"
59 | ---
60 | apiVersion: v1
61 | kind: Service
62 | metadata:
63 | name: external-dns-metrics
64 | labels:
65 | app: external-dns
66 | spec:
67 | ports:
68 | - name: metrics
69 | port: 7979
70 | protocol: TCP
71 | targetPort: metrics
72 | selector:
73 | app: external-dns
74 | ---
75 | apiVersion: v1
76 | kind: ServiceAccount
77 | metadata:
78 | name: external-dns
79 | ---
80 | apiVersion: rbac.authorization.k8s.io/v1beta1
81 | kind: ClusterRole
82 | metadata:
83 | name: external-dns
84 | rules:
85 | - apiGroups:
86 | - ""
87 | resources:
88 | - "services"
89 | verbs:
90 | - "get"
91 | - "watch"
92 | - "list"
93 | - apiGroups:
94 | - ""
95 | resources:
96 | - "pods"
97 | verbs:
98 | - "get"
99 | - "watch"
100 | - "list"
101 | - apiGroups:
102 | - "extensions"
103 | resources:
104 | - "ingresses"
105 | verbs:
106 | - "get"
107 | - "watch"
108 | - "list"
109 | - apiGroups:
110 | - ""
111 | resources:
112 | - "nodes"
113 | verbs:
114 | - "list"
115 | - apiGroups:
116 | - ""
117 | resources:
118 | - "endpoints"
119 | verbs:
120 | - "get"
121 | - "watch"
122 | - "list"
123 | ---
124 | apiVersion: rbac.authorization.k8s.io/v1beta1
125 | kind: ClusterRoleBinding
126 | metadata:
127 | name: external-dns-viewer
128 | roleRef:
129 | apiGroup: rbac.authorization.k8s.io
130 | kind: ClusterRole
131 | name: external-dns
132 | subjects:
133 | - kind: ServiceAccount
134 | name: external-dns
135 |
--------------------------------------------------------------------------------
/test/test_ingresses.yaml:
--------------------------------------------------------------------------------
1 | # Copyright (c) 2020 SIGHUP s.r.l All rights reserved.
2 | # Use of this source code is governed by a BSD-style
3 | # license that can be found in the LICENSE file.
4 |
5 | apiVersion: v1
6 | kind: Namespace
7 | metadata:
8 | name: testns
9 | ---
10 | apiVersion: extensions/v1beta1
11 | kind: Ingress
12 | metadata:
13 | annotations:
14 | kubernetes.io/ingress.class: "nginx"
15 | forecastle.stakater.com/expose: "true"
16 | forecastle.stakater.com/appName: "Grafana"
17 | forecastle.stakater.com/icon: "https://github.com/stakater/ForecastleIcons/raw/master/grafana.png"
18 | namespace: testns
19 | name: grafana
20 | spec:
21 | rules:
22 | - host: grafana.testdomain.com
23 | http:
24 | paths:
25 | - path: /
26 | backend:
27 | serviceName: grafana
28 | servicePort: http
29 | tls:
30 | - hosts:
31 | - grafana.testdomain.com
32 | ---
33 | apiVersion: extensions/v1beta1
34 | kind: Ingress
35 | metadata:
36 | annotations:
37 | kubernetes.io/ingress.class: "nginx"
38 | forecastle.stakater.com/expose: "true"
39 | forecastle.stakater.com/appName: "Prometheus"
40 | forecastle.stakater.com/icon: "https://github.com/stakater/ForecastleIcons/raw/master/prometheus.png"
41 | namespace: testns
42 | name: prometheus
43 | spec:
44 | rules:
45 | - host: prometheus.testdomain.com
46 | http:
47 | paths:
48 | - path: /
49 | backend:
50 | serviceName: external-dns-ui
51 | servicePort: http
52 | tls:
53 | - hosts:
54 | - prometheus.testdomain.com
55 | ---
56 | apiVersion: extensions/v1beta1
57 | kind: Ingress
58 | metadata:
59 | annotations:
60 | kubernetes.io/ingress.class: "nginx"
61 | forecastle.stakater.com/expose: "true"
62 | forecastle.stakater.com/appName: "Alert Manager"
63 | forecastle.stakater.com/icon: "https://github.com/stakater/ForecastleIcons/raw/master/prometheus.png"
64 | namespace: testns
65 | name: alertmanager
66 | spec:
67 | rules:
68 | - host: alertmanager.testdomain.com
69 | http:
70 | paths:
71 | - path: /
72 | backend:
73 | serviceName: external-dns-ui
74 | servicePort: http
75 | tls:
76 | - hosts:
77 | - alertmanager.testdomain.com
78 | ---
79 | apiVersion: extensions/v1beta1
80 | kind: Ingress
81 | metadata:
82 | namespace: testns
83 | annotations:
84 | kubernetes.io/ingress.class: "nginx"
85 | forecastle.stakater.com/expose: "true"
86 | forecastle.stakater.com/appName: "Cerebro"
87 | forecastle.stakater.com/icon: "https://github.com/stakater/ForecastleIcons/raw/master/cerebro.png"
88 | name: cerebro
89 | spec:
90 | rules:
91 | - host: cerebro.testdomain.com
92 | http:
93 | paths:
94 | - path: /
95 | backend:
96 | serviceName: external-dns-ui
97 | servicePort: http
98 | tls:
99 | - hosts:
100 | - cerebro.testdomain.com
101 | ---
102 | apiVersion: extensions/v1beta1
103 | kind: Ingress
104 | metadata:
105 | namespace: testns
106 | annotations:
107 | kubernetes.io/ingress.class: "nginx"
108 | forecastle.stakater.com/expose: "true"
109 | forecastle.stakater.com/appName: "Kibana"
110 | forecastle.stakater.com/icon: "https://github.com/stakater/ForecastleIcons/raw/master/kibana.png"
111 | name: kibana
112 | spec:
113 | rules:
114 | - host: kibana.testdomain.com
115 | http:
116 | paths:
117 | - path: /
118 | backend:
119 | serviceName: kibana
120 | servicePort: http
121 | tls:
122 | - hosts:
123 | - kibana.testdomain.com
124 | ---
125 | apiVersion: extensions/v1beta1
126 | kind: Ingress
127 | metadata:
128 | namespace: testns
129 | annotations:
130 | kubernetes.io/ingress.class: "nginx"
131 | forecastle.stakater.com/expose: "true"
132 | forecastle.stakater.com/appName: "Kubernetes Dashboard"
133 | forecastle.stakater.com/icon: "https://github.com/stakater/ForecastleIcons/raw/master/kubernetes.png"
134 | nginx.ingress.kubernetes.io/ssl-passthrough: "true"
135 | nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
136 | name: kubernetes-dashboard
137 | spec:
138 | rules:
139 | - host: kubernetes.testdomain.com
140 | http:
141 | paths:
142 | - path: /
143 | backend:
144 | serviceName: kubernetes-dashboard
145 | servicePort: 8443
146 | tls:
147 | - hosts:
148 | - kubernetes.testdomain.com
149 | ---
150 | apiVersion: extensions/v1beta1
151 | kind: Ingress
152 | metadata:
153 | namespace: testns
154 | annotations:
155 | kubernetes.io/ingress.class: "nginx"
156 | name: forecastle
157 | spec:
158 | rules:
159 | - host: testdomain.com
160 | http:
161 | paths:
162 | - path: /
163 | backend:
164 | serviceName: external-dns-ui
165 | servicePort: http
166 | tls:
167 | - hosts:
168 | - testdomain.com
169 | ---
170 | apiVersion: extensions/v1beta1
171 | kind: Ingress
172 | metadata:
173 | namespace: testns
174 | annotations:
175 | kubernetes.io/ingress.class: "nginx"
176 | forecastle.stakater.com/expose: "true"
177 | forecastle.stakater.com/appName: "Gatekeeper Policy Manager"
178 | name: gatekeeper-policy-manager
179 | spec:
180 | rules:
181 | - host: gatekeeper.testdomain.com
182 | http:
183 | paths:
184 | - path: /
185 | backend:
186 | serviceName: gatekeeper-policy-manager
187 | servicePort: http
188 | tls:
189 | - hosts:
190 | - gatekeeper.testdomain.com
191 | ---
192 | apiVersion: extensions/v1beta1
193 | kind: Ingress
194 | metadata:
195 | namespace: testns
196 | annotations:
197 | kubernetes.io/ingress.class: "nginx"
198 | forecastle.stakater.com/expose: "true"
199 | forecastle.stakater.com/appName: "Gatekeeper Policy Manager"
200 | name: gatekeeper-policy-manager-wrong-domain
201 | spec:
202 | rules:
203 | - host: gatekeeper.testdomain.wrong.com
204 | http:
205 | paths:
206 | - path: /
207 | backend:
208 | serviceName: gatekeeper-policy-manager
209 | servicePort: http
210 | tls:
211 | - hosts:
212 | - gatekeeper.testdomain.wrong.com
213 | ---
214 | apiVersion: extensions/v1beta1
215 | kind: Ingress
216 | metadata:
217 | namespace: testns
218 | annotations:
219 | kubernetes.io/ingress.class: "nginx"
220 | forecastle.stakater.com/expose: "true"
221 | forecastle.stakater.com/appName: "Gatekeeper Policy Manager"
222 | name: gatekeeper-policy-manager1
223 | spec:
224 | rules:
225 | - host: gatekeeper1.testdomain.com
226 | http:
227 | paths:
228 | - path: /
229 | backend:
230 | serviceName: gatekeeper-policy-manager
231 | servicePort: http
232 | tls:
233 | - hosts:
234 | - gatekeeper1.testdomain.com
235 | ---
236 | apiVersion: extensions/v1beta1
237 | kind: Ingress
238 | metadata:
239 | namespace: testns
240 | annotations:
241 | kubernetes.io/ingress.class: "nginx"
242 | forecastle.stakater.com/expose: "true"
243 | forecastle.stakater.com/appName: "Gatekeeper Policy Manager"
244 | name: gatekeeper-policy-manager2
245 | spec:
246 | rules:
247 | - host: gatekeeper2.testdomain.com
248 | http:
249 | paths:
250 | - path: /
251 | backend:
252 | serviceName: gatekeeper-policy-manager
253 | servicePort: http
254 | tls:
255 | - hosts:
256 | - gatekeeper2.testdomain.com
257 | ---
258 | apiVersion: extensions/v1beta1
259 | kind: Ingress
260 | metadata:
261 | namespace: testns
262 | annotations:
263 | kubernetes.io/ingress.class: "nginx"
264 | forecastle.stakater.com/expose: "true"
265 | forecastle.stakater.com/appName: "Gatekeeper Policy Manager"
266 | name: gatekeeper-policy-manager3
267 | spec:
268 | rules:
269 | - host: gatekeeper3.testdomain.com
270 | http:
271 | paths:
272 | - path: /
273 | backend:
274 | serviceName: gatekeeper-policy-manager
275 | servicePort: http
276 | tls:
277 | - hosts:
278 | - gatekeeper3.testdomain.com
279 |
--------------------------------------------------------------------------------