@homeflare/distilled-opnsense 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/README.md +95 -0
- package/dist/credentials.d.ts +39 -0
- package/dist/credentials.d.ts.map +1 -0
- package/dist/credentials.js +78 -0
- package/dist/credentials.js.map +1 -0
- package/dist/errors.d.ts +110 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +63 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +29 -0
- package/dist/index.js.map +1 -0
- package/dist/protocol.d.ts +13 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +115 -0
- package/dist/protocol.js.map +1 -0
- package/dist/retry.d.ts +56 -0
- package/dist/retry.d.ts.map +1 -0
- package/dist/retry.js +49 -0
- package/dist/retry.js.map +1 -0
- package/dist/services/firewall_alias.d.ts +243 -0
- package/dist/services/firewall_alias.d.ts.map +1 -0
- package/dist/services/firewall_alias.js +222 -0
- package/dist/services/firewall_alias.js.map +1 -0
- package/dist/services/firewall_category.d.ts +122 -0
- package/dist/services/firewall_category.d.ts.map +1 -0
- package/dist/services/firewall_category.js +161 -0
- package/dist/services/firewall_category.js.map +1 -0
- package/dist/services/firewall_filter.d.ts +289 -0
- package/dist/services/firewall_filter.d.ts.map +1 -0
- package/dist/services/firewall_filter.js +225 -0
- package/dist/services/firewall_filter.js.map +1 -0
- package/dist/services/firewall_group.d.ts +122 -0
- package/dist/services/firewall_group.d.ts.map +1 -0
- package/dist/services/firewall_group.js +154 -0
- package/dist/services/firewall_group.js.map +1 -0
- package/dist/services/index.d.ts +9 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +10 -0
- package/dist/services/index.js.map +1 -0
- package/dist/services/quagga_bgp.d.ts +1135 -0
- package/dist/services/quagga_bgp.d.ts.map +1 -0
- package/dist/services/quagga_bgp.js +1263 -0
- package/dist/services/quagga_bgp.js.map +1 -0
- package/dist/services/quagga_general.d.ts +55 -0
- package/dist/services/quagga_general.d.ts.map +1 -0
- package/dist/services/quagga_general.js +48 -0
- package/dist/services/quagga_general.js.map +1 -0
- package/dist/services/quagga_service.d.ts +60 -0
- package/dist/services/quagga_service.d.ts.map +1 -0
- package/dist/services/quagga_service.js +77 -0
- package/dist/services/quagga_service.js.map +1 -0
- package/dist/services/routing_settings.d.ts +192 -0
- package/dist/services/routing_settings.d.ts.map +1 -0
- package/dist/services/routing_settings.js +169 -0
- package/dist/services/routing_settings.js.map +1 -0
- package/dist/traits.d.ts +11 -0
- package/dist/traits.d.ts.map +1 -0
- package/dist/traits.js +11 -0
- package/dist/traits.js.map +1 -0
- package/package.json +75 -0
- package/src/credentials.ts +111 -0
- package/src/errors.ts +115 -0
- package/src/index.ts +32 -0
- package/src/protocol.ts +177 -0
- package/src/retry.ts +80 -0
- package/src/services/firewall_alias.ts +572 -0
- package/src/services/firewall_category.ts +359 -0
- package/src/services/firewall_filter.ts +671 -0
- package/src/services/firewall_group.ts +350 -0
- package/src/services/index.ts +9 -0
- package/src/services/quagga_bgp.ts +2955 -0
- package/src/services/quagga_general.ts +132 -0
- package/src/services/quagga_service.ts +182 -0
- package/src/services/routing_settings.ts +419 -0
- package/src/traits.ts +36 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
// AUTO-GENERATED by scripts/generate.ts from .generated-specs (specs/spec-mirror-opnsense). Do not edit.
|
|
2
|
+
import * as S from "@distilled.cloud/core/schema";
|
|
3
|
+
import * as API from "@distilled.cloud/core/api";
|
|
4
|
+
import * as T from "../traits.js";
|
|
5
|
+
import { OpnsenseProtocol, } from "../protocol.js";
|
|
6
|
+
import * as Retry from "../retry.js";
|
|
7
|
+
export const GatewayItemIpprotocol = S.String;
|
|
8
|
+
export const GatewayItem = /*@__PURE__*/ S.suspend(() => S.Struct({
|
|
9
|
+
uuid: S.optional(S.String),
|
|
10
|
+
disabled: S.String,
|
|
11
|
+
name: S.String,
|
|
12
|
+
descr: S.optional(S.String),
|
|
13
|
+
interface: S.String,
|
|
14
|
+
ipprotocol: GatewayItemIpprotocol,
|
|
15
|
+
gateway: S.optional(S.String),
|
|
16
|
+
defaultgw: S.optional(S.String),
|
|
17
|
+
fargw: S.optional(S.String),
|
|
18
|
+
monitor_disable: S.String,
|
|
19
|
+
monitor_noroute: S.optional(S.String),
|
|
20
|
+
monitor_killstates: S.optional(S.String),
|
|
21
|
+
monitor_killstates_priority: S.optional(S.String),
|
|
22
|
+
monitor: S.optional(S.String),
|
|
23
|
+
force_down: S.optional(S.String),
|
|
24
|
+
nosync: S.optional(S.String),
|
|
25
|
+
priority: S.String,
|
|
26
|
+
weight: S.String,
|
|
27
|
+
latencylow: S.optional(S.String),
|
|
28
|
+
latencyhigh: S.optional(S.String),
|
|
29
|
+
losslow: S.optional(S.String),
|
|
30
|
+
losshigh: S.optional(S.String),
|
|
31
|
+
interval: S.optional(S.String),
|
|
32
|
+
time_period: S.optional(S.String),
|
|
33
|
+
loss_interval: S.optional(S.String),
|
|
34
|
+
data_length: S.optional(S.String),
|
|
35
|
+
})).annotate({ identifier: "GatewayItem" });
|
|
36
|
+
export const AddGatewayRequest = /*@__PURE__*/ S.suspend(() => S.Struct({
|
|
37
|
+
gateway_item: S.optional(GatewayItem),
|
|
38
|
+
}).pipe(T.Http({
|
|
39
|
+
method: "POST",
|
|
40
|
+
uri: "/api/routing/settings/addGateway",
|
|
41
|
+
code: 200,
|
|
42
|
+
}))).annotate({
|
|
43
|
+
identifier: "AddGatewayRequest",
|
|
44
|
+
});
|
|
45
|
+
export const AddGatewayResult = S.String;
|
|
46
|
+
export const AddGatewayResponse = /*@__PURE__*/ S.suspend(() => S.Struct({
|
|
47
|
+
result: S.optional(AddGatewayResult),
|
|
48
|
+
uuid: S.optional(S.String),
|
|
49
|
+
})).annotate({
|
|
50
|
+
identifier: "AddGatewayResponse",
|
|
51
|
+
});
|
|
52
|
+
export const DelGatewayRequest = /*@__PURE__*/ S.suspend(() => S.Struct({
|
|
53
|
+
uuid: S.String.pipe(T.Label()),
|
|
54
|
+
}).pipe(T.Http({
|
|
55
|
+
method: "POST",
|
|
56
|
+
uri: "/api/routing/settings/delGateway/{uuid}",
|
|
57
|
+
code: 200,
|
|
58
|
+
}))).annotate({
|
|
59
|
+
identifier: "DelGatewayRequest",
|
|
60
|
+
});
|
|
61
|
+
export const DelGatewayResult = S.String;
|
|
62
|
+
export const DelGatewayResponse = /*@__PURE__*/ S.suspend(() => S.Struct({
|
|
63
|
+
result: S.optional(DelGatewayResult),
|
|
64
|
+
})).annotate({
|
|
65
|
+
identifier: "DelGatewayResponse",
|
|
66
|
+
});
|
|
67
|
+
export const GetRequest = /*@__PURE__*/ S.suspend(() => S.Struct({}).pipe(T.Http({ method: "GET", uri: "/api/routing/settings/get", code: 200 }))).annotate({ identifier: "GetRequest" });
|
|
68
|
+
export const ModelGateway_itemItemIpprotocol = S.String;
|
|
69
|
+
export const ModelGateway_itemItem = /*@__PURE__*/ S.suspend(() => S.Struct({
|
|
70
|
+
uuid: S.optional(S.String),
|
|
71
|
+
disabled: S.String,
|
|
72
|
+
name: S.String,
|
|
73
|
+
descr: S.optional(S.String),
|
|
74
|
+
interface: S.String,
|
|
75
|
+
ipprotocol: ModelGateway_itemItemIpprotocol,
|
|
76
|
+
gateway: S.optional(S.String),
|
|
77
|
+
defaultgw: S.optional(S.String),
|
|
78
|
+
fargw: S.optional(S.String),
|
|
79
|
+
monitor_disable: S.String,
|
|
80
|
+
monitor_noroute: S.optional(S.String),
|
|
81
|
+
monitor_killstates: S.optional(S.String),
|
|
82
|
+
monitor_killstates_priority: S.optional(S.String),
|
|
83
|
+
monitor: S.optional(S.String),
|
|
84
|
+
force_down: S.optional(S.String),
|
|
85
|
+
nosync: S.optional(S.String),
|
|
86
|
+
priority: S.String,
|
|
87
|
+
weight: S.String,
|
|
88
|
+
latencylow: S.optional(S.String),
|
|
89
|
+
latencyhigh: S.optional(S.String),
|
|
90
|
+
losslow: S.optional(S.String),
|
|
91
|
+
losshigh: S.optional(S.String),
|
|
92
|
+
interval: S.optional(S.String),
|
|
93
|
+
time_period: S.optional(S.String),
|
|
94
|
+
loss_interval: S.optional(S.String),
|
|
95
|
+
data_length: S.optional(S.String),
|
|
96
|
+
})).annotate({
|
|
97
|
+
identifier: "ModelGateway_itemItem",
|
|
98
|
+
});
|
|
99
|
+
export const ModelGateway_itemItemMap = /*@__PURE__*/ S.Record(S.String, ModelGateway_itemItem);
|
|
100
|
+
export const Model = /*@__PURE__*/ S.suspend(() => S.Struct({
|
|
101
|
+
gateway_item: S.optional(ModelGateway_itemItemMap),
|
|
102
|
+
})).annotate({ identifier: "Model" });
|
|
103
|
+
export const GetResponse = /*@__PURE__*/ S.suspend(() => S.Struct({
|
|
104
|
+
gateways: S.optional(Model),
|
|
105
|
+
})).annotate({ identifier: "GetResponse" });
|
|
106
|
+
export const SetRequest = /*@__PURE__*/ S.suspend(() => S.Struct({
|
|
107
|
+
gateways: S.optional(Model),
|
|
108
|
+
}).pipe(T.Http({ method: "POST", uri: "/api/routing/settings/set", code: 200 }))).annotate({ identifier: "SetRequest" });
|
|
109
|
+
export const SetResult = S.String;
|
|
110
|
+
export const SetResponse = /*@__PURE__*/ S.suspend(() => S.Struct({
|
|
111
|
+
result: S.optional(SetResult),
|
|
112
|
+
})).annotate({ identifier: "SetResponse" });
|
|
113
|
+
export const SetGatewayRequest = /*@__PURE__*/ S.suspend(() => S.Struct({
|
|
114
|
+
uuid: S.String.pipe(T.Label()),
|
|
115
|
+
gateway_item: S.optional(GatewayItem),
|
|
116
|
+
}).pipe(T.Http({
|
|
117
|
+
method: "POST",
|
|
118
|
+
uri: "/api/routing/settings/setGateway/{uuid}",
|
|
119
|
+
code: 200,
|
|
120
|
+
}))).annotate({
|
|
121
|
+
identifier: "SetGatewayRequest",
|
|
122
|
+
});
|
|
123
|
+
export const SetGatewayResult = S.String;
|
|
124
|
+
export const SetGatewayResponse = /*@__PURE__*/ S.suspend(() => S.Struct({
|
|
125
|
+
result: S.optional(SetGatewayResult),
|
|
126
|
+
})).annotate({
|
|
127
|
+
identifier: "SetGatewayResponse",
|
|
128
|
+
});
|
|
129
|
+
/** Add a new gateway_item item. On a validation failure the call fails with ValidationFailed instead of decoding this response. */
|
|
130
|
+
export const addGateway = /*@__PURE__*/ API.make(() => ({
|
|
131
|
+
input: AddGatewayRequest,
|
|
132
|
+
output: AddGatewayResponse,
|
|
133
|
+
errors: [],
|
|
134
|
+
protocol: OpnsenseProtocol,
|
|
135
|
+
retry: Retry.Retry,
|
|
136
|
+
}));
|
|
137
|
+
/** Delete a gateway_item item by uuid. */
|
|
138
|
+
export const delGateway = /*@__PURE__*/ API.make(() => ({
|
|
139
|
+
input: DelGatewayRequest,
|
|
140
|
+
output: DelGatewayResponse,
|
|
141
|
+
errors: [],
|
|
142
|
+
protocol: OpnsenseProtocol,
|
|
143
|
+
retry: Retry.Retry,
|
|
144
|
+
}));
|
|
145
|
+
/** Fetch the entire model tree (every section and array collection). */
|
|
146
|
+
export const get = /*@__PURE__*/ API.make(() => ({
|
|
147
|
+
input: GetRequest,
|
|
148
|
+
output: GetResponse,
|
|
149
|
+
errors: [],
|
|
150
|
+
protocol: OpnsenseProtocol,
|
|
151
|
+
retry: Retry.Retry,
|
|
152
|
+
}));
|
|
153
|
+
/** Replace the entire model tree in one call. On a validation failure the call fails with ValidationFailed instead of decoding this response. */
|
|
154
|
+
export const set = /*@__PURE__*/ API.make(() => ({
|
|
155
|
+
input: SetRequest,
|
|
156
|
+
output: SetResponse,
|
|
157
|
+
errors: [],
|
|
158
|
+
protocol: OpnsenseProtocol,
|
|
159
|
+
retry: Retry.Retry,
|
|
160
|
+
}));
|
|
161
|
+
/** Update an existing gateway_item item. On a validation failure the call fails with ValidationFailed instead of decoding this response. */
|
|
162
|
+
export const setGateway = /*@__PURE__*/ API.make(() => ({
|
|
163
|
+
input: SetGatewayRequest,
|
|
164
|
+
output: SetGatewayResponse,
|
|
165
|
+
errors: [],
|
|
166
|
+
protocol: OpnsenseProtocol,
|
|
167
|
+
retry: Retry.Retry,
|
|
168
|
+
}));
|
|
169
|
+
//# sourceMappingURL=routing_settings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routing_settings.js","sourceRoot":"","sources":["../../src/services/routing_settings.ts"],"names":[],"mappings":"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"}
|
package/dist/traits.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OPNsense SDK trait surface — hand-written.
|
|
3
|
+
*
|
|
4
|
+
* Re-exports the generic protocol traits from core so generated operations
|
|
5
|
+
* import everything from one place. OPNsense's request/response shapes need
|
|
6
|
+
* nothing beyond the generic label/query/header/body bindings `protocol.ts`
|
|
7
|
+
* already builds on — no sensitive-value wrapping, no bare-array responses,
|
|
8
|
+
* no provider-specific traits.
|
|
9
|
+
*/
|
|
10
|
+
export { Body, Header, Query, Label, Http, ResponseCode, HttpBody, FormDataFile, KeyDictionary, UnionCases, applyErrorMatchers, getErrorMatchers, type HttpTrait, type ErrorMatcher, bodySymbol, headerSymbol, querySymbol, labelSymbol, httpSymbol, responseCodeSymbol, httpBodySymbol, formDataFileSymbol, keyDictionarySymbol, unionCasesSymbol, errorMatchersSymbol, } from "@distilled.cloud/core/trait";
|
|
11
|
+
//# sourceMappingURL=traits.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"traits.d.ts","sourceRoot":"","sources":["../src/traits.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EACL,IAAI,EACJ,MAAM,EACN,KAAK,EACL,KAAK,EACL,IAAI,EACJ,YAAY,EACZ,QAAQ,EACR,YAAY,EACZ,aAAa,EACb,UAAU,EACV,kBAAkB,EAClB,gBAAgB,EAChB,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,UAAU,EACV,YAAY,EACZ,WAAW,EACX,WAAW,EACX,UAAU,EACV,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,6BAA6B,CAAC"}
|
package/dist/traits.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OPNsense SDK trait surface — hand-written.
|
|
3
|
+
*
|
|
4
|
+
* Re-exports the generic protocol traits from core so generated operations
|
|
5
|
+
* import everything from one place. OPNsense's request/response shapes need
|
|
6
|
+
* nothing beyond the generic label/query/header/body bindings `protocol.ts`
|
|
7
|
+
* already builds on — no sensitive-value wrapping, no bare-array responses,
|
|
8
|
+
* no provider-specific traits.
|
|
9
|
+
*/
|
|
10
|
+
export { Body, Header, Query, Label, Http, ResponseCode, HttpBody, FormDataFile, KeyDictionary, UnionCases, applyErrorMatchers, getErrorMatchers, bodySymbol, headerSymbol, querySymbol, labelSymbol, httpSymbol, responseCodeSymbol, httpBodySymbol, formDataFileSymbol, keyDictionarySymbol, unionCasesSymbol, errorMatchersSymbol, } from "@distilled.cloud/core/trait";
|
|
11
|
+
//# sourceMappingURL=traits.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"traits.js","sourceRoot":"","sources":["../src/traits.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EACL,IAAI,EACJ,MAAM,EACN,KAAK,EACL,KAAK,EACL,IAAI,EACJ,YAAY,EACZ,QAAQ,EACR,YAAY,EACZ,aAAa,EACb,UAAU,EACV,kBAAkB,EAClB,gBAAgB,EAGhB,UAAU,EACV,YAAY,EACZ,WAAW,EACX,WAAW,EACX,UAAU,EACV,kBAAkB,EAClB,cAAc,EACd,kBAAkB,EAClB,mBAAmB,EACnB,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,6BAA6B,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@homeflare/distilled-opnsense",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Interim npm home for @distilled.cloud/opnsense — see docs/distilled-interim.md. Not published upstream yet; the kit aliases @distilled.cloud/opnsense onto this package until it is.",
|
|
5
|
+
"homepage": "https://github.com/taslabs-net/homeflare-kit/tree/main/packages/distilled-opnsense#readme",
|
|
6
|
+
"bugs": "https://github.com/taslabs-net/homeflare-kit/issues",
|
|
7
|
+
"license": "Apache-2.0",
|
|
8
|
+
"author": "Timothy Schneider",
|
|
9
|
+
"repository": {
|
|
10
|
+
"type": "git",
|
|
11
|
+
"url": "git+https://github.com/taslabs-net/homeflare-kit.git",
|
|
12
|
+
"directory": "packages/distilled-opnsense"
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"src",
|
|
17
|
+
"README.md",
|
|
18
|
+
"LICENSE"
|
|
19
|
+
],
|
|
20
|
+
"type": "module",
|
|
21
|
+
"sideEffects": false,
|
|
22
|
+
"exports": {
|
|
23
|
+
".": {
|
|
24
|
+
"types": "./dist/index.d.ts",
|
|
25
|
+
"bun": "./src/index.ts",
|
|
26
|
+
"worker": "./src/index.ts",
|
|
27
|
+
"default": "./dist/index.js"
|
|
28
|
+
},
|
|
29
|
+
"./Credentials": {
|
|
30
|
+
"types": "./dist/credentials.d.ts",
|
|
31
|
+
"bun": "./src/credentials.ts",
|
|
32
|
+
"worker": "./src/credentials.ts",
|
|
33
|
+
"default": "./dist/credentials.js"
|
|
34
|
+
},
|
|
35
|
+
"./Errors": {
|
|
36
|
+
"types": "./dist/errors.d.ts",
|
|
37
|
+
"bun": "./src/errors.ts",
|
|
38
|
+
"worker": "./src/errors.ts",
|
|
39
|
+
"default": "./dist/errors.js"
|
|
40
|
+
},
|
|
41
|
+
"./Traits": {
|
|
42
|
+
"types": "./dist/traits.d.ts",
|
|
43
|
+
"bun": "./src/traits.ts",
|
|
44
|
+
"worker": "./src/traits.ts",
|
|
45
|
+
"default": "./dist/traits.js"
|
|
46
|
+
},
|
|
47
|
+
"./Protocol": {
|
|
48
|
+
"types": "./dist/protocol.d.ts",
|
|
49
|
+
"bun": "./src/protocol.ts",
|
|
50
|
+
"worker": "./src/protocol.ts",
|
|
51
|
+
"default": "./dist/protocol.js"
|
|
52
|
+
},
|
|
53
|
+
"./Retry": {
|
|
54
|
+
"types": "./dist/retry.d.ts",
|
|
55
|
+
"bun": "./src/retry.ts",
|
|
56
|
+
"worker": "./src/retry.ts",
|
|
57
|
+
"default": "./dist/retry.js"
|
|
58
|
+
},
|
|
59
|
+
"./*": {
|
|
60
|
+
"types": "./dist/services/*.d.ts",
|
|
61
|
+
"bun": "./src/services/*.ts",
|
|
62
|
+
"worker": "./src/services/*.ts",
|
|
63
|
+
"default": "./dist/services/*.js"
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
"publishConfig": {
|
|
67
|
+
"access": "public"
|
|
68
|
+
},
|
|
69
|
+
"dependencies": {
|
|
70
|
+
"@distilled.cloud/core": "1.0.0-rc.12"
|
|
71
|
+
},
|
|
72
|
+
"peerDependencies": {
|
|
73
|
+
"effect": "4.0.0-rc.115"
|
|
74
|
+
}
|
|
75
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OPNsense credentials — hand-written.
|
|
3
|
+
*
|
|
4
|
+
* OPNsense authenticates its `/api/*` surface with a key/secret pair sent
|
|
5
|
+
* as HTTP Basic auth: `Authorization: Basic base64(key:secret)` — verified
|
|
6
|
+
* both in source (`ApiControllerBase::beforeExecuteRoute`, mirrored at
|
|
7
|
+
* `specs/core/models/Base/ApiControllerBase.php`: it splits the decoded
|
|
8
|
+
* Basic-auth payload on `:` into `apiKey`/`apiSecret`, and works with ANY
|
|
9
|
+
* scheme word before the base64 blob, not just literally `Basic`) and in
|
|
10
|
+
* the vendor's own docs (`opnsense/docs`, `source/development/how-tos/
|
|
11
|
+
* api.rst`: a `curl -u <api-key>:<api-secret>` example against `.../api/...`,
|
|
12
|
+
* and the Python sample's `requests.get(..., auth=(api_key, api_secret))` — `requests`'
|
|
13
|
+
* `auth=` tuple IS HTTP Basic). The secret is generated once per key in the
|
|
14
|
+
* user manager and cannot be re-downloaded, so it is credential-shaped, not
|
|
15
|
+
* password-shaped — `Redacted` like a token, never compared or logged.
|
|
16
|
+
*
|
|
17
|
+
* Self-hosted, like Forgejo: there is no default host, so the edge/router's
|
|
18
|
+
* origin is part of the credential, not a hardcoded base URL.
|
|
19
|
+
*/
|
|
20
|
+
import * as EffectConfig from "effect/Config";
|
|
21
|
+
import * as Context from "effect/Context";
|
|
22
|
+
import * as Effect from "effect/Effect";
|
|
23
|
+
import * as Layer from "effect/Layer";
|
|
24
|
+
import * as Redacted from "effect/Redacted";
|
|
25
|
+
import { ConfigError } from "@distilled.cloud/core/errors";
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* OPNsense's own path prefix; every generated route's `T.Http({ uri })`
|
|
29
|
+
* already carries it (e.g. `/api/quagga/general/get` — see any
|
|
30
|
+
* `src/services/*.ts`), because it is the vendor's own real wire path, not
|
|
31
|
+
* an artifact of this converter. `buildRequest` in
|
|
32
|
+
* `@distilled.cloud/core/protocol-http` concatenates `baseUrl + uri`
|
|
33
|
+
* verbatim with no de-duplication, so `apiBaseUrl` MUST be the bare origin
|
|
34
|
+
* — appending `API_PATH` here as well produced a real, smoke-test-caught
|
|
35
|
+
* `/api/api/...` request (see `../scripts/smoke.ts` and
|
|
36
|
+
* `../README.md`'s "Known limitations"). `normalizeBaseUrl` therefore
|
|
37
|
+
* STRIPS a trailing `/api` a caller may have included (the doc comment on
|
|
38
|
+
* `Config.apiBaseUrl` below used to invite exactly that input), rather than
|
|
39
|
+
* adding one.
|
|
40
|
+
*/
|
|
41
|
+
export const API_PATH = "/api";
|
|
42
|
+
|
|
43
|
+
/** Normalize an OPNsense origin (or an already-complete `/api` root, accepted for caller convenience) down to the bare origin every generated route's own `uri` already assumes. */
|
|
44
|
+
export const normalizeBaseUrl = (baseUrl: string): string => {
|
|
45
|
+
// A loop, not a trailing-slash regex: that backtracks polynomially on a long
|
|
46
|
+
// run of "/" (CodeQL js/polynomial-redos), the same fix as distilled-netbox's.
|
|
47
|
+
let end = baseUrl.length;
|
|
48
|
+
while (end > 0 && baseUrl.charCodeAt(end - 1) === 47) end--;
|
|
49
|
+
const trimmed = baseUrl.slice(0, end);
|
|
50
|
+
return trimmed.endsWith(API_PATH)
|
|
51
|
+
? trimmed.slice(0, -API_PATH.length)
|
|
52
|
+
: trimmed;
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
export interface Config {
|
|
56
|
+
readonly apiKey: string;
|
|
57
|
+
readonly apiSecret: Redacted.Redacted<string>;
|
|
58
|
+
/** Bare origin, e.g. `https://edge.homeflare.dev` or `https://10.20.10.1` — a trailing `/api` is accepted and stripped, never doubled with a route's own `/api/...` prefix. */
|
|
59
|
+
readonly apiBaseUrl: string;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export class Credentials extends Context.Service<
|
|
63
|
+
Credentials,
|
|
64
|
+
Effect.Effect<Config>
|
|
65
|
+
>()("OpnsenseCredentials") {}
|
|
66
|
+
|
|
67
|
+
const envConfig = EffectConfig.all({
|
|
68
|
+
// No vendor-standard env var names exist for OPNsense's API (unlike
|
|
69
|
+
// Forgejo's own `FORGEJO_URL`/`FORGEJO_TOKEN`) — these follow this SDK's
|
|
70
|
+
// own naming.
|
|
71
|
+
apiKey: EffectConfig.String("OPNSENSE_API_KEY"),
|
|
72
|
+
apiSecret: EffectConfig.String("OPNSENSE_API_SECRET"),
|
|
73
|
+
baseUrl: EffectConfig.String("OPNSENSE_URL"),
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
export const CredentialsFromEnv = Layer.succeed(
|
|
77
|
+
Credentials,
|
|
78
|
+
envConfig.pipe(
|
|
79
|
+
Effect.mapError(
|
|
80
|
+
() =>
|
|
81
|
+
new ConfigError({
|
|
82
|
+
message:
|
|
83
|
+
"OPNSENSE_URL, OPNSENSE_API_KEY and OPNSENSE_API_SECRET environment variables are required",
|
|
84
|
+
}),
|
|
85
|
+
),
|
|
86
|
+
Effect.map(({ apiKey, apiSecret, baseUrl }) => ({
|
|
87
|
+
apiKey,
|
|
88
|
+
apiSecret: Redacted.make(apiSecret),
|
|
89
|
+
apiBaseUrl: normalizeBaseUrl(baseUrl),
|
|
90
|
+
})),
|
|
91
|
+
Effect.orDie,
|
|
92
|
+
),
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
/** Convenience layer from a plain key/secret and the box's origin (or API root). */
|
|
96
|
+
export const credentials = (config: {
|
|
97
|
+
readonly apiKey: string;
|
|
98
|
+
readonly apiSecret: string | Redacted.Redacted<string>;
|
|
99
|
+
readonly baseUrl: string;
|
|
100
|
+
}): Layer.Layer<Credentials> =>
|
|
101
|
+
Layer.succeed(
|
|
102
|
+
Credentials,
|
|
103
|
+
Effect.succeed({
|
|
104
|
+
apiKey: config.apiKey,
|
|
105
|
+
apiSecret:
|
|
106
|
+
typeof config.apiSecret === "string"
|
|
107
|
+
? Redacted.make(config.apiSecret)
|
|
108
|
+
: config.apiSecret,
|
|
109
|
+
apiBaseUrl: normalizeBaseUrl(config.baseUrl),
|
|
110
|
+
}),
|
|
111
|
+
);
|
package/src/errors.ts
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OPNsense-specific error types — hand-written.
|
|
3
|
+
*
|
|
4
|
+
* OPNsense is a 200-with-failure vendor (see `protocol.ts`'s module doc):
|
|
5
|
+
* most of what a caller needs to `catchTag` on never reaches an HTTP error
|
|
6
|
+
* status at all. This module's classes are read directly off
|
|
7
|
+
* `src/opnsense/www/api.php` (the `/api/*` front controller — mirrored at
|
|
8
|
+
* `specs/core/models/Base/` is the controller CONTRACT those bodies come
|
|
9
|
+
* from; `api.php` itself is not mirrored, since it is not model/controller
|
|
10
|
+
* source the converter reads, but its four `catch` clauses are exactly the
|
|
11
|
+
* four non-2xx/vendor-exception shapes below):
|
|
12
|
+
*
|
|
13
|
+
* catch UserException → getHttpCode() (500 unless a subclass
|
|
14
|
+
* overrides it) + {errorMessage,
|
|
15
|
+
* errorTitle, errorLevel} — a real
|
|
16
|
+
* business-rule denial (Alias/Category/
|
|
17
|
+
* Group's "in use" checks, Filter's
|
|
18
|
+
* "cannot move" checks), NOT a server
|
|
19
|
+
* fault: never retried.
|
|
20
|
+
* catch DispatchException → 404 {errorMessage} (route/controller/
|
|
21
|
+
* action not found — e.g. a plugin
|
|
22
|
+
* module that isn't installed).
|
|
23
|
+
* catch Error|Exception → 500 {errorMessage: "Unexpected error,
|
|
24
|
+
* check log for details"} (a PHP fault).
|
|
25
|
+
* (not sent) → the ORIGINAL response, when none of
|
|
26
|
+
* the above threw — this is everything
|
|
27
|
+
* else: the 401/403/400 auth/CSRF/JSON
|
|
28
|
+
* shapes from `ApiControllerBase::before
|
|
29
|
+
* ExecuteRoute` ({status:<code>,
|
|
30
|
+
* message}, `status` a NUMBER — do not
|
|
31
|
+
* confuse with the unrelated string
|
|
32
|
+
* `status` OPNsense's OWN operations
|
|
33
|
+
* return, e.g. service status/
|
|
34
|
+
* reconfigure) and the 200
|
|
35
|
+
* `{result:"failed", validations?}`
|
|
36
|
+
* shape every `ApiMutableModelController
|
|
37
|
+
* Base` mutation can answer with.
|
|
38
|
+
*/
|
|
39
|
+
import * as Schema from "effect/Schema";
|
|
40
|
+
import * as Category from "@distilled.cloud/core/category";
|
|
41
|
+
import {
|
|
42
|
+
ConfigError,
|
|
43
|
+
Unauthorized,
|
|
44
|
+
Forbidden,
|
|
45
|
+
BadRequest,
|
|
46
|
+
NotFound,
|
|
47
|
+
InternalServerError,
|
|
48
|
+
} from "@distilled.cloud/core/errors";
|
|
49
|
+
export {
|
|
50
|
+
ConfigError,
|
|
51
|
+
Unauthorized,
|
|
52
|
+
Forbidden,
|
|
53
|
+
BadRequest,
|
|
54
|
+
NotFound,
|
|
55
|
+
InternalServerError,
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
/** `{"result":"failed", validations?: {...}}` from `ApiMutableModelControllerBase::validate()`/`setBase`/`addBase`/`delBase`/`toggleBase` — always HTTP 200. `validations` is absent for a non-field failure (bad uuid, wrong verb); present and keyed `<prefix>.<field>` → one message or several for a real field error. */
|
|
59
|
+
export class ValidationFailed extends Schema.TaggedError<ValidationFailed>()(
|
|
60
|
+
"ValidationFailed",
|
|
61
|
+
{
|
|
62
|
+
validations: Schema.Record(
|
|
63
|
+
Schema.String,
|
|
64
|
+
Schema.Union([Schema.String, Schema.Array(Schema.String)]),
|
|
65
|
+
),
|
|
66
|
+
},
|
|
67
|
+
).pipe(Category.withBadRequestError) {}
|
|
68
|
+
|
|
69
|
+
/** A plain `UserException` (`errorLevel: "error"`, default HTTP 500) — a business-rule denial such as "Alias in use" or "cannot move to the same spot", not a server fault: `Category.withBadRequestError`, never retried. */
|
|
70
|
+
export class OpnsenseUserError extends Schema.TaggedError<OpnsenseUserError>()(
|
|
71
|
+
"OpnsenseUserError",
|
|
72
|
+
{ title: Schema.optional(Schema.String), message: Schema.String },
|
|
73
|
+
).pipe(Category.withBadRequestError) {}
|
|
74
|
+
|
|
75
|
+
/** A `UserWarningException` — HTTP 200, but the request did NOT do what was asked (`UserWarningException::getHttpCode()` is hard-coded 200). */
|
|
76
|
+
export class OpnsenseUserWarning extends Schema.TaggedError<OpnsenseUserWarning>()(
|
|
77
|
+
"OpnsenseUserWarning",
|
|
78
|
+
{ title: Schema.optional(Schema.String), message: Schema.String },
|
|
79
|
+
).pipe(Category.withBadRequestError) {}
|
|
80
|
+
|
|
81
|
+
/** A `UserInformationalException` — HTTP 200, an informational abort (e.g. "nothing to do"). */
|
|
82
|
+
export class OpnsenseUserNotice extends Schema.TaggedError<OpnsenseUserNotice>()(
|
|
83
|
+
"OpnsenseUserNotice",
|
|
84
|
+
{ title: Schema.optional(Schema.String), message: Schema.String },
|
|
85
|
+
).pipe(Category.withBadRequestError) {}
|
|
86
|
+
|
|
87
|
+
/** Unmapped failure — a response this SDK's protocol layer could not classify into any of the above (non-JSON body, a shape none of the known cases match). Carries the raw body for later cataloging. */
|
|
88
|
+
export class UnknownOpnsenseError extends Schema.TaggedError<UnknownOpnsenseError>()(
|
|
89
|
+
"UnknownOpnsenseError",
|
|
90
|
+
{ status: Schema.Number, body: Schema.Unknown },
|
|
91
|
+
).pipe(Category.withServerError) {}
|
|
92
|
+
|
|
93
|
+
/** Schema parse error wrapper. */
|
|
94
|
+
export class OpnsenseParseError extends Schema.TaggedError<OpnsenseParseError>()(
|
|
95
|
+
"OpnsenseParseError",
|
|
96
|
+
{ body: Schema.Unknown, cause: Schema.Unknown },
|
|
97
|
+
).pipe(Category.withParseError) {}
|
|
98
|
+
|
|
99
|
+
export type ClientErrors =
|
|
100
|
+
| ValidationFailed
|
|
101
|
+
| OpnsenseUserError
|
|
102
|
+
| OpnsenseUserWarning
|
|
103
|
+
| OpnsenseUserNotice
|
|
104
|
+
| UnknownOpnsenseError
|
|
105
|
+
| OpnsenseParseError;
|
|
106
|
+
|
|
107
|
+
/** Default errors every generated OPNsense operation carries — see the module doc for where each one comes from. */
|
|
108
|
+
export type DefaultErrors =
|
|
109
|
+
| Unauthorized
|
|
110
|
+
| Forbidden
|
|
111
|
+
| BadRequest
|
|
112
|
+
| NotFound
|
|
113
|
+
| InternalServerError
|
|
114
|
+
| ConfigError
|
|
115
|
+
| ClientErrors;
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @distilled.cloud/opnsense — OPNsense firewall API SDK for Effect.
|
|
3
|
+
*
|
|
4
|
+
* `./services` is generated by `scripts/generate.ts` from the Smithy models
|
|
5
|
+
* in `.generated-specs` (written by `scripts/convert.ts` from OPNsense's own
|
|
6
|
+
* model XML + API controller PHP, mirrored under `specs/`). Everything else
|
|
7
|
+
* in this folder is hand-written.
|
|
8
|
+
*
|
|
9
|
+
* One module per API controller in scope — `firewall_alias`,
|
|
10
|
+
* `firewall_category`, `firewall_group`, `firewall_filter`,
|
|
11
|
+
* `routing_settings`, `quagga_general`, `quagga_bgp`, `quagga_service` — see
|
|
12
|
+
* the package README for what each one covers and what was left out.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```ts
|
|
16
|
+
* import * as Opnsense from "@distilled.cloud/opnsense";
|
|
17
|
+
*
|
|
18
|
+
* const alias = yield* Opnsense.Services.firewall_alias.addAlias({
|
|
19
|
+
* alias: { name: "homeflare_edge", type: "host", content: "10.20.10.1" },
|
|
20
|
+
* });
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export * from "./credentials.ts";
|
|
24
|
+
export * from "./errors.ts";
|
|
25
|
+
export * as T from "./traits.ts";
|
|
26
|
+
export {
|
|
27
|
+
OpnsenseProtocol,
|
|
28
|
+
type OpnsenseOpError,
|
|
29
|
+
type OpnsenseOpContext,
|
|
30
|
+
} from "./protocol.ts";
|
|
31
|
+
export * as Retry from "./retry.ts";
|
|
32
|
+
export * as Services from "./services/index.ts";
|