mirror of
https://github.com/siderolabs/talos.git
synced 2025-10-30 16:01:12 +01:00
feat: implement machine config documents for event and log streaming
Fixes #7228 Add some changes to make Talos accept partial machine configuration without main v1alpha1 config. With this change, it's possible to connect a machine already running with machine configuration (v1alpha1), the following patch will connect to a local SideroLink endpoint: ```yaml apiVersion: v1alpha1 kind: SideroLinkConfig apiUrl: grpc://172.20.0.1:4000/?jointoken=foo --- apiVersion: v1alpha1 kind: KmsgLogConfig name: apiSink url: tcp://[fdae:41e4:649b:9303::1]:4001/ --- apiVersion: v1alpha1 kind: EventSinkConfig endpoint: "[fdae:41e4:649b:9303::1]:8080" ``` Signed-off-by: Andrey Smirnov <andrey.smirnov@talos-systems.com>
This commit is contained in:
parent
e241be85ba
commit
6be5a13d5d
11
go.sum
11
go.sum
@ -235,7 +235,6 @@ github.com/Microsoft/hcsshim v0.9.9/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfy
|
|||||||
github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU=
|
github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU=
|
||||||
github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY=
|
github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY=
|
||||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||||
github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
|
|
||||||
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
|
||||||
github.com/ProtonMail/go-crypto v0.0.0-20230321155629-9a39f2531310/go.mod h1:8TI4H3IbrackdNgv+92dI+rhpCaLqM0IfpgCgenFvRE=
|
github.com/ProtonMail/go-crypto v0.0.0-20230321155629-9a39f2531310/go.mod h1:8TI4H3IbrackdNgv+92dI+rhpCaLqM0IfpgCgenFvRE=
|
||||||
github.com/ProtonMail/go-crypto v0.0.0-20230518184743-7afd39499903 h1:ZK3C5DtzV2nVAQTx5S5jQvMeDqWtD1By5mOoyY/xJek=
|
github.com/ProtonMail/go-crypto v0.0.0-20230518184743-7afd39499903 h1:ZK3C5DtzV2nVAQTx5S5jQvMeDqWtD1By5mOoyY/xJek=
|
||||||
@ -538,7 +537,6 @@ github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCv
|
|||||||
github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||||
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM=
|
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM=
|
||||||
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4=
|
github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4=
|
||||||
github.com/fanliao/go-promise v0.0.0-20141029170127-1890db352a72/go.mod h1:PjfxuH4FZdUyfMdtBio2lsRr1AKEaVPwelzuHuh8Lqc=
|
|
||||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||||
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
|
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
|
||||||
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
|
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
|
||||||
@ -577,7 +575,6 @@ github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vb
|
|||||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
||||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
||||||
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
|
||||||
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
|
|
||||||
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
||||||
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
||||||
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||||
@ -795,7 +792,6 @@ github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhE
|
|||||||
github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I=
|
github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I=
|
||||||
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||||
github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE=
|
github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1BE=
|
||||||
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
|
||||||
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
|
github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek=
|
||||||
github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||||
@ -810,7 +806,6 @@ github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUq
|
|||||||
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
|
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
|
||||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||||
github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714 h1:/jC7qQFrv8CrSJVmaolDVOxTfS9kc36uB6H40kdbQq8=
|
github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714 h1:/jC7qQFrv8CrSJVmaolDVOxTfS9kc36uB6H40kdbQq8=
|
||||||
github.com/hugelgupf/socketpair v0.0.0-20190730060125-05d35a94e714/go.mod h1:2Goc3h8EklBH5mspfHFxBnEoURQCGzQQH1ga9Myjvis=
|
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||||
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||||
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||||
@ -842,7 +837,6 @@ github.com/josharian/native v1.0.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2C
|
|||||||
github.com/josharian/native v1.0.1-0.20221213033349-c1e37c09b531/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
|
github.com/josharian/native v1.0.1-0.20221213033349-c1e37c09b531/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
|
||||||
github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA=
|
github.com/josharian/native v1.1.0 h1:uuaP0hAbW7Y4l0ZRQ6C9zfb7Mg1mbFKry/xzDAfmtLA=
|
||||||
github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
|
github.com/josharian/native v1.1.0/go.mod h1:7X/raswPFr05uY3HiLlYeyQntB6OO7E/d2Cu7qoaN2w=
|
||||||
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
|
|
||||||
github.com/jsimonetti/rtnetlink v1.3.3 h1:ycpm3z8XlAzmaacVRjdUT3x6MM1o3YBXsXc7DXSRNCE=
|
github.com/jsimonetti/rtnetlink v1.3.3 h1:ycpm3z8XlAzmaacVRjdUT3x6MM1o3YBXsXc7DXSRNCE=
|
||||||
github.com/jsimonetti/rtnetlink v1.3.3/go.mod h1:mW4xSP3wkiqWxHMlfG/gOufp3XnhAxu7EhfABmrWSh8=
|
github.com/jsimonetti/rtnetlink v1.3.3/go.mod h1:mW4xSP3wkiqWxHMlfG/gOufp3XnhAxu7EhfABmrWSh8=
|
||||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||||
@ -854,7 +848,6 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1
|
|||||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
||||||
github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
|
|
||||||
github.com/jxskiss/base62 v1.1.0 h1:A5zbF8v8WXx2xixnAKD2w+abC+sIzYJX+nxmhA6HWFw=
|
github.com/jxskiss/base62 v1.1.0 h1:A5zbF8v8WXx2xixnAKD2w+abC+sIzYJX+nxmhA6HWFw=
|
||||||
github.com/jxskiss/base62 v1.1.0/go.mod h1:HhWAlUXvxKThfOlZbcuFzsqwtF5TcqS9ru3y5GfjWAc=
|
github.com/jxskiss/base62 v1.1.0/go.mod h1:HhWAlUXvxKThfOlZbcuFzsqwtF5TcqS9ru3y5GfjWAc=
|
||||||
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
|
||||||
@ -933,7 +926,6 @@ github.com/mdlayher/netx v0.0.0-20230430222610-7e21880baee8/go.mod h1:qhZhwMDNWw
|
|||||||
github.com/mdlayher/packet v1.0.0/go.mod h1:eE7/ctqDhoiRhQ44ko5JZU2zxB88g+JH/6jmnjzPjOU=
|
github.com/mdlayher/packet v1.0.0/go.mod h1:eE7/ctqDhoiRhQ44ko5JZU2zxB88g+JH/6jmnjzPjOU=
|
||||||
github.com/mdlayher/packet v1.1.2 h1:3Up1NG6LZrsgDVn6X4L9Ge/iyRyxFEFD9o6Pr3Q1nQY=
|
github.com/mdlayher/packet v1.1.2 h1:3Up1NG6LZrsgDVn6X4L9Ge/iyRyxFEFD9o6Pr3Q1nQY=
|
||||||
github.com/mdlayher/packet v1.1.2/go.mod h1:GEu1+n9sG5VtiRE4SydOmX5GTwyyYlteZiFU+x0kew4=
|
github.com/mdlayher/packet v1.1.2/go.mod h1:GEu1+n9sG5VtiRE4SydOmX5GTwyyYlteZiFU+x0kew4=
|
||||||
github.com/mdlayher/raw v0.0.0-20191009151244-50f2db8cc065/go.mod h1:7EpbotpCmVZcu+KCX4g9WaRNuu11uyhiW7+Le1dKawg=
|
|
||||||
github.com/mdlayher/socket v0.2.1/go.mod h1:QLlNPkFR88mRUNQIzRBMfXxwKal8H7u1h3bL1CV+f0E=
|
github.com/mdlayher/socket v0.2.1/go.mod h1:QLlNPkFR88mRUNQIzRBMfXxwKal8H7u1h3bL1CV+f0E=
|
||||||
github.com/mdlayher/socket v0.4.1 h1:eM9y2/jlbs1M615oshPQOHZzj6R6wMT7bX5NPiQvn2U=
|
github.com/mdlayher/socket v0.4.1 h1:eM9y2/jlbs1M615oshPQOHZzj6R6wMT7bX5NPiQvn2U=
|
||||||
github.com/mdlayher/socket v0.4.1/go.mod h1:cAqeGjoufqdxWkD7DkpyS+wcefOtmu5OQ8KuoJGIReA=
|
github.com/mdlayher/socket v0.4.1/go.mod h1:cAqeGjoufqdxWkD7DkpyS+wcefOtmu5OQ8KuoJGIReA=
|
||||||
@ -982,7 +974,6 @@ github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8m
|
|||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
|
||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
||||||
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
|
||||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||||
github.com/nberlee/go-netstat v0.1.2 h1:wgPV1YOUo+kDFypqiKgfxMtnSs1Wb42c7ahI4qyEUJc=
|
github.com/nberlee/go-netstat v0.1.2 h1:wgPV1YOUo+kDFypqiKgfxMtnSs1Wb42c7ahI4qyEUJc=
|
||||||
github.com/nberlee/go-netstat v0.1.2/go.mod h1:GvDCRLsUKMRN1wULkt7tpnDmjSIE6YGf5zeVq+mBO64=
|
github.com/nberlee/go-netstat v0.1.2/go.mod h1:GvDCRLsUKMRN1wULkt7tpnDmjSIE6YGf5zeVq+mBO64=
|
||||||
@ -1210,9 +1201,7 @@ github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0
|
|||||||
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||||
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
|
||||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||||
github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0=
|
|
||||||
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
|
||||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
|
||||||
|
|||||||
@ -11,10 +11,12 @@ import (
|
|||||||
"github.com/cosi-project/runtime/pkg/controller"
|
"github.com/cosi-project/runtime/pkg/controller"
|
||||||
"github.com/cosi-project/runtime/pkg/safe"
|
"github.com/cosi-project/runtime/pkg/safe"
|
||||||
"github.com/cosi-project/runtime/pkg/state"
|
"github.com/cosi-project/runtime/pkg/state"
|
||||||
|
"github.com/siderolabs/go-pointer"
|
||||||
"github.com/siderolabs/go-procfs/procfs"
|
"github.com/siderolabs/go-procfs/procfs"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
|
||||||
"github.com/siderolabs/talos/pkg/machinery/constants"
|
"github.com/siderolabs/talos/pkg/machinery/constants"
|
||||||
|
"github.com/siderolabs/talos/pkg/machinery/resources/config"
|
||||||
"github.com/siderolabs/talos/pkg/machinery/resources/runtime"
|
"github.com/siderolabs/talos/pkg/machinery/resources/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -30,7 +32,14 @@ func (ctrl *EventsSinkConfigController) Name() string {
|
|||||||
|
|
||||||
// Inputs implements controller.Controller interface.
|
// Inputs implements controller.Controller interface.
|
||||||
func (ctrl *EventsSinkConfigController) Inputs() []controller.Input {
|
func (ctrl *EventsSinkConfigController) Inputs() []controller.Input {
|
||||||
return nil
|
return []controller.Input{
|
||||||
|
{
|
||||||
|
Namespace: config.NamespaceName,
|
||||||
|
Type: config.MachineConfigType,
|
||||||
|
ID: pointer.To(config.V1Alpha1ID),
|
||||||
|
Kind: controller.InputWeak,
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Outputs implements controller.Controller interface.
|
// Outputs implements controller.Controller interface.
|
||||||
@ -62,6 +71,15 @@ func (ctrl *EventsSinkConfigController) Run(ctx context.Context, r controller.Ru
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cfg, err := safe.ReaderGetByID[*config.MachineConfig](ctx, r, config.V1Alpha1ID)
|
||||||
|
if err != nil && !state.IsNotFoundError(err) {
|
||||||
|
return fmt.Errorf("error getting machine config: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if cfg != nil && cfg.Config().Runtime().EventsEndpoint() != nil {
|
||||||
|
endpoint = *cfg.Config().Runtime().EventsEndpoint()
|
||||||
|
}
|
||||||
|
|
||||||
if endpoint == "" {
|
if endpoint == "" {
|
||||||
if err := r.Destroy(ctx, runtime.NewEventSinkConfig().Metadata()); err != nil && !state.IsNotFoundError(err) {
|
if err := r.Destroy(ctx, runtime.NewEventSinkConfig().Metadata()); err != nil && !state.IsNotFoundError(err) {
|
||||||
return fmt.Errorf("error destroying event sink config: %w", err)
|
return fmt.Errorf("error destroying event sink config: %w", err)
|
||||||
|
|||||||
@ -15,7 +15,10 @@ import (
|
|||||||
|
|
||||||
"github.com/siderolabs/talos/internal/app/machined/pkg/controllers/ctest"
|
"github.com/siderolabs/talos/internal/app/machined/pkg/controllers/ctest"
|
||||||
runtimectrls "github.com/siderolabs/talos/internal/app/machined/pkg/controllers/runtime"
|
runtimectrls "github.com/siderolabs/talos/internal/app/machined/pkg/controllers/runtime"
|
||||||
|
"github.com/siderolabs/talos/pkg/machinery/config/container"
|
||||||
|
runtimecfg "github.com/siderolabs/talos/pkg/machinery/config/types/runtime"
|
||||||
"github.com/siderolabs/talos/pkg/machinery/constants"
|
"github.com/siderolabs/talos/pkg/machinery/constants"
|
||||||
|
"github.com/siderolabs/talos/pkg/machinery/resources/config"
|
||||||
"github.com/siderolabs/talos/pkg/machinery/resources/runtime"
|
"github.com/siderolabs/talos/pkg/machinery/resources/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -33,10 +36,36 @@ func (suite *EventsSinkConfigSuite) TestEventSinkConfigNone() {
|
|||||||
rtestutils.AssertNoResource[*runtime.EventSinkConfig](suite.Ctx(), suite.T(), suite.State(), runtime.EventSinkConfigID)
|
rtestutils.AssertNoResource[*runtime.EventSinkConfig](suite.Ctx(), suite.T(), suite.State(), runtime.EventSinkConfigID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (suite *EventsSinkConfigSuite) TestEventSinkConfigMachineConfig() {
|
||||||
|
suite.Require().NoError(suite.Runtime().RegisterController(&runtimectrls.EventsSinkConfigController{}))
|
||||||
|
|
||||||
|
eventSinkConfig := &runtimecfg.EventSinkV1Alpha1{
|
||||||
|
Endpoint: "10.0.0.2:4444",
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg, err := container.New(eventSinkConfig)
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
|
||||||
|
suite.Require().NoError(suite.State().Create(suite.Ctx(), config.NewMachineConfig(cfg)))
|
||||||
|
|
||||||
|
rtestutils.AssertResources[*runtime.EventSinkConfig](suite.Ctx(), suite.T(), suite.State(), []resource.ID{runtime.EventSinkConfigID},
|
||||||
|
func(cfg *runtime.EventSinkConfig, asrt *assert.Assertions) {
|
||||||
|
asrt.Equal(
|
||||||
|
"10.0.0.2:4444",
|
||||||
|
cfg.TypedSpec().Endpoint,
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (suite *EventsSinkConfigSuite) TestEventSinkConfigCmdline() {
|
func (suite *EventsSinkConfigSuite) TestEventSinkConfigCmdline() {
|
||||||
cmdline := procfs.NewCmdline("")
|
cmdline := procfs.NewCmdline("")
|
||||||
cmdline.Append(constants.KernelParamEventsSink, "10.0.0.1:3333")
|
cmdline.Append(constants.KernelParamEventsSink, "10.0.0.1:3333")
|
||||||
|
|
||||||
|
cfg, err := container.New()
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
|
||||||
|
suite.Require().NoError(suite.State().Create(suite.Ctx(), config.NewMachineConfig(cfg)))
|
||||||
|
|
||||||
suite.Require().NoError(suite.Runtime().RegisterController(&runtimectrls.EventsSinkConfigController{
|
suite.Require().NoError(suite.Runtime().RegisterController(&runtimectrls.EventsSinkConfigController{
|
||||||
Cmdline: cmdline,
|
Cmdline: cmdline,
|
||||||
}))
|
}))
|
||||||
|
|||||||
@ -12,10 +12,13 @@ import (
|
|||||||
"github.com/cosi-project/runtime/pkg/controller"
|
"github.com/cosi-project/runtime/pkg/controller"
|
||||||
"github.com/cosi-project/runtime/pkg/safe"
|
"github.com/cosi-project/runtime/pkg/safe"
|
||||||
"github.com/cosi-project/runtime/pkg/state"
|
"github.com/cosi-project/runtime/pkg/state"
|
||||||
|
"github.com/siderolabs/gen/slices"
|
||||||
|
"github.com/siderolabs/go-pointer"
|
||||||
"github.com/siderolabs/go-procfs/procfs"
|
"github.com/siderolabs/go-procfs/procfs"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
|
||||||
"github.com/siderolabs/talos/pkg/machinery/constants"
|
"github.com/siderolabs/talos/pkg/machinery/constants"
|
||||||
|
"github.com/siderolabs/talos/pkg/machinery/resources/config"
|
||||||
"github.com/siderolabs/talos/pkg/machinery/resources/runtime"
|
"github.com/siderolabs/talos/pkg/machinery/resources/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -31,7 +34,14 @@ func (ctrl *KmsgLogConfigController) Name() string {
|
|||||||
|
|
||||||
// Inputs implements controller.Controller interface.
|
// Inputs implements controller.Controller interface.
|
||||||
func (ctrl *KmsgLogConfigController) Inputs() []controller.Input {
|
func (ctrl *KmsgLogConfigController) Inputs() []controller.Input {
|
||||||
return nil
|
return []controller.Input{
|
||||||
|
{
|
||||||
|
Namespace: config.NamespaceName,
|
||||||
|
Type: config.MachineConfigType,
|
||||||
|
ID: pointer.To(config.V1Alpha1ID),
|
||||||
|
Kind: controller.InputWeak,
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Outputs implements controller.Controller interface.
|
// Outputs implements controller.Controller interface.
|
||||||
@ -68,6 +78,21 @@ func (ctrl *KmsgLogConfigController) Run(ctx context.Context, r controller.Runti
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cfg, err := safe.ReaderGetByID[*config.MachineConfig](ctx, r, config.V1Alpha1ID)
|
||||||
|
if err != nil && !state.IsNotFoundError(err) {
|
||||||
|
return fmt.Errorf("error getting machine config: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if cfg != nil {
|
||||||
|
// remove duplicate URLs in case same destination is specified in both machine config and kernel args
|
||||||
|
destinations = append(destinations, slices.Filter(cfg.Config().Runtime().KmsgLogURLs(),
|
||||||
|
func(u *url.URL) bool {
|
||||||
|
return !slices.Contains(destinations, func(v *url.URL) bool {
|
||||||
|
return v.String() == u.String()
|
||||||
|
})
|
||||||
|
})...)
|
||||||
|
}
|
||||||
|
|
||||||
if len(destinations) == 0 {
|
if len(destinations) == 0 {
|
||||||
if err := r.Destroy(ctx, runtime.NewKmsgLogConfig().Metadata()); err != nil && !state.IsNotFoundError(err) {
|
if err := r.Destroy(ctx, runtime.NewKmsgLogConfig().Metadata()); err != nil && !state.IsNotFoundError(err) {
|
||||||
return fmt.Errorf("error destroying kmsg log config: %w", err)
|
return fmt.Errorf("error destroying kmsg log config: %w", err)
|
||||||
|
|||||||
@ -17,7 +17,11 @@ import (
|
|||||||
|
|
||||||
"github.com/siderolabs/talos/internal/app/machined/pkg/controllers/ctest"
|
"github.com/siderolabs/talos/internal/app/machined/pkg/controllers/ctest"
|
||||||
runtimectrls "github.com/siderolabs/talos/internal/app/machined/pkg/controllers/runtime"
|
runtimectrls "github.com/siderolabs/talos/internal/app/machined/pkg/controllers/runtime"
|
||||||
|
"github.com/siderolabs/talos/pkg/machinery/config/container"
|
||||||
|
"github.com/siderolabs/talos/pkg/machinery/config/types/meta"
|
||||||
|
runtimecfg "github.com/siderolabs/talos/pkg/machinery/config/types/runtime"
|
||||||
"github.com/siderolabs/talos/pkg/machinery/constants"
|
"github.com/siderolabs/talos/pkg/machinery/constants"
|
||||||
|
"github.com/siderolabs/talos/pkg/machinery/resources/config"
|
||||||
"github.com/siderolabs/talos/pkg/machinery/resources/runtime"
|
"github.com/siderolabs/talos/pkg/machinery/resources/runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -35,6 +39,45 @@ func (suite *KmsgLogConfigSuite) TestKmsgLogConfigNone() {
|
|||||||
rtestutils.AssertNoResource[*runtime.KmsgLogConfig](suite.Ctx(), suite.T(), suite.State(), runtime.KmsgLogConfigID)
|
rtestutils.AssertNoResource[*runtime.KmsgLogConfig](suite.Ctx(), suite.T(), suite.State(), runtime.KmsgLogConfigID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (suite *KmsgLogConfigSuite) TestKmsgLogConfigMachineConfig() {
|
||||||
|
cmdline := procfs.NewCmdline("")
|
||||||
|
cmdline.Append(constants.KernelParamLoggingKernel, "https://10.0.0.1:3333/logs")
|
||||||
|
|
||||||
|
suite.Require().NoError(suite.Runtime().RegisterController(&runtimectrls.KmsgLogConfigController{
|
||||||
|
Cmdline: cmdline,
|
||||||
|
}))
|
||||||
|
|
||||||
|
kmsgLogConfig1 := &runtimecfg.KmsgLogV1Alpha1{
|
||||||
|
MetaName: "1",
|
||||||
|
KmsgLogURL: meta.URL{
|
||||||
|
URL: must(url.Parse("https://10.0.0.2:4444/logs")),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
kmsgLogConfig2 := &runtimecfg.KmsgLogV1Alpha1{
|
||||||
|
MetaName: "2",
|
||||||
|
KmsgLogURL: meta.URL{
|
||||||
|
URL: must(url.Parse("https://10.0.0.1:3333/logs")),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg, err := container.New(kmsgLogConfig1, kmsgLogConfig2)
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
|
||||||
|
suite.Require().NoError(suite.State().Create(suite.Ctx(), config.NewMachineConfig(cfg)))
|
||||||
|
|
||||||
|
rtestutils.AssertResources[*runtime.KmsgLogConfig](suite.Ctx(), suite.T(), suite.State(), []resource.ID{runtime.KmsgLogConfigID},
|
||||||
|
func(cfg *runtime.KmsgLogConfig, asrt *assert.Assertions) {
|
||||||
|
asrt.Equal(
|
||||||
|
[]string{
|
||||||
|
"https://10.0.0.1:3333/logs",
|
||||||
|
"https://10.0.0.2:4444/logs",
|
||||||
|
},
|
||||||
|
slices.Map(cfg.TypedSpec().Destinations, func(u *url.URL) string { return u.String() }),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (suite *KmsgLogConfigSuite) TestKmsgLogConfigCmdline() {
|
func (suite *KmsgLogConfigSuite) TestKmsgLogConfigCmdline() {
|
||||||
cmdline := procfs.NewCmdline("")
|
cmdline := procfs.NewCmdline("")
|
||||||
cmdline.Append(constants.KernelParamLoggingKernel, "https://10.0.0.1:3333/logs")
|
cmdline.Append(constants.KernelParamLoggingKernel, "https://10.0.0.1:3333/logs")
|
||||||
@ -51,3 +94,11 @@ func (suite *KmsgLogConfigSuite) TestKmsgLogConfigCmdline() {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func must[T any](t T, err error) T {
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|||||||
@ -12,4 +12,5 @@ type Config interface {
|
|||||||
Machine() MachineConfig
|
Machine() MachineConfig
|
||||||
Cluster() ClusterConfig
|
Cluster() ClusterConfig
|
||||||
SideroLink() SideroLinkConfig
|
SideroLink() SideroLinkConfig
|
||||||
|
Runtime() RuntimeConfig
|
||||||
}
|
}
|
||||||
|
|||||||
52
pkg/machinery/config/config/runtime.go
Normal file
52
pkg/machinery/config/config/runtime.go
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
package config
|
||||||
|
|
||||||
|
import "net/url"
|
||||||
|
|
||||||
|
// RuntimeConfig defines the interface to access Talos runtime configuration.
|
||||||
|
type RuntimeConfig interface {
|
||||||
|
EventsEndpoint() *string
|
||||||
|
KmsgLogURLs() []*url.URL
|
||||||
|
}
|
||||||
|
|
||||||
|
// WrapRuntimeConfigList wraps a list of RuntimeConfig into a single RuntimeConfig aggregating the results.
|
||||||
|
func WrapRuntimeConfigList(configs ...RuntimeConfig) RuntimeConfig {
|
||||||
|
return runtimeConfigWrapper(configs)
|
||||||
|
}
|
||||||
|
|
||||||
|
type runtimeConfigWrapper []RuntimeConfig
|
||||||
|
|
||||||
|
func (w runtimeConfigWrapper) EventsEndpoint() *string {
|
||||||
|
return findFirstValue(w, func(c RuntimeConfig) *string {
|
||||||
|
return c.EventsEndpoint()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (w runtimeConfigWrapper) KmsgLogURLs() []*url.URL {
|
||||||
|
return aggregateValues(w, func(c RuntimeConfig) []*url.URL {
|
||||||
|
return c.KmsgLogURLs()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func findFirstValue[T any, R any](documents []T, getter func(T) *R) *R {
|
||||||
|
for _, document := range documents {
|
||||||
|
if value := getter(document); value != nil {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func aggregateValues[T any, R any](documents []T, getter func(T) []R) []R {
|
||||||
|
var result []R
|
||||||
|
|
||||||
|
for _, document := range documents {
|
||||||
|
result = append(result, getter(document)...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
@ -31,6 +31,6 @@ func FuzzConfigLoader(f *testing.F) {
|
|||||||
f.Fuzz(func(t *testing.T, b []byte) {
|
f.Fuzz(func(t *testing.T, b []byte) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
testConfigLoaderBytes(t, b)
|
testConfigLoaderBytes(t, b, false)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,6 +16,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// callMethods calls obj's "getter" methods recursively and fails on panic.
|
// callMethods calls obj's "getter" methods recursively and fails on panic.
|
||||||
|
//
|
||||||
|
//nolint:gocyclo
|
||||||
func callMethods(t testing.TB, obj reflect.Value, chain ...string) {
|
func callMethods(t testing.TB, obj reflect.Value, chain ...string) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
@ -44,6 +46,8 @@ func callMethods(t testing.TB, obj reflect.Value, chain ...string) {
|
|||||||
fallthrough
|
fallthrough
|
||||||
case "MarshalYAML":
|
case "MarshalYAML":
|
||||||
fallthrough
|
fallthrough
|
||||||
|
case "Doc":
|
||||||
|
fallthrough
|
||||||
case "Endpoint":
|
case "Endpoint":
|
||||||
// t.Logf("Skipping %v", nextChain)
|
// t.Logf("Skipping %v", nextChain)
|
||||||
continue
|
continue
|
||||||
@ -69,12 +73,16 @@ func callMethods(t testing.TB, obj reflect.Value, chain ...string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func testConfigLoaderBytes(t testing.TB, b []byte) {
|
func testConfigLoaderBytes(t testing.TB, b []byte, failOnError bool) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
p, err := configloader.NewFromBytes(b)
|
p, err := configloader.NewFromBytes(b)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Skipf("Failed to load, skipping: %s.", err)
|
if failOnError {
|
||||||
|
t.Fatalf("Failed to load: %s.", err)
|
||||||
|
} else {
|
||||||
|
t.Skipf("Failed to load, skipping: %s.", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
callMethods(t, reflect.ValueOf(p))
|
callMethods(t, reflect.ValueOf(p))
|
||||||
@ -95,7 +103,7 @@ func TestConfigLoader(t *testing.T) {
|
|||||||
b, err := os.ReadFile(file)
|
b, err := os.ReadFile(file)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
testConfigLoaderBytes(t, b)
|
testConfigLoaderBytes(t, b, true)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
12
pkg/machinery/config/configloader/testdata/multidoc1.test
vendored
Normal file
12
pkg/machinery/config/configloader/testdata/multidoc1.test
vendored
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
apiVersion: v1alpha1
|
||||||
|
kind: SideroLinkConfig
|
||||||
|
apiUrl: grpc://172.20.0.1:4000/?jointoken=foo
|
||||||
|
---
|
||||||
|
apiVersion: v1alpha1
|
||||||
|
kind: KmsgLogConfig
|
||||||
|
name: apiSink
|
||||||
|
url: tcp://[fdae:41e4:649b:9303::1]:4001/
|
||||||
|
---
|
||||||
|
apiVersion: v1alpha1
|
||||||
|
kind: EventSinkConfig
|
||||||
|
endpoint: "[fdae:41e4:649b:9303::1]:8080"
|
||||||
@ -112,7 +112,7 @@ func (container *Container) Debug() bool {
|
|||||||
// Persist implements config.Config interface.
|
// Persist implements config.Config interface.
|
||||||
func (container *Container) Persist() bool {
|
func (container *Container) Persist() bool {
|
||||||
if container.v1alpha1Config == nil {
|
if container.v1alpha1Config == nil {
|
||||||
return false
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
return container.v1alpha1Config.Persist()
|
return container.v1alpha1Config.Persist()
|
||||||
@ -136,15 +136,31 @@ func (container *Container) Cluster() config.ClusterConfig {
|
|||||||
return container.v1alpha1Config.Cluster()
|
return container.v1alpha1Config.Cluster()
|
||||||
}
|
}
|
||||||
|
|
||||||
// SideroLink implements config.Config interface.
|
func findMatchingDocs[T any](documents []config.Document) []T {
|
||||||
func (container *Container) SideroLink() config.SideroLinkConfig {
|
var result []T
|
||||||
for _, doc := range container.documents {
|
|
||||||
if c, ok := doc.(config.SideroLinkConfig); ok {
|
for _, doc := range documents {
|
||||||
return c
|
if c, ok := doc.(T); ok {
|
||||||
|
result = append(result, c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// SideroLink implements config.Config interface.
|
||||||
|
func (container *Container) SideroLink() config.SideroLinkConfig {
|
||||||
|
matching := findMatchingDocs[config.SideroLinkConfig](container.documents)
|
||||||
|
if len(matching) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return matching[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Runtime implements config.Config interface.
|
||||||
|
func (container *Container) Runtime() config.RuntimeConfig {
|
||||||
|
return config.WrapRuntimeConfigList(findMatchingDocs[config.RuntimeConfig](container.documents)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bytes returns source YAML representation (if available) or does default encoding.
|
// Bytes returns source YAML representation (if available) or does default encoding.
|
||||||
|
|||||||
31
pkg/machinery/config/types/runtime/deep_copy.generated.go
Normal file
31
pkg/machinery/config/types/runtime/deep_copy.generated.go
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
// Code generated by "deep-copy -type EventSinkV1Alpha1 -type KmsgLogV1Alpha1 -pointer-receiver -header-file ../../../../../hack/boilerplate.txt -o deep_copy.generated.go ."; DO NOT EDIT.
|
||||||
|
|
||||||
|
package runtime
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/url"
|
||||||
|
)
|
||||||
|
|
||||||
|
// DeepCopy generates a deep copy of *EventSinkV1Alpha1.
|
||||||
|
func (o *EventSinkV1Alpha1) DeepCopy() *EventSinkV1Alpha1 {
|
||||||
|
var cp EventSinkV1Alpha1 = *o
|
||||||
|
return &cp
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeepCopy generates a deep copy of *KmsgLogV1Alpha1.
|
||||||
|
func (o *KmsgLogV1Alpha1) DeepCopy() *KmsgLogV1Alpha1 {
|
||||||
|
var cp KmsgLogV1Alpha1 = *o
|
||||||
|
if o.KmsgLogURL.URL != nil {
|
||||||
|
cp.KmsgLogURL.URL = new(url.URL)
|
||||||
|
*cp.KmsgLogURL.URL = *o.KmsgLogURL.URL
|
||||||
|
if o.KmsgLogURL.URL.User != nil {
|
||||||
|
cp.KmsgLogURL.URL.User = new(url.Userinfo)
|
||||||
|
*cp.KmsgLogURL.URL.User = *o.KmsgLogURL.URL.User
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return &cp
|
||||||
|
}
|
||||||
84
pkg/machinery/config/types/runtime/event_sink.go
Normal file
84
pkg/machinery/config/types/runtime/event_sink.go
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
package runtime
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/siderolabs/go-pointer"
|
||||||
|
|
||||||
|
"github.com/siderolabs/talos/pkg/machinery/config/config"
|
||||||
|
"github.com/siderolabs/talos/pkg/machinery/config/internal/registry"
|
||||||
|
"github.com/siderolabs/talos/pkg/machinery/config/types/meta"
|
||||||
|
"github.com/siderolabs/talos/pkg/machinery/config/validation"
|
||||||
|
)
|
||||||
|
|
||||||
|
// EventSinkKind is a event sink config document kind.
|
||||||
|
const EventSinkKind = "EventSinkConfig"
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
registry.Register(EventSinkKind, func(version string) config.Document {
|
||||||
|
switch version {
|
||||||
|
case "v1alpha1":
|
||||||
|
return &EventSinkV1Alpha1{}
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check interfaces.
|
||||||
|
var (
|
||||||
|
_ config.RuntimeConfig = &EventSinkV1Alpha1{}
|
||||||
|
_ config.Validator = &EventSinkV1Alpha1{}
|
||||||
|
)
|
||||||
|
|
||||||
|
// EventSinkV1Alpha1 is a event sink config document.
|
||||||
|
type EventSinkV1Alpha1 struct {
|
||||||
|
meta.Meta `yaml:",inline"`
|
||||||
|
Endpoint string `yaml:"endpoint"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewEventSinkV1Alpha1 creates a new eventsink config document.
|
||||||
|
func NewEventSinkV1Alpha1() *EventSinkV1Alpha1 {
|
||||||
|
return &EventSinkV1Alpha1{
|
||||||
|
Meta: meta.Meta{
|
||||||
|
MetaKind: EventSinkKind,
|
||||||
|
MetaAPIVersion: "v1alpha1",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clone implements config.Document interface.
|
||||||
|
func (s *EventSinkV1Alpha1) Clone() config.Document {
|
||||||
|
return s.DeepCopy()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Runtime implements config.Config interface.
|
||||||
|
func (s *EventSinkV1Alpha1) Runtime() config.RuntimeConfig {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
// EventsEndpoint implements config.RuntimeConfig interface.
|
||||||
|
func (s *EventSinkV1Alpha1) EventsEndpoint() *string {
|
||||||
|
return pointer.To(s.Endpoint)
|
||||||
|
}
|
||||||
|
|
||||||
|
// KmsgLogURLs implements config.RuntimeConfig interface.
|
||||||
|
func (s *EventSinkV1Alpha1) KmsgLogURLs() []*url.URL {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate implements config.Validator interface.
|
||||||
|
func (s *EventSinkV1Alpha1) Validate(validation.RuntimeMode, ...validation.Option) ([]string, error) {
|
||||||
|
_, _, err := net.SplitHostPort(s.Endpoint)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("event sink endpoint: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
104
pkg/machinery/config/types/runtime/event_sink_test.go
Normal file
104
pkg/machinery/config/types/runtime/event_sink_test.go
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
package runtime_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "embed"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/siderolabs/talos/pkg/machinery/config/encoder"
|
||||||
|
"github.com/siderolabs/talos/pkg/machinery/config/types/runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:embed testdata/eventsink.yaml
|
||||||
|
var expectedEventSinkDocument []byte
|
||||||
|
|
||||||
|
func TestEventSinkMarshalStability(t *testing.T) {
|
||||||
|
cfg := runtime.NewEventSinkV1Alpha1()
|
||||||
|
cfg.Endpoint = "10.0.0.1:3333"
|
||||||
|
|
||||||
|
marshaled, err := encoder.NewEncoder(cfg).Encode()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
t.Log(string(marshaled))
|
||||||
|
|
||||||
|
assert.Equal(t, expectedEventSinkDocument, marshaled)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEventSinkValidate(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
for _, test := range []struct {
|
||||||
|
name string
|
||||||
|
cfg func() *runtime.EventSinkV1Alpha1
|
||||||
|
|
||||||
|
expectedError string
|
||||||
|
expectedWarnings []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "empty",
|
||||||
|
cfg: runtime.NewEventSinkV1Alpha1,
|
||||||
|
|
||||||
|
expectedError: "event sink endpoint: missing port in address",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "just IP",
|
||||||
|
cfg: func() *runtime.EventSinkV1Alpha1 {
|
||||||
|
cfg := runtime.NewEventSinkV1Alpha1()
|
||||||
|
cfg.Endpoint = "10.0.0.1"
|
||||||
|
|
||||||
|
return cfg
|
||||||
|
},
|
||||||
|
|
||||||
|
expectedError: "event sink endpoint: address 10.0.0.1: missing port in address",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "valid",
|
||||||
|
cfg: func() *runtime.EventSinkV1Alpha1 {
|
||||||
|
cfg := runtime.NewEventSinkV1Alpha1()
|
||||||
|
cfg.Endpoint = "[ff:80::01]:334"
|
||||||
|
|
||||||
|
return cfg
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
test := test
|
||||||
|
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
warnings, err := test.cfg().Validate(validationMode{})
|
||||||
|
|
||||||
|
assert.Equal(t, test.expectedWarnings, warnings)
|
||||||
|
|
||||||
|
if test.expectedError != "" {
|
||||||
|
assert.EqualError(t, err, test.expectedError)
|
||||||
|
} else {
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func must[T any](t T, err error) T {
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return t
|
||||||
|
}
|
||||||
|
|
||||||
|
type validationMode struct{}
|
||||||
|
|
||||||
|
func (validationMode) String() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (validationMode) RequiresInstall() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
109
pkg/machinery/config/types/runtime/kmsg_log.go
Normal file
109
pkg/machinery/config/types/runtime/kmsg_log.go
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
package runtime
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
|
|
||||||
|
"github.com/siderolabs/talos/pkg/machinery/config/config"
|
||||||
|
"github.com/siderolabs/talos/pkg/machinery/config/internal/registry"
|
||||||
|
"github.com/siderolabs/talos/pkg/machinery/config/types/meta"
|
||||||
|
"github.com/siderolabs/talos/pkg/machinery/config/validation"
|
||||||
|
)
|
||||||
|
|
||||||
|
// KmsgLogKind is a kmsg log config document kind.
|
||||||
|
const KmsgLogKind = "KmsgLogConfig"
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
registry.Register(KmsgLogKind, func(version string) config.Document {
|
||||||
|
switch version {
|
||||||
|
case "v1alpha1":
|
||||||
|
return &KmsgLogV1Alpha1{}
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check interfaces.
|
||||||
|
var (
|
||||||
|
_ config.RuntimeConfig = &KmsgLogV1Alpha1{}
|
||||||
|
_ config.NamedDocument = &KmsgLogV1Alpha1{}
|
||||||
|
_ config.Validator = &KmsgLogV1Alpha1{}
|
||||||
|
)
|
||||||
|
|
||||||
|
// KmsgLogV1Alpha1 is a event sink config document.
|
||||||
|
type KmsgLogV1Alpha1 struct {
|
||||||
|
meta.Meta `yaml:",inline"`
|
||||||
|
MetaName string `yaml:"name"`
|
||||||
|
KmsgLogURL meta.URL `yaml:"url"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewKmsgLogV1Alpha1 creates a new eventsink config document.
|
||||||
|
func NewKmsgLogV1Alpha1() *KmsgLogV1Alpha1 {
|
||||||
|
return &KmsgLogV1Alpha1{
|
||||||
|
Meta: meta.Meta{
|
||||||
|
MetaKind: KmsgLogKind,
|
||||||
|
MetaAPIVersion: "v1alpha1",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name implements config.NamedDocument interface.
|
||||||
|
func (s *KmsgLogV1Alpha1) Name() string {
|
||||||
|
return s.MetaName
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clone implements config.Document interface.
|
||||||
|
func (s *KmsgLogV1Alpha1) Clone() config.Document {
|
||||||
|
return s.DeepCopy()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Runtime implements config.Config interface.
|
||||||
|
func (s *KmsgLogV1Alpha1) Runtime() config.RuntimeConfig {
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
// EventsEndpoint implements config.RuntimeConfig interface.
|
||||||
|
func (s *KmsgLogV1Alpha1) EventsEndpoint() *string {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// KmsgLogURLs implements config.RuntimeConfig interface.
|
||||||
|
func (s *KmsgLogV1Alpha1) KmsgLogURLs() []*url.URL {
|
||||||
|
return []*url.URL{s.KmsgLogURL.URL}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Validate implements config.Validator interface.
|
||||||
|
func (s *KmsgLogV1Alpha1) Validate(validation.RuntimeMode, ...validation.Option) ([]string, error) {
|
||||||
|
if s.MetaName == "" {
|
||||||
|
return nil, fmt.Errorf("name is required")
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.KmsgLogURL.URL == nil {
|
||||||
|
return nil, fmt.Errorf("url is required")
|
||||||
|
}
|
||||||
|
|
||||||
|
switch s.KmsgLogURL.URL.Scheme {
|
||||||
|
case "tcp":
|
||||||
|
case "udp":
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("url scheme must be tcp:// or udp://")
|
||||||
|
}
|
||||||
|
|
||||||
|
switch s.KmsgLogURL.URL.Path {
|
||||||
|
case "/":
|
||||||
|
case "":
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("url path must be empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
if s.KmsgLogURL.URL.Port() == "" {
|
||||||
|
return nil, fmt.Errorf("url port is required")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
135
pkg/machinery/config/types/runtime/kmsg_log_test.go
Normal file
135
pkg/machinery/config/types/runtime/kmsg_log_test.go
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
package runtime_test
|
||||||
|
|
||||||
|
import (
|
||||||
|
_ "embed"
|
||||||
|
"net/url"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
|
"github.com/siderolabs/talos/pkg/machinery/config/encoder"
|
||||||
|
"github.com/siderolabs/talos/pkg/machinery/config/types/runtime"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:embed testdata/kmsglog.yaml
|
||||||
|
var expectedKmsgLogDocument []byte
|
||||||
|
|
||||||
|
func TestKmsgLogMarshalStability(t *testing.T) {
|
||||||
|
cfg := runtime.NewKmsgLogV1Alpha1()
|
||||||
|
cfg.MetaName = "apiSink"
|
||||||
|
cfg.KmsgLogURL.URL = must(url.Parse("https://kmsglog.api/logs"))
|
||||||
|
|
||||||
|
marshaled, err := encoder.NewEncoder(cfg).Encode()
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
t.Log(string(marshaled))
|
||||||
|
|
||||||
|
assert.Equal(t, expectedKmsgLogDocument, marshaled)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestKmsgLogValidate(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
for _, test := range []struct {
|
||||||
|
name string
|
||||||
|
cfg func() *runtime.KmsgLogV1Alpha1
|
||||||
|
|
||||||
|
expectedError string
|
||||||
|
expectedWarnings []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "empty",
|
||||||
|
cfg: runtime.NewKmsgLogV1Alpha1,
|
||||||
|
|
||||||
|
expectedError: "name is required",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no URL",
|
||||||
|
cfg: func() *runtime.KmsgLogV1Alpha1 {
|
||||||
|
cfg := runtime.NewKmsgLogV1Alpha1()
|
||||||
|
cfg.MetaName = "name1"
|
||||||
|
|
||||||
|
return cfg
|
||||||
|
},
|
||||||
|
|
||||||
|
expectedError: "url is required",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "wrong scheme",
|
||||||
|
cfg: func() *runtime.KmsgLogV1Alpha1 {
|
||||||
|
cfg := runtime.NewKmsgLogV1Alpha1()
|
||||||
|
cfg.MetaName = "name2"
|
||||||
|
cfg.KmsgLogURL.URL = must(url.Parse("https://some.destination/path"))
|
||||||
|
|
||||||
|
return cfg
|
||||||
|
},
|
||||||
|
|
||||||
|
expectedError: "url scheme must be tcp:// or udp://",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "extra path",
|
||||||
|
cfg: func() *runtime.KmsgLogV1Alpha1 {
|
||||||
|
cfg := runtime.NewKmsgLogV1Alpha1()
|
||||||
|
cfg.MetaName = "name5"
|
||||||
|
cfg.KmsgLogURL.URL = must(url.Parse("tcp://some.destination:34/path"))
|
||||||
|
|
||||||
|
return cfg
|
||||||
|
},
|
||||||
|
|
||||||
|
expectedError: "url path must be empty",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no port",
|
||||||
|
cfg: func() *runtime.KmsgLogV1Alpha1 {
|
||||||
|
cfg := runtime.NewKmsgLogV1Alpha1()
|
||||||
|
cfg.MetaName = "name6"
|
||||||
|
cfg.KmsgLogURL.URL = must(url.Parse("tcp://some.destination/"))
|
||||||
|
|
||||||
|
return cfg
|
||||||
|
},
|
||||||
|
|
||||||
|
expectedError: "url port is required",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "valid TCP",
|
||||||
|
cfg: func() *runtime.KmsgLogV1Alpha1 {
|
||||||
|
cfg := runtime.NewKmsgLogV1Alpha1()
|
||||||
|
cfg.MetaName = "name3"
|
||||||
|
cfg.KmsgLogURL.URL = must(url.Parse("tcp://10.2.3.4:5000/"))
|
||||||
|
|
||||||
|
return cfg
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "valid UDP",
|
||||||
|
cfg: func() *runtime.KmsgLogV1Alpha1 {
|
||||||
|
cfg := runtime.NewKmsgLogV1Alpha1()
|
||||||
|
cfg.MetaName = "name4"
|
||||||
|
cfg.KmsgLogURL.URL = must(url.Parse("udp://10.2.3.4:5000/"))
|
||||||
|
|
||||||
|
return cfg
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
test := test
|
||||||
|
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
warnings, err := test.cfg().Validate(validationMode{})
|
||||||
|
|
||||||
|
assert.Equal(t, test.expectedWarnings, warnings)
|
||||||
|
|
||||||
|
if test.expectedError != "" {
|
||||||
|
assert.EqualError(t, err, test.expectedError)
|
||||||
|
} else {
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
8
pkg/machinery/config/types/runtime/runtime.go
Normal file
8
pkg/machinery/config/types/runtime/runtime.go
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
// Package runtime provides Talos runtime config documents.
|
||||||
|
package runtime
|
||||||
|
|
||||||
|
//go:generate deep-copy -type EventSinkV1Alpha1 -type KmsgLogV1Alpha1 -pointer-receiver -header-file ../../../../../hack/boilerplate.txt -o deep_copy.generated.go .
|
||||||
3
pkg/machinery/config/types/runtime/testdata/eventsink.yaml
vendored
Normal file
3
pkg/machinery/config/types/runtime/testdata/eventsink.yaml
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
apiVersion: v1alpha1
|
||||||
|
kind: EventSinkConfig
|
||||||
|
endpoint: 10.0.0.1:3333
|
||||||
4
pkg/machinery/config/types/runtime/testdata/kmsglog.yaml
vendored
Normal file
4
pkg/machinery/config/types/runtime/testdata/kmsglog.yaml
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
apiVersion: v1alpha1
|
||||||
|
kind: KmsgLogConfig
|
||||||
|
name: apiSink
|
||||||
|
url: https://kmsglog.api/logs
|
||||||
@ -6,11 +6,13 @@
|
|||||||
package siderolink
|
package siderolink
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
|
||||||
"github.com/siderolabs/talos/pkg/machinery/config/config"
|
"github.com/siderolabs/talos/pkg/machinery/config/config"
|
||||||
"github.com/siderolabs/talos/pkg/machinery/config/internal/registry"
|
"github.com/siderolabs/talos/pkg/machinery/config/internal/registry"
|
||||||
"github.com/siderolabs/talos/pkg/machinery/config/types/meta"
|
"github.com/siderolabs/talos/pkg/machinery/config/types/meta"
|
||||||
|
"github.com/siderolabs/talos/pkg/machinery/config/validation"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:generate deep-copy -type ConfigV1Alpha1 -pointer-receiver -header-file ../../../../../hack/boilerplate.txt -o deep_copy.generated.go .
|
//go:generate deep-copy -type ConfigV1Alpha1 -pointer-receiver -header-file ../../../../../hack/boilerplate.txt -o deep_copy.generated.go .
|
||||||
@ -30,7 +32,11 @@ func init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check interfaces.
|
// Check interfaces.
|
||||||
var _ config.SecretDocument = &ConfigV1Alpha1{}
|
var (
|
||||||
|
_ config.SecretDocument = &ConfigV1Alpha1{}
|
||||||
|
_ config.SideroLinkConfig = &ConfigV1Alpha1{}
|
||||||
|
_ config.Validator = &ConfigV1Alpha1{}
|
||||||
|
)
|
||||||
|
|
||||||
// ConfigV1Alpha1 is a siderolink config document.
|
// ConfigV1Alpha1 is a siderolink config document.
|
||||||
type ConfigV1Alpha1 struct {
|
type ConfigV1Alpha1 struct {
|
||||||
@ -78,3 +84,26 @@ func (s *ConfigV1Alpha1) APIUrl() *url.URL {
|
|||||||
|
|
||||||
return s.APIUrlConfig.URL
|
return s.APIUrlConfig.URL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Validate implements config.Validator interface.
|
||||||
|
func (s *ConfigV1Alpha1) Validate(validation.RuntimeMode, ...validation.Option) ([]string, error) {
|
||||||
|
if s.APIUrlConfig.URL == nil {
|
||||||
|
return nil, fmt.Errorf("apiUrl is required")
|
||||||
|
}
|
||||||
|
|
||||||
|
switch s.APIUrlConfig.URL.Scheme {
|
||||||
|
case "https":
|
||||||
|
case "grpc":
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("apiUrl scheme must be https:// or grpc://")
|
||||||
|
}
|
||||||
|
|
||||||
|
switch s.APIUrlConfig.URL.Path {
|
||||||
|
case "/":
|
||||||
|
case "":
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("apiUrl path must be empty")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|||||||
@ -17,6 +17,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestRedact(t *testing.T) {
|
func TestRedact(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
cfg := siderolink.NewConfigV1Alpha1()
|
cfg := siderolink.NewConfigV1Alpha1()
|
||||||
cfg.APIUrlConfig.URL = must(url.Parse("https://siderolink.api/join?jointoken=secret&user=alice"))
|
cfg.APIUrlConfig.URL = must(url.Parse("https://siderolink.api/join?jointoken=secret&user=alice"))
|
||||||
|
|
||||||
@ -31,6 +33,8 @@ func TestRedact(t *testing.T) {
|
|||||||
var expectedDocument []byte
|
var expectedDocument []byte
|
||||||
|
|
||||||
func TestMarshalStability(t *testing.T) {
|
func TestMarshalStability(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
cfg := siderolink.NewConfigV1Alpha1()
|
cfg := siderolink.NewConfigV1Alpha1()
|
||||||
cfg.APIUrlConfig.URL = must(url.Parse("https://siderolink.api/join?jointoken=secret&user=alice"))
|
cfg.APIUrlConfig.URL = must(url.Parse("https://siderolink.api/join?jointoken=secret&user=alice"))
|
||||||
|
|
||||||
@ -40,6 +44,72 @@ func TestMarshalStability(t *testing.T) {
|
|||||||
assert.Equal(t, expectedDocument, marshaled)
|
assert.Equal(t, expectedDocument, marshaled)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestValidate(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
for _, test := range []struct {
|
||||||
|
name string
|
||||||
|
cfg func() *siderolink.ConfigV1Alpha1
|
||||||
|
|
||||||
|
expectedError string
|
||||||
|
expectedWarnings []string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "empty",
|
||||||
|
cfg: siderolink.NewConfigV1Alpha1,
|
||||||
|
|
||||||
|
expectedError: "apiUrl is required",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "wrong scheme",
|
||||||
|
cfg: func() *siderolink.ConfigV1Alpha1 {
|
||||||
|
cfg := siderolink.NewConfigV1Alpha1()
|
||||||
|
cfg.APIUrlConfig.URL = must(url.Parse("http://siderolink.api/"))
|
||||||
|
|
||||||
|
return cfg
|
||||||
|
},
|
||||||
|
|
||||||
|
expectedError: "apiUrl scheme must be https:// or grpc://",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "extra path",
|
||||||
|
cfg: func() *siderolink.ConfigV1Alpha1 {
|
||||||
|
cfg := siderolink.NewConfigV1Alpha1()
|
||||||
|
cfg.APIUrlConfig.URL = must(url.Parse("grpc://siderolink.api/path?jointoken=foo"))
|
||||||
|
|
||||||
|
return cfg
|
||||||
|
},
|
||||||
|
|
||||||
|
expectedError: "apiUrl path must be empty",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "valid",
|
||||||
|
cfg: func() *siderolink.ConfigV1Alpha1 {
|
||||||
|
cfg := siderolink.NewConfigV1Alpha1()
|
||||||
|
cfg.APIUrlConfig.URL = must(url.Parse("https://siderolink.api:434/?jointoken=foo"))
|
||||||
|
|
||||||
|
return cfg
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
test := test
|
||||||
|
|
||||||
|
t.Run(test.name, func(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
warnings, err := test.cfg().Validate(validationMode{})
|
||||||
|
|
||||||
|
assert.Equal(t, test.expectedWarnings, warnings)
|
||||||
|
|
||||||
|
if test.expectedError != "" {
|
||||||
|
assert.EqualError(t, err, test.expectedError)
|
||||||
|
} else {
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func must[T any](t T, err error) T {
|
func must[T any](t T, err error) T {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
@ -47,3 +117,13 @@ func must[T any](t T, err error) T {
|
|||||||
|
|
||||||
return t
|
return t
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type validationMode struct{}
|
||||||
|
|
||||||
|
func (validationMode) String() string {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func (validationMode) RequiresInstall() bool {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|||||||
@ -6,6 +6,7 @@
|
|||||||
package types
|
package types
|
||||||
|
|
||||||
import (
|
import (
|
||||||
_ "github.com/siderolabs/talos/pkg/machinery/config/types/siderolink" //nolint:revive
|
_ "github.com/siderolabs/talos/pkg/machinery/config/types/runtime" //nolint:revive
|
||||||
|
_ "github.com/siderolabs/talos/pkg/machinery/config/types/siderolink"
|
||||||
_ "github.com/siderolabs/talos/pkg/machinery/config/types/v1alpha1"
|
_ "github.com/siderolabs/talos/pkg/machinery/config/types/v1alpha1"
|
||||||
)
|
)
|
||||||
|
|||||||
@ -52,17 +52,25 @@ func (c *Config) APIVersion() string {
|
|||||||
|
|
||||||
// Debug implements the config.Provider interface.
|
// Debug implements the config.Provider interface.
|
||||||
func (c *Config) Debug() bool {
|
func (c *Config) Debug() bool {
|
||||||
|
if c == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
return pointer.SafeDeref(c.ConfigDebug)
|
return pointer.SafeDeref(c.ConfigDebug)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Persist implements the config.Provider interface.
|
// Persist implements the config.Provider interface.
|
||||||
func (c *Config) Persist() bool {
|
func (c *Config) Persist() bool {
|
||||||
|
if c == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
return pointer.SafeDeref(c.ConfigPersist)
|
return pointer.SafeDeref(c.ConfigPersist)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Machine implements the config.Provider interface.
|
// Machine implements the config.Provider interface.
|
||||||
func (c *Config) Machine() config.MachineConfig {
|
func (c *Config) Machine() config.MachineConfig {
|
||||||
if c.MachineConfig == nil {
|
if c == nil || c.MachineConfig == nil {
|
||||||
return &MachineConfig{}
|
return &MachineConfig{}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,7 +99,7 @@ func (m *MachineConfig) NodeLabels() config.NodeLabels {
|
|||||||
|
|
||||||
// Cluster implements the config.Provider interface.
|
// Cluster implements the config.Provider interface.
|
||||||
func (c *Config) Cluster() config.ClusterConfig {
|
func (c *Config) Cluster() config.ClusterConfig {
|
||||||
if c.ClusterConfig == nil {
|
if c == nil || c.ClusterConfig == nil {
|
||||||
return &ClusterConfig{}
|
return &ClusterConfig{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user