Skip to content

Commit

Permalink
Initial Commit
Browse files Browse the repository at this point in the history
  • Loading branch information
nzbr committed Sep 7, 2022
0 parents commit 19a66ec
Show file tree
Hide file tree
Showing 19 changed files with 1,398 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/bin/
/node_modules/

/pulumictl/
8 changes: 8 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions .idea/infrastructure.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 13 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"singleQuote": true,
"trailingComma": "all",
"bracketSameLine": true,
"tabWidth": 4
}
5 changes: 5 additions & 0 deletions Pulumi.prod.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
config:
desec:api_token:
secure: AAABAAqQPqxX+9MIeFWrfpzKFGkeKEeS9njkTy8rEN9tcGgVejbCTtaS2OH0YA9RQx38DmIqISNG5MIv
digitalocean:token:
secure: AAABACjg0nhPk9pV8s2L7TmlKewdNsNKlzWhQCajhvuB8czHwt16PPDdkPQtK2YUBw+VzrIDT5VlkOfgw2m2ukJtLMQxS7YtVQqyZIblZlTGth4Iwi0bO8Qvl5sfXHqYazmWPXgUvA==
3 changes: 3 additions & 0 deletions Pulumi.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
name: infrastructure
runtime: nodejs
description: nzbr's infrastructure configuration
16 changes: 16 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"name": "infrastructure",
"main": "src/index.ts",
"devDependencies": {
"@types/node": "^14",
"prettier": "^2.7.1",
"typescript": "^4.8.2"
},
"dependencies": {
"@pulumi/desec": "file:pulumi-desec/sdk/nodejs/bin",
"@pulumi/digitalocean": "^4.15.2",
"@pulumi/kubernetes": "^3.0.0",
"@pulumi/kubernetesx": "^0.1.5",
"@pulumi/pulumi": "^3.0.0"
}
}
1 change: 1 addition & 0 deletions pulumi-desec
Submodule pulumi-desec added at e2ead2
93 changes: 93 additions & 0 deletions src/component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import {
Resource,
ComponentResource,
ComponentResourceOptions,
ResourceOptions,
} from '@pulumi/pulumi';

type Resources = { [key: string]: () => Resource };
export const resources: Resources = {};

type Components = { [key: string]: Component };
export const components: Components = {};

export type ResourceClass<
T extends Resource,
A extends object,
O extends ResourceOptions,
> = new (name: string, args: A, opts?: O | ResourceOptions) => T;

export class Component extends ComponentResource {
public type: string;
public name: string;
public parent: Component | null;

protected resources: Resources = {};

constructor(
parent: Component | null,
name: string,
opts?: ComponentResourceOptions,
) {
const _type = parent ? `${parent.type}:${name}` : `nzbr:${name}`;
const _name = parent ? `${parent.name}/${name}` : name;
super(
_type,
_name,
{},
{
...opts,
parent: parent ? parent : undefined,
},
);

this.type = _type;
this.name = _name;
this.parent = parent;

if (this.name in (parent ? parent.resources : resources)) {
throw new Error(`Component ${this.name} already exists`);
}

components[this.name] = this;
}

protected mk<
T extends Resource,
A extends object,
O extends ResourceOptions,
>(name: string, Type: ResourceClass<T, A, O>, args: () => A, opts?: O) {
if (name in this.resources) {
throw new Error(`Resource ${this.name}:${name} already exists`);
}

const fullName = `${this.name}/${name}`;

const resource = mkSingleton(
() =>
new Type(fullName, args(), {
...opts,
parent: this,
}),
);

this.resources[name] = resource;
resources[fullName] = resource;
}
}

export function evaluateResources(): void {
for (let name in resources) {
resources[name]();
}
}

function mkSingleton<T>(fn: () => T): () => T {
let value: T;
return () => {
if (!value) {
value = fn();
}
return value;
};
}
14 changes: 14 additions & 0 deletions src/desec/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Component } from '../component';
import * as desec from '@pulumi/desec';
import * as servers from './servers';
import { NzbrLinkComponent } from './nzbr-link';
import { NzbrDeComponent } from './nzbr-de';

export class DesecComponent extends Component {
constructor() {
super(null, 'desec');

new NzbrDeComponent(this);
new NzbrLinkComponent(this);
}
}
135 changes: 135 additions & 0 deletions src/desec/nzbr-de.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
import { Domain, RRSet } from '@pulumi/desec';
import { Component } from '../component';
import * as servers from './servers';

