diff --git a/go.mod b/go.mod index 8a88acb5..b00f1edd 100644 --- a/go.mod +++ b/go.mod @@ -24,13 +24,13 @@ require ( github.com/sdcio/cache v0.0.38 github.com/sdcio/logger v0.0.3 github.com/sdcio/schema-server v0.0.33 - github.com/sdcio/sdc-protos v0.0.47 + github.com/sdcio/sdc-protos v0.0.49 github.com/sdcio/yang-parser v0.0.12 github.com/spf13/cobra v1.10.1 github.com/spf13/pflag v1.0.10 go.uber.org/mock v0.6.0 - google.golang.org/grpc v1.77.0 - google.golang.org/protobuf v1.36.10 + google.golang.org/grpc v1.78.0 + google.golang.org/protobuf v1.36.11 gopkg.in/yaml.v2 v2.4.0 sigs.k8s.io/controller-runtime v0.20.4 ) @@ -89,16 +89,16 @@ require ( go.opentelemetry.io/otel/metric v1.38.0 // indirect go.opentelemetry.io/otel/trace v1.38.0 // indirect go.yaml.in/yaml/v2 v2.4.2 // indirect - golang.org/x/crypto v0.43.0 // indirect + golang.org/x/crypto v0.44.0 // indirect golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa // indirect - golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 // indirect + golang.org/x/net v0.47.0 // indirect golang.org/x/oauth2 v0.32.0 // indirect - golang.org/x/sync v0.17.0 // indirect - golang.org/x/sys v0.37.0 // indirect - golang.org/x/term v0.36.0 // indirect - golang.org/x/text v0.30.0 // indirect + golang.org/x/sync v0.18.0 // indirect + golang.org/x/sys v0.38.0 // indirect + golang.org/x/term v0.37.0 // indirect + golang.org/x/text v0.31.0 // indirect golang.org/x/time v0.8.0 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index fabbbc23..afe5b525 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,8 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= +cloud.google.com/go/compute/metadata v0.9.0 h1:pDUj4QMoPejqq20dK0Pg2N4yG9zIkYGdBtwLoEkH9Zs= +cloud.google.com/go/compute/metadata v0.9.0/go.mod h1:E0bWwX5wTnLPedCKqk3pJmVgCBSM6qQI1yTBdEb3C10= github.com/AlekSi/pointer v1.2.0 h1:glcy/gc4h8HnG2Z3ZECSzZ1IX1x2JxRVuDzaJwQE0+w= github.com/AlekSi/pointer v1.2.0/go.mod h1:gZGfd3dpW4vEc/UlyfKKi1roIqcCgwOIvb0tSNSBle0= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= @@ -178,6 +180,8 @@ github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/scrapli/scrapligo v1.3.3 h1:D9zj1QrOYNYAQ30YT7wfQBINvPGxvs5L5Lz+2LnL7V4= github.com/scrapli/scrapligo v1.3.3/go.mod h1:pOWxVyPsQRrWTrkoSSDg05tjOqtWfLffAZtAsCc0w3M= @@ -189,8 +193,8 @@ github.com/sdcio/logger v0.0.3 h1:IFUbObObGry+S8lHGwOQKKRxJSuOphgRU/hxVhOdMOM= github.com/sdcio/logger v0.0.3/go.mod h1:yWaOxK/G6vszjg8tKZiMqiEjlZouHsjFME4zSk+SAEA= github.com/sdcio/schema-server v0.0.33 h1:RTeQMIchynAPSQaf61CZBgYHCCpsyDLEAWJn+ZKImIo= github.com/sdcio/schema-server v0.0.33/go.mod h1:q8leN1KhRNTnnqf6yxvkDk5tFl6DAsHcl81usVgYpoI= -github.com/sdcio/sdc-protos v0.0.47 h1:1SD8Ifx7MRc6fqjuJIM1wQ2NGEwjYj+QWgHNgENJiT4= -github.com/sdcio/sdc-protos v0.0.47/go.mod h1:cVCYbMq+tu7EKXyJKFq3p2bsCwjvXbxwsyOoMGiQddw= +github.com/sdcio/sdc-protos v0.0.49 h1:GpLTDEyNnQxO5fjY7b8Y4xMP8f9kr4bbCHPJYVZkK00= +github.com/sdcio/sdc-protos v0.0.49/go.mod h1:huh1QVE023w+reU2Gt6h1f83R3lJidcFLbQje7cMY1M= github.com/sdcio/yang-parser v0.0.12 h1:RSSeqfAOIsJx5Lno5u4/ezyOmQYUduQ22rBfU/mtpJ4= github.com/sdcio/yang-parser v0.0.12/go.mod h1:CBqn3Miq85qmFVGHxHXHLluXkaIOsTzV06IM4DW6+D4= github.com/sirikothe/gotextfsm v1.0.1-0.20200816110946-6aa2cfd355e4 h1:FHUL2HofYJuslFOQdy/JjjP36zxqIpd/dcoiwLMIs7k= @@ -227,6 +231,18 @@ go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6 go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/otel v1.38.0 h1:RkfdswUDRimDg0m2Az18RKOsnI8UDzppJAtj01/Ymk8= +go.opentelemetry.io/otel v1.38.0/go.mod h1:zcmtmQ1+YmQM9wrNsTGV/q/uyusom3P8RxwExxkZhjM= +go.opentelemetry.io/otel/metric v1.38.0 h1:Kl6lzIYGAh5M159u9NgiRkmoMKjvbsKtYRwgfrA6WpA= +go.opentelemetry.io/otel/metric v1.38.0/go.mod h1:kB5n/QoRM8YwmUahxvI3bO34eVtQf2i4utNVLr9gEmI= +go.opentelemetry.io/otel/sdk v1.38.0 h1:l48sr5YbNf2hpCUj/FoGhW9yDkl+Ma+LrVl8qaM5b+E= +go.opentelemetry.io/otel/sdk v1.38.0/go.mod h1:ghmNdGlVemJI3+ZB5iDEuk4bWA3GkTpW+DOoZMYBVVg= +go.opentelemetry.io/otel/sdk/metric v1.38.0 h1:aSH66iL0aZqo//xXzQLYozmWrXxyFkBJ6qT5wthqPoM= +go.opentelemetry.io/otel/sdk/metric v1.38.0/go.mod h1:dg9PBnW9XdQ1Hd6ZnRz689CbtrUp0wMMs9iPcgT9EZA= +go.opentelemetry.io/otel/trace v1.38.0 h1:Fxk5bKrDZJUH+AMyyIXGcFAPah0oRcT+LuNtJrmcNLE= +go.opentelemetry.io/otel/trace v1.38.0/go.mod h1:j1P9ivuFsTceSWe1oY+EeW3sc+Pp42sO++GHkg4wwhs= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -244,8 +260,8 @@ go.yaml.in/yaml/v2 v2.4.2/go.mod h1:081UH+NErpNdqlCXm3TtEran0rJZGxAYx9hb/ELlsPU= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.43.0 h1:dduJYIi3A3KOfdGOHX8AVZ/jGiyPa3IbBozJ5kNuE04= -golang.org/x/crypto v0.43.0/go.mod h1:BFbav4mRNlXJL4wNeejLpWxB7wMbc79PdRGhWKncxR0= +golang.org/x/crypto v0.44.0 h1:A97SsFvM3AIwEEmTBiaxPPTYpDC47w720rdiiUvgoAU= +golang.org/x/crypto v0.44.0/go.mod h1:013i+Nw79BMiQiMsOPcVCB5ZIJbYkerPrGnOa00tvmc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa h1:t2QcU6V556bFjYgu4L6C+6VrCPyJZ+eyRsABUPs1mz4= golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa/go.mod h1:BHOTPb3L19zxehTsLoJXVaTktb06DFgmdW6Wb9s8jqk= @@ -263,18 +279,20 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82 h1:6/3JGEh1C88g7m+qzzTbl3A0FtsLguXieqofVLU/JAo= -golang.org/x/net v0.46.1-0.20251013234738-63d1a5100f82/go.mod h1:Q9BGdFy1y4nkUwiLvT5qtyhAnEHgnQ/zd8PfU6nc210= +golang.org/x/net v0.47.0 h1:Mx+4dIFzqraBXUugkia1OOvlD6LemFo1ALMHjrXDOhY= +golang.org/x/net v0.47.0/go.mod h1:/jNxtkgq5yWUGYkaZGqo27cfGZ1c5Nen03aYrrKpVRU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.32.0 h1:jsCblLleRMDrxMN29H3z/k1KliIvpLgCkE6R8FXXNgY= golang.org/x/oauth2 v0.32.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= +golang.org/x/oauth2 v0.32.0 h1:jsCblLleRMDrxMN29H3z/k1KliIvpLgCkE6R8FXXNgY= +golang.org/x/oauth2 v0.32.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug= -golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= +golang.org/x/sync v0.18.0 h1:kr88TuHDroi+UVf+0hZnirlk8o8T+4MrK6mr60WkH/I= +golang.org/x/sync v0.18.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -284,14 +302,14 @@ golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.37.0 h1:fdNQudmxPjkdUTPnLn5mdQv7Zwvbvpaxqs831goi9kQ= -golang.org/x/sys v0.37.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= -golang.org/x/term v0.36.0 h1:zMPR+aF8gfksFprF/Nc/rd1wRS1EI6nDBGyWAvDzx2Q= -golang.org/x/term v0.36.0/go.mod h1:Qu394IJq6V6dCBRgwqshf3mPF85AqzYEzofzRdZkWss= +golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc= +golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/term v0.37.0 h1:8EGAD0qCmHYZg6J17DvsMy9/wJ7/D/4pV/wfnld5lTU= +golang.org/x/term v0.37.0/go.mod h1:5pB4lxRNYYVZuTLmy8oR2BH8dflOR+IbTYFD8fi3254= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k= -golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM= +golang.org/x/text v0.31.0 h1:aC8ghyu4JhP8VojJ2lEHBnochRno1sgL6nEi9WGFGMM= +golang.org/x/text v0.31.0/go.mod h1:tKRAlv61yKIjGGHX/4tP1LTbc13YSec1pxVEWXzfoeM= golang.org/x/time v0.8.0 h1:9i3RxcPv3PZnitoVGMPDKZSq1xW1gK1Xy3ArNOGZfEg= golang.org/x/time v0.8.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -303,8 +321,8 @@ golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE= -golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w= +golang.org/x/tools v0.38.0 h1:Hx2Xv8hISq8Lm16jvBZ2VQf+RLmbd7wVUsALibYI/IQ= +golang.org/x/tools v0.38.0/go.mod h1:yEsQ/d/YK8cjh0L6rZlY8tgtlKiBNTL14pGDJPJpYQs= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -318,17 +336,17 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8 h1:M1rk8KBnUsBDg1oPGHNCxG4vc1f49epmTO7xscSajMk= -google.golang.org/genproto/googleapis/rpc v0.0.0-20251022142026-3a174f9686a8/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda h1:i/Q+bfisr7gq6feoJnS/DlpdwEL4ihp41fvRiM3Ork0= +google.golang.org/genproto/googleapis/rpc v0.0.0-20251029180050-ab9386a59fda/go.mod h1:7i2o+ce6H/6BluujYR+kqX3GKH+dChPTQU19wjRPiGk= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.77.0 h1:wVVY6/8cGA6vvffn+wWK5ToddbgdU3d8MNENr4evgXM= -google.golang.org/grpc v1.77.0/go.mod h1:z0BY1iVj0q8E1uSQCjL9cppRj+gnZjzDnzV0dHhrNig= -google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= -google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= +google.golang.org/grpc v1.78.0 h1:K1XZG/yGDJnzMdd/uZHAkVqJE+xIDOcmdSFZkBUicNc= +google.golang.org/grpc v1.78.0/go.mod h1:I47qjTo4OKbMkjA/aOOwxDIiPSBofUtQUI5EfpWvW7U= +google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= +google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= diff --git a/main.go b/main.go index 724bd8fe..717e8315 100644 --- a/main.go +++ b/main.go @@ -30,7 +30,6 @@ import ( "github.com/go-logr/logr" "github.com/sdcio/data-server/pkg/config" "github.com/sdcio/data-server/pkg/server" - "github.com/sdcio/logger" logf "github.com/sdcio/logger" "github.com/spf13/pflag" ) @@ -61,10 +60,10 @@ func main() { ReplaceAttr: logf.ReplaceTimeAttr, } if debug { - slogOpts.Level = slog.Level(-logger.VDebug) + slogOpts.Level = slog.Level(-logf.VDebug) } if trace { - slogOpts.Level = slog.Level(-logger.VTrace) + slogOpts.Level = slog.Level(-logf.VTrace) } log := logr.FromSlogHandler(slog.NewJSONHandler(os.Stdout, slogOpts)) diff --git a/pkg/datastore/target/netconf/xml2SchemapbAdapter.go b/pkg/datastore/target/netconf/xml2SchemapbAdapter.go index 6828fa66..ee7e5b48 100644 --- a/pkg/datastore/target/netconf/xml2SchemapbAdapter.go +++ b/pkg/datastore/target/netconf/xml2SchemapbAdapter.go @@ -21,7 +21,6 @@ import ( "github.com/beevik/etree" schemaClient "github.com/sdcio/data-server/pkg/datastore/clients/schema" - "github.com/sdcio/data-server/pkg/utils" logf "github.com/sdcio/logger" sdcpb "github.com/sdcio/sdc-protos/sdcpb" ) @@ -123,7 +122,7 @@ func (x *XML2sdcpbConfigAdapter) transformContainer(ctx context.Context, e *etre if cPElem[len(cPElem)-1].Key == nil { cPElem[len(cPElem)-1].Key = map[string]string{} } - tv, err := utils.Convert(ctx, e.FindElement("./"+ls.Name).Text(), ls.Type) + tv, err := sdcpb.TVFromString(ls.Type, e.FindElement("./"+ls.Name).Text(), 0) if err != nil { return err } @@ -209,7 +208,7 @@ func (x *XML2sdcpbConfigAdapter) transformField(ctx context.Context, e *etree.El } // process terminal values - tv, err := utils.Convert(ctx, e.Text(), schemaLeafType) + tv, err := sdcpb.TVFromString(schemaLeafType, e.Text(), 0) if err != nil { return fmt.Errorf("unable to convert value [%s] at path [%s] according to SchemaLeafType [%+v]: %w", e.Text(), e.GetPath(), schemaLeafType, err) } @@ -244,7 +243,7 @@ func (x *XML2sdcpbConfigAdapter) transformLeafList(ctx context.Context, e *etree // process terminal values data := strings.TrimSpace(e.Text()) - tv, err := utils.Convert(ctx, data, slt) + tv, err := sdcpb.TVFromString(slt, data, 0) if err != nil { return fmt.Errorf("failed to convert value %s to type %s: %w", data, slt.Type, err) } diff --git a/pkg/tree/default_value.go b/pkg/tree/default_value.go index 22f0e812..62276ca4 100644 --- a/pkg/tree/default_value.go +++ b/pkg/tree/default_value.go @@ -5,7 +5,6 @@ import ( "fmt" "github.com/sdcio/data-server/pkg/tree/types" - "github.com/sdcio/data-server/pkg/utils" sdcpb "github.com/sdcio/sdc-protos/sdcpb" ) @@ -28,7 +27,7 @@ func DefaultValueRetrieve(ctx context.Context, schema *sdcpb.SchemaElem, path *s if defaultVal == "" { return nil, fmt.Errorf("no defaults defined for schema path: %s", path.ToXPath(false)) } - tv, err = utils.Convert(ctx, defaultVal, schem.Field.GetType()) + tv, err = sdcpb.TVFromString(schem.Field.GetType(), defaultVal, 0) if err != nil { return nil, err } @@ -39,7 +38,7 @@ func DefaultValueRetrieve(ctx context.Context, schema *sdcpb.SchemaElem, path *s } tvlist := make([]*sdcpb.TypedValue, 0, len(listDefaults)) for _, dv := range schem.Leaflist.GetDefaults() { - tvelem, err := utils.Convert(ctx, dv, schem.Leaflist.GetType()) + tvelem, err := sdcpb.TVFromString(schem.Leaflist.GetType(), dv, 0) if err != nil { return nil, fmt.Errorf("error converting default to typed value for %s, type: %s ; value: %s; err: %v", path.ToXPath(false), schem.Leaflist.GetType().GetTypeName(), dv, err) } diff --git a/pkg/tree/importer/xml/xml_tree_importer.go b/pkg/tree/importer/xml/xml_tree_importer.go index 1e78b955..3ca4dc36 100644 --- a/pkg/tree/importer/xml/xml_tree_importer.go +++ b/pkg/tree/importer/xml/xml_tree_importer.go @@ -5,7 +5,6 @@ import ( "github.com/beevik/etree" "github.com/sdcio/data-server/pkg/tree/importer" - "github.com/sdcio/data-server/pkg/utils" sdcpb "github.com/sdcio/sdc-protos/sdcpb" ) @@ -51,7 +50,7 @@ func (x *XmlTreeImporter) GetKeyValue() (string, error) { } func (x *XmlTreeImporter) GetTVValue(ctx context.Context, slt *sdcpb.SchemaLeafType) (*sdcpb.TypedValue, error) { - return utils.Convert(ctx, x.elem.Text(), slt) + return sdcpb.TVFromString(slt, x.elem.Text(), 0) } func (x *XmlTreeImporter) GetName() string { diff --git a/pkg/tree/sharedEntryAttributes.go b/pkg/tree/sharedEntryAttributes.go index d8025333..b813424f 100644 --- a/pkg/tree/sharedEntryAttributes.go +++ b/pkg/tree/sharedEntryAttributes.go @@ -18,6 +18,7 @@ import ( "github.com/sdcio/data-server/pkg/utils" logf "github.com/sdcio/logger" sdcpb "github.com/sdcio/sdc-protos/sdcpb" + sdcpbutils "github.com/sdcio/sdc-protos/utils" "github.com/sdcio/sdc-protos/tree_persist" ) @@ -249,7 +250,7 @@ func (s *sharedEntryAttributes) checkAndCreateKeysAsLeafs(ctx context.Context, i } // convert the key value to the schema defined Typed_Value - tv, err := utils.Convert(ctx, item.PathName(), k.GetType()) + tv, err := sdcpb.TVFromString(k.GetType(), item.PathName(), 0) if err != nil { return err } @@ -1047,7 +1048,7 @@ func (s *sharedEntryAttributes) validateRange(resultChan chan<- *types.Validatio switch typeSchema.TypeName { case "uint8", "uint16", "uint32", "uint64": // procede with the unsigned ints - urnges := utils.NewUrnges() + urnges := sdcpbutils.NewRnges[uint64]() // add the defined ranges to the ranges struct for _, r := range typeSchema.GetRange() { urnges.AddRange(r.Min.Value, r.Max.Value) @@ -1061,7 +1062,7 @@ func (s *sharedEntryAttributes) validateRange(resultChan chan<- *types.Validatio case "int8", "int16", "int32", "int64": // procede with the signed ints - srnges := utils.NewSrnges() + srnges := sdcpbutils.NewRnges[int64]() for _, r := range typeSchema.GetRange() { // get the value min := int64(r.GetMin().GetValue()) diff --git a/pkg/utils/converter.go b/pkg/utils/converter.go index 8586e586..1f056d6a 100644 --- a/pkg/utils/converter.go +++ b/pkg/utils/converter.go @@ -4,10 +4,8 @@ import ( "bytes" "context" "encoding/json" - "errors" "fmt" "reflect" - "strconv" "strings" "github.com/sdcio/logger" @@ -88,7 +86,7 @@ func (c *Converter) ExpandUpdate(ctx context.Context, upd *sdcpb.Update) ([]*sdc return nil, err } // convert key string value to real typedvalue - newUpd.Value, err = ConvertToTypedValue(rsp.GetSchema(), v, 0) + newUpd.Value, err = sdcpb.SchemaElemToTV(rsp.GetSchema(), v, 0) if err != nil { return nil, err } @@ -149,18 +147,16 @@ func (c *Converter) ExpandUpdate(ctx context.Context, upd *sdcpb.Update) ([]*sdc upd.Value = &sdcpb.TypedValue{Value: &sdcpb.TypedValue_StringVal{StringVal: string(jsonValue)}} } - if upd.Value.GetStringVal() != "" && rsp.Field.GetType().GetTypeName() != "string" { - upd.Value, err = Convert(ctx, upd.GetValue().GetStringVal(), rsp.Field.GetType()) - if err != nil { - return nil, err - } - } - // We expect that all identityrefs are sent by schema-server as a identityref type now, not string - if rsp.Field.GetType().Type == "identityref" && upd.GetValue().GetStringVal() != "" { - upd.Value, err = Convert(ctx, upd.GetValue().GetStringVal(), rsp.Field.GetType()) - if err != nil { - return nil, err + if upd.GetValue().GetStringVal() != "" { + switch { + case rsp.Field.GetType().GetTypeName() != "string", + rsp.Field.GetType().Type == "identityref": + + upd.Value, err = sdcpb.TVFromString(rsp.Field.GetType(), upd.GetValue().GetStringVal(), 0) + if err != nil { + return nil, err + } } } @@ -204,7 +200,7 @@ func (c *Converter) ExpandUpdateKeysAsLeaf(ctx context.Context, upd *sdcpb.Updat return nil, err } - intUpd.Value, err = TypedValueToYANGType(&sdcpb.TypedValue{Value: &sdcpb.TypedValue_StringVal{StringVal: v}}, schemaRsp.GetSchema()) + intUpd.Value, err = sdcpb.SchemaElemToTV(schemaRsp.GetSchema(), v, 0) if err != nil { return nil, err } @@ -307,7 +303,7 @@ func (c *Converter) ExpandContainerValue(ctx context.Context, p *sdcpb.Path, jv if err != nil { return nil, err } - upd.Value, err = TypedValueToYANGType(&sdcpb.TypedValue{Value: &sdcpb.TypedValue_StringVal{StringVal: fmt.Sprintf("%v", v)}}, schemaRsp.GetSchema()) + upd.Value, err = sdcpb.SchemaElemToTV(schemaRsp.GetSchema(), fmt.Sprintf("%v", v), 0) if err != nil { return nil, err } @@ -332,12 +328,7 @@ func (c *Converter) ExpandContainerValue(ctx context.Context, p *sdcpb.Path, jv switch x := v.(type) { case []any: for _, e := range x { - tv := &sdcpb.TypedValue{ - Value: &sdcpb.TypedValue_StringVal{ - StringVal: fmt.Sprintf("%v", e), - }, - } - tvYangType, err := TypedValueToYANGType(tv, se) + tvYangType, err := sdcpb.SchemaElemToTV(se, fmt.Sprintf("%v", e), 0) if err != nil { return nil, err } @@ -411,148 +402,6 @@ func (c *Converter) ExpandContainerValue(ctx context.Context, p *sdcpb.Path, jv } } -func TypedValueToYANGType(tv *sdcpb.TypedValue, schemaObject *sdcpb.SchemaElem) (*sdcpb.TypedValue, error) { - switch tv.Value.(type) { - case *sdcpb.TypedValue_AsciiVal: - return ConvertToTypedValue(schemaObject, tv.GetAsciiVal(), tv.GetTimestamp()) - case *sdcpb.TypedValue_BoolVal: - return tv, nil - case *sdcpb.TypedValue_BytesVal: - return tv, nil - case *sdcpb.TypedValue_DecimalVal: - return tv, nil - case *sdcpb.TypedValue_FloatVal: - return tv, nil - case *sdcpb.TypedValue_DoubleVal: - return tv, nil - case *sdcpb.TypedValue_IntVal: - return tv, nil - case *sdcpb.TypedValue_StringVal: - return ConvertToTypedValue(schemaObject, tv.GetStringVal(), tv.GetTimestamp()) - case *sdcpb.TypedValue_UintVal: - return tv, nil - case *sdcpb.TypedValue_JsonIetfVal: // TODO: - case *sdcpb.TypedValue_JsonVal: // TODO: - case *sdcpb.TypedValue_LeaflistVal: - return tv, nil - case *sdcpb.TypedValue_ProtoBytes: - return tv, nil - case *sdcpb.TypedValue_AnyVal: - return tv, nil - case *sdcpb.TypedValue_IdentityrefVal: - return ConvertToTypedValue(schemaObject, tv.GetStringVal(), tv.GetTimestamp()) - } - return tv, nil -} - -func ConvertToTypedValue(schemaObject *sdcpb.SchemaElem, v string, ts uint64) (*sdcpb.TypedValue, error) { - var schemaType *sdcpb.SchemaLeafType - switch { - case schemaObject.GetField() != nil: - schemaType = schemaObject.GetField().GetType() - case schemaObject.GetLeaflist() != nil: - schemaType = schemaObject.GetLeaflist().GetType() - case schemaObject.GetContainer() != nil: - if !schemaObject.GetContainer().IsPresence { - return nil, errors.New("non presence container update") - } - return nil, nil - } - return convertStringToTv(schemaType, v, ts) -} - -func convertStringToTv(schemaType *sdcpb.SchemaLeafType, v string, ts uint64) (*sdcpb.TypedValue, error) { - // convert field or leaf-list schema elem - switch schemaType.GetType() { - case "string": - return &sdcpb.TypedValue{ - - Value: &sdcpb.TypedValue_StringVal{StringVal: v}, - }, nil - case "uint64", "uint32", "uint16", "uint8": - i, err := strconv.ParseUint(v, 10, 64) - if err != nil { - return nil, err - } - return &sdcpb.TypedValue{ - Timestamp: ts, - Value: &sdcpb.TypedValue_UintVal{UintVal: i}, - }, nil - case "int64", "int32", "int16", "int8": - i, err := strconv.ParseInt(v, 10, 64) - if err != nil { - return nil, err - } - return &sdcpb.TypedValue{ - Timestamp: ts, - Value: &sdcpb.TypedValue_IntVal{IntVal: i}, - }, nil - case "boolean": - b, err := strconv.ParseBool(v) - if err != nil { - return nil, err - } - return &sdcpb.TypedValue{ - Timestamp: ts, - Value: &sdcpb.TypedValue_BoolVal{BoolVal: b}, - }, nil - case "decimal64": - decimalVal, err := ParseDecimal64(v) - if err != nil { - return nil, err - } - return &sdcpb.TypedValue{ - Value: &sdcpb.TypedValue_DecimalVal{ - DecimalVal: decimalVal, - }, - }, nil - case "identityref": - before, name, found := strings.Cut(v, ":") - if !found { - name = before - } - prefix, ok := schemaType.IdentityPrefixesMap[name] - if !ok { - identities := make([]string, 0, len(schemaType.IdentityPrefixesMap)) - for k := range schemaType.IdentityPrefixesMap { - identities = append(identities, k) - } - return nil, fmt.Errorf("identity %s not found, possible values are %s", v, strings.Join(identities, ", ")) - } - module, ok := schemaType.ModulePrefixMap[name] - if !ok { - identities := make([]string, 0, len(schemaType.IdentityPrefixesMap)) - for k := range schemaType.IdentityPrefixesMap { - identities = append(identities, k) - } - return nil, fmt.Errorf("identity %s not found, possible values are %s", v, strings.Join(identities, ", ")) - } - return &sdcpb.TypedValue{ - Timestamp: ts, - Value: &sdcpb.TypedValue_IdentityrefVal{IdentityrefVal: &sdcpb.IdentityRef{Value: name, Prefix: prefix, Module: module}}, - }, nil - case "leafref": - return convertStringToTv(schemaType.LeafrefTargetType, v, ts) - case "union": - for _, ut := range schemaType.GetUnionTypes() { - tv, err := convertStringToTv(ut, v, ts) - if err == nil { - return tv, nil - } - } - return nil, fmt.Errorf("invalid value %s for union type: %v", v, schemaType) - case "enumeration": - // TODO: get correct type, assuming string - return &sdcpb.TypedValue{ - Timestamp: ts, - Value: &sdcpb.TypedValue_StringVal{StringVal: v}, - }, nil - case "": // presence ? - return &sdcpb.TypedValue{}, nil - } - return nil, nil -} - func getItem(ctx context.Context, s string, cs *sdcpb.SchemaElem_Container, scb SchemaClientBound) (any, bool) { f, ok := getField(s, cs) if ok { diff --git a/pkg/utils/leaf_convert.go b/pkg/utils/leaf_convert.go index 44dea401..89e89aef 100644 --- a/pkg/utils/leaf_convert.go +++ b/pkg/utils/leaf_convert.go @@ -15,368 +15,14 @@ package utils import ( - "context" "fmt" - "math" - "regexp" "strconv" "strings" - logf "github.com/sdcio/logger" sdcpb "github.com/sdcio/sdc-protos/sdcpb" "google.golang.org/protobuf/types/known/emptypb" ) -func Convert(ctx context.Context, value string, lst *sdcpb.SchemaLeafType) (*sdcpb.TypedValue, error) { - log := logf.FromContext(ctx) - if lst == nil { - return nil, fmt.Errorf("schemaleaftype cannot be nil") - } - switch lst.Type { - case "string": - return ConvertString(ctx, value, lst) - case "union": - return ConvertUnion(ctx, value, lst.UnionTypes) - case "boolean": - return ConvertBoolean(value, lst) - case "int8": - // TODO: HEX and OCTAL pre-processing for all INT types - // https://www.rfc-editor.org/rfc/rfc6020.html#page-112 - return ConvertInt8(value, lst) - case "int16": - return ConvertInt16(value, lst) - case "int32": - return ConvertInt32(value, lst) - case "int64": - return ConvertInt64(value, lst) - case "uint8": - return ConvertUint8(value, lst) - case "uint16": - return ConvertUint16(value, lst) - case "uint32": - return ConvertUint32(value, lst) - case "uint64": - // TODO: fraction-digits (https://www.rfc-editor.org/rfc/rfc6020.html#section-9.3.4) - return ConvertUint64(value, lst) - case "enumeration": - return ConvertEnumeration(value, lst) - case "empty": - return &sdcpb.TypedValue{Value: &sdcpb.TypedValue_EmptyVal{}}, nil - case "bits": - return ConvertBits(value, lst) - case "binary": // https://www.rfc-editor.org/rfc/rfc6020.html#section-9.8 - return ConvertBinary(ctx, value, lst) - case "leafref": // https://www.rfc-editor.org/rfc/rfc6020.html#section-9.9 - // leafrefs are being treated as strings. - // further validation needs to happen later in the process - return ConvertLeafRef(ctx, value, lst) - case "identityref": //TODO: https://www.rfc-editor.org/rfc/rfc6020.html#section-9.10 - return ConvertIdentityRef(value, lst) - case "instance-identifier": //TODO: https://www.rfc-editor.org/rfc/rfc6020.html#section-9.13 - return ConvertInstanceIdentifier(ctx, value, lst) - case "decimal64": - return ConvertDecimal64(value, lst) - } - log.V(logf.VDebug).Info("type conversion not implemented", "type", lst.Type) - return ConvertString(ctx, value, lst) -} - -func ConvertInstanceIdentifier(ctx context.Context, value string, slt *sdcpb.SchemaLeafType) (*sdcpb.TypedValue, error) { - // delegate to string, validation is left for a different party at a later stage in processing - return ConvertString(ctx, value, slt) -} - -func ConvertIdentityRef(value string, slt *sdcpb.SchemaLeafType) (*sdcpb.TypedValue, error) { - return convertStringToTv(slt, value, 0) -} - -func ConvertBinary(ctx context.Context, value string, slt *sdcpb.SchemaLeafType) (*sdcpb.TypedValue, error) { - // Binary is basically a base64 encoded string that might carry a length restriction - // so we should be fine with delegating to string - return ConvertString(ctx, value, slt) -} - -func ConvertLeafRef(ctx context.Context, value string, slt *sdcpb.SchemaLeafType) (*sdcpb.TypedValue, error) { - // a leafref should basically be a string value that also exists somewhere else in the config as a value. - // we leave the validation of the leafrefs to a different party at a later stage - return ConvertString(ctx, value, slt) -} - -func ConvertEnumeration(value string, slt *sdcpb.SchemaLeafType) (*sdcpb.TypedValue, error) { - // iterate the valid values as per schema - for _, item := range slt.EnumNames { - // if value is found, return a StringVal - if value == item { - return &sdcpb.TypedValue{ - Value: &sdcpb.TypedValue_StringVal{ - StringVal: value, - }, - }, nil - } - } - // If value is not found return an error - return nil, fmt.Errorf("value %q does not match any valid enum values [%s]", value, strings.Join(slt.EnumNames, ", ")) -} - -func ConvertBoolean(value string, _ *sdcpb.SchemaLeafType) (*sdcpb.TypedValue, error) { - bval, err := strconv.ParseBool(value) - if err != nil { - // if it is any other value, return error - return nil, err - } - // otherwise return the BoolVal TypedValue - return &sdcpb.TypedValue{ - Value: &sdcpb.TypedValue_BoolVal{ - BoolVal: bval, - }, - }, nil -} - -func ConvertSdcpbNumberToUint64(mm *sdcpb.Number) (uint64, error) { - if mm.Negative { - return 0, fmt.Errorf("negative number to uint conversion") - } - return mm.Value, nil -} - -func intAbs(x int64) uint64 { - ui := uint64(x) - if x < 0 { - return ^(ui) + 1 - } - return ui -} - -func ConvertSdcpbNumberToInt64(mm *sdcpb.Number) (int64, error) { - if mm.Negative { - if mm.Value > intAbs(math.MinInt64) { - return 0, fmt.Errorf("error converting -%d to int64: overflow", mm.Value) - } - return -int64(mm.Value), nil - } - - if mm.Value > math.MaxInt64 { - return 0, fmt.Errorf("error converting %d to int64 overflow", mm.Value) - } - return int64(mm.Value), nil -} - -func convertUint(value string, minMaxs []*sdcpb.SchemaMinMaxType, ranges *URnges) (*sdcpb.TypedValue, error) { - if ranges == nil { - ranges = NewUrnges() - } - for _, x := range minMaxs { - min, err := ConvertSdcpbNumberToUint64(x.Min) - if err != nil { - return nil, err - } - max, err := ConvertSdcpbNumberToUint64(x.Max) - if err != nil { - return nil, err - } - ranges.AddRange(min, max) - } - - // validate the value against the ranges - val, err := ranges.IsWithinAnyRangeString(value) - if err != nil { - return nil, err - } - // return the TypedValue - return val, nil -} - -func ConvertUint8(value string, lst *sdcpb.SchemaLeafType) (*sdcpb.TypedValue, error) { - // create the ranges - ranges := NewUrnges() - ranges.AddRange(0, math.MaxUint8) - - return convertUint(value, lst.Range, ranges) -} - -func ConvertUint16(value string, lst *sdcpb.SchemaLeafType) (*sdcpb.TypedValue, error) { - // create the ranges - ranges := NewUrnges() - ranges.AddRange(0, math.MaxUint16) - - return convertUint(value, lst.Range, ranges) -} - -func ConvertUint32(value string, lst *sdcpb.SchemaLeafType) (*sdcpb.TypedValue, error) { - // create the ranges - ranges := NewUrnges() - ranges.AddRange(0, math.MaxUint32) - - return convertUint(value, lst.Range, ranges) -} - -func ConvertUint64(value string, lst *sdcpb.SchemaLeafType) (*sdcpb.TypedValue, error) { - // create the ranges - ranges := NewUrnges() - - return convertUint(value, lst.Range, ranges) -} - -func convertInt(value string, minMaxs []*sdcpb.SchemaMinMaxType, ranges *SRnges) (*sdcpb.TypedValue, error) { - for _, x := range minMaxs { - min, err := ConvertSdcpbNumberToInt64(x.Min) - if err != nil { - return nil, err - } - max, err := ConvertSdcpbNumberToInt64(x.Max) - if err != nil { - return nil, err - } - ranges.AddRange(min, max) - } - - // validate the value against the ranges - val, err := ranges.IsWithinAnyRangeString(value) - if err != nil { - return nil, err - } - // return the TypedValue - return val, nil -} - -func ConvertInt8(value string, lst *sdcpb.SchemaLeafType) (*sdcpb.TypedValue, error) { - // create the ranges - ranges := NewSrnges() - ranges.AddRange(math.MinInt8, math.MaxInt8) - - return convertInt(value, lst.Range, ranges) -} - -func ConvertInt16(value string, lst *sdcpb.SchemaLeafType) (*sdcpb.TypedValue, error) { - // create the ranges - ranges := NewSrnges() - ranges.AddRange(math.MinInt16, math.MaxInt16) - - return convertInt(value, lst.Range, ranges) -} - -func ConvertInt32(value string, lst *sdcpb.SchemaLeafType) (*sdcpb.TypedValue, error) { - // create the ranges - ranges := NewSrnges() - ranges.AddRange(math.MinInt32, math.MaxInt32) - - return convertInt(value, lst.Range, ranges) -} -func ConvertInt64(value string, lst *sdcpb.SchemaLeafType) (*sdcpb.TypedValue, error) { - // create the ranges - ranges := NewSrnges() - - return convertInt(value, lst.Range, ranges) -} - -func XMLRegexConvert(s string) string { - - cTest := func(r rune, prev rune) bool { - // if ^ is not following a [ or if $ we want to return true - return (r == '^' && prev != '[') || r == '$' - } - - b := strings.Builder{} - b.Grow(len(s) + len(s)/4) - slashes := 0 - prevR := rune(0) - - for _, r := range s { - if r == '\\' { - slashes++ - prevR = r - b.WriteRune(r) - continue - } - - if cTest(r, prevR) && slashes%2 == 0 { - b.WriteRune('\\') - } - - slashes = 0 - prevR = r - b.WriteRune(r) - } - return b.String() -} - -func ConvertString(ctx context.Context, value string, lst *sdcpb.SchemaLeafType) (*sdcpb.TypedValue, error) { - log := logf.FromContext(ctx) - // check length of the string if the length property is set - // length will contain a range like string definition "5..60" or "7..10|40..45" - if len(lst.Length) != 0 { - _, err := convertUint(strconv.Itoa(len(value)), lst.Length, nil) - - if err != nil { - return nil, err - } - - } - - overallMatch := true - // If the type has multiple "pattern" statements, the expressions are - // ANDed together, i.e., all such expressions have to match. - for _, sp := range lst.Patterns { - // The set of metacharacters is not the same between XML schema and perl/python/go REs - // the set of metacharacters for XML is: .\?*+{}()[] (https://www.w3.org/TR/xmlschema-2/#dt-metac) - // the set of metacharacters defined in go is: \.+*?()|[]{}^$ (go/libexec/src/regexp/regexp.go:714) - // we need therefore to escape some values - // TODO check about '^' - - escaped := XMLRegexConvert(sp.Pattern) - re, err := regexp.Compile(escaped) - if err != nil { - log.Error(err, "unable to compile regex", "pattern", sp.Pattern) - } - match := re.MatchString(value) - // if it is a match and not inverted - // or it is not a match but inverted - // then this is valid - if (match && !sp.Inverted) || (!match && sp.Inverted) { - continue - } else { - overallMatch = false - break - } - } - if overallMatch { - return &sdcpb.TypedValue{ - Value: &sdcpb.TypedValue_StringVal{ - StringVal: value, - }, - }, nil - } - return nil, fmt.Errorf("%q does not match patterns", value) - -} - -func ConvertDecimal64(value string, lst *sdcpb.SchemaLeafType) (*sdcpb.TypedValue, error) { - d64, err := ParseDecimal64(value) - if err != nil { - return nil, err - } - - return &sdcpb.TypedValue{ - Value: &sdcpb.TypedValue_DecimalVal{ - DecimalVal: d64, - }, - }, nil -} - -func ConvertUnion(ctx context.Context, value string, slts []*sdcpb.SchemaLeafType) (*sdcpb.TypedValue, error) { - // iterate over the union types try to convert without error - for _, slt := range slts { - tv, err := Convert(ctx, value, slt) - // if no error type conversion was fine - if err != nil { - continue - } - // return the TypedValue - return tv, nil - } - return nil, fmt.Errorf("no union type fit the provided value %q", value) -} - func ConvertJsonValueToTv(d any, slt *sdcpb.SchemaLeafType) (*sdcpb.TypedValue, error) { var err error switch slt.Type { @@ -395,7 +41,7 @@ func ConvertJsonValueToTv(d any, slt *sdcpb.SchemaLeafType) (*sdcpb.TypedValue, if !ok { return nil, fmt.Errorf("error converting %v to string", v) } - return convertStringToTv(slt, v, 0) + return sdcpb.TVFromString(slt, v, 0) case "uint64", "uint32", "uint16", "uint8": var i uint64 switch v := d.(type) { @@ -492,49 +138,3 @@ func ConvertJsonValueToTv(d any, slt *sdcpb.SchemaLeafType) (*sdcpb.TypedValue, return nil, fmt.Errorf("error no case matched when converting from json to TV: %v, %v", d, slt) } - -func validateBitString(value string, allowed []*sdcpb.Bit) bool { - //split string to individual bits - bits := strings.Fields(value) - // empty string is fine - if len(bits) == 0 { - return true - } - // track pos inside allowed slice - pos := 0 - for _, b := range bits { - // increase pos until we get to an allowed bit or we reach the end of the slice - for pos < len(allowed) && allowed[pos].GetName() != b { - pos++ - } - // if we are at the end of the array, we did not validate - if pos == len(allowed) { - return false - } - //move past found element - pos++ - } - return true -} - -func ConvertBits(value string, slt *sdcpb.SchemaLeafType) (*sdcpb.TypedValue, error) { - if slt == nil { - return nil, fmt.Errorf("type information is nil") - } - if len(slt.Bits) == 0 { - return nil, fmt.Errorf("type information is missing bits information") - } - if validateBitString(value, slt.Bits) { - return &sdcpb.TypedValue{ - Value: &sdcpb.TypedValue_StringVal{ - StringVal: value, - }, - }, nil - } - // If value is not valid return an error - validBits := make([]string, 0, len(slt.Bits)) - for _, b := range slt.Bits { - validBits = append(validBits, b.GetName()) - } - return nil, fmt.Errorf("value %q does not follow required bit ordering [%s]", value, strings.Join(validBits, " ")) -} diff --git a/pkg/utils/leaf_convert_test.go b/pkg/utils/leaf_convert_test.go deleted file mode 100644 index 571a528e..00000000 --- a/pkg/utils/leaf_convert_test.go +++ /dev/null @@ -1,168 +0,0 @@ -package utils - -import ( - "reflect" - "testing" - - sdcpb "github.com/sdcio/sdc-protos/sdcpb" - "google.golang.org/protobuf/proto" -) - -func TestXMLRegexConvert(t *testing.T) { - - tests := []struct { - name string - in string - want string - }{ - { - name: "anchors become literals", - in: `^\d+$`, - want: `\^\d+\$`, - }, - { - name: "already-escaped anchors stay escaped", - in: `foo\$bar`, - want: `foo\$bar`, - }, - { - name: "caret in char class is left alone, dollar is escaped", - in: `[^\w]+$`, - want: `[^\w]+\$`, - }, - { - name: "caret later inside char class is escaped", - in: `[a^b]`, - want: `[a\^b]`, - }, - { - name: "caret escaped inside char class is escaped", - in: `[\^]`, - want: `[\^]`, - }, - { - name: "caret in char class multiple times, dollar is escaped", - in: `[^a^b]`, - want: `[^a\^b]`, - }, - { - name: "anchors preceded by a single back-slash stay escaped", - in: `\^test\$`, - want: `\^test\$`, - }, - { - name: "empty string", - in: ``, - want: ``, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - if got := XMLRegexConvert(tt.in); !reflect.DeepEqual(got, tt.want) { - t.Errorf("XMLRegexConvert() = %v, want %v", got, tt.want) - } - }) - } -} - -func TestValidateBitString(t *testing.T) { - ref := []*sdcpb.Bit{ - {Name: "a", Position: 0}, - {Name: "b", Position: 0}, - {Name: "c", Position: 0}, - } - - tests := []struct { - name string - input string - want bool - }{ - {"empty string", "", true}, - {"exact match", "a b c", true}, - {"skipped middle", "a c", true}, - {"single first element", "a", true}, - {"single last element", "c", true}, - {"out of order", "a c b", false}, - {"wrong order overall", "b c a", false}, - {"unknown single element", "d", false}, - {"unknown element in valid", "a c d", false}, - {"duplicate token", "a a", false}, - {"leading / trailing spaces", " a b ", true}, - {"input longer than schema", "a b c d", false}, - } - - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - got := validateBitString(tc.input, ref) - if got != tc.want { - t.Fatalf("validateBitString(%q) = %v, want %v", tc.input, got, tc.want) - } - }) - } -} - -func TestConvertBits(t *testing.T) { - slt := &sdcpb.SchemaLeafType{ - Bits: []*sdcpb.Bit{{Name: "a", Position: 0}, {Name: "b", Position: 1}, {Name: "c", Position: 2}}, - } - sltEmpty := &sdcpb.SchemaLeafType{} - - sTv := func(s string) *sdcpb.TypedValue { - return &sdcpb.TypedValue{Value: &sdcpb.TypedValue_StringVal{StringVal: s}} - } - - type inStruct struct { - value string - slt *sdcpb.SchemaLeafType - } - - tests := []struct { - name string - input inStruct - want *sdcpb.TypedValue - wantErr bool - }{ - { - "valid value", - inStruct{"a b c", slt}, - sTv("a b c"), - false, - }, - { - "invalid value", - inStruct{"c b a", slt}, - nil, - true, - }, - {"empty schema, empty input", - inStruct{"", sltEmpty}, - nil, - true, - }, - {"empty schema, non-empty input", - inStruct{"a", sltEmpty}, - nil, - true, - }, - {"nil schema pointer", - inStruct{"a", nil}, - nil, - true, - }, - } - - for _, tc := range tests { - t.Run(tc.name, func(t *testing.T) { - got, err := ConvertBits(tc.input.value, tc.input.slt) - if tc.wantErr && err == nil { - t.Fatalf("wanted error, got nil") - } - if !tc.wantErr && err != nil { - t.Fatalf("wanted no error, got %v", err) - } - if !proto.Equal(got, tc.want) { - t.Fatalf("ConvertBits(%q, %q) = %v, want %v", tc.input.value, tc.input.slt, got, tc.want) - } - }) - } -} diff --git a/pkg/utils/srnges.go b/pkg/utils/srnges.go deleted file mode 100644 index b66f192e..00000000 --- a/pkg/utils/srnges.go +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright 2024 Nokia -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package utils - -import ( - "fmt" - "strconv" - "strings" - - sdcpb "github.com/sdcio/sdc-protos/sdcpb" -) - -// urnges represents a collection of rng (range) -type SRnges struct { - rnges []*SRng -} - -// urng represents a single unsigned range -type SRng struct { - min int64 - max int64 -} - -func NewSrnges() *SRnges { - r := &SRnges{} - return r -} - -func (r *SRng) IsInRange(value int64) bool { - // return the result - return r.min <= value && value <= r.max -} - -func (r *SRng) String() string { - // return the result - return fmt.Sprintf("%d..%d", r.min, r.max) -} - -func (r *SRnges) IsWithinAnyRange(val int64) bool { - // if no ranges defined, return the tv - if len(r.rnges) == 0 { - return true - } - // check the ranges - for _, rng := range r.rnges { - if rng.IsInRange(val) { - return true - } - } - return false - -} - -func (r *SRnges) IsWithinAnyRangeString(value string) (*sdcpb.TypedValue, error) { - if len(value) == 0 { - return nil, nil - } - intValue, err := strconv.ParseInt(value, 10, 64) - if err != nil { - return nil, err - } - - // create the TypedValue already - tv := &sdcpb.TypedValue{ - Value: &sdcpb.TypedValue_IntVal{ - IntVal: intValue, - }, - } - if r.IsWithinAnyRange(intValue) { - return tv, nil - } - return nil, fmt.Errorf("%q not within ranges", value) -} - -func (r *SRnges) AddRange(min, max int64) { - // to make sure the value is in the general limits of the datatype uint8|16|32|64 - // we add the min max as a seperate additional range - r.rnges = append(r.rnges, &SRng{ - min: min, - max: max, - }) -} - -func (r *SRnges) String() string { - sb := &strings.Builder{} - sep := "" - sb.WriteString("[ ") - for _, ur := range r.rnges { - sb.WriteString(sep) - sb.WriteString(ur.String()) - sep = " | " - } - sb.WriteString(" ]") - return sb.String() -} diff --git a/pkg/utils/urnges.go b/pkg/utils/urnges.go deleted file mode 100644 index 4a3cfc49..00000000 --- a/pkg/utils/urnges.go +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright 2024 Nokia -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package utils - -import ( - "fmt" - "strconv" - "strings" - - sdcpb "github.com/sdcio/sdc-protos/sdcpb" -) - -// URnges represents a collection of rng (range) -type URnges struct { - rnges []*URng -} - -// URng represents a single unsigned range -type URng struct { - min uint64 - max uint64 -} - -func NewUrnges() *URnges { - r := &URnges{} - return r -} - -func (r *URng) IsInRange(value uint64) bool { - // return the result - return r.min <= value && value <= r.max -} - -func (r *URng) String() string { - // return the result - return fmt.Sprintf("%d..%d", r.min, r.max) -} - -func (r *URnges) IsWithinAnyRange(val uint64) bool { - // if no ranges defined, return the tv - if len(r.rnges) == 0 { - return true - } - // check the ranges - for _, rng := range r.rnges { - if rng.IsInRange(val) { - return true - } - } - return false -} - -func (r *URnges) IsWithinAnyRangeString(value string) (*sdcpb.TypedValue, error) { - if len(value) == 0 { - return nil, nil - } - uintValue, err := strconv.ParseUint(value, 10, 64) - if err != nil { - return nil, err - } - // create the TypedValue already - tv := &sdcpb.TypedValue{ - Value: &sdcpb.TypedValue_UintVal{ - UintVal: uintValue, - }, - } - - // if no ranges defined, return the tv - if len(r.rnges) == 0 { - return tv, nil - } - // check the ranges - for _, rng := range r.rnges { - if rng.IsInRange(uintValue) { - return tv, nil - } - } - return nil, fmt.Errorf("%q not within ranges", value) -} - -func (r *URnges) AddRange(min, max uint64) { - // to make sure the value is in the general limits of the datatype uint8|16|32|64 - // we add the min max as a seperate additional range - r.rnges = append(r.rnges, &URng{ - min: min, - max: max, - }) -} - -func (r *URnges) String() string { - sb := &strings.Builder{} - sep := "" - sb.WriteString("[ ") - for _, ur := range r.rnges { - sb.WriteString(sep) - sb.WriteString(ur.String()) - sep = ", " - } - sb.WriteString(" ]") - return sb.String() -}