export class NzbrDeComponent extends Component {
constructor(parent: Component) {
const domain = 'nzbr.de';
super(parent, domain);

this.mk(domain, Domain, () => ({
name: domain,
}));

this.mk('@4', RRSet, () => ({
domain: (this.resources[domain]() as Domain).name,
subname: '',
type: 'A',
records: servers.ip4,
ttl: 3600,
}));

this.mk('@6', RRSet, () => ({
domain: (this.resources[domain]() as Domain).name,
subname: '',
type: 'AAAA',
records: servers.ip6,
ttl: 3600,
}));

for (let srv in servers.all) {
this.mk(`${srv}4`, RRSet, () => ({
domain: (this.resources[domain]() as Domain).name,
subname: srv,
type: 'A',
records: [servers.all[srv].ip4],
ttl: 3600,
}));

this.mk(`${srv}6`, RRSet, () => ({
domain: (this.resources[domain]() as Domain).name,
subname: srv,
type: 'AAAA',
records: [servers.all[srv].ip6],
ttl: 3600,
}));
}

const cnames: { [key: string]: string } = {
'*': domain,
pages: domain,
'*.pages': domain,
autoconfig: 'mailbox.org',
};
for (let subdomain in cnames) {
this.mk(subdomain, RRSet, () => ({
domain: (this.resources[domain]() as Domain).name,
subname: subdomain,
type: 'CNAME',
records: [`${cnames[subdomain]}.`],
ttl: 3600,
}));
}

this.mk('CAA', RRSet, () => ({
domain: (this.resources[domain]() as Domain).name,
subname: '',
type: 'CAA',
records: [
'0 iodef "mailto:[email protected]"',
'0 issue "letsencrypt.org"',
],
ttl: 3600,
}));

this.mk('MX', RRSet, () => ({
domain: (this.resources[domain]() as Domain).name,
subname: '',
type: 'MX',
records: [
'10 mxext1.mailbox.org.',
'10 mxext2.mailbox.org.',
'20 mxext3.mailbox.org.',
],
ttl: 3600,
}));

this.mk('_autodiscover._tcp', RRSet, () => ({
domain: (this.resources[domain]() as Domain).name,
subname: '_autodiscover._tcp',
type: 'SRV',
records: ['0 0 443 mailbox.org.'],
ttl: 3600,
}));

this.mk('_matrix._tcp', RRSet, () => ({
domain: (this.resources[domain]() as Domain).name,
subname: '_matrix._tcp',
type: 'SRV',
records: ['10 0 8448 nzbr.de.'],
ttl: 3600,
}));

this.mk('mbo0001._domainkey', RRSet, () => ({
domain: (this.resources[domain]() as Domain).name,
subname: 'mbo0001._domainkey',
type: 'TXT',
records: [
'v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA2K4PavXoNY8eGK2u61LIQlOHS8f5sWsCK5b+HMOfo0M+aNHwfqlVdzi/IwmYnuDKuXYuCllrgnxZ4fG4yVaux58v9grVsFHdzdjPlAQfp5rkiETYpCMZwgsmdseJ4CoZaosPHLjPumFE/Ua2WAQQljnunsM9TONM9L6KxrO9t5IISD1XtJb0bq1lVI/e72k3mnPd/q77qzhTDmwN4TSNJZN8sxzUJx9HNSMRRoEIHSDLTIJUK+Up8IeCx0B7CiOzG5w/cHyZ3AM5V8lkqBaTDK46AwTkTVGJf59QxUZArG3FEH5vy9HzDmy0tGG+053/x4RqkhqMg5/ClDm+lpZqWwIDAQAB',
],
ttl: 3600,
}));

this.mk('mbo0002._domainkey', RRSet, () => ({
domain: (this.resources[domain]() as Domain).name,
subname: 'mbo0002._domainkey',
type: 'TXT',
records: [
'v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqxEKIg2c48ecfmy/+rj35sBOhdfIYGNDCMeHy0b36DX6MNtS7zA/VDR2q5ubtHzraL5uUGas8kb/33wtrWFYxierLRXy12qj8ItdYCRugu9tXTByEED05WdBtRzJmrb8YBMfeK0E0K3wwoWfhIk/wzKbjMkbqYBOTYLlIcVGQWzOfN7/n3n+VChfu6sGFK3k2qrJNnw22iFy4C8Ks7j77+tCpm0PoUwA2hOdLrRw3ldx2E9PH0GVwIMJRgekY6cS7DrbHrj/AeGlwfwwCSi9T23mYvc79nVrh2+82ZqmkpZSTD2qq+ukOkyjdRuUPck6e2b+x141Nzd81dIZVfOEiwIDAQAB',
],
ttl: 3600,
}));

this.mk('TXT', RRSet, () => ({
domain: (this.resources[domain]() as Domain).name,
subname: '',
type: 'TXT',
records: [
'v=spf1 include:mailbox.org',
'keybase-site-verification=IHbqhzQ-aIeUKJe62gOi-TWUd03XI9gGbe5wDLSRYsQ',
'google-site-verification=by8RxWHKo7pjLplm89eHT5u4QkVW23MibKc9wXpOODA',
],
ttl: 3600,
}));
}
}
Loading

0 comments on commit 19a66ec

Please sign in to comment.