From 577976dbff79031e31c64b220f5b5f08e0babe4b Mon Sep 17 00:00:00 2001 From: wenovus Date: Wed, 2 Aug 2023 12:26:37 -0700 Subject: [PATCH 01/15] Add Diff CLI --- cmd/check.go | 60 +++++ cmd/root.go | 72 ++++++ go.mod | 38 ++- go.sum | 452 +++++++++++++++++++++++++++++++++++- main.go | 21 ++ ocdiff/ocdiff.go | 244 +++++++++++++++++++ post_results/main.go | 152 ------------ post_results/misc-checks.go | 166 +++++++++++++ 8 files changed, 1034 insertions(+), 171 deletions(-) create mode 100644 cmd/check.go create mode 100644 cmd/root.go create mode 100644 main.go create mode 100644 ocdiff/ocdiff.go diff --git a/cmd/check.go b/cmd/check.go new file mode 100644 index 0000000..faa1998 --- /dev/null +++ b/cmd/check.go @@ -0,0 +1,60 @@ +// Copyright 2023 Google Inc. +// +// 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 cmd + +import ( + "fmt" + + "github.com/openconfig/models-ci/ocdiff" + "github.com/spf13/cobra" + "github.com/spf13/viper" +) + +// checkCmd represents the check command +// FIXME(wenbli): Update comments. +var checkCmd = &cobra.Command{ + Use: "diff", + Short: "A brief description of your command", + Long: `A longer description that spans multiple lines and likely contains examples +and usage of using your command. For example: + +Cobra is a CLI library for Go that empowers applications. +This application is a tool to generate the needed files +to quickly create a Cobra application.`, + RunE: func(cmd *cobra.Command, args []string) error { + viper.BindPFlags(cmd.Flags()) + report, err := ocdiff.ReportDiff(viper.GetStringSlice("oldp"), viper.GetStringSlice("newp"), viper.GetStringSlice("oldfiles"), viper.GetStringSlice("newfiles")) + if err != nil { + return err + } + + if viper.GetBool("disallowed-incompats") { + fmt.Printf(report.ReportDisallowedIncompats()) + } else { + fmt.Printf(report.ReportAll()) + } + return nil + }, +} + +func init() { + rootCmd.AddCommand(checkCmd) + + checkCmd.Flags().StringSlice("oldp", []string{}, "search path for old set of YANG files") + checkCmd.Flags().StringSlice("newp", []string{}, "search path for new set of YANG files") + checkCmd.Flags().StringSlice("oldfiles", []string{}, "comma-separated list of old YANG files") + checkCmd.Flags().StringSlice("newfiles", []string{}, "comma-separated list of new YANG files") + checkCmd.Flags().Bool("disallowed-incompats", false, "only show disallowed (per semver.org) backwards-incompatible changes. Note that the backwards-incompatible checks are not exhausive.") +} diff --git a/cmd/root.go b/cmd/root.go new file mode 100644 index 0000000..03a8f3f --- /dev/null +++ b/cmd/root.go @@ -0,0 +1,72 @@ +/* +Copyright © 2023 Google Inc. +*/ +package cmd + +import ( + "fmt" + "os" + + "github.com/spf13/cobra" + "github.com/spf13/viper" +) + +var cfgFile string + +// rootCmd represents the base command when called without any subcommands +var rootCmd = &cobra.Command{ + Use: "openconfig-models-ci", + Short: "A brief description of your application", + Long: `A longer description that spans multiple lines and likely contains +examples and usage of using your application. For example: + +Cobra is a CLI library for Go that empowers applications. +This application is a tool to generate the needed files +to quickly create a Cobra application.`, + // Uncomment the following line if your bare application + // has an action associated with it: + // Run: func(cmd *cobra.Command, args []string) { }, +} + +// Execute adds all child commands to the root command and sets flags appropriately. +// This is called by main.main(). It only needs to happen once to the rootCmd. +func Execute() { + err := rootCmd.Execute() + if err != nil { + os.Exit(1) + } +} + +func init() { + cobra.OnInitialize(initConfig) + + // Here you will define your flags and configuration settings. + // Cobra supports persistent flags, which, if defined here, + // will be global for your application. + + rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.openconfig-models-ci.yaml)") +} + +// initConfig reads in config file and ENV variables if set. +func initConfig() { + if cfgFile != "" { + // Use config file from the flag. + viper.SetConfigFile(cfgFile) + } else { + // Find home directory. + home, err := os.UserHomeDir() + cobra.CheckErr(err) + + // Search config in home directory with name ".openconfig-models-ci" (without extension). + viper.AddConfigPath(home) + viper.SetConfigType("yaml") + viper.SetConfigName(".openconfig-models-ci") + } + + viper.AutomaticEnv() // read in environment variables that match + + // If a config file is found, read it in. + if err := viper.ReadInConfig(); err == nil { + fmt.Fprintln(os.Stderr, "Using config file:", viper.ConfigFileUsed()) + } +} diff --git a/go.mod b/go.mod index 05cabe2..2dd6167 100644 --- a/go.mod +++ b/go.mod @@ -1,17 +1,39 @@ module github.com/openconfig/models-ci -go 1.14 +go 1.18 require ( github.com/Masterminds/semver/v3 v3.1.1 - github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b - github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0 - github.com/google/go-cmp v0.4.1 + github.com/golang/glog v1.1.0 + github.com/golang/protobuf v1.5.3 + github.com/google/go-cmp v0.5.9 github.com/google/go-github v17.0.0+incompatible - github.com/google/go-querystring v1.0.0 // indirect github.com/openconfig/gnmi v0.0.0-20200508230933-d19cebf5e7be github.com/openconfig/goyang v1.0.0 - golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d - google.golang.org/protobuf v1.21.0 - gopkg.in/yaml.v3 v3.0.0-20200506231410-2ff61e1afc86 + github.com/spf13/cobra v1.7.0 + github.com/spf13/viper v1.16.0 + golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b + golang.org/x/oauth2 v0.7.0 + google.golang.org/protobuf v1.30.0 + gopkg.in/yaml.v3 v3.0.1 +) + +require ( + github.com/fsnotify/fsnotify v1.6.0 // indirect + github.com/google/go-querystring v1.0.0 // indirect + github.com/hashicorp/hcl v1.0.0 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect + github.com/magiconair/properties v1.8.7 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/pelletier/go-toml/v2 v2.0.8 // indirect + github.com/spf13/afero v1.9.5 // indirect + github.com/spf13/cast v1.5.1 // indirect + github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/subosito/gotenv v1.4.2 // indirect + golang.org/x/net v0.10.0 // indirect + golang.org/x/sys v0.8.0 // indirect + golang.org/x/text v0.9.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect ) diff --git a/go.sum b/go.sum index 18f7e5a..f3eb6f0 100644 --- a/go.sum +++ b/go.sum @@ -1,36 +1,160 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/cenkalti/backoff/v4 v4.0.0/go.mod h1:eEew/i+1Q6OrCDZh3WiXYv3+nJwBASZ8Bog/87DQnVg= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= +github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= +github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= +github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE= +github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0 h1:aRz0NBceriICVtjhCgKkDvl+RudKu1CT6h0ZvUTrNfE= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1 h1:/exdXoGamhu5ONeUJH0deniYLWYvQwW66yvlfiiKTu0= github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY= github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/protobuf v3.11.4+incompatible/go.mod h1:lUQ9D1ePzbH2PrIS7ob/bjm9HXyH5WHB0Akwh7URreM= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +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/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= +github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/openconfig/gnmi v0.0.0-20200414194230-1597cc0f2600/go.mod h1:M/EcuapNQgvzxo1DDXHK4tx3QpYM/uG4l591v33jG2A= github.com/openconfig/gnmi v0.0.0-20200508230933-d19cebf5e7be h1:VEK8utxoyZu/hkpjLxvuBmK5yW3NmBo/v/Wu5VQAJVs= github.com/openconfig/gnmi v0.0.0-20200508230933-d19cebf5e7be/go.mod h1:M/EcuapNQgvzxo1DDXHK4tx3QpYM/uG4l591v33jG2A= @@ -39,56 +163,362 @@ github.com/openconfig/goyang v1.0.0 h1:nYaFu7BOAk/eQn4CgAUjgYPfp3J6CdXrBryp32E5C github.com/openconfig/goyang v1.0.0/go.mod h1:vX61x01Q46AzbZUzG617vWqh/cB+aisc+RrNkXRd3W8= github.com/openconfig/ygot v0.6.0/go.mod h1:o30svNf7O0xK+R35tlx95odkDmZWS9JyWWQSmIhqwAs= github.com/pborman/getopt v0.0.0-20190409184431-ee0cd42419d3/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= +github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= +github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= +github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= +github.com/spf13/cast v1.5.1 h1:R+kOtfhWQE6TVQzY+4D7wJLBgkdVasCEFxSUBYBYIlA= +github.com/spf13/cast v1.5.1/go.mod h1:b9PdjNptOpzXr7Rq1q9gJML/2cdGQAo69NKzQ10KN48= +github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= +github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= +github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.16.0 h1:rGGH0XDZhdUOryiDWjmIvUSWpbNqisK8Wk0Vyefw8hc= +github.com/spf13/viper v1.16.0/go.mod h1:yg78JgCJcbrQOvV9YLXgkLaZqUidkY9K+Dd1FofRzQg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= +github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8= +github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b h1:r+vk0EmXNmekl0S0BascoeeoHk/L7wmaW2QF90K+kYI= +golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a h1:GuSPYbZzB5/dcLNCwLQLsg3obCJtX9IJhpXkvY7kzk0= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/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-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.7.0 h1:qe6s0zUXlPX80/dITx3440hWZ7GwMwgDDyrSGTPJG/g= +golang.org/x/oauth2 v0.7.0/go.mod h1:hPLQkd9LyjfXTiRohC/41GhcFqxisoUQ99sCUOHO9x4= 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-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/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-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/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.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 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-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +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= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= 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.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0 h1:qdOKuR/EIArgaWNjetjgTzgVTAZ+S/WXVrq9HW9zimw= google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200506231410-2ff61e1afc86 h1:OfFoIUYv/me30yv7XlMy4F9RJw8DEm8WQ6QG1Ph4bH0= -gopkg.in/yaml.v3 v3.0.0-20200506231410-2ff61e1afc86/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/main.go b/main.go new file mode 100644 index 0000000..0bd47fe --- /dev/null +++ b/main.go @@ -0,0 +1,21 @@ +// Copyright 2023 Google Inc. +// +// 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 main + +import "github.com/openconfig/models-ci/cmd" + +func main() { + cmd.Execute() +} diff --git a/ocdiff/ocdiff.go b/ocdiff/ocdiff.go new file mode 100644 index 0000000..622c77b --- /dev/null +++ b/ocdiff/ocdiff.go @@ -0,0 +1,244 @@ +// Copyright 2023 Google Inc. +// +// 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. + +// ocdiff checks for backwards-compatibility between two sets of YANG +// files. +package ocdiff + +import ( + "fmt" + "strings" + + "github.com/Masterminds/semver/v3" + "github.com/openconfig/goyang/pkg/yang" + "github.com/openconfig/goyang/pkg/yangentry" + "golang.org/x/exp/slices" +) + +// ReportDiff returns a diff report given options for compiling two sets of +// YANG files. +func ReportDiff(oldpaths, newpaths, oldfiles, newfiles []string) (*DiffReport, error) { + oldEntries, oldModuleVersions, err := flattenedEntries(oldpaths, oldfiles) + if err != nil { + return nil, err + } + + newEntries, newModuleVersions, err := flattenedEntries(newpaths, newfiles) + if err != nil { + return nil, err + } + + return diffMaps(oldEntries, newEntries, oldModuleVersions, newModuleVersions), nil +} + +type YANGNode struct { + path string + schema *yang.Entry + allowIncompat bool +} + +type YANGNodeUpdate struct { + path string + oldSchema *yang.Entry + newSchema *yang.Entry + allowIncompat bool + incompatComments []string + oldVersion *semver.Version + NewVersion *semver.Version +} + +type DiffReport struct { + NewNodes []*YANGNode + UpdatedNodes []*YANGNodeUpdate + DeletedNodes []*YANGNode + OldModuleVersions map[string]*semver.Version + NewModuleVersions map[string]*semver.Version +} + +// ReportDisallowedIncompats reports any backward-incompatible changes disallowed by version increments. +func (r *DiffReport) ReportDisallowedIncompats() string { + r.Sort() + var b strings.Builder + for _, del := range r.DeletedNodes { + if !del.allowIncompat && (del.schema.IsLeaf() || del.schema.IsLeafList()) { + b.WriteString(fmt.Sprintf("leaf deleted: %s\n", del.schema.Path())) + } + } + for _, upd := range r.UpdatedNodes { + if !upd.allowIncompat && len(upd.incompatComments) > 0 { + b.WriteString(fmt.Sprintf("node updated %s: %s\n", upd.oldSchema.Path(), strings.Join(upd.incompatComments, "\n\t"))) + } + } + return b.String() +} + +// ReportAll reports all YANG changes. +func (r *DiffReport) ReportAll() string { + r.Sort() + var b strings.Builder + for _, del := range r.DeletedNodes { + if del.schema.IsLeaf() || del.schema.IsLeafList() { + b.WriteString(fmt.Sprintf("leaf deleted: %s\n", del.schema.Path())) + } + } + for _, upd := range r.UpdatedNodes { + if len(upd.incompatComments) > 0 { + b.WriteString(fmt.Sprintf("node updated %s: %s\n", upd.oldSchema.Path(), strings.Join(upd.incompatComments, "\n\t"))) + } else { + b.WriteString(fmt.Sprintf("node updated %s\n", upd.oldSchema.Path())) + } + } + for _, added := range r.NewNodes { + if added.schema.IsLeaf() || added.schema.IsLeafList() { + b.WriteString(fmt.Sprintf("leaf added: %s\n", added.schema.Path())) + } + } + return b.String() +} + +func (r *DiffReport) Sort() { + slices.SortFunc(r.NewNodes, func(a, b *YANGNode) int { return strings.Compare(a.path, b.path) }) + slices.SortFunc(r.DeletedNodes, func(a, b *YANGNode) int { return strings.Compare(a.path, b.path) }) + slices.SortFunc(r.UpdatedNodes, func(a, b *YANGNodeUpdate) int { return strings.Compare(a.path, b.path) }) +} + +func getKind(e *yang.Entry) string { + if e.Type != nil { + return fmt.Sprint(e.Type.Kind) + } else { + return fmt.Sprint(e.Kind) + } +} + +func (r *DiffReport) entryAllowsIncompat(e *yang.Entry) bool { + moduleName := belongingModule(yang.RootNode(e.Node)) + oldVersion, newVersion := r.OldModuleVersions[moduleName], r.NewModuleVersions[moduleName] + if oldVersion == nil || newVersion == nil { + // This happens if the openconfig-version is not found (e.g. in IETF modules). + return true + } + return oldVersion.Major() == 0 || oldVersion.Major() > newVersion.Major() +} + +func (r *DiffReport) addPair(o *yang.Entry, n *yang.Entry) error { + switch { + case o == nil && n == nil: + case o == nil: + r.NewNodes = append(r.NewNodes, &YANGNode{ + schema: n, + path: n.Path(), + }) + case n == nil: + r.DeletedNodes = append(r.DeletedNodes, &YANGNode{ + schema: o, + path: o.Path(), + allowIncompat: r.entryAllowsIncompat(o), + }) + default: + upd := &YANGNodeUpdate{ + oldSchema: o, + newSchema: n, + path: o.Path(), + allowIncompat: r.entryAllowsIncompat(o), + } + updated := false + if oldKind, newKind := getKind(o), getKind(n); oldKind != newKind { + upd.incompatComments = append(upd.incompatComments, fmt.Sprintf("type changed from %s to %s", oldKind, newKind)) + updated = true + } + if updated { + r.UpdatedNodes = append(r.UpdatedNodes, upd) + } + } + return nil +} + +// belongingModule returns the module name if m is a module and the belonging +// module name if m is a submodule. +func belongingModule(m *yang.Module) string { + if m.Kind() == "submodule" { + return m.BelongsTo.Name + } + return m.Name +} + +func getOpenConfigModuleVersion(e *yang.Entry) (*semver.Version, error) { + m, ok := e.Node.(*yang.Module) + if !ok { + return nil, fmt.Errorf("cannot convert entry %q to *yang.Module", e.Name) + } + + for _, e := range m.Extensions { + keywordParts := strings.Split(e.Keyword, ":") + if len(keywordParts) != 2 { + // Unrecognized extension declaration + continue + } + pfx, ext := strings.TrimSpace(keywordParts[0]), strings.TrimSpace(keywordParts[1]) + if ext == "openconfig-version" { + if extMod := yang.FindModuleByPrefix(m, pfx); extMod != nil && belongingModule(extMod) == "openconfig-extensions" { + v, err := semver.StrictNewVersion(e.Argument) + if err != nil { + return nil, err + } + return v, nil + } + } + } + return nil, fmt.Errorf("did not find openconfig-extensions:openconfig-version statement in module %q", m.Name) +} + +func flattenedEntries(paths, files []string) (map[string]*yang.Entry, map[string]*semver.Version, error) { + moduleEntryMap, errs := yangentry.Parse(files, paths) + if errs != nil { + return nil, nil, fmt.Errorf("%v", errs) + } + + moduleVersions := map[string]*semver.Version{} + var entries []*yang.Entry + for moduleName, entry := range moduleEntryMap { + entries = append(entries, flattenedEntriesAux(entry)...) + if version, err := getOpenConfigModuleVersion(entry); err == nil { + moduleVersions[moduleName] = version + } + } + + entryMap := map[string]*yang.Entry{} + for _, entry := range entries { + entryMap[entry.Path()] = entry + } + return entryMap, moduleVersions, nil +} + +func flattenedEntriesAux(entry *yang.Entry) []*yang.Entry { + entries := []*yang.Entry{entry} + for _, entry := range entry.Dir { + entries = append(entries, flattenedEntriesAux(entry)...) + } + return entries +} + +func diffMaps(oldEntries, newEntries map[string]*yang.Entry, oldModuleVersions, newModuleVersions map[string]*semver.Version) *DiffReport { + report := &DiffReport{ + OldModuleVersions: oldModuleVersions, + NewModuleVersions: newModuleVersions, + } + for path, oldEntry := range oldEntries { + report.addPair(oldEntry, newEntries[path]) + } + for path, newEntry := range newEntries { + report.addPair(oldEntries[path], newEntry) + } + return report +} diff --git a/post_results/main.go b/post_results/main.go index fbabae8..0d2f741 100644 --- a/post_results/main.go +++ b/post_results/main.go @@ -20,14 +20,12 @@ import ( "io/ioutil" "os" "path/filepath" - "sort" "strconv" "strings" "text/template" "log" - "github.com/Masterminds/semver/v3" "github.com/openconfig/models-ci/commonci" "github.com/openconfig/models-ci/util" ) @@ -118,156 +116,6 @@ func readFile(path string) (string, error) { return string(outBytes), nil } -// readYangFilesList reads a file containing a list of YANG files, and returns -// a slice of these files. An unrecognized line causes an error to be returned. -// The error checking is not robust, but should be sufficient for our limited use. -func readYangFilesList(path string) ([]string, error) { - filesStr, err := readFile(path) - if err != nil { - return nil, err - } - - fileMap := map[string]bool{} - for _, line := range strings.Split(filesStr, "\n") { - line = strings.TrimSpace(line) - if line == "" { - continue - } - fileSegments := strings.Split(line, "/") - yangFileName := strings.TrimSpace(fileSegments[len(fileSegments)-1]) - if !strings.HasSuffix(yangFileName, ".yang") { - return nil, fmt.Errorf("while parsing %s: unrecognized line, expected a path ending in a YANG file: %s", path, line) - } - fileMap[yangFileName] = true - } - - var files []string - for f := range fileMap { - files = append(files, f) - } - sort.Strings(files) - return files, nil -} - -// readGoyangVersionsLog returns a map of YANG files to file attributes as parsed from the log. -// The file should be a list of YANG file to space-separated attributes. -// e.g. -// foo.yang: openconfig-version:"1.2.3" revision-version:"2.3.4" -func readGoyangVersionsLog(logPath string, masterBranch bool, fileProperties map[string]map[string]string) error { - fileLog, err := readFile(logPath) - if err != nil { - return err - } - for _, line := range strings.Split(fileLog, "\n") { - line = strings.TrimSpace(line) - if line == "" { - continue - } - fileSegments := strings.SplitN(line, ":", 2) - yangFileName := strings.TrimSpace(fileSegments[0]) - if !strings.HasSuffix(yangFileName, ".yang") { - return fmt.Errorf("while parsing %s: unrecognized line heading %q, expected a \".yang:\" start to the line: %q", logPath, yangFileName, line) - } - propertyMap, ok := fileProperties[yangFileName] - if !ok { - propertyMap = map[string]string{} - fileProperties[yangFileName] = propertyMap - } - - if !masterBranch { - propertyMap["reachable"] = "true" - } - - for _, property := range strings.Fields(strings.TrimSpace(fileSegments[1])) { - segments := strings.SplitN(property, ":", 2) - if len(segments) != 2 { - return fmt.Errorf("while parsing %s: unrecognized property substring, expected \":\"\"\" separated by spaces: %q", logPath, property) - } - name, value := segments[0], segments[1] - if value[0] == '"' { - if len(value) == 1 || value[len(value)-1] != '"' { - return fmt.Errorf("while parsing %s: Got invalid property value format: %s -- if the property value starts with a quote, it is assumed to be an enclosing quote", logPath, property) - } - value = value[1 : len(value)-1] // Remove enclosing quotes. - } - switch name { - case "openconfig-version", "belonging-module", "latest-revision-version": - if masterBranch { - name = "master-" + name - } - propertyMap[name] = value - default: - log.Printf("skipped unrecognized YANG file property: %s", property) - } - } - } - return nil -} - -// checkSemverIncrease checks that newVersion is greater than the oldVersion -// according to semantic versioning rules. -// Note that any increase is fine, including jumps, e.g. 1.0.0 -> 1.0.2. -// If there isn't an increase, a descriptive error message is returned. -func checkSemverIncrease(oldVersion, newVersion, versionStringName string) (*semver.Version, *semver.Version, error) { - newV, err := semver.StrictNewVersion(newVersion) - if err != nil { - return nil, nil, fmt.Errorf("invalid version string: %q", newVersion) - } - oldV, err := semver.StrictNewVersion(oldVersion) - switch { - case err != nil: - return nil, nil, fmt.Errorf("unexpected error, base branch version string unparseable: %q", oldVersion) - case newV.Equal(oldV): - return nil, nil, fmt.Errorf("file updated but %s string not updated: %q", versionStringName, oldVersion) - case !newV.GreaterThan(oldV): - return nil, nil, fmt.Errorf("new semantic version not valid, old version: %q, new version: %q", oldVersion, newVersion) - default: - return oldV, newV, nil - } -} - -type fileAndVersion struct { - name string - version *semver.Version -} - -// versionGroupViolationsHTML returns the version violations where a group of -// module/submodule files don't have matching versions. -func versionGroupViolationsHTML(moduleFileGroups map[string][]fileAndVersion) []string { - var violations []string - - var modules []string - for m := range moduleFileGroups { - modules = append(modules, m) - } - sort.Strings(modules) - for _, moduleName := range modules { - latestVersion := semver.MustParse("0.0.0") - latestVersionModule := "" - for _, nameAndVersion := range moduleFileGroups[moduleName] { - if nameAndVersion.version.GreaterThan(latestVersion) { - latestVersion = nameAndVersion.version - latestVersionModule = nameAndVersion.name - } - } - latestVersionString := latestVersion.Original() - - var violation strings.Builder - for _, nameAndVersion := range moduleFileGroups[moduleName] { - if version := nameAndVersion.version.Original(); version != latestVersionString { - if violation.Len() != 0 { - violation.WriteString(",") - } - violation.WriteString(fmt.Sprintf(" %s (%s)", nameAndVersion.name, version)) - } - } - if violation.Len() != 0 { - violations = append(violations, sprintLineHTML("module set %s is at %s (%s), non-matching files:%s", moduleName, latestVersionString, latestVersionModule, violation.String())) - } - } - return violations -} - // processStandardOutput takes raw pyang/confd output and transforms it to an // HTML format for display on a GitHub gist comment. // Errors are displayed in front of warnings. diff --git a/post_results/misc-checks.go b/post_results/misc-checks.go index 9053aac..ced6494 100644 --- a/post_results/misc-checks.go +++ b/post_results/misc-checks.go @@ -1,8 +1,24 @@ +// Copyright 2023 Google Inc. +// +// 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 main import ( "fmt" + "log" "path/filepath" + "sort" "strings" "github.com/Masterminds/semver/v3" @@ -141,3 +157,153 @@ func processMiscChecksOutput(resultsDir string) (string, bool, versionRecordSlic return out.String(), pass, versionRecords, nil } + +// readYangFilesList reads a file containing a list of YANG files, and returns +// a slice of these files. An unrecognized line causes an error to be returned. +// The error checking is not robust, but should be sufficient for our limited use. +func readYangFilesList(path string) ([]string, error) { + filesStr, err := readFile(path) + if err != nil { + return nil, err + } + + fileMap := map[string]bool{} + for _, line := range strings.Split(filesStr, "\n") { + line = strings.TrimSpace(line) + if line == "" { + continue + } + fileSegments := strings.Split(line, "/") + yangFileName := strings.TrimSpace(fileSegments[len(fileSegments)-1]) + if !strings.HasSuffix(yangFileName, ".yang") { + return nil, fmt.Errorf("while parsing %s: unrecognized line, expected a path ending in a YANG file: %s", path, line) + } + fileMap[yangFileName] = true + } + + var files []string + for f := range fileMap { + files = append(files, f) + } + sort.Strings(files) + return files, nil +} + +// readGoyangVersionsLog returns a map of YANG files to file attributes as parsed from the log. +// The file should be a list of YANG file to space-separated attributes. +// e.g. +// foo.yang: openconfig-version:"1.2.3" revision-version:"2.3.4" +func readGoyangVersionsLog(logPath string, masterBranch bool, fileProperties map[string]map[string]string) error { + fileLog, err := readFile(logPath) + if err != nil { + return err + } + for _, line := range strings.Split(fileLog, "\n") { + line = strings.TrimSpace(line) + if line == "" { + continue + } + fileSegments := strings.SplitN(line, ":", 2) + yangFileName := strings.TrimSpace(fileSegments[0]) + if !strings.HasSuffix(yangFileName, ".yang") { + return fmt.Errorf("while parsing %s: unrecognized line heading %q, expected a \".yang:\" start to the line: %q", logPath, yangFileName, line) + } + propertyMap, ok := fileProperties[yangFileName] + if !ok { + propertyMap = map[string]string{} + fileProperties[yangFileName] = propertyMap + } + + if !masterBranch { + propertyMap["reachable"] = "true" + } + + for _, property := range strings.Fields(strings.TrimSpace(fileSegments[1])) { + segments := strings.SplitN(property, ":", 2) + if len(segments) != 2 { + return fmt.Errorf("while parsing %s: unrecognized property substring, expected \":\"\"\" separated by spaces: %q", logPath, property) + } + name, value := segments[0], segments[1] + if value[0] == '"' { + if len(value) == 1 || value[len(value)-1] != '"' { + return fmt.Errorf("while parsing %s: Got invalid property value format: %s -- if the property value starts with a quote, it is assumed to be an enclosing quote", logPath, property) + } + value = value[1 : len(value)-1] // Remove enclosing quotes. + } + switch name { + case "openconfig-version", "belonging-module", "latest-revision-version": + if masterBranch { + name = "master-" + name + } + propertyMap[name] = value + default: + log.Printf("skipped unrecognized YANG file property: %s", property) + } + } + } + return nil +} + +// checkSemverIncrease checks that newVersion is greater than the oldVersion +// according to semantic versioning rules. +// Note that any increase is fine, including jumps, e.g. 1.0.0 -> 1.0.2. +// If there isn't an increase, a descriptive error message is returned. +func checkSemverIncrease(oldVersion, newVersion, versionStringName string) (*semver.Version, *semver.Version, error) { + newV, err := semver.StrictNewVersion(newVersion) + if err != nil { + return nil, nil, fmt.Errorf("invalid version string: %q", newVersion) + } + oldV, err := semver.StrictNewVersion(oldVersion) + switch { + case err != nil: + return nil, nil, fmt.Errorf("unexpected error, base branch version string unparseable: %q", oldVersion) + case newV.Equal(oldV): + return nil, nil, fmt.Errorf("file updated but %s string not updated: %q", versionStringName, oldVersion) + case !newV.GreaterThan(oldV): + return nil, nil, fmt.Errorf("new semantic version not valid, old version: %q, new version: %q", oldVersion, newVersion) + default: + return oldV, newV, nil + } +} + +type fileAndVersion struct { + name string + version *semver.Version +} + +// versionGroupViolationsHTML returns the version violations where a group of +// module/submodule files don't have matching versions. +func versionGroupViolationsHTML(moduleFileGroups map[string][]fileAndVersion) []string { + var violations []string + + var modules []string + for m := range moduleFileGroups { + modules = append(modules, m) + } + sort.Strings(modules) + for _, moduleName := range modules { + latestVersion := semver.MustParse("0.0.0") + latestVersionModule := "" + for _, nameAndVersion := range moduleFileGroups[moduleName] { + if nameAndVersion.version.GreaterThan(latestVersion) { + latestVersion = nameAndVersion.version + latestVersionModule = nameAndVersion.name + } + } + latestVersionString := latestVersion.Original() + + var violation strings.Builder + for _, nameAndVersion := range moduleFileGroups[moduleName] { + if version := nameAndVersion.version.Original(); version != latestVersionString { + if violation.Len() != 0 { + violation.WriteString(",") + } + violation.WriteString(fmt.Sprintf(" %s (%s)", nameAndVersion.name, version)) + } + } + if violation.Len() != 0 { + violations = append(violations, sprintLineHTML("module set %s is at %s (%s), non-matching files:%s", moduleName, latestVersionString, latestVersionModule, violation.String())) + } + } + return violations +} From 4d8439d9c1dd944a04c1cf9faae7a58fa39e839e Mon Sep 17 00:00:00 2001 From: wenovus Date: Wed, 2 Aug 2023 12:58:50 -0700 Subject: [PATCH 02/15] use updated goyang --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 2dd6167..2f69efc 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/google/go-cmp v0.5.9 github.com/google/go-github v17.0.0+incompatible github.com/openconfig/gnmi v0.0.0-20200508230933-d19cebf5e7be - github.com/openconfig/goyang v1.0.0 + github.com/openconfig/goyang v1.3.1-0.20230802195157-66c4789eced9 github.com/spf13/cobra v1.7.0 github.com/spf13/viper v1.16.0 golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b diff --git a/go.sum b/go.sum index f3eb6f0..aebf7c9 100644 --- a/go.sum +++ b/go.sum @@ -159,8 +159,8 @@ github.com/openconfig/gnmi v0.0.0-20200414194230-1597cc0f2600/go.mod h1:M/EcuapN github.com/openconfig/gnmi v0.0.0-20200508230933-d19cebf5e7be h1:VEK8utxoyZu/hkpjLxvuBmK5yW3NmBo/v/Wu5VQAJVs= github.com/openconfig/gnmi v0.0.0-20200508230933-d19cebf5e7be/go.mod h1:M/EcuapNQgvzxo1DDXHK4tx3QpYM/uG4l591v33jG2A= github.com/openconfig/goyang v0.0.0-20200115183954-d0a48929f0ea/go.mod h1:dhXaV0JgHJzdrHi2l+w0fZrwArtXL7jEFoiqLEdmkvU= -github.com/openconfig/goyang v1.0.0 h1:nYaFu7BOAk/eQn4CgAUjgYPfp3J6CdXrBryp32E5CjI= -github.com/openconfig/goyang v1.0.0/go.mod h1:vX61x01Q46AzbZUzG617vWqh/cB+aisc+RrNkXRd3W8= +github.com/openconfig/goyang v1.3.1-0.20230802195157-66c4789eced9 h1:TWT6wGfCW4yTQaT7iVjbNCj2HR7DDBhFeENsc+P0BTU= +github.com/openconfig/goyang v1.3.1-0.20230802195157-66c4789eced9/go.mod h1:vX61x01Q46AzbZUzG617vWqh/cB+aisc+RrNkXRd3W8= github.com/openconfig/ygot v0.6.0/go.mod h1:o30svNf7O0xK+R35tlx95odkDmZWS9JyWWQSmIhqwAs= github.com/pborman/getopt v0.0.0-20190409184431-ee0cd42419d3/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= From fca23508b280e7e49ad017827c218b0e09f816c8 Mon Sep 17 00:00:00 2001 From: wenovus Date: Wed, 2 Aug 2023 13:06:25 -0700 Subject: [PATCH 03/15] Improve error msg --- cmd/check.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/cmd/check.go b/cmd/check.go index faa1998..389e2e3 100644 --- a/cmd/check.go +++ b/cmd/check.go @@ -16,6 +16,7 @@ package cmd import ( "fmt" + "os" "github.com/openconfig/models-ci/ocdiff" "github.com/spf13/cobra" @@ -41,7 +42,10 @@ to quickly create a Cobra application.`, } if viper.GetBool("disallowed-incompats") { - fmt.Printf(report.ReportDisallowedIncompats()) + if out := report.ReportDisallowedIncompats(); out != "" { + fmt.Printf("Backward-incompatible changes not covered by version increments per semver.org:\n%s", out) + os.Exit(1) + } } else { fmt.Printf(report.ReportAll()) } From 94a63b55556f323fbf7e1c00819e2c141371de33 Mon Sep 17 00:00:00 2001 From: wenovus Date: Thu, 3 Aug 2023 10:40:18 -0700 Subject: [PATCH 04/15] Add reason --- ocdiff/ocdiff.go | 74 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 49 insertions(+), 25 deletions(-) diff --git a/ocdiff/ocdiff.go b/ocdiff/ocdiff.go index 622c77b..4ad1093 100644 --- a/ocdiff/ocdiff.go +++ b/ocdiff/ocdiff.go @@ -43,19 +43,21 @@ func ReportDiff(oldpaths, newpaths, oldfiles, newfiles []string) (*DiffReport, e } type YANGNode struct { - path string - schema *yang.Entry - allowIncompat bool + path string + schema *yang.Entry + allowIncompat bool + allowOrDisallowIncompatReason string } type YANGNodeUpdate struct { - path string - oldSchema *yang.Entry - newSchema *yang.Entry - allowIncompat bool - incompatComments []string - oldVersion *semver.Version - NewVersion *semver.Version + path string + oldSchema *yang.Entry + newSchema *yang.Entry + allowIncompat bool + allowOrDisallowIncompatReason string + incompatComments []string + oldVersion *semver.Version + NewVersion *semver.Version } type DiffReport struct { @@ -72,12 +74,12 @@ func (r *DiffReport) ReportDisallowedIncompats() string { var b strings.Builder for _, del := range r.DeletedNodes { if !del.allowIncompat && (del.schema.IsLeaf() || del.schema.IsLeafList()) { - b.WriteString(fmt.Sprintf("leaf deleted: %s\n", del.schema.Path())) + b.WriteString(fmt.Sprintf("leaf deleted: %s (%s)\n", del.schema.Path(), del.allowOrDisallowIncompatReason)) } } for _, upd := range r.UpdatedNodes { if !upd.allowIncompat && len(upd.incompatComments) > 0 { - b.WriteString(fmt.Sprintf("node updated %s: %s\n", upd.oldSchema.Path(), strings.Join(upd.incompatComments, "\n\t"))) + b.WriteString(fmt.Sprintf("node updated %s (%s): %s\n", upd.oldSchema.Path(), upd.allowOrDisallowIncompatReason, strings.Join(upd.incompatComments, "\n\t"))) } } return b.String() @@ -121,14 +123,32 @@ func getKind(e *yang.Entry) string { } } -func (r *DiffReport) entryAllowsIncompat(e *yang.Entry) bool { - moduleName := belongingModule(yang.RootNode(e.Node)) +func definingModuleName(e *yang.Entry) string { + if definingModule := yang.RootNode(e.Node); definingModule != nil { + return definingModule.Name + } + return "" +} + +func (r *DiffReport) entryAllowsIncompat(e *yang.Entry) (bool, string) { + moduleName := definingModuleName(e) + //moduleName := belongingModule(yang.RootNode(e.Node)) oldVersion, newVersion := r.OldModuleVersions[moduleName], r.NewModuleVersions[moduleName] - if oldVersion == nil || newVersion == nil { - // This happens if the openconfig-version is not found (e.g. in IETF modules). - return true + + switch { + case oldVersion == nil, newVersion == nil: + // This can happen if the openconfig-version is not found (e.g. in IETF modules). + // + // In other cases, we will just be conservative and allow the + // incompatibility since we don't want to block the PR. + return true, fmt.Sprintf("%q: oldVersion (%v) or newVersion (%v) is nil", moduleName, oldVersion, newVersion) + case oldVersion.Major() == 0: + return true, fmt.Sprintf("%q: oldVersion is at version 0 (%v)", moduleName, oldVersion) + case newVersion.Major() > oldVersion.Major(): + return true, fmt.Sprintf("%q: newVersion incremented major version (%v -> %v)", moduleName, oldVersion, newVersion) + default: + return false, fmt.Sprintf("%q: oldVersion (%v) -> newVersion (%v) does not allow for backwards-incompatible changes", moduleName, oldVersion, newVersion) } - return oldVersion.Major() == 0 || oldVersion.Major() > newVersion.Major() } func (r *DiffReport) addPair(o *yang.Entry, n *yang.Entry) error { @@ -140,17 +160,21 @@ func (r *DiffReport) addPair(o *yang.Entry, n *yang.Entry) error { path: n.Path(), }) case n == nil: + allowIncompat, allowOrDisallowIncompatReason := r.entryAllowsIncompat(o) r.DeletedNodes = append(r.DeletedNodes, &YANGNode{ - schema: o, - path: o.Path(), - allowIncompat: r.entryAllowsIncompat(o), + schema: o, + path: o.Path(), + allowIncompat: allowIncompat, + allowOrDisallowIncompatReason: allowOrDisallowIncompatReason, }) default: + allowIncompat, allowOrDisallowIncompatReason := r.entryAllowsIncompat(o) upd := &YANGNodeUpdate{ - oldSchema: o, - newSchema: n, - path: o.Path(), - allowIncompat: r.entryAllowsIncompat(o), + oldSchema: o, + newSchema: n, + path: o.Path(), + allowIncompat: allowIncompat, + allowOrDisallowIncompatReason: allowOrDisallowIncompatReason, } updated := false if oldKind, newKind := getKind(o), getKind(n); oldKind != newKind { From 15b19a40ef2ee1062549c6e151c18986c0db64bd Mon Sep 17 00:00:00 2001 From: wenovus Date: Thu, 3 Aug 2023 10:58:12 -0700 Subject: [PATCH 05/15] Add banner --- cmd/check.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/check.go b/cmd/check.go index 389e2e3..1335945 100644 --- a/cmd/check.go +++ b/cmd/check.go @@ -43,7 +43,7 @@ to quickly create a Cobra application.`, if viper.GetBool("disallowed-incompats") { if out := report.ReportDisallowedIncompats(); out != "" { - fmt.Printf("Backward-incompatible changes not covered by version increments per semver.org:\n%s", out) + fmt.Printf("-----------Backward-incompatible changes not covered by version increments per semver.org-----------\n%s", out) os.Exit(1) } } else { From 26f9b1ba15a54f5aee44edd10e237e86fee367ee Mon Sep 17 00:00:00 2001 From: wenovus Date: Thu, 3 Aug 2023 11:49:00 -0700 Subject: [PATCH 06/15] move to openconfig-ci --- cmd/check.go | 3 ++- go.mod | 2 +- go.sum | 4 ++-- main.go => openconfig-ci/main.go | 0 4 files changed, 5 insertions(+), 4 deletions(-) rename main.go => openconfig-ci/main.go (100%) diff --git a/cmd/check.go b/cmd/check.go index 1335945..ade8984 100644 --- a/cmd/check.go +++ b/cmd/check.go @@ -43,10 +43,11 @@ to quickly create a Cobra application.`, if viper.GetBool("disallowed-incompats") { if out := report.ReportDisallowedIncompats(); out != "" { - fmt.Printf("-----------Backward-incompatible changes not covered by version increments per semver.org-----------\n%s", out) + fmt.Printf("-----------Breaking changes that need a major version increment (note that this check is not exhaustive)-----------\n%s", out) os.Exit(1) } } else { + fmt.Printf("-----------List of all YANG node changes-----------\n") fmt.Printf(report.ReportAll()) } return nil diff --git a/go.mod b/go.mod index 2f69efc..277b66a 100644 --- a/go.mod +++ b/go.mod @@ -9,7 +9,7 @@ require ( github.com/google/go-cmp v0.5.9 github.com/google/go-github v17.0.0+incompatible github.com/openconfig/gnmi v0.0.0-20200508230933-d19cebf5e7be - github.com/openconfig/goyang v1.3.1-0.20230802195157-66c4789eced9 + github.com/openconfig/goyang v1.4.1 github.com/spf13/cobra v1.7.0 github.com/spf13/viper v1.16.0 golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b diff --git a/go.sum b/go.sum index aebf7c9..9e303cd 100644 --- a/go.sum +++ b/go.sum @@ -159,8 +159,8 @@ github.com/openconfig/gnmi v0.0.0-20200414194230-1597cc0f2600/go.mod h1:M/EcuapN github.com/openconfig/gnmi v0.0.0-20200508230933-d19cebf5e7be h1:VEK8utxoyZu/hkpjLxvuBmK5yW3NmBo/v/Wu5VQAJVs= github.com/openconfig/gnmi v0.0.0-20200508230933-d19cebf5e7be/go.mod h1:M/EcuapNQgvzxo1DDXHK4tx3QpYM/uG4l591v33jG2A= github.com/openconfig/goyang v0.0.0-20200115183954-d0a48929f0ea/go.mod h1:dhXaV0JgHJzdrHi2l+w0fZrwArtXL7jEFoiqLEdmkvU= -github.com/openconfig/goyang v1.3.1-0.20230802195157-66c4789eced9 h1:TWT6wGfCW4yTQaT7iVjbNCj2HR7DDBhFeENsc+P0BTU= -github.com/openconfig/goyang v1.3.1-0.20230802195157-66c4789eced9/go.mod h1:vX61x01Q46AzbZUzG617vWqh/cB+aisc+RrNkXRd3W8= +github.com/openconfig/goyang v1.4.1 h1:OmkovLj01iOskzviwnoXkWWY0fwfhPVGTAKKCMSbgeE= +github.com/openconfig/goyang v1.4.1/go.mod h1:vX61x01Q46AzbZUzG617vWqh/cB+aisc+RrNkXRd3W8= github.com/openconfig/ygot v0.6.0/go.mod h1:o30svNf7O0xK+R35tlx95odkDmZWS9JyWWQSmIhqwAs= github.com/pborman/getopt v0.0.0-20190409184431-ee0cd42419d3/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= diff --git a/main.go b/openconfig-ci/main.go similarity index 100% rename from main.go rename to openconfig-ci/main.go From 65fa7927c48eb7a87b9ade76c557478a6fc6bee4 Mon Sep 17 00:00:00 2001 From: wenovus Date: Thu, 3 Aug 2023 11:55:18 -0700 Subject: [PATCH 07/15] Remove banner --- cmd/check.go | 1 - 1 file changed, 1 deletion(-) diff --git a/cmd/check.go b/cmd/check.go index ade8984..c04d5d1 100644 --- a/cmd/check.go +++ b/cmd/check.go @@ -47,7 +47,6 @@ to quickly create a Cobra application.`, os.Exit(1) } } else { - fmt.Printf("-----------List of all YANG node changes-----------\n") fmt.Printf(report.ReportAll()) } return nil From 312f8d617a582ebf46aaf488827c9bdea9641223 Mon Sep 17 00:00:00 2001 From: wenovus Date: Thu, 3 Aug 2023 13:59:03 -0700 Subject: [PATCH 08/15] Improve error strings --- cmd/check.go | 2 +- ocdiff/ocdiff.go | 163 +++++++++++++++++++++++++++++------------------ 2 files changed, 101 insertions(+), 64 deletions(-) diff --git a/cmd/check.go b/cmd/check.go index c04d5d1..822534c 100644 --- a/cmd/check.go +++ b/cmd/check.go @@ -36,7 +36,7 @@ This application is a tool to generate the needed files to quickly create a Cobra application.`, RunE: func(cmd *cobra.Command, args []string) error { viper.BindPFlags(cmd.Flags()) - report, err := ocdiff.ReportDiff(viper.GetStringSlice("oldp"), viper.GetStringSlice("newp"), viper.GetStringSlice("oldfiles"), viper.GetStringSlice("newfiles")) + report, err := ocdiff.NewDiffReport(viper.GetStringSlice("oldp"), viper.GetStringSlice("newp"), viper.GetStringSlice("oldfiles"), viper.GetStringSlice("newfiles")) if err != nil { return err } diff --git a/ocdiff/ocdiff.go b/ocdiff/ocdiff.go index 4ad1093..1c5a553 100644 --- a/ocdiff/ocdiff.go +++ b/ocdiff/ocdiff.go @@ -26,9 +26,9 @@ import ( "golang.org/x/exp/slices" ) -// ReportDiff returns a diff report given options for compiling two sets of +// NewDiffReport returns a diff report given options for compiling two sets of // YANG files. -func ReportDiff(oldpaths, newpaths, oldfiles, newfiles []string) (*DiffReport, error) { +func NewDiffReport(oldpaths, newpaths, oldfiles, newfiles []string) (*DiffReport, error) { oldEntries, oldModuleVersions, err := flattenedEntries(oldpaths, oldfiles) if err != nil { return nil, err @@ -42,77 +42,85 @@ func ReportDiff(oldpaths, newpaths, oldfiles, newfiles []string) (*DiffReport, e return diffMaps(oldEntries, newEntries, oldModuleVersions, newModuleVersions), nil } -type YANGNode struct { - path string - schema *yang.Entry - allowIncompat bool - allowOrDisallowIncompatReason string +// yangNodeInfo contains all information of a single new/deleted node necessary +// for printing a report. +type yangNodeInfo struct { + path string + schema *yang.Entry + allowIncompat bool + versionChangeDesc string } -type YANGNodeUpdate struct { - path string - oldSchema *yang.Entry - newSchema *yang.Entry - allowIncompat bool - allowOrDisallowIncompatReason string - incompatComments []string - oldVersion *semver.Version - NewVersion *semver.Version +// yangNodeUpdateInfo contains all information of a single updated node necessary +// for printing a report. +type yangNodeUpdateInfo struct { + path string + oldSchema *yang.Entry + newSchema *yang.Entry + allowIncompat bool + versionChangeDesc string + incompatComments []string } +// DiffReport contains information necessary to print out a diff report between +// two sets of OpenConfig YANG files. type DiffReport struct { - NewNodes []*YANGNode - UpdatedNodes []*YANGNodeUpdate - DeletedNodes []*YANGNode + newNodes []*yangNodeInfo + updatedNodes []*yangNodeUpdateInfo + deletedNodes []*yangNodeInfo OldModuleVersions map[string]*semver.Version NewModuleVersions map[string]*semver.Version } // ReportDisallowedIncompats reports any backward-incompatible changes disallowed by version increments. func (r *DiffReport) ReportDisallowedIncompats() string { - r.Sort() - var b strings.Builder - for _, del := range r.DeletedNodes { - if !del.allowIncompat && (del.schema.IsLeaf() || del.schema.IsLeafList()) { - b.WriteString(fmt.Sprintf("leaf deleted: %s (%s)\n", del.schema.Path(), del.allowOrDisallowIncompatReason)) - } - } - for _, upd := range r.UpdatedNodes { - if !upd.allowIncompat && len(upd.incompatComments) > 0 { - b.WriteString(fmt.Sprintf("node updated %s (%s): %s\n", upd.oldSchema.Path(), upd.allowOrDisallowIncompatReason, strings.Join(upd.incompatComments, "\n\t"))) - } - } - return b.String() + return r.report(reportOptions{onlyReportDisallowedIncompats: true}) } // ReportAll reports all YANG changes. func (r *DiffReport) ReportAll() string { + return r.report(reportOptions{}) +} + +type reportOptions struct { + onlyReportDisallowedIncompats bool +} + +func (r *DiffReport) report(opts reportOptions) string { r.Sort() var b strings.Builder - for _, del := range r.DeletedNodes { - if del.schema.IsLeaf() || del.schema.IsLeafList() { - b.WriteString(fmt.Sprintf("leaf deleted: %s\n", del.schema.Path())) + for _, del := range r.deletedNodes { + if !opts.onlyReportDisallowedIncompats || !del.allowIncompat { + if del.schema.IsLeaf() || del.schema.IsLeafList() { + b.WriteString(fmt.Sprintf("leaf deleted: %s (%s)\n", del.schema.Path(), del.versionChangeDesc)) + } } } - for _, upd := range r.UpdatedNodes { + for _, upd := range r.updatedNodes { if len(upd.incompatComments) > 0 { - b.WriteString(fmt.Sprintf("node updated %s: %s\n", upd.oldSchema.Path(), strings.Join(upd.incompatComments, "\n\t"))) + nodeTypeDesc := "non-leaf" + if upd.oldSchema.IsLeaf() || upd.oldSchema.IsLeafList() { + nodeTypeDesc = "leaf" + } + b.WriteString(fmt.Sprintf("%s updated: %s: %s (%s)\n", nodeTypeDesc, upd.oldSchema.Path(), strings.Join(upd.incompatComments, "\n\t"), upd.versionChangeDesc)) } else { - b.WriteString(fmt.Sprintf("node updated %s\n", upd.oldSchema.Path())) + b.WriteString(fmt.Sprintf("node updated %s (%s)\n", upd.oldSchema.Path(), upd.versionChangeDesc)) } } - for _, added := range r.NewNodes { - if added.schema.IsLeaf() || added.schema.IsLeafList() { - b.WriteString(fmt.Sprintf("leaf added: %s\n", added.schema.Path())) + if !opts.onlyReportDisallowedIncompats { + for _, added := range r.newNodes { + if added.schema.IsLeaf() || added.schema.IsLeafList() { + b.WriteString(fmt.Sprintf("leaf added: %s (%s)\n", added.schema.Path(), added.versionChangeDesc)) + } } } return b.String() } func (r *DiffReport) Sort() { - slices.SortFunc(r.NewNodes, func(a, b *YANGNode) int { return strings.Compare(a.path, b.path) }) - slices.SortFunc(r.DeletedNodes, func(a, b *YANGNode) int { return strings.Compare(a.path, b.path) }) - slices.SortFunc(r.UpdatedNodes, func(a, b *YANGNodeUpdate) int { return strings.Compare(a.path, b.path) }) + slices.SortFunc(r.newNodes, func(a, b *yangNodeInfo) int { return strings.Compare(a.path, b.path) }) + slices.SortFunc(r.deletedNodes, func(a, b *yangNodeInfo) int { return strings.Compare(a.path, b.path) }) + slices.SortFunc(r.updatedNodes, func(a, b *yangNodeUpdateInfo) int { return strings.Compare(a.path, b.path) }) } func getKind(e *yang.Entry) string { @@ -124,57 +132,86 @@ func getKind(e *yang.Entry) string { } func definingModuleName(e *yang.Entry) string { + if e == nil { + return "" + } if definingModule := yang.RootNode(e.Node); definingModule != nil { return definingModule.Name } return "" } +func (r *DiffReport) getModuleAndVersions(e *yang.Entry) (string, *semver.Version, *semver.Version) { + moduleName := definingModuleName(e) + return moduleName, r.OldModuleVersions[moduleName], r.NewModuleVersions[moduleName] +} + +func incompatAllowed(oldVersion, newVersion *semver.Version) bool { + switch { + case oldVersion == nil, newVersion == nil: + // This can happen if the openconfig-version is not found (e.g. in IETF modules). + // + // In other cases, we will just be conservative and allow the + // incompatibility since we don't want to block the PR. + return true + case oldVersion.Major() == 0: + return true + case newVersion.Major() > oldVersion.Major(): + return true + default: + return false + } +} + func (r *DiffReport) entryAllowsIncompat(e *yang.Entry) (bool, string) { moduleName := definingModuleName(e) //moduleName := belongingModule(yang.RootNode(e.Node)) oldVersion, newVersion := r.OldModuleVersions[moduleName], r.NewModuleVersions[moduleName] + versionChangeDesc := fmt.Sprintf("%q: openconfig-version change %v -> %v", moduleName, oldVersion, newVersion) + switch { case oldVersion == nil, newVersion == nil: // This can happen if the openconfig-version is not found (e.g. in IETF modules). // // In other cases, we will just be conservative and allow the // incompatibility since we don't want to block the PR. - return true, fmt.Sprintf("%q: oldVersion (%v) or newVersion (%v) is nil", moduleName, oldVersion, newVersion) + return true, versionChangeDesc case oldVersion.Major() == 0: - return true, fmt.Sprintf("%q: oldVersion is at version 0 (%v)", moduleName, oldVersion) + return true, versionChangeDesc case newVersion.Major() > oldVersion.Major(): - return true, fmt.Sprintf("%q: newVersion incremented major version (%v -> %v)", moduleName, oldVersion, newVersion) + return true, versionChangeDesc default: - return false, fmt.Sprintf("%q: oldVersion (%v) -> newVersion (%v) does not allow for backwards-incompatible changes", moduleName, oldVersion, newVersion) + return false, versionChangeDesc } } func (r *DiffReport) addPair(o *yang.Entry, n *yang.Entry) error { + moduleName, oldVersion, newVersion := r.getModuleAndVersions(o) + versionChangeDesc := fmt.Sprintf("%q: openconfig-version change %v -> %v", moduleName, oldVersion, newVersion) + allowIncompat := incompatAllowed(oldVersion, newVersion) + switch { case o == nil && n == nil: case o == nil: - r.NewNodes = append(r.NewNodes, &YANGNode{ + r.newNodes = append(r.newNodes, &yangNodeInfo{ schema: n, path: n.Path(), }) case n == nil: - allowIncompat, allowOrDisallowIncompatReason := r.entryAllowsIncompat(o) - r.DeletedNodes = append(r.DeletedNodes, &YANGNode{ - schema: o, - path: o.Path(), - allowIncompat: allowIncompat, - allowOrDisallowIncompatReason: allowOrDisallowIncompatReason, + r.deletedNodes = append(r.deletedNodes, &yangNodeInfo{ + schema: o, + path: o.Path(), + allowIncompat: allowIncompat, + versionChangeDesc: versionChangeDesc, }) default: - allowIncompat, allowOrDisallowIncompatReason := r.entryAllowsIncompat(o) - upd := &YANGNodeUpdate{ - oldSchema: o, - newSchema: n, - path: o.Path(), - allowIncompat: allowIncompat, - allowOrDisallowIncompatReason: allowOrDisallowIncompatReason, + upd := &yangNodeUpdateInfo{ + oldSchema: o, + newSchema: n, + path: o.Path(), + allowIncompat: allowIncompat, + versionChangeDesc: versionChangeDesc, } updated := false if oldKind, newKind := getKind(o), getKind(n); oldKind != newKind { @@ -182,7 +219,7 @@ func (r *DiffReport) addPair(o *yang.Entry, n *yang.Entry) error { updated = true } if updated { - r.UpdatedNodes = append(r.UpdatedNodes, upd) + r.updatedNodes = append(r.updatedNodes, upd) } } return nil From 742647cf8214642201287d1495ce5dcea1dfe187 Mon Sep 17 00:00:00 2001 From: wenovus Date: Thu, 3 Aug 2023 14:33:57 -0700 Subject: [PATCH 09/15] improve style --- cmd/check.go | 11 +++++-- ocdiff/ocdiff.go | 80 +++++++++++++++++++++++++----------------------- 2 files changed, 51 insertions(+), 40 deletions(-) diff --git a/cmd/check.go b/cmd/check.go index 822534c..f971129 100644 --- a/cmd/check.go +++ b/cmd/check.go @@ -41,13 +41,19 @@ to quickly create a Cobra application.`, return err } + var opts []ocdiff.Option + if viper.GetBool("github-comment") { + opts = append(opts, ocdiff.WithGithubCommentStyle()) + } + if viper.GetBool("disallowed-incompats") { - if out := report.ReportDisallowedIncompats(); out != "" { + opts = append(opts, ocdiff.WithDisallowedIncompatsOnly()) + if out := report.Report(opts...); out != "" { fmt.Printf("-----------Breaking changes that need a major version increment (note that this check is not exhaustive)-----------\n%s", out) os.Exit(1) } } else { - fmt.Printf(report.ReportAll()) + fmt.Printf(report.Report(opts...)) } return nil }, @@ -61,4 +67,5 @@ func init() { checkCmd.Flags().StringSlice("oldfiles", []string{}, "comma-separated list of old YANG files") checkCmd.Flags().StringSlice("newfiles", []string{}, "comma-separated list of new YANG files") checkCmd.Flags().Bool("disallowed-incompats", false, "only show disallowed (per semver.org) backwards-incompatible changes. Note that the backwards-incompatible checks are not exhausive.") + checkCmd.Flags().Bool("github-comment", false, "Show output suitable for posting in a GitHub comment.") } diff --git a/ocdiff/ocdiff.go b/ocdiff/ocdiff.go index 1c5a553..b5464b2 100644 --- a/ocdiff/ocdiff.go +++ b/ocdiff/ocdiff.go @@ -72,45 +72,72 @@ type DiffReport struct { NewModuleVersions map[string]*semver.Version } -// ReportDisallowedIncompats reports any backward-incompatible changes disallowed by version increments. -func (r *DiffReport) ReportDisallowedIncompats() string { - return r.report(reportOptions{onlyReportDisallowedIncompats: true}) +// Option can be used to modify the report outputs. +type Option func(*reportOptions) + +// WithDisallowedIncompatsOnly indicates to report only backward-incompatible +// changes disallowed by version increments. +func WithDisallowedIncompatsOnly() Option { + return func(o *reportOptions) { + o.onlyReportDisallowedIncompats = true + } +} + +// WithGithubCommentStyle indicates to report with GitHub comment styling. +func WithGithubCommentStyle() Option { + return func(o *reportOptions) { + o.githubComment = true + } } -// ReportAll reports all YANG changes. -func (r *DiffReport) ReportAll() string { - return r.report(reportOptions{}) +// resolveOpts applies all the options and returns a struct containing the result. +func resolveOpts(opts []Option) *reportOptions { + o := &reportOptions{} + for _, opt := range opts { + opt(o) + } + return o } type reportOptions struct { onlyReportDisallowedIncompats bool + githubComment bool } -func (r *DiffReport) report(opts reportOptions) string { +func (r *DiffReport) Report(options ...Option) string { + opts := resolveOpts(options) r.Sort() + fmtstr := "%s %s: %s (%s)\n" + if opts.githubComment { + fmtstr = "%s %s: `%s`\n\t(%s)\n" + } var b strings.Builder for _, del := range r.deletedNodes { if !opts.onlyReportDisallowedIncompats || !del.allowIncompat { if del.schema.IsLeaf() || del.schema.IsLeafList() { - b.WriteString(fmt.Sprintf("leaf deleted: %s (%s)\n", del.schema.Path(), del.versionChangeDesc)) + b.WriteString(fmt.Sprintf(fmtstr, "leaf", "deleted", del.path, del.versionChangeDesc)) } } } for _, upd := range r.updatedNodes { + nodeTypeDesc := "non-leaf" + if upd.oldSchema.IsLeaf() || upd.oldSchema.IsLeafList() { + nodeTypeDesc = "leaf" + } if len(upd.incompatComments) > 0 { - nodeTypeDesc := "non-leaf" - if upd.oldSchema.IsLeaf() || upd.oldSchema.IsLeafList() { - nodeTypeDesc = "leaf" + fmtstr := "%s updated: %s: %s (%s)\n" + if opts.githubComment { + fmtstr = "%s updated: `%s`\n\t%s\n\t(%s)\n" } - b.WriteString(fmt.Sprintf("%s updated: %s: %s (%s)\n", nodeTypeDesc, upd.oldSchema.Path(), strings.Join(upd.incompatComments, "\n\t"), upd.versionChangeDesc)) + b.WriteString(fmt.Sprintf(fmtstr, nodeTypeDesc, upd.path, strings.Join(upd.incompatComments, "\n\t"), upd.versionChangeDesc)) } else { - b.WriteString(fmt.Sprintf("node updated %s (%s)\n", upd.oldSchema.Path(), upd.versionChangeDesc)) + b.WriteString(fmt.Sprintf(fmtstr, nodeTypeDesc, "updated", upd.path, upd.versionChangeDesc)) } } if !opts.onlyReportDisallowedIncompats { for _, added := range r.newNodes { if added.schema.IsLeaf() || added.schema.IsLeafList() { - b.WriteString(fmt.Sprintf("leaf added: %s (%s)\n", added.schema.Path(), added.versionChangeDesc)) + b.WriteString(fmt.Sprintf(fmtstr, "leaf", "added", fmtstr, added.path, added.versionChangeDesc)) } } } @@ -163,32 +190,9 @@ func incompatAllowed(oldVersion, newVersion *semver.Version) bool { } } -func (r *DiffReport) entryAllowsIncompat(e *yang.Entry) (bool, string) { - moduleName := definingModuleName(e) - //moduleName := belongingModule(yang.RootNode(e.Node)) - oldVersion, newVersion := r.OldModuleVersions[moduleName], r.NewModuleVersions[moduleName] - - versionChangeDesc := fmt.Sprintf("%q: openconfig-version change %v -> %v", moduleName, oldVersion, newVersion) - - switch { - case oldVersion == nil, newVersion == nil: - // This can happen if the openconfig-version is not found (e.g. in IETF modules). - // - // In other cases, we will just be conservative and allow the - // incompatibility since we don't want to block the PR. - return true, versionChangeDesc - case oldVersion.Major() == 0: - return true, versionChangeDesc - case newVersion.Major() > oldVersion.Major(): - return true, versionChangeDesc - default: - return false, versionChangeDesc - } -} - func (r *DiffReport) addPair(o *yang.Entry, n *yang.Entry) error { moduleName, oldVersion, newVersion := r.getModuleAndVersions(o) - versionChangeDesc := fmt.Sprintf("%q: openconfig-version change %v -> %v", moduleName, oldVersion, newVersion) + versionChangeDesc := fmt.Sprintf("%q: openconfig-version %v -> %v", moduleName, oldVersion, newVersion) allowIncompat := incompatAllowed(oldVersion, newVersion) switch { From 46f4f971932b6eaa022f0f897e7336d624127d2a Mon Sep 17 00:00:00 2001 From: wenovus Date: Thu, 3 Aug 2023 14:47:42 -0700 Subject: [PATCH 10/15] Improve github-comment output --- ocdiff/ocdiff.go | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/ocdiff/ocdiff.go b/ocdiff/ocdiff.go index b5464b2..9cd3f99 100644 --- a/ocdiff/ocdiff.go +++ b/ocdiff/ocdiff.go @@ -109,7 +109,7 @@ func (r *DiffReport) Report(options ...Option) string { r.Sort() fmtstr := "%s %s: %s (%s)\n" if opts.githubComment { - fmtstr = "%s %s: `%s`\n\t(%s)\n" + fmtstr = "%s %s: `%s`\n* (%s)\n\n" } var b strings.Builder for _, del := range r.deletedNodes { @@ -126,10 +126,12 @@ func (r *DiffReport) Report(options ...Option) string { } if len(upd.incompatComments) > 0 { fmtstr := "%s updated: %s: %s (%s)\n" + comments := strings.Join(upd.incompatComments, "\n\t") if opts.githubComment { - fmtstr = "%s updated: `%s`\n\t%s\n\t(%s)\n" + fmtstr = "%s updated: `%s`\n* %s\n* (%s)\n\n" + comments = strings.Join(upd.incompatComments, "\n* ") } - b.WriteString(fmt.Sprintf(fmtstr, nodeTypeDesc, upd.path, strings.Join(upd.incompatComments, "\n\t"), upd.versionChangeDesc)) + b.WriteString(fmt.Sprintf(fmtstr, nodeTypeDesc, upd.path, comments, upd.versionChangeDesc)) } else { b.WriteString(fmt.Sprintf(fmtstr, nodeTypeDesc, "updated", upd.path, upd.versionChangeDesc)) } From 2401790e977a9d18a1023c77cc8e8bc80bcf3f83 Mon Sep 17 00:00:00 2001 From: wenovus Date: Thu, 3 Aug 2023 16:11:56 -0700 Subject: [PATCH 11/15] Add tests --- go.mod | 8 +- go.sum | 14 +- ocdiff/ocdiff.go | 24 +- ocdiff/ocdiff_test.go | 102 ++ ocdiff/testdata/disallowed-incompats.txt | 7 + .../github-comment-disallowed-incompats.txt | 27 + ocdiff/testdata/github-comment.txt | 60 + ocdiff/testdata/no-options.txt | 18 + .../yang/incl/openconfig-extensions.yang | 206 +++ ocdiff/testdata/yang/incl/types/.spec.yml | 10 + .../incl/types/openconfig-inet-types.yang | 478 ++++++ .../yang/incl/types/openconfig-types.yang | 471 ++++++ .../incl/types/openconfig-yang-types.yang | 230 +++ ocdiff/testdata/yang/new/platform/.spec.yml | 43 + .../platform/openconfig-platform-common.yang | 247 +++ .../openconfig-platform-controller-card.yang | 81 + .../new/platform/openconfig-platform-cpu.yang | 72 + .../new/platform/openconfig-platform-ext.yang | 82 + .../platform/openconfig-platform-fabric.yang | 81 + .../new/platform/openconfig-platform-fan.yang | 76 + .../platform/openconfig-platform-healthz.yang | 137 ++ ...penconfig-platform-integrated-circuit.yang | 180 +++ .../openconfig-platform-linecard.yang | 157 ++ ...openconfig-platform-pipeline-counters.yang | 1341 +++++++++++++++++ .../platform/openconfig-platform-port.yang | 306 ++++ .../new/platform/openconfig-platform-psu.yang | 146 ++ .../openconfig-platform-software.yang | 100 ++ .../platform/openconfig-platform-types.yang | 541 +++++++ .../new/platform/openconfig-platform.yang | 1205 +++++++++++++++ ocdiff/testdata/yang/old/platform/.spec.yml | 43 + .../platform/openconfig-platform-common.yang | 240 +++ .../openconfig-platform-controller-card.yang | 81 + .../old/platform/openconfig-platform-cpu.yang | 72 + .../old/platform/openconfig-platform-ext.yang | 82 + .../platform/openconfig-platform-fabric.yang | 81 + .../old/platform/openconfig-platform-fan.yang | 76 + .../platform/openconfig-platform-healthz.yang | 137 ++ ...penconfig-platform-integrated-circuit.yang | 180 +++ .../openconfig-platform-linecard.yang | 151 ++ ...openconfig-platform-pipeline-counters.yang | 1341 +++++++++++++++++ .../platform/openconfig-platform-port.yang | 300 ++++ .../old/platform/openconfig-platform-psu.yang | 146 ++ .../openconfig-platform-software.yang | 100 ++ .../platform/openconfig-platform-types.yang | 541 +++++++ .../old/platform/openconfig-platform.yang | 1198 +++++++++++++++ 45 files changed, 11203 insertions(+), 16 deletions(-) create mode 100644 ocdiff/ocdiff_test.go create mode 100644 ocdiff/testdata/disallowed-incompats.txt create mode 100644 ocdiff/testdata/github-comment-disallowed-incompats.txt create mode 100644 ocdiff/testdata/github-comment.txt create mode 100644 ocdiff/testdata/no-options.txt create mode 100644 ocdiff/testdata/yang/incl/openconfig-extensions.yang create mode 100644 ocdiff/testdata/yang/incl/types/.spec.yml create mode 100644 ocdiff/testdata/yang/incl/types/openconfig-inet-types.yang create mode 100644 ocdiff/testdata/yang/incl/types/openconfig-types.yang create mode 100644 ocdiff/testdata/yang/incl/types/openconfig-yang-types.yang create mode 100644 ocdiff/testdata/yang/new/platform/.spec.yml create mode 100644 ocdiff/testdata/yang/new/platform/openconfig-platform-common.yang create mode 100644 ocdiff/testdata/yang/new/platform/openconfig-platform-controller-card.yang create mode 100644 ocdiff/testdata/yang/new/platform/openconfig-platform-cpu.yang create mode 100644 ocdiff/testdata/yang/new/platform/openconfig-platform-ext.yang create mode 100644 ocdiff/testdata/yang/new/platform/openconfig-platform-fabric.yang create mode 100644 ocdiff/testdata/yang/new/platform/openconfig-platform-fan.yang create mode 100644 ocdiff/testdata/yang/new/platform/openconfig-platform-healthz.yang create mode 100644 ocdiff/testdata/yang/new/platform/openconfig-platform-integrated-circuit.yang create mode 100644 ocdiff/testdata/yang/new/platform/openconfig-platform-linecard.yang create mode 100644 ocdiff/testdata/yang/new/platform/openconfig-platform-pipeline-counters.yang create mode 100644 ocdiff/testdata/yang/new/platform/openconfig-platform-port.yang create mode 100644 ocdiff/testdata/yang/new/platform/openconfig-platform-psu.yang create mode 100644 ocdiff/testdata/yang/new/platform/openconfig-platform-software.yang create mode 100644 ocdiff/testdata/yang/new/platform/openconfig-platform-types.yang create mode 100644 ocdiff/testdata/yang/new/platform/openconfig-platform.yang create mode 100644 ocdiff/testdata/yang/old/platform/.spec.yml create mode 100644 ocdiff/testdata/yang/old/platform/openconfig-platform-common.yang create mode 100644 ocdiff/testdata/yang/old/platform/openconfig-platform-controller-card.yang create mode 100644 ocdiff/testdata/yang/old/platform/openconfig-platform-cpu.yang create mode 100644 ocdiff/testdata/yang/old/platform/openconfig-platform-ext.yang create mode 100644 ocdiff/testdata/yang/old/platform/openconfig-platform-fabric.yang create mode 100644 ocdiff/testdata/yang/old/platform/openconfig-platform-fan.yang create mode 100644 ocdiff/testdata/yang/old/platform/openconfig-platform-healthz.yang create mode 100644 ocdiff/testdata/yang/old/platform/openconfig-platform-integrated-circuit.yang create mode 100644 ocdiff/testdata/yang/old/platform/openconfig-platform-linecard.yang create mode 100644 ocdiff/testdata/yang/old/platform/openconfig-platform-pipeline-counters.yang create mode 100644 ocdiff/testdata/yang/old/platform/openconfig-platform-port.yang create mode 100644 ocdiff/testdata/yang/old/platform/openconfig-platform-psu.yang create mode 100644 ocdiff/testdata/yang/old/platform/openconfig-platform-software.yang create mode 100644 ocdiff/testdata/yang/old/platform/openconfig-platform-types.yang create mode 100644 ocdiff/testdata/yang/old/platform/openconfig-platform.yang diff --git a/go.mod b/go.mod index 277b66a..d02b314 100644 --- a/go.mod +++ b/go.mod @@ -8,13 +8,14 @@ require ( github.com/golang/protobuf v1.5.3 github.com/google/go-cmp v0.5.9 github.com/google/go-github v17.0.0+incompatible - github.com/openconfig/gnmi v0.0.0-20200508230933-d19cebf5e7be + github.com/openconfig/gnmi v0.10.0 github.com/openconfig/goyang v1.4.1 + github.com/openconfig/ygot v0.29.9 github.com/spf13/cobra v1.7.0 github.com/spf13/viper v1.16.0 golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b golang.org/x/oauth2 v0.7.0 - google.golang.org/protobuf v1.30.0 + google.golang.org/protobuf v1.31.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -26,6 +27,7 @@ require ( github.com/magiconair/properties v1.8.7 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/pelletier/go-toml/v2 v2.0.8 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect github.com/spf13/afero v1.9.5 // indirect github.com/spf13/cast v1.5.1 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect @@ -35,5 +37,7 @@ require ( golang.org/x/sys v0.8.0 // indirect golang.org/x/text v0.9.0 // indirect google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 // indirect + google.golang.org/grpc v1.58.0-dev // indirect gopkg.in/ini.v1 v1.67.0 // indirect ) diff --git a/go.sum b/go.sum index 9e303cd..ed7df38 100644 --- a/go.sum +++ b/go.sum @@ -156,12 +156,14 @@ github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3v github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/openconfig/gnmi v0.0.0-20200414194230-1597cc0f2600/go.mod h1:M/EcuapNQgvzxo1DDXHK4tx3QpYM/uG4l591v33jG2A= -github.com/openconfig/gnmi v0.0.0-20200508230933-d19cebf5e7be h1:VEK8utxoyZu/hkpjLxvuBmK5yW3NmBo/v/Wu5VQAJVs= -github.com/openconfig/gnmi v0.0.0-20200508230933-d19cebf5e7be/go.mod h1:M/EcuapNQgvzxo1DDXHK4tx3QpYM/uG4l591v33jG2A= +github.com/openconfig/gnmi v0.10.0 h1:kQEZ/9ek3Vp2Y5IVuV2L/ba8/77TgjdXg505QXvYmg8= +github.com/openconfig/gnmi v0.10.0/go.mod h1:Y9os75GmSkhHw2wX8sMsxfI7qRGAEcDh8NTa5a8vj6E= github.com/openconfig/goyang v0.0.0-20200115183954-d0a48929f0ea/go.mod h1:dhXaV0JgHJzdrHi2l+w0fZrwArtXL7jEFoiqLEdmkvU= github.com/openconfig/goyang v1.4.1 h1:OmkovLj01iOskzviwnoXkWWY0fwfhPVGTAKKCMSbgeE= github.com/openconfig/goyang v1.4.1/go.mod h1:vX61x01Q46AzbZUzG617vWqh/cB+aisc+RrNkXRd3W8= github.com/openconfig/ygot v0.6.0/go.mod h1:o30svNf7O0xK+R35tlx95odkDmZWS9JyWWQSmIhqwAs= +github.com/openconfig/ygot v0.29.9 h1:SCDD3Vs0qeYgBu+tqynxgSXsgHMomAnB57Yzhe5221M= +github.com/openconfig/ygot v0.29.9/go.mod h1:dmcOYUbSoFRiIj8Wv8ZDXApdnSEbmCdQVNANnXogjD0= github.com/pborman/getopt v0.0.0-20190409184431-ee0cd42419d3/go.mod h1:85jBQOZwpVEaDAr341tbn15RS4fCAsIst0qp7i8ex1o= github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= @@ -472,6 +474,8 @@ google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 h1:0nDDozoAU19Qb2HwhXadU8OcsiO/09cnTqhUtq2MEOM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -488,6 +492,8 @@ google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.58.0-dev h1:BggFp6joqwbgXlqFIogQr6r35o+BnzYw54An5wzoSLA= +google.golang.org/grpc v1.58.0-dev/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -500,8 +506,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= +google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/ocdiff/ocdiff.go b/ocdiff/ocdiff.go index 9cd3f99..b3d14a9 100644 --- a/ocdiff/ocdiff.go +++ b/ocdiff/ocdiff.go @@ -68,8 +68,8 @@ type DiffReport struct { newNodes []*yangNodeInfo updatedNodes []*yangNodeUpdateInfo deletedNodes []*yangNodeInfo - OldModuleVersions map[string]*semver.Version - NewModuleVersions map[string]*semver.Version + oldModuleVersions map[string]*semver.Version + newModuleVersions map[string]*semver.Version } // Option can be used to modify the report outputs. @@ -139,7 +139,7 @@ func (r *DiffReport) Report(options ...Option) string { if !opts.onlyReportDisallowedIncompats { for _, added := range r.newNodes { if added.schema.IsLeaf() || added.schema.IsLeafList() { - b.WriteString(fmt.Sprintf(fmtstr, "leaf", "added", fmtstr, added.path, added.versionChangeDesc)) + b.WriteString(fmt.Sprintf(fmtstr, "leaf", "added", added.path, added.versionChangeDesc)) } } } @@ -165,14 +165,14 @@ func definingModuleName(e *yang.Entry) string { return "" } if definingModule := yang.RootNode(e.Node); definingModule != nil { - return definingModule.Name + return belongingModule(definingModule) } return "" } func (r *DiffReport) getModuleAndVersions(e *yang.Entry) (string, *semver.Version, *semver.Version) { moduleName := definingModuleName(e) - return moduleName, r.OldModuleVersions[moduleName], r.NewModuleVersions[moduleName] + return moduleName, r.oldModuleVersions[moduleName], r.newModuleVersions[moduleName] } func incompatAllowed(oldVersion, newVersion *semver.Version) bool { @@ -200,9 +200,11 @@ func (r *DiffReport) addPair(o *yang.Entry, n *yang.Entry) error { switch { case o == nil && n == nil: case o == nil: + newModuleName, oldVersion, newVersion := r.getModuleAndVersions(n) r.newNodes = append(r.newNodes, &yangNodeInfo{ - schema: n, - path: n.Path(), + schema: n, + path: n.Path(), + versionChangeDesc: fmt.Sprintf("%q: openconfig-version %v -> %v", newModuleName, oldVersion, newVersion), }) case n == nil: r.deletedNodes = append(r.deletedNodes, &yangNodeInfo{ @@ -298,14 +300,16 @@ func flattenedEntriesAux(entry *yang.Entry) []*yang.Entry { func diffMaps(oldEntries, newEntries map[string]*yang.Entry, oldModuleVersions, newModuleVersions map[string]*semver.Version) *DiffReport { report := &DiffReport{ - OldModuleVersions: oldModuleVersions, - NewModuleVersions: newModuleVersions, + oldModuleVersions: oldModuleVersions, + newModuleVersions: newModuleVersions, } for path, oldEntry := range oldEntries { report.addPair(oldEntry, newEntries[path]) } for path, newEntry := range newEntries { - report.addPair(oldEntries[path], newEntry) + if oldEntries[path] == nil { + report.addPair(oldEntries[path], newEntry) + } } return report } diff --git a/ocdiff/ocdiff_test.go b/ocdiff/ocdiff_test.go new file mode 100644 index 0000000..e3eb311 --- /dev/null +++ b/ocdiff/ocdiff_test.go @@ -0,0 +1,102 @@ +// Copyright 2023 Google Inc. +// +// 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 ocdiff + +import ( + "flag" + "os" + "path/filepath" + "testing" + + "github.com/openconfig/ygot/testutil" +) + +var updateGolden = flag.Bool("update_golden", false, "Update golden files") + +func getAllYANGFiles(t *testing.T, path string) []string { + t.Helper() + var files []string + if err := filepath.Walk(path, + func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if filepath.Ext(info.Name()) == ".yang" { + files = append(files, path) + } + return nil + }, + ); err != nil { + t.Fatal(err) + } + return files +} + +func TestDiffReport(t *testing.T) { + tests := []struct { + name string + inOpts []Option + wantFile string + }{{ + name: "no-options", + wantFile: "testdata/no-options.txt", + }, { + name: "github-comment", + inOpts: []Option{ + WithGithubCommentStyle(), + }, + wantFile: "testdata/github-comment.txt", + }, { + name: "disallowed-incompats", + inOpts: []Option{ + WithDisallowedIncompatsOnly(), + }, + wantFile: "testdata/disallowed-incompats.txt", + }, { + name: "github-comment-disallowed-incompats", + inOpts: []Option{ + WithGithubCommentStyle(), + WithDisallowedIncompatsOnly(), + }, + wantFile: "testdata/github-comment-disallowed-incompats.txt", + }} + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + report, err := NewDiffReport([]string{"testdata/yang/incl"}, []string{"testdata/yang/incl"}, getAllYANGFiles(t, "testdata/yang/old"), getAllYANGFiles(t, "testdata/yang/new")) + if err != nil { + t.Fatal(err) + } + gotReport := report.Report(tt.inOpts...) + wantFileBytes, rferr := os.ReadFile(tt.wantFile) + if rferr != nil { + t.Fatalf("os.ReadFile(%q) error: %v", tt.wantFile, rferr) + } + + if wantReport := string(wantFileBytes); gotReport != wantReport { + if *updateGolden { + if err := os.WriteFile(tt.wantFile, []byte(gotReport), 0644); err != nil { + t.Fatal(err) + } + } + // Use difflib to generate a unified diff between the + // two code snippets such that this is simpler to debug + // in the test output. + diff, _ := testutil.GenerateUnifiedDiff(wantReport, gotReport) + t.Errorf("did not return correct report (file: %v), diff:\n%s", tt.wantFile, diff) + } + }) + } +} diff --git a/ocdiff/testdata/disallowed-incompats.txt b/ocdiff/testdata/disallowed-incompats.txt new file mode 100644 index 0000000..f157dab --- /dev/null +++ b/ocdiff/testdata/disallowed-incompats.txt @@ -0,0 +1,7 @@ +leaf deleted: /openconfig-platform/components/component/linecard/state/slot-id ("openconfig-platform-linecard": openconfig-version 1.1.0 -> 1.2.0) +leaf updated: /openconfig-platform/components/component/chassis/utilization/resources/resource/state/used: type changed from uint64 to uint32 ("openconfig-platform": openconfig-version 0.23.0 -> 0.24.0) +leaf updated: /openconfig-platform/components/component/integrated-circuit/utilization/resources/resource/state/used: type changed from uint64 to uint32 ("openconfig-platform": openconfig-version 0.23.0 -> 0.24.0) +leaf updated: /openconfig-platform/components/component/linecard/state/colour: type changed from string to binary ("openconfig-platform-linecard": openconfig-version 1.1.0 -> 1.2.0) +leaf updated: /openconfig-platform/components/component/linecard/utilization/resources/resource/state/used: type changed from uint64 to uint32 ("openconfig-platform": openconfig-version 0.23.0 -> 0.24.0) +leaf updated: /openconfig-platform/components/component/port/breakout-mode/groups/group/config/num-physical-channels: type changed from uint8 to uint16 ("openconfig-platform-port": openconfig-version 1.0.1 -> 2.0.0) +leaf updated: /openconfig-platform/components/component/port/breakout-mode/groups/group/state/num-physical-channels: type changed from uint8 to uint16 ("openconfig-platform-port": openconfig-version 1.0.1 -> 2.0.0) diff --git a/ocdiff/testdata/github-comment-disallowed-incompats.txt b/ocdiff/testdata/github-comment-disallowed-incompats.txt new file mode 100644 index 0000000..4679b88 --- /dev/null +++ b/ocdiff/testdata/github-comment-disallowed-incompats.txt @@ -0,0 +1,27 @@ +leaf deleted: `/openconfig-platform/components/component/linecard/state/slot-id` +* ("openconfig-platform-linecard": openconfig-version 1.1.0 -> 1.2.0) + +leaf updated: `/openconfig-platform/components/component/chassis/utilization/resources/resource/state/used` +* type changed from uint64 to uint32 +* ("openconfig-platform": openconfig-version 0.23.0 -> 0.24.0) + +leaf updated: `/openconfig-platform/components/component/integrated-circuit/utilization/resources/resource/state/used` +* type changed from uint64 to uint32 +* ("openconfig-platform": openconfig-version 0.23.0 -> 0.24.0) + +leaf updated: `/openconfig-platform/components/component/linecard/state/colour` +* type changed from string to binary +* ("openconfig-platform-linecard": openconfig-version 1.1.0 -> 1.2.0) + +leaf updated: `/openconfig-platform/components/component/linecard/utilization/resources/resource/state/used` +* type changed from uint64 to uint32 +* ("openconfig-platform": openconfig-version 0.23.0 -> 0.24.0) + +leaf updated: `/openconfig-platform/components/component/port/breakout-mode/groups/group/config/num-physical-channels` +* type changed from uint8 to uint16 +* ("openconfig-platform-port": openconfig-version 1.0.1 -> 2.0.0) + +leaf updated: `/openconfig-platform/components/component/port/breakout-mode/groups/group/state/num-physical-channels` +* type changed from uint8 to uint16 +* ("openconfig-platform-port": openconfig-version 1.0.1 -> 2.0.0) + diff --git a/ocdiff/testdata/github-comment.txt b/ocdiff/testdata/github-comment.txt new file mode 100644 index 0000000..aad0a28 --- /dev/null +++ b/ocdiff/testdata/github-comment.txt @@ -0,0 +1,60 @@ +leaf deleted: `/openconfig-platform/components/component/chassis/utilization/resources/resource/state/max-limit` +* ("openconfig-platform": openconfig-version 0.23.0 -> 0.24.0) + +leaf deleted: `/openconfig-platform/components/component/integrated-circuit/utilization/resources/resource/state/max-limit` +* ("openconfig-platform": openconfig-version 0.23.0 -> 0.24.0) + +leaf deleted: `/openconfig-platform/components/component/linecard/state/slot-id` +* ("openconfig-platform-linecard": openconfig-version 1.1.0 -> 1.2.0) + +leaf deleted: `/openconfig-platform/components/component/linecard/utilization/resources/resource/state/max-limit` +* ("openconfig-platform": openconfig-version 0.23.0 -> 0.24.0) + +leaf deleted: `/openconfig-platform/components/component/port/breakout-mode/groups/group/config/num-breakouts` +* ("openconfig-platform-port": openconfig-version 1.0.1 -> 2.0.0) + +leaf deleted: `/openconfig-platform/components/component/port/breakout-mode/groups/group/state/num-breakouts` +* ("openconfig-platform-port": openconfig-version 1.0.1 -> 2.0.0) + +leaf updated: `/openconfig-platform/components/component/chassis/utilization/resources/resource/state/used` +* type changed from uint64 to uint32 +* ("openconfig-platform": openconfig-version 0.23.0 -> 0.24.0) + +leaf updated: `/openconfig-platform/components/component/integrated-circuit/utilization/resources/resource/state/used` +* type changed from uint64 to uint32 +* ("openconfig-platform": openconfig-version 0.23.0 -> 0.24.0) + +leaf updated: `/openconfig-platform/components/component/linecard/state/colour` +* type changed from string to binary +* ("openconfig-platform-linecard": openconfig-version 1.1.0 -> 1.2.0) + +leaf updated: `/openconfig-platform/components/component/linecard/utilization/resources/resource/state/used` +* type changed from uint64 to uint32 +* ("openconfig-platform": openconfig-version 0.23.0 -> 0.24.0) + +leaf updated: `/openconfig-platform/components/component/port/breakout-mode/groups/group/config/num-physical-channels` +* type changed from uint8 to uint16 +* ("openconfig-platform-port": openconfig-version 1.0.1 -> 2.0.0) + +leaf updated: `/openconfig-platform/components/component/port/breakout-mode/groups/group/state/num-physical-channels` +* type changed from uint8 to uint16 +* ("openconfig-platform-port": openconfig-version 1.0.1 -> 2.0.0) + +leaf added: `/openconfig-platform/components/component/chassis/utilization/resources/resource/state/total` +* ("openconfig-platform": openconfig-version 0.23.0 -> 0.24.0) + +leaf added: `/openconfig-platform/components/component/integrated-circuit/utilization/resources/resource/state/total` +* ("openconfig-platform": openconfig-version 0.23.0 -> 0.24.0) + +leaf added: `/openconfig-platform/components/component/linecard/state/slot-identifier` +* ("openconfig-platform-linecard": openconfig-version 1.1.0 -> 1.2.0) + +leaf added: `/openconfig-platform/components/component/linecard/utilization/resources/resource/state/total` +* ("openconfig-platform": openconfig-version 0.23.0 -> 0.24.0) + +leaf added: `/openconfig-platform/components/component/port/breakout-mode/groups/group/config/break-num` +* ("openconfig-platform-port": openconfig-version 1.0.1 -> 2.0.0) + +leaf added: `/openconfig-platform/components/component/port/breakout-mode/groups/group/state/break-num` +* ("openconfig-platform-port": openconfig-version 1.0.1 -> 2.0.0) + diff --git a/ocdiff/testdata/no-options.txt b/ocdiff/testdata/no-options.txt new file mode 100644 index 0000000..8f90dbf --- /dev/null +++ b/ocdiff/testdata/no-options.txt @@ -0,0 +1,18 @@ +leaf deleted: /openconfig-platform/components/component/chassis/utilization/resources/resource/state/max-limit ("openconfig-platform": openconfig-version 0.23.0 -> 0.24.0) +leaf deleted: /openconfig-platform/components/component/integrated-circuit/utilization/resources/resource/state/max-limit ("openconfig-platform": openconfig-version 0.23.0 -> 0.24.0) +leaf deleted: /openconfig-platform/components/component/linecard/state/slot-id ("openconfig-platform-linecard": openconfig-version 1.1.0 -> 1.2.0) +leaf deleted: /openconfig-platform/components/component/linecard/utilization/resources/resource/state/max-limit ("openconfig-platform": openconfig-version 0.23.0 -> 0.24.0) +leaf deleted: /openconfig-platform/components/component/port/breakout-mode/groups/group/config/num-breakouts ("openconfig-platform-port": openconfig-version 1.0.1 -> 2.0.0) +leaf deleted: /openconfig-platform/components/component/port/breakout-mode/groups/group/state/num-breakouts ("openconfig-platform-port": openconfig-version 1.0.1 -> 2.0.0) +leaf updated: /openconfig-platform/components/component/chassis/utilization/resources/resource/state/used: type changed from uint64 to uint32 ("openconfig-platform": openconfig-version 0.23.0 -> 0.24.0) +leaf updated: /openconfig-platform/components/component/integrated-circuit/utilization/resources/resource/state/used: type changed from uint64 to uint32 ("openconfig-platform": openconfig-version 0.23.0 -> 0.24.0) +leaf updated: /openconfig-platform/components/component/linecard/state/colour: type changed from string to binary ("openconfig-platform-linecard": openconfig-version 1.1.0 -> 1.2.0) +leaf updated: /openconfig-platform/components/component/linecard/utilization/resources/resource/state/used: type changed from uint64 to uint32 ("openconfig-platform": openconfig-version 0.23.0 -> 0.24.0) +leaf updated: /openconfig-platform/components/component/port/breakout-mode/groups/group/config/num-physical-channels: type changed from uint8 to uint16 ("openconfig-platform-port": openconfig-version 1.0.1 -> 2.0.0) +leaf updated: /openconfig-platform/components/component/port/breakout-mode/groups/group/state/num-physical-channels: type changed from uint8 to uint16 ("openconfig-platform-port": openconfig-version 1.0.1 -> 2.0.0) +leaf added: /openconfig-platform/components/component/chassis/utilization/resources/resource/state/total ("openconfig-platform": openconfig-version 0.23.0 -> 0.24.0) +leaf added: /openconfig-platform/components/component/integrated-circuit/utilization/resources/resource/state/total ("openconfig-platform": openconfig-version 0.23.0 -> 0.24.0) +leaf added: /openconfig-platform/components/component/linecard/state/slot-identifier ("openconfig-platform-linecard": openconfig-version 1.1.0 -> 1.2.0) +leaf added: /openconfig-platform/components/component/linecard/utilization/resources/resource/state/total ("openconfig-platform": openconfig-version 0.23.0 -> 0.24.0) +leaf added: /openconfig-platform/components/component/port/breakout-mode/groups/group/config/break-num ("openconfig-platform-port": openconfig-version 1.0.1 -> 2.0.0) +leaf added: /openconfig-platform/components/component/port/breakout-mode/groups/group/state/break-num ("openconfig-platform-port": openconfig-version 1.0.1 -> 2.0.0) diff --git a/ocdiff/testdata/yang/incl/openconfig-extensions.yang b/ocdiff/testdata/yang/incl/openconfig-extensions.yang new file mode 100644 index 0000000..2e0fd9f --- /dev/null +++ b/ocdiff/testdata/yang/incl/openconfig-extensions.yang @@ -0,0 +1,206 @@ +module openconfig-extensions { + + yang-version "1"; + + // namespace + namespace "http://openconfig.net/yang/openconfig-ext"; + + prefix "oc-ext"; + + // meta + organization "OpenConfig working group"; + + contact + "OpenConfig working group + www.openconfig.net"; + + description + "This module provides extensions to the YANG language to allow + OpenConfig specific functionality and meta-data to be defined."; + + oc-ext:openconfig-version "0.5.1"; + + revision "2022-10-05" { + description + "Add missing version statement."; + reference "0.5.1"; + } + + revision "2020-06-16" { + description + "Add extension for POSIX pattern statements."; + reference "0.5.0"; + } + + revision "2018-10-17" { + description + "Add extension for regular expression type."; + reference "0.4.0"; + } + + revision "2017-04-11" { + description + "rename password type to 'hashed' and clarify description"; + reference "0.3.0"; + } + + revision "2017-01-29" { + description + "Added extension for annotating encrypted values."; + reference "0.2.0"; + } + + revision "2015-10-09" { + description + "Initial OpenConfig public release"; + reference "0.1.0"; + } + + + // extension statements + extension openconfig-version { + argument "semver" { + yin-element false; + } + description + "The OpenConfig version number for the module. This is + expressed as a semantic version number of the form: + x.y.z + where: + * x corresponds to the major version, + * y corresponds to a minor version, + * z corresponds to a patch version. + This version corresponds to the model file within which it is + defined, and does not cover the whole set of OpenConfig models. + + Individual YANG modules are versioned independently -- the + semantic version is generally incremented only when there is a + change in the corresponding file. Submodules should always + have the same semantic version as their parent modules. + + A major version number of 0 indicates that this model is still + in development (whether within OpenConfig or with industry + partners), and is potentially subject to change. + + Following a release of major version 1, all modules will + increment major revision number where backwards incompatible + changes to the model are made. + + The minor version is changed when features are added to the + model that do not impact current clients use of the model. + + The patch-level version is incremented when non-feature changes + (such as bugfixes or clarifications to human-readable + descriptions that do not impact model functionality) are made + that maintain backwards compatibility. + + The version number is stored in the module meta-data."; + } + + extension openconfig-hashed-value { + description + "This extension provides an annotation on schema nodes to + indicate that the corresponding value should be stored and + reported in hashed form. + + Hash algorithms are by definition not reversible. Clients + reading the configuration or applied configuration for the node + should expect to receive only the hashed value. Values written + in cleartext will be hashed. This annotation may be used on + nodes such as secure passwords in which the device never reports + a cleartext value, even if the input is provided as cleartext."; + } + + extension regexp-posix { + description + "This extension indicates that the regular expressions included + within the YANG module specified are conformant with the POSIX + regular expression format rather than the W3C standard that is + specified by RFC6020 and RFC7950."; + } + + extension posix-pattern { + argument "pattern" { + yin-element false; + } + description + "Provides a POSIX ERE regular expression pattern statement as an + alternative to YANG regular expresssions based on XML Schema Datatypes. + It is used the same way as the standard YANG pattern statement defined in + RFC6020 and RFC7950, but takes an argument that is a POSIX ERE regular + expression string."; + reference + "POSIX Extended Regular Expressions (ERE) Specification: + https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_04"; + } + + extension telemetry-on-change { + description + "The telemetry-on-change annotation is specified in the context + of a particular subtree (container, or list) or leaf within the + YANG schema. Where specified, it indicates that the value stored + by the nodes within the context change their value only in response + to an event occurring. The event may be local to the target, for + example - a configuration change, or external - such as the failure + of a link. + + When a telemetry subscription allows the target to determine whether + to export the value of a leaf in a periodic or event-based fashion + (e.g., TARGET_DEFINED mode in gNMI), leaves marked as + telemetry-on-change should only be exported when they change, + i.e., event-based."; + } + + extension telemetry-atomic { + description + "The telemetry-atomic annotation is specified in the context of + a subtree (containre, or list), and indicates that all nodes + within the subtree are always updated together within the data + model. For example, all elements under the subtree may be updated + as a result of a new alarm being raised, or the arrival of a new + protocol message. + + Transport protocols may use the atomic specification to determine + optimisations for sending or storing the corresponding data."; + } + + extension operational { + description + "The operational annotation is specified in the context of a + grouping, leaf, or leaf-list within a YANG module. It indicates + that the nodes within the context are derived state on the device. + + OpenConfig data models divide nodes into the following three categories: + + - intended configuration - these are leaves within a container named + 'config', and are the writable configuration of a target. + - applied configuration - these are leaves within a container named + 'state' and are the currently running value of the intended configuration. + - derived state - these are the values within the 'state' container which + are not part of the applied configuration of the device. Typically, they + represent state values reflecting underlying operational counters, or + protocol statuses."; + } + + extension catalog-organization { + argument "org" { + yin-element false; + } + description + "This extension specifies the organization name that should be used within + the module catalogue on the device for the specified YANG module. It stores + a pithy string where the YANG organization statement may contain more + details."; + } + + extension origin { + argument "origin" { + yin-element false; + } + description + "This extension specifies the name of the origin that the YANG module + falls within. This allows multiple overlapping schema trees to be used + on a single network element without requiring module based prefixing + of paths."; + } +} diff --git a/ocdiff/testdata/yang/incl/types/.spec.yml b/ocdiff/testdata/yang/incl/types/.spec.yml new file mode 100644 index 0000000..44811de --- /dev/null +++ b/ocdiff/testdata/yang/incl/types/.spec.yml @@ -0,0 +1,10 @@ +- name: openconfig-types + docs: + - yang/types/openconfig-types.yang + - yang/types/openconfig-yang-types.yang + - yang/types/openconfig-inet-types.yang + build: + - yang/types/openconfig-types.yang + - yang/types/openconfig-yang-types.yang + - yang/types/openconfig-inet-types.yang + run-ci: false diff --git a/ocdiff/testdata/yang/incl/types/openconfig-inet-types.yang b/ocdiff/testdata/yang/incl/types/openconfig-inet-types.yang new file mode 100644 index 0000000..3d3ed42 --- /dev/null +++ b/ocdiff/testdata/yang/incl/types/openconfig-inet-types.yang @@ -0,0 +1,478 @@ +module openconfig-inet-types { + + yang-version "1"; + namespace "http://openconfig.net/yang/types/inet"; + prefix "oc-inet"; + + import openconfig-extensions { prefix "oc-ext"; } + + organization + "OpenConfig working group"; + + contact + "OpenConfig working group + www.openconfig.net"; + + description + "This module contains a set of Internet address related + types for use in OpenConfig modules. + + Portions of this code were derived from IETF RFC 6021. + Please reproduce this note if possible. + + IETF code is subject to the following copyright and license: + Copyright (c) IETF Trust and the persons identified as authors of + the code. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, is permitted pursuant to, and subject to the license + terms contained in, the Simplified BSD License set forth in + Section 4.c of the IETF Trust's Legal Provisions Relating + to IETF Documents (http://trustee.ietf.org/license-info)."; + + oc-ext:openconfig-version "0.6.0"; + + revision "2023-02-06" { + description + "Add ipv6-link-local and ipv6-address-type"; + reference "0.6.0"; + } + + revision "2021-08-17" { + description + "Add ip-address-zoned typedef as a union between ipv4-address-zoned + and ipv6-address-zoned types."; + reference "0.5.0"; + } + + revision "2021-07-14" { + description + "Use auto-generated regex for ipv4 pattern statements: + - ipv4-address + - ipv4-address-zoned + - ipv4-prefix"; + reference "0.4.1"; + } + + revision "2021-01-07" { + description + "Remove module extension oc-ext:regexp-posix by making pattern regexes + conform to RFC7950. + + Types impacted: + - ipv4-address + - ipv4-address-zoned + - ipv6-address + - domain-name"; + reference "0.4.0"; + } + + revision "2020-10-12" { + description + "Fix anchors for domain-name pattern."; + reference "0.3.5"; + } + + revision "2020-06-30" { + description + "Add OpenConfig POSIX pattern extensions and add anchors for domain-name + pattern."; + reference "0.3.4"; + } + + revision "2019-04-25" { + description + "Fix regex bug for ipv6-prefix type"; + reference "0.3.3"; + } + + revision "2018-11-21" { + description + "Add OpenConfig module metadata extensions."; + reference "0.3.2"; + } + + revision 2017-08-24 { + description + "Minor formatting fixes."; + reference "0.3.1"; + } + + revision 2017-07-06 { + description + "Add domain-name and host typedefs"; + reference "0.3.0"; + } + + revision 2017-04-03 { + description + "Add ip-version typedef."; + reference "0.2.0"; + } + + revision 2017-04-03 { + description + "Update copyright notice."; + reference "0.1.1"; + } + + revision 2017-01-26 { + description + "Initial module for inet types"; + reference "0.1.0"; + } + + // OpenConfig specific extensions for module metadata. + oc-ext:catalog-organization "openconfig"; + oc-ext:origin "openconfig"; + + // IPv4 and IPv6 types. + + typedef ipv4-address { + type string { + pattern + '([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|' + + '[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}'; + oc-ext:posix-pattern + '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|' + + '[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3})$'; + } + description + "An IPv4 address in dotted quad notation using the default + zone."; + } + + typedef ipv4-address-zoned { + type string { + pattern + '([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|' + + '[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}(%[a-zA-Z0-9_]+)'; + oc-ext:posix-pattern + '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|' + + '[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}(%[a-zA-Z0-9_]+))$'; + } + description + "An IPv4 address in dotted quad notation. This type allows + specification of a zone index to disambiguate identical + address values. For link-local addresses, the index is + typically the interface index or interface name."; + } + + typedef ipv6-address { + type string { + pattern + // Must support compression through different lengths + // therefore this regexp is complex. + '(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|' + + '([0-9a-fA-F]{1,4}:){1,7}:|' + + '([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|' + + '([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|' + + '([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|' + + '([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|' + + '([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|' + + '[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|' + + ':((:[0-9a-fA-F]{1,4}){1,7}|:)' + + ')'; + oc-ext:posix-pattern + // Must support compression through different lengths + // therefore this regexp is complex. + '^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|' + + '([0-9a-fA-F]{1,4}:){1,7}:|' + + '([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|' + + '([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|' + + '([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|' + + '([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|' + + '([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|' + + '[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|' + + ':((:[0-9a-fA-F]{1,4}){1,7}|:)' + + ')$'; + } + description + "An IPv6 address represented as either a full address; shortened + or mixed-shortened formats, using the default zone."; + } + + typedef ipv6-address-zoned { + type string { + pattern + // Must support compression through different lengths + // therefore this regexp is complex. + '^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|' + + '([0-9a-fA-F]{1,4}:){1,7}:|' + + '([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|' + + '([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|' + + '([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|' + + '([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|' + + '([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|' + + '[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|' + + ':((:[0-9a-fA-F]{1,4}){1,7}|:)' + + ')(%[a-zA-Z0-9_]+)$'; + oc-ext:posix-pattern + // Must support compression through different lengths + // therefore this regexp is complex. + '^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|' + + '([0-9a-fA-F]{1,4}:){1,7}:|' + + '([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|' + + '([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|' + + '([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|' + + '([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|' + + '([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|' + + '[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|' + + ':((:[0-9a-fA-F]{1,4}){1,7}|:)' + + ')(%[a-zA-Z0-9_]+)$'; + } + description + "An IPv6 address represented as either a full address; shortened + or mixed-shortened formats. This type allows specification of + a zone index to disambiguate identical address values. For + link-local addresses, the index is typically the interface + index or interface name."; + } + + typedef ipv4-prefix { + type string { + pattern + '([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|' + + '[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}/([0-9]|[12][0-9]|' + + '3[0-2])'; + oc-ext:posix-pattern + '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|' + + '[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}/([0-9]|[12][0-9]|' + + '3[0-2]))$'; + } + description + "An IPv4 prefix represented in dotted quad notation followed by + a slash and a CIDR mask (0 <= mask <= 32)."; + } + + typedef ipv6-prefix { + type string { + pattern + '(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|' + + '([0-9a-fA-F]{1,4}:){1,7}:|' + + '([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|' + + '([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|' + + '([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|' + + '([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|' + + '([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|' + + '[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|' + + ':((:[0-9a-fA-F]{1,4}){1,7}|:)' + + ')/(12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9])'; + oc-ext:posix-pattern + '^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|' + + '([0-9a-fA-F]{1,4}:){1,7}:|' + + '([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|' + + '([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|' + + '([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|' + + '([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|' + + '([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|' + + '[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|' + + ':((:[0-9a-fA-F]{1,4}){1,7}|:)' + + ')/(12[0-8]|1[0-1][0-9]|[1-9][0-9]|[0-9])$'; + } + description + "An IPv6 prefix represented in full, shortened, or mixed + shortened format followed by a slash and CIDR mask + (0 <= mask <= 128)."; + } + + typedef ip-address { + type union { + type ipv4-address; + type ipv6-address; + } + description + "An IPv4 or IPv6 address with no prefix specified."; + } + + typedef ip-address-zoned { + type union { + type ipv4-address-zoned; + type ipv6-address-zoned; + } + description + "An IPv4 or IPv6 address with no prefix specified and an optional + zone index."; + } + + typedef ip-prefix { + type union { + type ipv4-prefix; + type ipv6-prefix; + } + description + "An IPv4 or IPv6 prefix."; + } + + typedef ip-version { + type enumeration { + enum UNKNOWN { + value 0; + description + "An unknown or unspecified version of the Internet + protocol."; + } + enum IPV4 { + value 4; + description + "The IPv4 protocol as defined in RFC 791."; + } + enum IPV6 { + value 6; + description + "The IPv6 protocol as defined in RFC 2460."; + } + } + description + "This value represents the version of the IP protocol. + Note that integer representation of the enumerated values + are not specified, and are not required to follow the + InetVersion textual convention in SMIv2."; + reference + "RFC 791: Internet Protocol + RFC 2460: Internet Protocol, Version 6 (IPv6) Specification + RFC 4001: Textual Conventions for Internet Network Addresses"; + } + + typedef ipv6-address-type { + type enumeration { + enum GLOBAL_UNICAST { + description + "The IPv6 address is a global unicast address type and must be in + the format defined in RFC 4291 section 2.4."; + } + enum LINK_LOCAL_UNICAST { + description + "The IPv6 address is a Link-Local unicast address type and must be + in the format defined in RFC 4291 section 2.4."; + } + } + description + "The value represents the type of IPv6 address"; + reference + "RFC 4291: IP Version 6 Addressing Architecture + section 2.5"; + } + + typedef domain-name { + type string { + length "1..253"; + pattern + '(((([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.)*' + + '([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.?)' + + '|\.)'; + oc-ext:posix-pattern + '^(((([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.)*' + + '([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.?)' + + '|\.)$'; + } + description + "The domain-name type represents a DNS domain name. + Fully quallified left to the models which utilize this type. + + Internet domain names are only loosely specified. Section + 3.5 of RFC 1034 recommends a syntax (modified in Section + 2.1 of RFC 1123). The pattern above is intended to allow + for current practice in domain name use, and some possible + future expansion. It is designed to hold various types of + domain names, including names used for A or AAAA records + (host names) and other records, such as SRV records. Note + that Internet host names have a stricter syntax (described + in RFC 952) than the DNS recommendations in RFCs 1034 and + 1123, and that systems that want to store host names in + schema nodes using the domain-name type are recommended to + adhere to this stricter standard to ensure interoperability. + + The encoding of DNS names in the DNS protocol is limited + to 255 characters. Since the encoding consists of labels + prefixed by a length bytes and there is a trailing NULL + byte, only 253 characters can appear in the textual dotted + notation. + + Domain-name values use the US-ASCII encoding. Their canonical + format uses lowercase US-ASCII characters. Internationalized + domain names MUST be encoded in punycode as described in RFC + 3492"; + } + + typedef host { + type union { + type ip-address; + type domain-name; + } + description + "The host type represents either an unzoned IP address or a DNS + domain name."; + } + + typedef as-number { + type uint32; + description + "A numeric identifier for an autonomous system (AS). An AS is a + single domain, under common administrative control, which forms + a unit of routing policy. Autonomous systems can be assigned a + 2-byte identifier, or a 4-byte identifier which may have public + or private scope. Private ASNs are assigned from dedicated + ranges. Public ASNs are assigned from ranges allocated by IANA + to the regional internet registries (RIRs)."; + reference + "RFC 1930 Guidelines for creation, selection, and registration + of an Autonomous System (AS) + RFC 4271 A Border Gateway Protocol 4 (BGP-4)"; + } + + typedef dscp { + type uint8 { + range "0..63"; + } + description + "A differentiated services code point (DSCP) marking within the + IP header."; + reference + "RFC 2474 Definition of the Differentiated Services Field + (DS Field) in the IPv4 and IPv6 Headers"; + } + + typedef ipv6-flow-label { + type uint32 { + range "0..1048575"; + } + description + "The IPv6 flow-label is a 20-bit value within the IPv6 header + which is optionally used by the source of the IPv6 packet to + label sets of packets for which special handling may be + required."; + reference + "RFC 2460 Internet Protocol, Version 6 (IPv6) Specification"; + } + + typedef port-number { + type uint16; + description + "A 16-bit port number used by a transport protocol such as TCP + or UDP."; + reference + "RFC 768 User Datagram Protocol + RFC 793 Transmission Control Protocol"; + } + + typedef uri { + type string; + description + "An ASCII-encoded Uniform Resource Identifier (URI) as defined + in RFC 3986."; + reference + "RFC 3986 Uniform Resource Identifier (URI): Generic Syntax"; + } + + typedef url { + type string; + description + "An ASCII-encoded Uniform Resource Locator (URL) as defined + in RFC 3986, section 1.1.3"; + reference + "RFC 3986, paragraph 1.1.3"; + } + +} diff --git a/ocdiff/testdata/yang/incl/types/openconfig-types.yang b/ocdiff/testdata/yang/incl/types/openconfig-types.yang new file mode 100644 index 0000000..89e32d5 --- /dev/null +++ b/ocdiff/testdata/yang/incl/types/openconfig-types.yang @@ -0,0 +1,471 @@ +module openconfig-types { + yang-version "1"; + + namespace "http://openconfig.net/yang/openconfig-types"; + + prefix "oc-types"; + + // import statements + import openconfig-extensions { prefix oc-ext; } + + // meta + organization + "OpenConfig working group"; + + contact + "OpenConfig working group + netopenconfig@googlegroups.com"; + + description + "This module contains a set of general type definitions that + are used across OpenConfig models. It can be imported by modules + that make use of these types."; + + oc-ext:openconfig-version "0.6.0"; + + revision "2019-04-16" { + description + "Clarify definition of timeticks64."; + reference "0.6.0"; + } + + revision "2018-11-21" { + description + "Add OpenConfig module metadata extensions."; + reference "0.5.1"; + } + + revision "2018-05-05" { + description + "Add grouping of min-max-time and + included them to all stats with min/max/avg"; + reference "0.5.0"; + } + + revision "2018-01-16" { + description + "Add interval to min/max/avg stats; add percentage stat"; + reference "0.4.0"; + } + + revision "2017-08-16" { + description + "Apply fix for ieetfloat32 length parameter"; + reference "0.3.3"; + } + + revision "2017-01-13" { + description + "Add ADDRESS_FAMILY identity"; + reference "0.3.2"; + } + + revision "2016-11-14" { + description + "Correct length of ieeefloat32"; + reference "0.3.1"; + } + + revision "2016-11-11" { + description + "Additional types - ieeefloat32 and routing-password"; + reference "0.3.0"; + } + + revision "2016-05-31" { + description + "OpenConfig public release"; + reference "0.2.0"; + } + + // OpenConfig specific extensions for module metadata. + oc-ext:regexp-posix; + oc-ext:catalog-organization "openconfig"; + oc-ext:origin "openconfig"; + + typedef percentage { + type uint8 { + range "0..100"; + } + description + "Integer indicating a percentage value"; + } + + typedef std-regexp { + type string; + description + "This type definition is a placeholder for a standard + definition of a regular expression that can be utilised in + OpenConfig models. Further discussion is required to + consider the type of regular expressions that are to be + supported. An initial proposal is POSIX compatible."; + } + + typedef timeticks64 { + type uint64; + units "nanoseconds"; + description + "The timeticks64 represents the time, modulo 2^64 in + nanoseconds between two epochs. The leaf using this + type must define the epochs that tests are relative to."; + } + + typedef ieeefloat32 { + type binary { + length "4"; + } + description + "An IEEE 32-bit floating point number. The format of this number + is of the form: + 1-bit sign + 8-bit exponent + 23-bit fraction + The floating point value is calculated using: + (-1)**S * 2**(Exponent-127) * (1+Fraction)"; + } + + typedef routing-password { + type string; + description + "This type is indicative of a password that is used within + a routing protocol which can be returned in plain text to the + NMS by the local system. Such passwords are typically stored + as encrypted strings. Since the encryption used is generally + well known, it is possible to extract the original value from + the string - and hence this format is not considered secure. + Leaves specified with this type should not be modified by + the system, and should be returned to the end-user in plain + text. This type exists to differentiate passwords, which + may be sensitive, from other string leaves. It could, for + example, be used by the NMS to censor this data when + viewed by particular users."; + } + + typedef stat-interval { + type uint64; + units nanoseconds; + description + "A time interval over which a set of statistics is computed. + A common usage is to report the interval over which + avg/min/max stats are computed and reported."; + } + + grouping stat-interval-state { + description + "Reusable leaf definition for stats computation interval"; + + leaf interval { + type oc-types:stat-interval; + description + "If supported by the system, this reports the time interval + over which the min/max/average statistics are computed by + the system."; + } + } + + grouping min-max-time { + description + "Common grouping for recording the absolute time at which + the minimum and maximum values occurred in the statistics"; + + leaf min-time { + type oc-types:timeticks64; + description + "The absolute time at which the minimum value occurred. + The value is the timestamp in nanoseconds relative to + the Unix Epoch (Jan 1, 1970 00:00:00 UTC)."; + } + + leaf max-time { + type oc-types:timeticks64; + description + "The absolute time at which the maximum value occurred. + The value is the timestamp in nanoseconds relative to + the Unix Epoch (Jan 1, 1970 00:00:00 UTC)."; + } + } + + grouping avg-min-max-stats-precision1 { + description + "Common nodes for recording average, minimum, and + maximum values for a statistic. These values all have + fraction-digits set to 1. Statistics are computed + and reported based on a moving time interval (e.g., the last + 30s). If supported by the device, the time interval over which + the statistics are computed is also reported."; + + leaf avg { + type decimal64 { + fraction-digits 1; + } + description + "The arithmetic mean value of the statistic over the + time interval."; + } + + leaf min { + type decimal64 { + fraction-digits 1; + } + description + "The minimum value of the statistic over the time + interval."; + } + + leaf max { + type decimal64 { + fraction-digits 1; + } + description + "The maximum value of the statitic over the time + interval."; + } + + uses stat-interval-state; + uses min-max-time; + } + + grouping avg-min-max-instant-stats-precision1 { + description + "Common grouping for recording an instantaneous statistic value + in addition to avg-min-max stats"; + + leaf instant { + type decimal64 { + fraction-digits 1; + } + description + "The instantaneous value of the statistic."; + } + + uses avg-min-max-stats-precision1; + } + + grouping avg-min-max-instant-stats-precision2-dB { + description + "Common grouping for recording dB values with 2 decimal + precision. Values include the instantaneous, average, + minimum, and maximum statistics. Statistics are computed + and reported based on a moving time interval (e.g., the last + 30s). If supported by the device, the time interval over which + the statistics are computed, and the times at which the minimum + and maximum values occurred, are also reported."; + + leaf instant { + type decimal64 { + fraction-digits 2; + } + units dB; + description + "The instantaneous value of the statistic."; + } + + leaf avg { + type decimal64 { + fraction-digits 2; + } + units dB; + description + "The arithmetic mean value of the statistic over the + time interval."; + } + + leaf min { + type decimal64 { + fraction-digits 2; + } + units dB; + description + "The minimum value of the statistic over the time interval."; + } + + leaf max { + type decimal64 { + fraction-digits 2; + } + units dB; + description + "The maximum value of the statistic over the time + interval."; + } + + uses stat-interval-state; + uses min-max-time; + } + + grouping avg-min-max-instant-stats-precision2-dBm { + description + "Common grouping for recording dBm values with 2 decimal + precision. Values include the instantaneous, average, + minimum, and maximum statistics. Statistics are computed + and reported based on a moving time interval (e.g., the last + 30s). If supported by the device, the time interval over which + the statistics are computed, and the times at which the minimum + and maximum values occurred, are also reported."; + + leaf instant { + type decimal64 { + fraction-digits 2; + } + units dBm; + description + "The instantaneous value of the statistic."; + } + + leaf avg { + type decimal64 { + fraction-digits 2; + } + units dBm; + description + "The arithmetic mean value of the statistic over the + time interval."; + } + + leaf min { + type decimal64 { + fraction-digits 2; + } + units dBm; + description + "The minimum value of the statistic over the time + interval."; + } + + leaf max { + type decimal64 { + fraction-digits 2; + } + units dBm; + description + "The maximum value of the statistic over the time interval."; + } + + uses stat-interval-state; + uses min-max-time; + } + + grouping avg-min-max-instant-stats-precision2-mA { + description + "Common grouping for recording mA values with 2 decimal + precision. Values include the instantaneous, average, + minimum, and maximum statistics. Statistics are computed + and reported based on a moving time interval (e.g., the last + 30s). If supported by the device, the time interval over which + the statistics are computed, and the times at which the minimum + and maximum values occurred, are also reported."; + + leaf instant { + type decimal64 { + fraction-digits 2; + } + units mA; + description + "The instantaneous value of the statistic."; + } + + leaf avg { + type decimal64 { + fraction-digits 2; + } + units mA; + description + "The arithmetic mean value of the statistic over the + time interval."; + } + + leaf min { + type decimal64 { + fraction-digits 2; + } + units mA; + description + "The minimum value of the statistic over the time + interval."; + } + + leaf max { + type decimal64 { + fraction-digits 2; + } + units mA; + description + "The maximum value of the statistic over the time + interval."; + } + + uses stat-interval-state; + uses min-max-time; + } + + grouping avg-min-max-instant-stats-pct { + description + "Common grouping for percentage statistics. + Values include the instantaneous, average, + minimum, and maximum statistics. Statistics are computed + and reported based on a moving time interval (e.g., the last + 30s). If supported by the device, the time interval over which + the statistics are computed, and the times at which the minimum + and maximum values occurred, are also reported."; + + leaf instant { + type oc-types:percentage; + description + "The instantaneous percentage value."; + } + + leaf avg { + type oc-types:percentage; + description + "The arithmetic mean value of the percentage measure of the + statistic over the time interval."; + } + + leaf min { + type oc-types:percentage; + description + "The minimum value of the percentage measure of the + statistic over the time interval."; + } + + leaf max { + type oc-types:percentage; + description + "The maximum value of the percentage measure of the + statistic over the time interval."; + } + + uses stat-interval-state; + uses min-max-time; + } + + identity ADDRESS_FAMILY { + description + "A base identity for all address families"; + } + + identity IPV4 { + base ADDRESS_FAMILY; + description + "The IPv4 address family"; + } + + identity IPV6 { + base ADDRESS_FAMILY; + description + "The IPv6 address family"; + } + + identity MPLS { + base ADDRESS_FAMILY; + description + "The MPLS address family"; + } + + identity L2_ETHERNET { + base ADDRESS_FAMILY; + description + "The 802.3 Ethernet address family"; + } + +} diff --git a/ocdiff/testdata/yang/incl/types/openconfig-yang-types.yang b/ocdiff/testdata/yang/incl/types/openconfig-yang-types.yang new file mode 100644 index 0000000..c978cd0 --- /dev/null +++ b/ocdiff/testdata/yang/incl/types/openconfig-yang-types.yang @@ -0,0 +1,230 @@ +module openconfig-yang-types { + + yang-version "1"; + namespace "http://openconfig.net/yang/types/yang"; + prefix "oc-yang"; + + import openconfig-extensions { prefix "oc-ext"; } + + organization + "OpenConfig working group"; + + contact + "OpenConfig working group + www.openconfig.net"; + + description + "This module contains a set of extension types to the + YANG builtin types that are used across multiple + OpenConfig models. + + Portions of this code were derived from IETF RFC 6021. + Please reproduce this note if possible. + + IETF code is subject to the following copyright and license: + Copyright (c) IETF Trust and the persons identified as authors of + the code. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, is permitted pursuant to, and subject to the license + terms contained in, the Simplified BSD License set forth in + Section 4.c of the IETF Trust's Legal Provisions Relating + to IETF Documents (http://trustee.ietf.org/license-info)."; + + oc-ext:openconfig-version "0.3.1"; + + revision "2021-07-14" { + description + "Use auto-generated regex for certain pattern statements: + - dotted-quad + - date-and-time + - date + + For date-and-time, allow lowercase z and t in the pattern."; + reference "0.3.1"; + } + + revision "2021-03-02" { + description + "Fix date-and-time and date's pattern statement, and remove the + regexp-posix extension, which makes pattern statements conform to the + YANG standard."; + reference "0.3.0"; + } + + revision "2020-06-30" { + description + "Add OpenConfig POSIX pattern extensions."; + reference "0.2.2"; + } + + revision "2018-11-21" { + description + "Add OpenConfig module metadata extensions."; + reference "0.2.1"; + } + + revision 2018-04-24 { + description + "Add date typedef"; + reference "0.2.0"; + } + + revision 2017-07-30 { + description + "Fixed unprintable character"; + reference "0.1.2"; + } + + revision 2017-04-03 { + description + "Update copyright notice."; + reference "0.1.1"; + } + + revision 2017-01-26 { + description + "Initial module for inet types"; + reference "0.1.0"; + } + + // OpenConfig specific extensions for module metadata. + oc-ext:catalog-organization "openconfig"; + oc-ext:origin "openconfig"; + + typedef dotted-quad { + type string { + pattern + '([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|' + + '[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3}'; + oc-ext:posix-pattern + '^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\.([0-9]|' + + '[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])){3})$'; + } + description + "An unsigned 32-bit integer expressed as a dotted quad. The + format is four octets written as decimal numbers separated + with a period character."; + } + + typedef hex-string { + type string { + pattern '[0-9a-fA-F]*'; + oc-ext:posix-pattern '^[0-9a-fA-F]*$'; + } + description + "A string consisting of a hexadecimal characters."; + } + + typedef counter32 { + type uint32; + description + + "A 32-bit counter. A counter value is a monotonically increasing + value which is used to express a count of a number of + occurrences of a particular event or entity. When the counter + reaches its maximum value, in this case 2^32-1, it wraps to 0. + + Discontinuities in the counter are generally triggered only when + the counter is reset to zero."; + } + + typedef counter64 { + type uint64; + description + "A 64-bit counter. A counter value is a monotonically increasing + value which is used to express a count of a number of + occurrences of a particular event or entity. When a counter64 + reaches its maximum value, 2^64-1, it loops to zero. + Discontinuities in a counter are generally triggered only when + the counter is reset to zero, through operator or system + intervention."; + } + + typedef date-and-time { + type string { + pattern + '[0-9]{4}\-(0[1-9]|1[0-2])\-(0[1-9]|[12][0-9]|3[01])[Tt](0[0-9]|' + + '1[0-9]|2[0-3]):(0[0-9]|[1-5][0-9]):(0[0-9]|[1-5][0-9]|' + + '60)(\.[0-9]+)?([Zz]|([+-](0[0-9]|1[0-9]|2[0-3]):(0[0-9]|' + + '[1-5][0-9])))'; + oc-ext:posix-pattern + '^([0-9]{4}\-(0[1-9]|1[0-2])\-(0[1-9]|[12][0-9]|3[01])[Tt](0[0-9]|' + + '1[0-9]|2[0-3]):(0[0-9]|[1-5][0-9]):(0[0-9]|[1-5][0-9]|' + + '60)(\.[0-9]+)?([Zz]|([+-](0[0-9]|1[0-9]|2[0-3]):(0[0-9]|' + + '[1-5][0-9]))))$'; + } + description + "A date and time, expressed in the format described in RFC3339. + That is to say: + + YYYY-MM-DDTHH:MM:SSZ+-hh:mm + + where YYYY is the year, MM is the month expressed as a two-digit + month (zero padding if required), DD is the day of the month, + expressed as a two digit value. T is the literal character 'T', + HH is the hour of the day expressed as a two digit number, using + the 24-hour clock, MM is the minute of the hour expressed as a + two digit number. Z is the literal character 'Z', followed by a + timezone offset expressed in hours (hh) and minutes (mm), both + expressed as two digit numbers. The time offset is specified as + a positive or negative offset to UTC using the '+' or '-' + character preceding the offset. + + Optionally, fractional seconds can be expressed after the minute + of the hour as a decimal number of unspecified precision + reflecting fractions of a second."; + reference + "RFC3339 - Date and Time on the Internet: Timestamps"; + } + + typedef date { + type string { + pattern + '[0-9]{4}\-(0[1-9]|1[0-2])\-(0[1-9]|[12][0-9]|3[01])'; + oc-ext:posix-pattern + '^([0-9]{4}\-(0[1-9]|1[0-2])\-(0[1-9]|[12][0-9]|3[01]))$'; + } + description + "A full UTC date, expressed in the format described in RFC3339. + That is to say: + + YYYY-MM-DD + + where YYYY is the year, MM is the month expressed as a two-digit + month (zero padding if required), DD is the day of the month, + expressed as a two digit value."; + + reference + "RFC3339 - Date and Time on the Internet: full-date"; + } + + typedef gauge64 { + type uint64; + description + "A gauge value may increase or decrease - and reflects a value + at a particular point in time. If the value of the variable + being modeled using the gauge exceeds its maximum - 2^64-1 in + this case - the gauge is set to its maximum value."; + } + + typedef phys-address { + type string { + pattern '([0-9a-fA-F]{2}(:[0-9a-fA-F]{2})*)?'; + oc-ext:posix-pattern '^([0-9a-fA-F]{2}(:[0-9a-fA-F]{2})*)?$'; + } + description + "A physical layer address, expressed as a series of pairs of + hexadecimal digits."; + } + + typedef mac-address { + type string { + pattern '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}'; + oc-ext:posix-pattern '^[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}$'; + } + description + "An IEEE 802 MAC address"; + } +} diff --git a/ocdiff/testdata/yang/new/platform/.spec.yml b/ocdiff/testdata/yang/new/platform/.spec.yml new file mode 100644 index 0000000..59ffb1c --- /dev/null +++ b/ocdiff/testdata/yang/new/platform/.spec.yml @@ -0,0 +1,43 @@ +- name: openconfig-platform + docs: + - yang/platform/openconfig-platform.yang + - yang/platform/openconfig-platform-common.yang + - yang/platform/openconfig-platform-types.yang + - yang/platform/openconfig-platform-transceiver.yang + - yang/platform/openconfig-platform-linecard.yang + - yang/platform/openconfig-platform-port.yang + - yang/platform/openconfig-platform-psu.yang + - yang/platform/openconfig-platform-fan.yang + - yang/platform/openconfig-platform-cpu.yang + - yang/platform/openconfig-platform-ext.yang + - yang/platform/openconfig-platform-software.yang + - yang/platform/openconfig-platform-fabric.yang + - yang/platform/openconfig-platform-pipeline-counters.yang + - yang/platform/openconfig-platform-integrated-circuit.yang + - yang/platform/openconfig-platform-controller-card.yang + - yang/platform/openconfig-platform-healthz.yang + - yang/p4rt/openconfig-p4rt.yang + - yang/system/openconfig-alarms.yang + - yang/optical-transport/openconfig-terminal-device.yang + - yang/optical-transport/openconfig-transport-line-common.yang + build: + - yang/platform/openconfig-platform.yang + - yang/platform/openconfig-platform-common.yang + - yang/platform/openconfig-platform-transceiver.yang + - yang/platform/openconfig-platform-linecard.yang + - yang/platform/openconfig-platform-port.yang + - yang/platform/openconfig-platform-psu.yang + - yang/platform/openconfig-platform-fan.yang + - yang/platform/openconfig-platform-ext.yang + - yang/platform/openconfig-platform-cpu.yang + - yang/platform/openconfig-platform-software.yang + - yang/platform/openconfig-platform-fabric.yang + - yang/platform/openconfig-platform-pipeline-counters.yang + - yang/platform/openconfig-platform-integrated-circuit.yang + - yang/platform/openconfig-platform-controller-card.yang + - yang/platform/openconfig-platform-healthz.yang + - yang/p4rt/openconfig-p4rt.yang + - yang/system/openconfig-alarms.yang + - yang/optical-transport/openconfig-terminal-device.yang + - yang/optical-transport/openconfig-transport-line-common.yang + run-ci: true diff --git a/ocdiff/testdata/yang/new/platform/openconfig-platform-common.yang b/ocdiff/testdata/yang/new/platform/openconfig-platform-common.yang new file mode 100644 index 0000000..7a288dc --- /dev/null +++ b/ocdiff/testdata/yang/new/platform/openconfig-platform-common.yang @@ -0,0 +1,247 @@ +submodule openconfig-platform-common { + + yang-version "1"; + + belongs-to openconfig-platform { + prefix "oc-platform"; + } + + import openconfig-platform-types { prefix oc-platform-types; } + import openconfig-extensions { prefix oc-ext; } + import openconfig-types { prefix oc-types; } + + organization "OpenConfig working group"; + + contact + "OpenConfig working group + www.openconfig.net"; + + description + "This modules contains common groupings that are used in multiple + components within the platform module."; + + oc-ext:openconfig-version "0.24.0"; + + revision "2023-07-13" { + description + "Refactor resource utilization threshold config into a separate grouping. + Update 'utilization resource' to 'resource utilization'."; + reference "0.24.0"; + } + + revision "2023-02-13" { + description + "Refactor resource utilization threshold config into a separate grouping. + Update 'utilization resource' to 'resource utilization'."; + reference "0.23.0"; + } + + revision "2022-12-20" { + description + "Add threshold and threshold-exceeded for resource usage."; + reference "0.22.0"; + } + + revision "2022-12-19" { + description + "Update last-high-watermark timestamp documentation."; + reference "0.21.1"; + } + + revision "2022-09-26" { + description + "Add state data for base-mac-address."; + reference "0.21.0"; + } + + revision "2022-08-31" { + description + "Add new state data for component CLEI code."; + reference "0.20.0"; + } + + revision "2022-07-28" { + description + "Add grouping for component power management"; + reference "0.19.0"; + } + + revision "2022-07-11" { + description + "Add switchover ready"; + reference "0.18.0"; + } + + revision "2022-06-10" { + description + "Specify units and epoch for switchover and reboot times."; + reference "0.17.0"; + } + + revision "2022-04-21" { + description + "Add platform utilization."; + reference "0.16.0"; + } + + // extension statements + + // feature statements + + // identity statements + + // typedef statements + + // grouping statements + + grouping platform-resource-utilization-top { + description + "Top level grouping of platform resource utilization."; + + container utilization { + description + "Resource utilization of the component."; + + container resources { + description + "Enclosing container for the resources in this component."; + + list resource { + key "name"; + description + "List of resources, keyed by resource name."; + + leaf name { + type leafref { + path "../config/name"; + } + description + "References the resource name."; + } + + container config { + description + "Configuration data for each resource."; + + uses platform-resource-utilization-config; + } + + container state { + config false; + description + "Operational state data for each resource."; + + uses platform-resource-utilization-config; + uses platform-resource-utilization-state; + } + } + } + } + } + + grouping resource-utilization-threshold-common { + description + "Common threshold configuration model for resource utilization."; + leaf used-threshold-upper { + type oc-types:percentage; + description + "The used percentage value (used / (used + free) * 100) that + when crossed will set utilization-threshold-exceeded to 'true'."; + } + + leaf used-threshold-upper-clear { + type oc-types:percentage; + description + "The used percentage value (used / (used + free) * 100) that when + crossed will set utilization-threshold-exceeded to 'false'."; + } + } + + grouping platform-resource-utilization-config { + description + "Configuration data for resource utilization."; + + leaf name { + type string; + description + "Resource name within the component."; + } + + uses resource-utilization-threshold-common; + } + + grouping platform-resource-utilization-state { + description + "Operational state data for resource utilization."; + + leaf used { + type uint32; + description + "Number of entries currently in use for the resource."; + } + + leaf committed { + type uint64; + description + "Number of entries currently reserved for this resource. This is only + relevant to tables which allocate a block of resource for a given + feature."; + } + + leaf free { + type uint64; + description + "Number of entries available to use."; + } + + leaf total { + type uint64; + description + "Maximum number of entries available for the resource. The value + is the theoretical maximum resource utilization possible."; + } + + leaf high-watermark { + type uint64; + description + "A watermark of highest number of entries used for this resource."; + } + + leaf last-high-watermark { + type oc-types:timeticks64; + description + "The timestamp when the high-watermark was last updated. The value + is the timestamp in nanoseconds relative to the Unix Epoch + (Jan 1, 1970 00:00:00 UTC)."; + } + + leaf used-threshold-upper-exceeded { + type boolean; + description + "This value is set to true when the used percentage value + (used / (used + free) * 100) has crossed the used-threshold-upper for this + resource and false when the used percentage value has crossed the configured + used-threshold-upper-clear value for this resource."; + } + } + + grouping component-power-management { + description + "Common grouping for managing component power"; + + leaf power-admin-state { + type oc-platform-types:component-power-type; + default POWER_ENABLED; + description + "Enable or disable power to the component"; + } + } + + // data definition statements + + // augment statements + + // rpc statements + + // notification statements +} diff --git a/ocdiff/testdata/yang/new/platform/openconfig-platform-controller-card.yang b/ocdiff/testdata/yang/new/platform/openconfig-platform-controller-card.yang new file mode 100644 index 0000000..1bea20f --- /dev/null +++ b/ocdiff/testdata/yang/new/platform/openconfig-platform-controller-card.yang @@ -0,0 +1,81 @@ +module openconfig-platform-controller-card { + + yang-version "1"; + + // namespace + namespace "http://openconfig.net/yang/platform/controller-card"; + + prefix "oc-ctrl-card"; + + import openconfig-platform { prefix oc-platform; } + import openconfig-extensions { prefix oc-ext; } + + + // meta + organization "OpenConfig working group"; + + contact + "OpenConfig working group + www.openconfig.net"; + + description + "This module defines data related to CONTROLLER_CARD components in + the openconfig-platform model"; + + oc-ext:openconfig-version "0.1.0"; + + revision "2022-07-28" { + description + "Initial revision"; + reference "0.1.0"; + } + + // OpenConfig specific extensions for module metadata. + oc-ext:catalog-organization "openconfig"; + oc-ext:origin "openconfig"; + + // extension statements + + // feature statements + + // identity statements + + // typedef statements + + // grouping statements + + grouping controller-card-config { + description + "Configuration data for controller card components"; + + uses oc-platform:component-power-management; + } + + // data definition statements + + // augment statements + + augment "/oc-platform:components/oc-platform:component/" + + "oc-platform:controller-card/oc-platform:config" { + description + "Adding controller card data to physical inventory. This subtree + is only valid when the type of the component is CONTROLLER_CARD."; + + uses controller-card-config; + } + + augment "/oc-platform:components/oc-platform:component/" + + "oc-platform:controller-card/oc-platform:state" { + description + "Adding controller card data to physical inventory. This subtree + is only valid when the type of the component is CONTROLLER_CARD."; + + uses controller-card-config; + } + + // rpc statements + + // notification statements + +} + diff --git a/ocdiff/testdata/yang/new/platform/openconfig-platform-cpu.yang b/ocdiff/testdata/yang/new/platform/openconfig-platform-cpu.yang new file mode 100644 index 0000000..4182c77 --- /dev/null +++ b/ocdiff/testdata/yang/new/platform/openconfig-platform-cpu.yang @@ -0,0 +1,72 @@ +module openconfig-platform-cpu { + + yang-version "1"; + + // namespace + namespace "http://openconfig.net/yang/platform/cpu"; + + prefix "oc-cpu"; + + import openconfig-platform { prefix oc-platform; } + import openconfig-types { prefix oc-types; } + import openconfig-extensions { prefix oc-ext; } + + + // meta + organization "OpenConfig working group"; + + contact + "OpenConfig working group + www.openconfig.net"; + + description + "This module defines data related to FAN components in the + OpenConfig platform model."; + + oc-ext:openconfig-version "0.1.1"; + + revision "2018-11-21" { + description + "Add OpenConfig module metadata extensions."; + reference "0.1.1"; + } + + revision "2018-01-30" { + description + "Initial revision"; + reference "0.1.0"; + } + + // OpenConfig specific extensions for module metadata. + oc-ext:regexp-posix; + oc-ext:catalog-organization "openconfig"; + oc-ext:origin "openconfig"; + + grouping component-cpu-utilization { + description + "Per-component CPU statistics"; + + container utilization { + description + "Statistics representing CPU utilization of the + component."; + + container state { + config false; + description + "Operational state variables relating to the utilization + of the CPU."; + + uses oc-types:avg-min-max-instant-stats-pct; + } + } + } + + augment "/oc-platform:components/oc-platform:component/" + + "oc-platform:cpu" { + description + "Adding CPU utilization data to component model"; + + uses component-cpu-utilization; + } +} diff --git a/ocdiff/testdata/yang/new/platform/openconfig-platform-ext.yang b/ocdiff/testdata/yang/new/platform/openconfig-platform-ext.yang new file mode 100644 index 0000000..2e95427 --- /dev/null +++ b/ocdiff/testdata/yang/new/platform/openconfig-platform-ext.yang @@ -0,0 +1,82 @@ +module openconfig-platform-ext { + + yang-version "1"; + + // namespace + namespace "http://openconfig.net/yang/platform/extension"; + + prefix "oc-platform-ext"; + + import openconfig-platform { prefix oc-platform; } + import openconfig-extensions { prefix oc-ext; } + + + // meta + organization "OpenConfig working group"; + + contact + "OpenConfig working group + www.openconfig.net"; + + description + "This module defines optional extensions to the OpenConfig + platform model."; + + oc-ext:openconfig-version "0.1.1"; + + revision "2018-11-21" { + description + "Add OpenConfig module metadata extensions."; + reference "0.1.1"; + } + + revision "2018-01-18" { + description + "Initial revision"; + reference "0.1.0"; + } + + // OpenConfig specific extensions for module metadata. + oc-ext:regexp-posix; + oc-ext:catalog-organization "openconfig"; + oc-ext:origin "openconfig"; + + // identity statements + + // typedef statements + + // grouping statements + + + grouping platform-component-ext-state { + description + "Operational state data for platform components"; + + leaf entity-id { + type uint32; + description + "A unique numeric identifier assigned by the system to the + component. This identifier may be used to represent the + corresponding SNMP Entity MIB identifier."; + } + } + + + // data definition statements + + // augment statements + + augment "/oc-platform:components/oc-platform:component/" + + "oc-platform:state" { + description + "Adding extension state data to components"; + + uses platform-component-ext-state; + } + + // rpc statements + + // notification statements + +} + diff --git a/ocdiff/testdata/yang/new/platform/openconfig-platform-fabric.yang b/ocdiff/testdata/yang/new/platform/openconfig-platform-fabric.yang new file mode 100644 index 0000000..95d106c --- /dev/null +++ b/ocdiff/testdata/yang/new/platform/openconfig-platform-fabric.yang @@ -0,0 +1,81 @@ +module openconfig-platform-fabric { + + yang-version "1"; + + // namespace + namespace "http://openconfig.net/yang/platform/fabric"; + + prefix "oc-fabric"; + + import openconfig-platform { prefix oc-platform; } + import openconfig-extensions { prefix oc-ext; } + + + // meta + organization "OpenConfig working group"; + + contact + "OpenConfig working group + www.openconfig.net"; + + description + "This module defines data related to FABRIC components in + the openconfig-platform model"; + + oc-ext:openconfig-version "0.1.0"; + + revision "2022-07-28" { + description + "Initial revision"; + reference "0.1.0"; + } + + // OpenConfig specific extensions for module metadata. + oc-ext:catalog-organization "openconfig"; + oc-ext:origin "openconfig"; + + // extension statements + + // feature statements + + // identity statements + + // typedef statements + + // grouping statements + + grouping fabric-config { + description + "Configuration data for fabric components"; + + uses oc-platform:component-power-management; + } + + // data definition statements + + // augment statements + + augment "/oc-platform:components/oc-platform:component/" + + "oc-platform:fabric/oc-platform:config" { + description + "Adding fabric data to physical inventory. This subtree + is only valid when the type of the component is FABRIC."; + + uses fabric-config; + } + + augment "/oc-platform:components/oc-platform:component/" + + "oc-platform:fabric/oc-platform:state" { + description + "Adding fabric data to physical inventory. This subtree + is only valid when the type of the component is FABRIC."; + + uses fabric-config; + } + + // rpc statements + + // notification statements + +} + diff --git a/ocdiff/testdata/yang/new/platform/openconfig-platform-fan.yang b/ocdiff/testdata/yang/new/platform/openconfig-platform-fan.yang new file mode 100644 index 0000000..cd4a381 --- /dev/null +++ b/ocdiff/testdata/yang/new/platform/openconfig-platform-fan.yang @@ -0,0 +1,76 @@ +module openconfig-platform-fan { + + yang-version "1"; + + // namespace + namespace "http://openconfig.net/yang/platform/fan"; + + prefix "oc-fan"; + + import openconfig-platform { prefix oc-platform; } + import openconfig-extensions { prefix oc-ext; } + + + // meta + organization "OpenConfig working group"; + + contact + "OpenConfig working group + www.openconfig.net"; + + description + "This module defines data related to FAN components in the + OpenConfig platform model."; + + oc-ext:openconfig-version "0.1.1"; + + revision "2018-11-21" { + description + "Add OpenConfig module metadata extensions."; + reference "0.1.1"; + } + + revision "2018-01-18" { + description + "Initial revision"; + reference "0.1.0"; + } + + // OpenConfig specific extensions for module metadata. + oc-ext:regexp-posix; + oc-ext:catalog-organization "openconfig"; + oc-ext:origin "openconfig"; + + // identity statements + + // typedef statements + + // grouping statements + + grouping fan-state { + description + "Operational state data for fan components"; + + leaf speed { + type uint32; + units rpm; + description + "Current (instantaneous) fan speed"; + } + } + + + // data definition statements + + // augment statements + + augment "/oc-platform:components/oc-platform:component/" + + "oc-platform:fan/oc-platform:state" { + description + "Adding fan data to component model"; + + uses fan-state; + } + +} + diff --git a/ocdiff/testdata/yang/new/platform/openconfig-platform-healthz.yang b/ocdiff/testdata/yang/new/platform/openconfig-platform-healthz.yang new file mode 100644 index 0000000..11e44d3 --- /dev/null +++ b/ocdiff/testdata/yang/new/platform/openconfig-platform-healthz.yang @@ -0,0 +1,137 @@ +module openconfig-platform-healthz { + + yang-version "1"; + + // namespace + namespace "http://openconfig.net/yang/platform/healthz"; + + prefix "oc-platform-healthz"; + + import openconfig-extensions { prefix oc-ext; } + import openconfig-types { prefix oc-types; } + import openconfig-platform { prefix oc-platform; } + + // meta + organization "OpenConfig working group"; + + contact + "OpenConfig working group + www.openconfig.net"; + + description + "This model defines health-related variables for components + within the openconfig-platform model (which defines the + the /components hierarchy). It is designed to be used in + conjunction with the gNOI Healthz service (see + https://github.com/openconfig/gnoi/blob/main/healthz/README.md). + + The health variables included in this model are streamed via + telemetry interfaces, where gNOI.Healthz is used to retrieve + further diagnostic and debugging informaton from a network + device."; + + oc-ext:openconfig-version "0.1.1"; + + revision "2023-04-11" { + description + "Clarification for healthz state transition and unhealthy-count leaf"; + reference "0.1.1"; + } + + revision "2023-01-23" { + description + "Initial healthz variable revision"; + reference "0.1.0"; + } + + + grouping platform-health-top { + description + "Grouping containing health-related parameters."; + + container healthz { + description + "The health of the component. The paramaters within this + container indicate the status of the component beyond whether + it is operationally up or down. When a signal is received + that a component is in an unhealthy state the gNOI.Healthz + service can be used to retrieve further diagnostic information + relating to the component. + + The contents of this directory relate only to the specific + component that it is associated with. In the case that child + components become unhealthy and this causes a parent component + to be unhealthy, the new unhealthy status should be reported at + both components, such that an interested system can take the + relevant actions (e.g., retrieve the Healthz output, or + apply mitigation actions)."; + reference + "https://github.com/openconfig/gnoi/tree/main/healthz"; + + container state { + config false; + description + "Operational state parameters relating to component health."; + uses platform-health-state; + } + } + } + + grouping platform-health-state { + description + "Operational state parameters relating to a platform component's + health."; + + leaf status { + type enumeration { + enum UNSPECIFIED { + description + "The component's health status has not yet been checked + by the system."; + } + + enum HEALTHY { + description + "The component is in a HEALTHY state, and is operating + within the expected parameters."; + } + + enum UNHEALTHY { + description + "The component is in a unhealthy state, it is not + performing the function expected of it."; + } + } + description + "The status of the component, indicating its current health."; + oc-ext:telemetry-on-change; + } + + leaf last-unhealthy { + type oc-types:timeticks64; + description + "The time at which the component as last observed to be unhealthy + represented as nanoseconds since the Unix epoch. Unhealthy is defined + as the component being in a state other than HEALTHY."; + oc-ext:telemetry-on-change; + } + + leaf unhealthy-count { + type uint64; + description + "The number of status checks that have determined this component + to be in an unhealthy state. This counter should be incremented + when the component transitions from the HEALTHY to any other + state such that the value reflects the number of times the + component has become unhealthy."; + oc-ext:telemetry-on-change; + } + } + + augment "/oc-platform:components/oc-platform:component" { + description + "Augment healthz information into the /components/component hierarchy."; + + uses platform-health-top; + } +} diff --git a/ocdiff/testdata/yang/new/platform/openconfig-platform-integrated-circuit.yang b/ocdiff/testdata/yang/new/platform/openconfig-platform-integrated-circuit.yang new file mode 100644 index 0000000..67fec32 --- /dev/null +++ b/ocdiff/testdata/yang/new/platform/openconfig-platform-integrated-circuit.yang @@ -0,0 +1,180 @@ +module openconfig-platform-integrated-circuit { + yang-version "1"; + + namespace "http://openconfig.net/yang/platform/integrated-circuit"; + + prefix "oc-ic"; + + import openconfig-platform { prefix oc-platform; } + import openconfig-extensions { prefix oc-ext; } + + organization "OpenConfig working group"; + contact + "OpenConfig working group + www.openconfig.net"; + + description + "This module defines extensions to the OpenConfig platform model + that apply to integrated circuit (INTEGRATED_CIRCUIT) components. + These components are generically forwarding NPUs or ASICs within + the system for which configuration or state is applicable."; + + oc-ext:openconfig-version "0.3.1"; + + revision "2022-04-20" { + description + "Remove unused import"; + reference "0.3.1"; + } + + revision "2021-08-09" { + description + "Amendments to the platform capacity model."; + reference "0.3.0"; + } + + revision "2021-07-08" { + description + "Adding integrated circuit memory parity error counters."; + reference "0.2.0"; + } + + revision "2021-06-21" { + description + "Fix typos in description statements."; + reference "0.1.2"; + } + + revision "2021-06-16" { + description + "Remove trailing whitespace."; + reference "0.1.1"; + } + + revision "2021-05-16" { + description + "Initial revision with platform capacity."; + reference "0.1.0"; + } + + oc-ext:catalog-organization "openconfig"; + oc-ext:origin "openconfig"; + + grouping backplane-facing-capacity-structural { + description + "Structural grouping for reporting on backplane-facing capacity of an integrated + circuit."; + + container backplane-facing-capacity { + description + "This container allows a particular INTEGRATED_CIRCUIT to report its + available backplane-facing bandwidth. Where an integrated circuit is connected + by one or more links to the system's backplane, the capacity is the total cross- + sectional bandwidth available from the input ports of the integrated circuit + across the fabric. The capacity should also reflect the operational status of + the links."; + + container state { + config false; + description + "Operational state parameters relating to backplane capacity."; + + uses backplane-capacity-state; + } + } + } + + grouping backplane-capacity-state { + description + "Operational state relating to backplane capacity."; + + leaf total { + type uint64; + units "bits per second"; + description + "Total backplane-facing capacity that is available in the presence + of no link failures or degradation."; + oc-ext:telemetry-on-change; + } + + leaf total-operational-capacity { + type uint64; + units "bits per second"; + description + "Total backplane-facing capacity that is currently available based + on the active links."; + oc-ext:telemetry-on-change; + } + + leaf consumed-capacity { + type uint64; + units "bits per second"; + description + "Backplane-facing capacity that is consumed by front-panel ports that are connected + to the integrated circuit and are operationally up."; + oc-ext:telemetry-on-change; + } + + leaf available-pct { + type uint16; + description + "Percentage of the total backplane-facing capacity that is currently available to the front + panel ports taking into account failures and/or degradation within the system. + + In the case that there is more backplane-facing capacity available than the front-panel + ports consume, this value may be greater than 100%."; + oc-ext:telemetry-on-change; + } + } + + grouping integrated-circuit-memory { + description + "Structural grouping for integrated circuit memory."; + + container memory { + description + "Container for integrated circuit memory."; + + container state { + config false; + description + "Operational state parameters relating to integrated circuit memory."; + + uses integrated-circuit-memory-state; + } + } + } + + grouping integrated-circuit-memory-state { + description + "Counters that correspond to parity errors in integrated circuit memory"; + + leaf corrected-parity-errors { + type uint64; + description + "Number of corrected parity errors. Single bit ECC errors can be + detected and corrected by most integrated circuits."; + } + + leaf uncorrected-parity-errors { + type uint64; + description + "Number of uncorrected parity errors. Multi-bit ECC errors can be + detected but cannot be corrected by most integrated circuits."; + } + + leaf total-parity-errors { + type uint64; + description + "Total number of parity errors. This includes both the corrected and + uncorrected parity errors."; + } + } + + augment "/oc-platform:components/oc-platform:component/oc-platform:integrated-circuit" { + description + "Augment integrated circuit components with backplane-facing capacity and memory errors."; + uses backplane-facing-capacity-structural; + uses integrated-circuit-memory; + } +} diff --git a/ocdiff/testdata/yang/new/platform/openconfig-platform-linecard.yang b/ocdiff/testdata/yang/new/platform/openconfig-platform-linecard.yang new file mode 100644 index 0000000..0cf581c --- /dev/null +++ b/ocdiff/testdata/yang/new/platform/openconfig-platform-linecard.yang @@ -0,0 +1,157 @@ +module openconfig-platform-linecard { + + yang-version "1"; + + // namespace + namespace "http://openconfig.net/yang/platform/linecard"; + + prefix "oc-linecard"; + + import openconfig-platform { prefix oc-platform; } + import openconfig-extensions { prefix oc-ext; } + + + // meta + organization "OpenConfig working group"; + + contact + "OpenConfig working group + www.openconfig.net"; + + description + "This module defines data related to LINECARD components in + the openconfig-platform model"; + + oc-ext:openconfig-version "1.2.0"; + + revision "2023-07-13" { + description + "Renamed platform-utilization-top to platform-resource-utilization-top."; + reference "1.2.0"; + } + + revision "2023-02-13" { + description + "Renamed platform-utilization-top to platform-resource-utilization-top."; + reference "1.1.0"; + } + + revision "2022-07-28" { + description + "Remove leaf power-admin-state and use a common definition + instead."; + reference "1.0.0"; + } + + revision "2022-04-21" { + description + "Add platform utilization to linecard."; + reference "0.2.0"; + } + + revision "2020-05-10" { + description + "Remove when statement that references read-only entity from + a read-write context."; + reference "0.1.2"; + } + + revision "2018-11-21" { + description + "Add OpenConfig module metadata extensions."; + reference "0.1.1"; + } + + revision "2017-08-03" { + description + "Initial revision"; + reference "0.1.0"; + } + + // OpenConfig specific extensions for module metadata. + oc-ext:regexp-posix; + oc-ext:catalog-organization "openconfig"; + oc-ext:origin "openconfig"; + + // extension statements + + // feature statements + + // identity statements + + // typedef statements + + // grouping statements + + grouping linecard-config { + description + "Configuration data for linecard components"; + + uses oc-platform:component-power-management; + } + + grouping linecard-state { + description + "Operational state data for linecard components"; + + leaf slot-identifier { + type string; + description + "Identifier for the slot or chassis position in which the + linecard is installed"; + } + + leaf colour { + type binary; + description + "linecard colour"; + } + } + + grouping linecard-top { + description + "Top-level grouping for linecard data"; + + container linecard { + description + "Top-level container for linecard data"; + + container config { + description + "Configuration data for linecards"; + + uses linecard-config; + } + + container state { + + config false; + + description + "Operational state data for linecards"; + + uses linecard-config; + uses linecard-state; + } + uses oc-platform:platform-resource-utilization-top; + } + } + + // data definition statements + + // augment statements + + augment "/oc-platform:components/oc-platform:component" { + description + "Adding linecard data to physical inventory. This subtree + is only valid when the type of the component is LINECARD."; + + uses linecard-top; + } + + // rpc statements + + // notification statements + +} + diff --git a/ocdiff/testdata/yang/new/platform/openconfig-platform-pipeline-counters.yang b/ocdiff/testdata/yang/new/platform/openconfig-platform-pipeline-counters.yang new file mode 100644 index 0000000..e4bad82 --- /dev/null +++ b/ocdiff/testdata/yang/new/platform/openconfig-platform-pipeline-counters.yang @@ -0,0 +1,1341 @@ +module openconfig-platform-pipeline-counters { + + yang-version "1"; + + namespace "http://openconfig.net/yang/platform-pipeline-counters"; + prefix "oc-ppc"; + + import openconfig-yang-types { prefix oc-yang; } + import openconfig-types { prefix oc-types; } + import openconfig-extensions { prefix oc-ext; } + import openconfig-platform { prefix oc-platform; } + + organization + "OpenConfig working group"; + + contact + "OpenConfig working group + www.openconfig.net"; + + description + "Provide fine grain, per-Integrated Circuit (IC), telemetry data streams + that will identify the health, any packet drops, and any errors on the IC. + With this additional telemetry, the health of the IC, packet drops and + errors, can be explicitly monitored not only on a specific router, but also + on a specific IC on a specific router. The IC is divided into 5 platform + independent sub-blocks. + 1. IC Interface Subsystem + 2. Queueing Subsystem + 3. Lookup Subsystem + 4. Host Interface + 5. Fabric Interface. + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + | | + | +---------------------------------------------------------------+ | + | | Integrated +---------------------------------------+ | | + | | Circuit | Host Interface | | | + | | +---------------------------------------+ | | + | | +------------+ | | + | | +-----------+ | Lookup | +-------------+ | | + | | | IC | | Subsystem | | Fabric | | | + | | | Interface | | | | Interface | | | + | | | Subsystem | +------------+ | | | | + | | +-----------+ +-------------+ +-------------+ | | + | | | Queueing | | | + | | | Subsystem | | | + | | +-------------+ | | + | | | | + | +---------------------------------------------------------------+ | + | | + +-------------------------------------------------------------------+ + Each IC implementation inside forwarding engines may have a different set of + counters. Some counters have different names but the same + functionality and can be grouped together. Most counters are different + between IC families and will have to be aggregated as generic counters. The + aggregation could mean either a specific IC counter needs to be mapped to + one of the values specified in this model, or it may require multiple IC + counters aggregated to produce one of the values in this model. + The following classes of counters will generalize the types of + statistics that are provided from each of the above 5 blocks. + A. Packet Counters + B. Drop Counters + C. Error Counters + The advantage of grouping all the packet counters for all 5 blocks, + all drop counters from all 5 blocks, and all error counters from all + 5 blocks, is to have the abililty to receive all drop counters from + all 5 blocks, for example, with one request."; + + oc-ext:openconfig-version "0.4.0"; + oc-ext:catalog-organization "openconfig"; + oc-ext:origin "openconfig"; + + revision "2023-02-03" { + description + "Add vendor-specific control-plane traffic queue counters"; + reference "0.4.0"; + } + + revision "2022-12-01" { + description + "Add uRPF aggregate drop counter."; + reference "0.3.1"; + } + + revision "2022-11-09" { + description + "Add container for vendor specific drop counters."; + reference "0.3.0"; + } + + revision "2022-01-19" { + description + "Fixed typo for aggregate field."; + reference "0.2.1"; + } + + revision "2021-10-16" { + description + "Update pipeline error counters to allow for multiple errors + per block."; + reference "0.2.0"; + } + + revision "2020-07-31" { + description + "Initial revision of platform pipeline counters."; + reference "0.1.0"; + } + + grouping platform-pipeline-top { + description + "Top-level structural grouping for platform pipeline + counters."; + + container pipeline-counters { + config false; + description + "Top-level container for the packet, drop, and error counters for the + five NPU sub-blocks."; + container packet { + description + "IC packet counters for all five NPU sub-blocks."; + container interface-block { + description + "The IC interface subsystem connects the IC to the external PHY or + MAC."; + + // We do not need a 'config' container here since there is no configurable state for a particular + // entity. + + container state { + description + "State and counters corresponding to the interface subsystem of + the IC."; + + uses pipeline-counters-packet-interface-block-state; + } + } + + container lookup-block { + description + "The IC lookup subsystem perform the next hop lookup of the packet + and other forwarding features such as firewall filters."; + + container state { + description + "State and counters corresponding to the lookup subsystem of the + IC."; + + uses pipeline-counters-packet-lookup-block-state; + } + } + + container queueing-block { + description + "The IC queueing subsystem buffers the packet while processing it + and queues the packet for delivery to the next stage"; + + container state { + description + "State and counters corresponding to the queueing subsystem of + the IC."; + + uses pipeline-counters-packet-queueing-block-state; + } + } + + container fabric-block { + description + "The IC fabric block subsystem connects the IC to the external + systems fabric subsystem"; + + container state { + description + "State and counters corresponding to the fabric subsystem of the + IC."; + + uses pipeline-counters-packet-fabric-block-state; + } + } + + container host-interface-block { + description + "The IC host interface block subsystem connects the IC to the + external systems host or control subsystem"; + + container state { + description + "State and counters corresponding to the host interface subsystem + of the IC."; + + uses pipeline-counters-packet-host-interface-block-state; + } + } + } + + container drop { + description + "IC drop counters for all five NPU sub-blocks."; + container state { + description + "State container for IC drop counters"; + + uses pipeline-drop-packet-state; + } + + + container interface-block { + description + "The IC interface subsystem connects the IC to the external PHY or + MAC."; + + // We do not need a 'config' container here since there is no configurable state for a particular + // entity. + + container state { + description + "Drop counters corresponding to the interface subsystem of the + IC."; + + uses pipeline-drop-packet-interface-block-state; + } + } + + container lookup-block { + description + "The IC lookup subsystem perform the next hop lookup of the packet + and other forwarding features such as firewall filters."; + + container state { + description + "Drop counters corresponding to the lookup subsystem of the IC."; + + uses pipeline-drop-packet-lookup-block-state; + } + } + + container queueing-block { + description + "The IC queueing subsystem buffers the packet while processing it + and queues the packet for delivery to the next stage"; + + container state { + description + "Drop counters corresponding to the queueing subsystem of the + IC."; + + uses pipeline-drop-packet-queueing-block-state; + } + } + + container fabric-block { + description + "The IC fabric block subsystem connects the IC to the external + systems fabric subsystem"; + + container state { + description + "Drop counters corresponding to the fabric subsystem of the IC."; + + uses pipeline-drop-packet-fabric-block-state; + } + } + + container host-interface-block { + description + "The IC host interface block subsystem connects the IC to the + external systems host or control subsystem"; + + container state { + description + "Drop counters corresponding to the host interface subsystem of + the IC."; + + uses pipeline-drop-packet-host-interface-block-state; + } + } + + uses pipeline-vendor-drop-packets; + } + + container errors { + description + "IC errors for all five NPU sub-blocks."; + container interface-block { + description + "The IC interface subsystem connects the IC to the external PHY or + MAC."; + + list interface-block-error { + key "name"; + description + "An individual error within the interface block. Each error counter + is uniquely identified by the name of the error."; + + leaf name { + type leafref { + path "../state/name"; + } + description + "Reference to the name of the error being described."; + } + + container state { + description + "Errors corresponding to the interface subsystem of the IC."; + + uses pipeline-errors-packet-interface-block-state; + } + } + } + + container lookup-block { + description + "The IC lookup subsystem perform the next hop lookup of the packet + and other forwarding features such as firewall filters."; + + list lookup-block-error { + key "name"; + description + "An individual error within the lookup block. Each error counter + is uniquely identified by the name of the error."; + + leaf name { + type leafref { + path "../state/name"; + } + description + "Reference to the name of the error being described."; + } + + container state { + description + "Errors corresponding to the lookup subsystem of the IC."; + + uses pipeline-errors-packet-lookup-block-state; + } + } + } + + container queueing-block { + description + "The IC queueing subsystem buffers the packet while processing it + and queues the packet for delivery to the next stage"; + + list queueing-block-error { + key "name"; + description + "An individual error within the queueing block. Each error counter + is uniquely identified by the name of the error."; + + leaf name { + type leafref { + path "../state/name"; + } + description + "Reference to the name of the error being described."; + } + + container state { + description + "Errors corresponding to the queueing subsystem of the IC."; + + uses pipeline-errors-packet-queueing-block-state; + } + } + } + + container fabric-block { + description + "The IC fabric block subsystem connects the IC to the external + systems fabric subsystem"; + + list fabric-block-error { + key "name"; + description + "An individual error within the fabric block. Each error counter + is uniquely identified by the name of the error."; + + leaf name { + type leafref { + path "../state/name"; + } + description + "Reference to the name of the error being described."; + } + + container state { + description + "Errors corresponding to the fabric subsystem of the IC."; + + uses pipeline-errors-packet-fabric-block-state; + } + } + } + + container host-interface-block { + description + "The IC host interface block subsystem connects the IC to the + external systems host or control subsystem"; + + list host-interface-error { + key "name"; + description + "An individual error within the host interface block. Each error + counter is uniquely identified by the name of the error."; + + leaf name { + type leafref { + path "../state/name"; + } + description + "Reference to the name of the error being described."; + } + + container state { + description + "Errors corresponding to the host interface subsystem of + the IC."; + + uses pipeline-errors-packet-host-interface-block-state; + } + } + } + } + + uses pipeline-control-plane-top; + } + } + + grouping pipeline-packets-common { + description + "A common set of packet counters that apply to multiple packet sections."; + + leaf in-packets { + type oc-yang:counter64; + description + "Incoming packets towards the integrated-circuit interface + subsystem block from the line interfaces or fabric."; + } + + leaf out-packets { + type oc-yang:counter64; + description + "Outgoing packets towards the line interfaces or fabric from the + integrated-circuit interface subsystem block."; + } + + leaf in-bytes { + type oc-yang:counter64; + description + "Incoming bytes towards the integrated-circuit interface + subsystem block from the line interfaces or fabric."; + } + + leaf out-bytes { + type oc-yang:counter64; + description + "Outgoing bytes towards the line interfaces or fabric from the + integrated-circuit interface subsystem block."; + } + } + + grouping pipeline-counters-common-high-low-packets { + description + "A common set of high and low priority packet counters that apply to + multiple packet sections."; + + leaf in-high-priority-packets { + type oc-yang:counter64; + description + "Incoming high priority packets towards the integrated-circuit + fabric subsystem block from the previous NPU sub block."; + } + + leaf out-high-priority-packets { + type oc-yang:counter64; + description + "Outgoing high priority packets towards the fabric from the + integrated-circuit fabric subsystem block."; + } + + leaf in-low-priority-packets { + type oc-yang:counter64; + description + "Incoming low priority packets towards the integrated-circuit fabric + subsystem block from the previous NPU sub block."; + } + + leaf out-low-priority-packets { + type oc-yang:counter64; + description + "Outgoing low priority packets towards the fabric from the + integrated-circuit fabric subsystem block."; + } + + } + + grouping pipeline-counters-packet-interface-block-state { + description + "Each counter will aggregate incoming and outgoing packets and bytes + that connect the IC to the external MAC or PHY."; + + uses pipeline-packets-common; + + } + + grouping pipeline-counters-packet-lookup-block-state { + description + "The IC lookup subsystem counters include total packets/bytes in/out of + the lookup subsystem and performance metrics for key functionality of this + subsystem such as lookup memory usage, nexthop memory usage, ACL, + and firewall usage"; + + leaf lookup-utilization { + type oc-types:percentage; + description + "The integrated-circuit lookup subsystem block utilization percentage."; + } + + uses pipeline-packets-common; + + leaf lookup-memory { + type uint64; + units bytes; + description + "The total amount of memory available in the lookup subsystem."; + } + + leaf lookup-memory-used { + type uint64; + units bytes; + description + "The amount of memory used in the lookup subsystem."; + } + + leaf nexthop-memory { + type uint64; + units bytes; + description + "The total amount of nexthop memory available in the lookup subsystem."; + } + + leaf nexthop-memory-used { + type uint64; + units bytes; + description + "The amount of nexthops memory used in the lookup subsystem."; + } + + leaf acl-memory-total-entries { + type uint64; + description + "Total firewall or ACL memory counter measured in entries."; + } + + leaf acl-memory-used-entries { + type uint64; + description + "Amount of used firewall or ACL memory counter measured in entries. + The number of used entries must include the entries + that are 'allocated but free' if the memory reaping algorithm makes + these entries practically unusable."; + } + + leaf acl-memory-total-bytes { + type uint64; + units bytes; + description + "Total firewall or ACL memory counter measured in bytes."; + } + + leaf acl-memory-used-bytes { + type uint64; + units bytes; + description + "Amount of used firewall or ACL memory counter measured in bytes. + The number of used bytes must include the bytes + that are 'allocated but free' if the memory reaping algorithm makes + these bytes practically unusable"; + } + + leaf fragment-total-pkts { + type oc-yang:counter64; + description + "Total number of fragments generated by the CPU."; + } + + } + + grouping pipeline-counters-packet-queueing-block-state { + description + "The IC queueing subsystem counters include packets/bytes in/out of the + queueing subsystem and performance metrics for key functionality of this + subsystem such as memory used and loopback counts."; + + uses pipeline-packets-common; + + leaf queue-memory { + type uint64; + units bytes; + description + "The total amount of memory available in the queue subsystem."; + } + + leaf queue-memory-used { + type uint64; + units bytes; + description + "The amount of memory used in the queue subsystem."; + } + + leaf loopback-packets { + type oc-yang:counter64; + description + "The number of packets in the loopback or re-circulate subsystem."; + } + + leaf loopback-bytes { + type uint64; + units bytes; + description + "The number of bytes in the loopback or re-circulate subsystem."; + } + + } + + grouping pipeline-counters-packet-fabric-block-state { + description + "The IC fabric subsystem counters include packets/cells in/out of the + fabric subsystem and performance metrics for key functionality of this + subsystem such as high and low priority packet counts."; + + leaf in-cells { + type oc-yang:counter64; + description + "Incoming cells towards the integrated-circuit fabric + subsystem block from the previous NPU sub block."; + } + + leaf out-cells { + type oc-yang:counter64; + description + "Outgoing cells towards the fabric from the + integrated-circuit fabric subsystem block."; + } + + uses pipeline-packets-common; + + leaf in-high-priority-cells { + type oc-yang:counter64; + description + "Incoming high priority cells towards the integrated-circuit fabric + subsystem block from the previous NPU sub block."; + } + + leaf out-high-priority-cells { + type oc-yang:counter64; + description + "Outgoing high priority cells towards the fabric from the + integrated-circuit fabric subsystem block."; + } + + leaf in-low-priority-cells { + type oc-yang:counter64; + description + "Incoming low priority cells towards the integrated-circuit fabric + subsystem block from the previous NPU sub block."; + } + + leaf out-low-priority-cells { + type oc-yang:counter64; + description + "Outgoing low priority cells towards the fabric from the + integrated-circuit fabric subsystem block."; + } + + uses pipeline-counters-common-high-low-packets; + + } + + grouping pipeline-counters-packet-host-interface-block-state { + description + "The IC host interface counters include packets/bytes in/out of the + host interface subsystem and performance metrics for key functionality + of this subsystem such as fragmented packet counts and hi/low priority + packet counts"; + + uses pipeline-packets-common; + + leaf fragment-punt-pkts{ + type oc-yang:counter64; + description + "The packets that were successfully punted to CPU due to egress MTU + exceeded."; + } + + uses pipeline-counters-common-high-low-packets; + + } + + grouping pipeline-drops-common { + description + "A common set of drop counters that apply to multiple drop sections."; + + leaf oversubscription { + type oc-yang:counter64; + description + "Number of packets dropped due to oversubscription of the + integrated-circuit subsystem block."; + } + } + + grouping pipeline-drops-common-high-low { + description + "A common set of drop counters for high and low priority."; + + leaf in-high-priority { + type oc-yang:counter64; + description + "Incoming high priority drops towards this integrated-circuit + subsystem block from the previous NPU sub-block or interface."; + } + + leaf out-high-priority { + type oc-yang:counter64; + description + "Outgoing high priority drops towards the fabric/interface from this + integrated-circuit subsystem block."; + } + + leaf in-low-priority { + type oc-yang:counter64; + description + "Incoming low priority drops towards this integrated-circuit + subsystem block from the previous NPU sub-block or interface."; + } + + leaf out-low-priority { + type oc-yang:counter64; + description + "Outgoing low priority drops towards the fabric/interface from this + integrated-circuit subsystem block."; + } + } + + grouping pipeline-drop-packet-interface-block-state { + description + "Each drop counter will aggregate incoming and outgoing packets, and + oversubscription drops that connect the IC to the external MAC or PHY."; + + uses pipeline-drops-common; + + leaf in-drops { + type oc-yang:counter64; + description + "Incoming drops towards the integrated-circuit interface + subsystem block from the interfaces due to any reason."; + } + + leaf out-drops { + type oc-yang:counter64; + description + "Outgoing drops towards the interfaces from the + integrated-circuit interface subsystem block due to any reason."; + } + + } + + grouping pipeline-drop-packet-lookup-block-state { + description + "The IC lookup subsystem drop counters track key functionality of this + subsystem such as Oversubscription, no-route, no-label, no-NH, invalid- + packets, forwarding-policy, incorrect-software, rate-limit, fragments, + and firewall drops"; + + uses pipeline-drops-common; + + leaf no-route { + type oc-yang:counter64; + description + "Packets dropped due to no FIB entry for this ipv4 or ipv6 lookup."; + } + + leaf no-label { + type oc-yang:counter64; + description + "Packets dropped due to no FIB entry for this MPLS label."; + } + + leaf no-nexthop { + type oc-yang:counter64; + description + "Packets dropped due to no nexthop information - either the nexthop is + not programmed, or there is an invalid nexthop, or there is no ARP + information so the nexthop is in invalid state."; + } + + leaf invalid-packet { + type oc-yang:counter64; + description + "Packets dropped due to invalid packet format for ipv4, ipv6, or MPLS."; + } + + leaf forwarding-policy { + type oc-yang:counter64; + description + "Packets dropped due to either a filter applied as part of a forwarding + policy or dropped due to a policy-based-routing policy lookup."; + } + + leaf incorrect-software-state { + type oc-yang:counter64; + description + "Packets dropped due to any incorrect or invalid software state of the + forwarding structures during lookup."; + } + + leaf rate-limit { + type oc-yang:counter64; + description + "Packets dropped due to rate limiters - either user configured rate + limiters or system rate limiters in the forwarding path."; + } + + leaf fragment-total-drops { + type oc-yang:counter64; + description + "Total number of packets dropped that could not be fragmented by NPU + due to DF bit."; + } + + leaf lookup-aggregate { + type oc-yang:counter64; + description + "Packets dropped due to aggregate lookup drop counters - this counter + is sometimes referred to as Normal Discards or + ENQ_DISCARDED_PACKET_COUNTER."; + } + + leaf acl-drops { + type oc-yang:counter64; + description + "Packets dropped due to firewall or acl terms."; + } + + } + + grouping pipeline-drop-packet-queueing-block-state { + description + "The IC queueing subsystem drop counters track key functionality of this + subsystem such as oversubscription, memory-limit, incorrect-state, and + loopback drops."; + + uses pipeline-drops-common; + + leaf memory-limit { + type oc-yang:counter64; + description + "Packets dropped due to running out of the queue memory."; + } + + leaf incorrect-state { + type oc-yang:counter64; + description + "Packets dropped due to hardware of software incorrect state of VOQs, + or fabric queues, or interface queues."; + } + + leaf lookup-queue { + type oc-yang:counter64; + description + "Packets dropped in either the lookup or recirculation path."; + } + + } + + grouping pipeline-drop-packet-fabric-block-state { + description + "The IC fabric subsystem drop counters track key functionality of this + subsystem such as oversubscription, lost-packets, high and low priority + packet drops."; + + uses pipeline-drops-common; + + leaf lost-packets { + type oc-yang:counter64; + description + "Fabric drops due to re-ordering, or due to packets arriving late, or + due to some loss in the fabric."; + } + + uses pipeline-drops-common-high-low; + + leaf fabric-aggregate { + type oc-yang:counter64; + description + "Aggregate of fabric-in and fabric-out drops."; + } + + } + + grouping pipeline-drop-packet-host-interface-block-state { + description + "The IC host interface drop counters track key funcitonality of this + subsystem such as oversubscription, rate-limit, fragment, and + hi/low priority drop counts"; + + uses pipeline-drops-common; + + leaf rate-limit { + type oc-yang:counter64; + description + "Packet drops due to the rate limit in the integrated-circuit host + subsystem block."; + } + + uses pipeline-drops-common-high-low; + + leaf fragment-punt { + type oc-yang:counter64; + description + "The packets that were failed to punt to CPU due to policing rate."; + } + + leaf host-aggregate { + type oc-yang:counter64; + description + "Aggregate of all the drops in the host path."; + } + + } + + grouping pipeline-errors-common { + description + "A common set of error counters that apply to multiple error sections."; + + leaf name { + type string; + description + "Name of the interrupt, hardware error, or software error in the NPU."; + } + + leaf count { + type uint64; + description + "Total count of errors of this type."; + } + + leaf threshold { + type uint64; + description + "Number of errors before a recovery action is automatically + taken by the system."; + } + + leaf-list action { + type enumeration { + enum LOG { + description + "Log a descriptive message."; + } + enum LINECARD_REBOOT { + description + "The line card is brought offline and then back online."; + } + enum LINECARD_OFFLINE { + description + "The line card is brought offline."; + } + enum NPU_RESET { + description + "The NPU is brought offline and then back online."; + } + enum NPU_OFFLINE { + description + "The NPU is brought offline."; + } + enum GET_DIAGNOSTIC_INFO { + description + "Diagnostic data is gathered at the time of the problem."; + } + enum ALARM { + description + "An Alarm is raised"; + } + } + description + "Error actions that are taken by the system - log, linecard reboot, + linecard offline, NPU reset, NPU offline, gather diagnostic data, + raise an alarm."; + } + + leaf active { + type boolean; + default false; + description + "The error is currently in an active state. When the system detects + that the specified threshold is exceeded, this value should be set to + true."; + oc-ext:telemetry-on-change; + } + + leaf level { + type enumeration { + enum FATAL { + description + "The Fatal error causes total packet loss"; + } + enum MAJOR { + description + "The Major error causes persistent packet loss"; + } + enum MINOR { + description + "The Minor error is an indication of some past problem, but now is + corrected"; + } + enum INFORMATIONAL { + description + "Some problem happened that is not packet loss affecting."; + } + } + description + "The severity of the error that is being recorded by the system. This + value can be used by a consumer to determine the action when this error + is recorded."; + } + } + + grouping pipeline-errors-packet-interface-block-state { + description + "Error counter will aggregate the errors that connect the IC to the + external MAC or PHY. Each error should contain the name, count, + last-occurrence, threshold, action, and severity level."; + + uses pipeline-errors-common; + + } + + grouping pipeline-errors-packet-lookup-block-state { + description + "The IC lookup subsystem error counters include the errors encountered by + the lookup subsystem. Each error should contain the name, count, + last-occurrence, threshold, action, and severity level."; + + uses pipeline-errors-common; + + } + + grouping pipeline-errors-packet-queueing-block-state { + description + "The IC queueing subsystem error counters include the errors encountered + by the queueing subsystem. Each error should contain the name, count, + last-occurrence, threshold, action, and severity level."; + + uses pipeline-errors-common; + + } + + grouping pipeline-errors-packet-fabric-block-state { + description + "The IC fabric subsystem error counters include the errors encountered by + the fabric subsystem. Each error should contain the name, count, + last-occurrence, threshold, action, and severity level."; + + uses pipeline-errors-common; + + } + + grouping pipeline-errors-packet-host-interface-block-state { + description + "The IC host interface error counters include the errors encountered by + the host interface subsystem. Each error should contain the name, count, + last-occurrence, threshold, action, and severity level."; + + uses pipeline-errors-common; + + } + + grouping pipeline-drop-packet-state { + description + "Grouping of pipeline drop packet state."; + + leaf adverse-aggregate { + type oc-yang:counter64; + description + "This captures the aggregation of all counters where the switch is + unexpectedly dropping packets. Occurrence of these drops on a stable + (no recent hardware or config changes) and otherwise healthy + switch needs further investigation."; + } + + leaf congestion-aggregate { + type oc-yang:counter64; + description + "This tracks the aggregation of all counters where the expected + conditions of packet drops due to internal congestion in some block of + the hardware that may not be visible in through other congestion + indicators like interface discards or queue drop counters."; + } + + leaf packet-processing-aggregate { + type oc-yang:counter64; + description + "This aggregation of counters represents the conditions in which + packets are dropped due to legitimate forwarding decisions (ACL drops, + No Route etc.)"; + } + + leaf urpf-aggregate { + type oc-yang:counter64; + description + "This aggregation of counters represents the conditions in which + packets are dropped due to failing uRPF lookup check. This counter + and the packet-processing-aggregate counter should be incremented + for each uRPF packet drop."; + } + + } + + grouping pipeline-vendor-drop-packets { + description + "Grouping for vendor specific drop packets"; + + container vendor { + description + "Counters within these containers are defined and augmented by vendors. + As each ASIC and vendor has different implementation and internal + parts where packets may be dropped at any point in time. Providing + specific hardware counters provides better visibility into traffic drop. + + The recommended usage of this container is to create an augment at + .../pipeline-counter/drop/vendor that contains additional vendor/platform + specific containers. + + e.g. + augment /components/component/integrated-circuit/pipeline-counter/drop/vendor { + container { + container { + uses pipeline-vendor-drop-containers; + } + } + }"; + + reference + "https://github.com/openconfig/public/tree/master/doc/vendor_counter_guide.md"; + } + } + + grouping pipeline-vendor-drop-containers { + description + "A utility grouping for vendors to insert when augmenting the vendor + drop counters container .../pipeline-counter/drop/vendor. + + Counters that cannot differentiate between adverse, congestion, and + packet-processing should still be exposed as a vendor-specific, + packet-processing counter."; + + reference + "https://github.com/openconfig/public/tree/master/doc/vendor_counter_guide.md"; + + container adverse { + description + "These counters capture where the switch is unexpectedly dropping + packets. Occurrence of these drops on a stable (no recent hardware + or config changes) and otherwise healthy switch needs further + investigation. + + The sum of all counters under this container should match the value in + .../pipeline-counters/drop/state/adverse-aggregate"; + + container state { + description + "State container for vendor specific adverse counters."; + } + } + + container congestion { + description + "These counters track expected conditions of packet drops due to + internal congestion in some block of the hardware that may not be + visible in through other congestion indicators like interface + discards or queue drop counters. + + The sum of all counters under this container should match the value in + .../pipeline-counters/drop/state/congestion-aggregate"; + + container state { + description + "State container for vendor specific congestion counters."; + } + } + + container packet-processing { + description + "These counters represent the conditions in which packets are dropped + due to legitimate forwarding decisions (ACL drops, No Route etc.) + + The sum of all counters under this container should match the value in + .../pipeline-counters/drop/state/packet-processing-aggregate"; + + container state { + description + "State container for vendor specific packet processing counters."; + } + } + } + + grouping control-plane-traffic-counters-state { + description + "Control plane traffic counter state grouping."; + + leaf queued-aggregate { + type oc-yang:counter64; + description + "This captures the aggregation of all counters where the switch has enqueued + traffic related to the control-plane."; + } + + leaf queued-bytes-aggregate { + type oc-yang:counter64; + description + "This captures the aggregation of all counters in bytes where the switch has + enqueued traffic related to the control-plane."; + } + + leaf dropped-aggregate { + type oc-yang:counter64; + description + "This captures the aggregation of all counters where the switch has dropped + traffic related to the control-plane."; + } + + leaf dropped-bytes-aggregate { + type oc-yang:counter64; + description + "This captures the aggregation of all counters in bytes where the switch has + dropped traffic related to the control-plane."; + } + } + + grouping control-plane-traffic-vendor-counters { + description + "A utility grouping for vendors to use when augmenting the vendor-specific + control-plane traffic container."; + + leaf queued { + type oc-yang:counter64; + description + "This counter counts the number of packets enqueued. + + This counter should contribute to the total aggregate of + .../pipeline-counters/control-plane-traffic/state/queued-aggregate."; + } + + leaf queued-bytes { + type oc-yang:counter64; + description + "This counter counts the number of bytes enqueued. + + This counter should contribute to the total aggregate of + .../pipeline-counters/control-plane-traffic/state/queued-bytes-aggregate."; + } + + leaf dropped { + type oc-yang:counter64; + description + "This counter counts the number of packets dropped. + + This counter should contribute to the total aggregate of + .../pipeline-counters/control-plane-traffic/state/dropped-aggregate."; + } + + leaf dropped-bytes { + type oc-yang:counter64; + description + "This counter counts the number of bytes dropped. + + This counter should contribute to the total aggregate of + .../pipeline-counters/control-plane-traffic/state/dropped-bytes-aggregate."; + } + } + + grouping pipeline-control-plane-top { + description + "Top-level structural grouping for control-plane traffic counters."; + + container control-plane-traffic { + description + "Counters that are related to traffic destined to the control-plane."; + + container state { + config false; + description + "State container for control-plane traffic counters."; + + uses control-plane-traffic-counters-state; + } + + container vendor { + description + "Counters within these containers are defined and augmented by vendors. + As each ASIC and vendor has different implementation and internal + parts where packets may be dropped at any point in time. Providing + vendor-specific counters provides better visibility into control-plane traffic. + + The recommended usage of this container is to create an augment at + .../pipeline-counter/control-plane-traffic/vendor that contains additional + vendor/platform specific containers. + + e.g. + augment /components/component/integrated-circuit/pipeline-counter/control-plane-traffic/vendor { + container { + container { + container state { + leaf counter-a { + uses control-plane-traffic-vendor-counters; + } + + leaf counter-b { + uses control-plane-traffic-vendor-counters; + } + } + } + } + }"; + + reference + "https://github.com/openconfig/public/tree/master/doc/vendor_counter_guide.md"; + } + } + } + + augment "/oc-platform:components/oc-platform:component/oc-platform:integrated-circuit" { + description + "Add operational state data that corresponds to sub-blocks of an integrated + circuit (NPU, ASIC) to the platform model."; + + uses platform-pipeline-top; + } +} diff --git a/ocdiff/testdata/yang/new/platform/openconfig-platform-port.yang b/ocdiff/testdata/yang/new/platform/openconfig-platform-port.yang new file mode 100644 index 0000000..02db3b3 --- /dev/null +++ b/ocdiff/testdata/yang/new/platform/openconfig-platform-port.yang @@ -0,0 +1,306 @@ +module openconfig-platform-port { + + yang-version "1"; + + // namespace + namespace "http://openconfig.net/yang/platform/port"; + + prefix "oc-port"; + + // import some basic types + import openconfig-platform { prefix oc-platform; } + import openconfig-extensions { prefix oc-ext; } + + // meta + organization "OpenConfig working group"; + + contact + "OpenConfig working group + www.openconfig.net"; + + description + "This module defines data related to PORT components in the + openconfig-platform model"; + + oc-ext:openconfig-version "2.0.0"; + + revision "2023-07-22" { + description + "Clarify use of the interface-ref type."; + reference "2.0.0"; + } + + revision "2023-03-22" { + description + "Clarify use of the interface-ref type."; + reference "1.0.1"; + } + + revision "2023-01-19" { + description + "Add clarification of the definition of a physical channel, and + example configurations."; + reference "1.0.0"; + } + + revision "2021-10-01" { + description + "Fix indentation for 'list group'"; + reference "0.4.2"; + } + + revision "2021-06-16" { + description + "Remove trailing whitespace"; + reference "0.4.1"; + } + + revision "2021-04-22" { + description + "Adding support for flexible port breakout."; + reference "0.4.0"; + } + + revision "2020-05-06" { + description + "Ensure that when statements in read-write contexts + reference only read-write leaves."; + reference "0.3.3"; + } + + revision "2018-11-21" { + description + "Add OpenConfig module metadata extensions."; + reference "0.3.2"; + } + + revision "2018-11-07" { + description + "Fixed error in when statement path"; + reference "0.3.1"; + } + + revision "2018-01-20" { + description + "Added augmentation for interface-to-port reference"; + reference "0.3.0"; + } + + revision "2017-11-17" { + description + "Corrected augmentation path for port data"; + reference "0.2.0"; + } + + revision "2016-10-24" { + description + "Initial revision"; + reference "0.1.0"; + } + + // OpenConfig specific extensions for module metadata. + oc-ext:regexp-posix; + oc-ext:catalog-organization "openconfig"; + oc-ext:origin "openconfig"; + + // extension statements + + // feature statements + + // identity statements + + // typedef statements + + // grouping statements + + grouping group-config { + description + "Configuration data for the breakout group."; + + leaf index { + type uint8; + description + "Each index specifies breakouts that are identical in + terms of speed and the number of physical channels."; + } + + leaf break-num { + type uint8; + description + "Sets the number of interfaces using this breakout group."; + } + + leaf num-physical-channels { + type uint16; + description + "Sets the number of lanes or physical channels assigned + to the interfaces in this breakout group. This leaf need + not be set if there is only one breakout group where all + the interfaces are of equal speed and have equal number + of physical channels. + + The physical channels referred to by this leaf are + electrical channels towards the transceiver."; + } + } + + grouping group-state { + description + "Operational state data for the port breakout group."; + } + + grouping port-breakout-top { + description + "Top-level grouping for port breakout data."; + + container breakout-mode { + description + "Top-level container for port breakout-mode data."; + + container groups { + description + "Top level container for breakout groups data. + + When a device has the capability to break a port into + interfaces of different speeds and different number of + physical channels, it can breakout a 400G OSFP port with + 8 physical channels (with support for 25G NRZ, 50G PAM4 + and 100G PAM4) into mixed speed interfaces. Particularly, to + break out into two 100G ports with different modulation, and a 200G + port, a user must configure 1 interface with 2 physical channels + 1 interface with 4 physical channels and 1 interface with + 2 physical channels. With this configuration the interface in + 1st breakout group would use 50G PAM4 modulation, interface + in 2nd breakout group would use 25G NRZ modulation and the + interface in 3rd breakout group would use 100G PAM4 modulation + This configuration would result in 3 entries in the breakout + groups list. The example configuration for this case is shown below: + + { + \"groups\": { + \"group\": [ + { + \"config\": { + \"breakout-speed\": \"SPEED_100GB\", + \"index\": 0, + \"num-breakouts\": 1, + \"num-physical-channels\": 2 + }, + \"index\": 0 + }, + { + \"config\": { + \"breakout-speed\": \"SPEED_100GB\", + \"index\": 1, + \"num-breakouts\": 1, + \"num-physical-channels\": 4 + }, + \"index\": 1 + }, + { + \"config\": { + \"breakout-speed\": \"SPEED_200GB\", + \"index\": 2, + \"num-breakouts\": 1, + \"num-physical-channels\": 2 + }, + \"index\": 2 + } + ] + } + } + + When a device does not have the capability to break a port + into interfaces of different speeds and different number of + physical channels, in order to breakout a 400G OSFP port with + 8 physical channels into 50G breakout ports it would use 8 interfaces + with 1 physical channel each. This would result in 1 entry in the + breakout groups list. The example configuration for this case is + shown below: + + { + \"groups\": { + \"group\": [ + { + \"config\": { + \"breakout-speed\": \"SPEED_50GB\", + \"index\": 0, + \"num-breakouts\": 8, + \"num-physical-channels\": 1 + }, + \"index\": 0 + } + ] + } + } + + Similarly, if a 400G-DR4 interface (8 electrical channels at 50Gbps) + is to be broken out into 4 100Gbps ports, the following configuration + is used: + + { + \"groups\": { + \"group\": [ + { + \"config\": { + \"breakout-speed\": \"SPEED_100GB\", + \"index\": 0, + \"num-breakouts\": 4, + \"num-physical-channels\": 2 + }, + \"index\": 0 + } + ] + } + }"; + + list group { + key "index"; + description + "List of breakout groups."; + + leaf index { + type leafref { + path "../config/index"; + } + description + "Index of the breakout group entry in the breakout groups list."; + } + + container config { + description + "Configuration data for breakout group."; + uses group-config; + } + + container state { + config false; + description + "Operational state data for breakout group."; + + uses group-config; + uses group-state; + } + } + } + } + } + + // data definition statements + + // augment statements + + augment "/oc-platform:components/oc-platform:component/" + + "oc-platform:port" { + description + "Adding port breakout data to physical platform data. This subtree + is only valid when the type of the component is PORT."; + + uses port-breakout-top; + } + + // rpc statements + + // notification statements + +} diff --git a/ocdiff/testdata/yang/new/platform/openconfig-platform-psu.yang b/ocdiff/testdata/yang/new/platform/openconfig-platform-psu.yang new file mode 100644 index 0000000..02d6e96 --- /dev/null +++ b/ocdiff/testdata/yang/new/platform/openconfig-platform-psu.yang @@ -0,0 +1,146 @@ +module openconfig-platform-psu { + + yang-version "1"; + + // namespace + namespace "http://openconfig.net/yang/platform/psu"; + + prefix "oc-platform-psu"; + + // import some basic types + import openconfig-extensions { prefix oc-ext; } + import openconfig-types { prefix oc-types; } + import openconfig-platform { prefix oc-platform; } + + + // meta + organization "OpenConfig working group"; + + contact + "OpenConfig working group + www.openconfig.net"; + + description + "This module defines a schema for power supply components in + the OpenConfig platform model."; + + oc-ext:openconfig-version "0.2.1"; + + revision "2018-11-21" { + description + "Add OpenConfig module metadata extensions."; + reference "0.2.1"; + } + + revision "2018-01-16" { + description + "Changed admin state leaf name"; + reference "0.2.0"; + } + + revision "2017-12-21" { + description + "Initial revision"; + reference "0.1.0"; + } + + // OpenConfig specific extensions for module metadata. + oc-ext:regexp-posix; + oc-ext:catalog-organization "openconfig"; + oc-ext:origin "openconfig"; + + // identity statements + + // typedef statements + + // grouping statements + + grouping psu-config { + description + "Configuration data for power supply components"; + + leaf enabled { + type boolean; + default true; + description + "Adminsitrative control on the on/off state of the power + supply unit."; + } + } + + grouping psu-state { + description + "Operational state data for power supply components"; + + + // TODO(aashaikh): May need to convert some of these to + // interval statistics once decided on which leaves to include. + leaf capacity { + type oc-types:ieeefloat32; + units watts; + description + "Maximum power capacity of the power supply."; + } + + leaf input-current { + type oc-types:ieeefloat32; + units amps; + description + "The input current draw of the power supply."; + } + + leaf input-voltage { + type oc-types:ieeefloat32; + units volts; + description + "Input voltage to the power supply."; + } + + leaf output-current { + type oc-types:ieeefloat32; + units amps; + description + "The output current supplied by the power supply."; + } + + leaf output-voltage { + type oc-types:ieeefloat32; + units volts; + description + "Output voltage supplied by the power supply."; + } + + leaf output-power { + type oc-types:ieeefloat32; + units watts; + description + "Output power supplied by the power supply."; + } + } + + // data definition statements + + // augment statements + + augment "/oc-platform:components/oc-platform:component/" + + "oc-platform:power-supply/oc-platform:config" { + description + "Adds power supply data to component operational state."; + + uses psu-config; + } + + augment "/oc-platform:components/oc-platform:component/" + + "oc-platform:power-supply/oc-platform:state" { + description + "Adds power supply data to component operational state."; + + uses psu-config; + uses psu-state; + } + + + // rpc statements + + // notification statements +} \ No newline at end of file diff --git a/ocdiff/testdata/yang/new/platform/openconfig-platform-software.yang b/ocdiff/testdata/yang/new/platform/openconfig-platform-software.yang new file mode 100644 index 0000000..96fd456 --- /dev/null +++ b/ocdiff/testdata/yang/new/platform/openconfig-platform-software.yang @@ -0,0 +1,100 @@ +module openconfig-platform-software { + + yang-version "1"; + + // namespace + namespace "http://openconfig.net/yang/platform/software-module"; + + prefix "oc-sw-module"; + + import openconfig-platform { + prefix oc-platform; + } + + import openconfig-extensions { + prefix oc-ext; + } + + // meta + organization + "OpenConfig working group"; + + contact + "OpenConfig working group + www.openconfig.net"; + + description + "This module defines data related to software components in + the openconfig-platform model"; + + oc-ext:openconfig-version "0.1.1"; + + revision "2021-06-16" { + description + "Remove trailing whitespace"; + reference "0.1.1"; + } + + revision "2021-01-18" { + description + "Initial revision."; + reference "0.1.0"; + } + + // OpenConfig specific extensions for module metadata. + oc-ext:catalog-organization "openconfig"; + oc-ext:origin "openconfig"; + + // extension statements + // feature statements + // identity statements + identity SOFTWARE_MODULE_TYPE { + description + "Base identity for defining various types of software + modules."; + } + + identity USERSPACE_PACKAGE_BUNDLE { + base SOFTWARE_MODULE_TYPE; + description + "A collection of userspace software modules that are grouped, and + possibly versioned, together. A package bundle may have + subcomponents that represent individual elements in the bundle + and their properties."; + } + + identity USERSPACE_PACKAGE { + base SOFTWARE_MODULE_TYPE; + description + "An individual software package that runs in user space. The + package may be part of a package bundle."; + } + + // typedef statements + // grouping statements + grouping sw-module-state { + description + "Operational state data for software module components"; + + leaf module-type { + type identityref { + base SOFTWARE_MODULE_TYPE; + } + description + "Type of the software module"; + } + } + + // data definition statements + // augment statements + augment "/oc-platform:components/oc-platform:component/" + + "oc-platform:software-module/oc-platform:state" { + description + "Adding software module operational data to physical inventory. + This subtree is only valid when the type of the component is + SOFTWARE_MODULE."; + + uses sw-module-state; + } +} + diff --git a/ocdiff/testdata/yang/new/platform/openconfig-platform-types.yang b/ocdiff/testdata/yang/new/platform/openconfig-platform-types.yang new file mode 100644 index 0000000..d28881f --- /dev/null +++ b/ocdiff/testdata/yang/new/platform/openconfig-platform-types.yang @@ -0,0 +1,541 @@ +module openconfig-platform-types { + + yang-version "1"; + + // namespace + namespace "http://openconfig.net/yang/platform-types"; + + prefix "oc-platform-types"; + + import openconfig-types { prefix oc-types; } + import openconfig-extensions { prefix oc-ext; } + + // meta + organization + "OpenConfig working group"; + + contact + "OpenConfig working group + www.openconfig.net"; + + description + "This module defines data types (e.g., YANG identities) + to support the OpenConfig component inventory model."; + + oc-ext:openconfig-version "1.6.0"; + + revision "2023-06-27" { + description + "Add WIFI_ACCESS_POINT"; + reference "1.6.0"; + } + + revision "2022-07-28" { + description + "Add grouping for component power management"; + reference "1.5.0"; + } + + revision "2022-03-27" { + description + "Add identity for BIOS"; + reference "1.4.0"; + } + + revision "2022-02-02" { + description + "Add support for component reboot and switchover."; + reference "1.3.0"; + } + + revision "2021-07-29" { + description + "Add several avg-min-max-instant-stats groupings"; + reference "1.2.0"; + } + + revision "2021-01-18" { + description + "Add identity for software modules"; + reference "1.1.0"; + } + + revision "2019-06-03" { + description + "Add OpenConfig component operating system patch type."; + reference "1.0.0"; + } + + revision "2018-11-21" { + description + "Add OpenConfig module metadata extensions."; + reference "0.10.1"; + } + + revision "2018-11-16" { + description + "Added FEC_MODE_TYPE and FEC_STATUS_TYPE"; + reference "0.10.0"; + } + + revision "2018-05-05" { + description + "Added min-max-time to + avg-min-max-instant-stats-precision1-celsius, + added new CONTROLLER_CARD identity"; + reference "0.9.0"; + } + + revision "2018-01-16" { + description + "Added new per-component common data; add temp alarm"; + reference "0.8.0"; + } + + revision "2017-12-14" { + description + "Added anchor containers for component data, added new + component types"; + reference "0.7.0"; + } + + revision "2017-08-16" { + description + "Added power state enumerated type"; + reference "0.6.0"; + } + + revision "2016-12-22" { + description + "Added temperature state variable to component"; + reference "0.5.0"; + } + + // OpenConfig specific extensions for module metadata. + oc-ext:regexp-posix; + oc-ext:catalog-organization "openconfig"; + oc-ext:origin "openconfig"; + + // grouping statements + grouping avg-min-max-instant-stats-precision1-celsius { + description + "Common grouping for recording temperature values in + Celsius with 1 decimal precision. Values include the + instantaneous, average, minimum, and maximum statistics"; + + leaf instant { + type decimal64 { + fraction-digits 1; + } + units celsius; + description + "The instantaneous value of the statistic."; + } + + leaf avg { + type decimal64 { + fraction-digits 1; + } + units celsius; + description + "The arithmetic mean value of the statistic over the + sampling period."; + } + + leaf min { + type decimal64 { + fraction-digits 1; + } + units celsius; + description + "The minimum value of the statistic over the sampling + period"; + } + + leaf max { + type decimal64 { + fraction-digits 1; + } + units celsius; + description + "The maximum value of the statistic over the sampling + period"; + } + + uses oc-types:stat-interval-state; + uses oc-types:min-max-time; + } + + grouping avg-min-max-instant-stats-precision2-volts { + description + "Common grouping for recording voltage values in + volts with 2 decimal precision. Values include the + instantaneous, average, minimum, and maximum statistics. + If supported by the device, the time interval over which + the statistics are computed, and the times at which the + minimum and maximum values occurred, are also reported."; + + leaf instant { + type decimal64 { + fraction-digits 2; + } + units volts; + description + "The instantaneous value of the statistic."; + } + + leaf avg { + type decimal64 { + fraction-digits 2; + } + units volts; + description + "The arithmetic mean value of the statistic over the + sampling period."; + } + + leaf min { + type decimal64 { + fraction-digits 2; + } + units volts; + description + "The minimum value of the statistic over the sampling + period"; + } + + leaf max { + type decimal64 { + fraction-digits 2; + } + units volts; + description + "The maximum value of the statistic over the sampling + period"; + } + + uses oc-types:stat-interval-state; + uses oc-types:min-max-time; + } + + grouping component-redundant-role-switchover-reason { + description + "Common grouping for recording the reason of a component's + redundant role switchover. For example two supervisors in + a device, one as primary the other as secondary, switchover + can happen in different scenarios, e.g. user requested, + system error, priority contention, etc."; + + leaf trigger { + type component-redundant-role-switchover-reason-trigger; + description + "Records the generic triggers, e.g. user or system + initiated the switchover."; + } + + leaf details { + type string; + description + "Records detailed description of why the switchover happens. + For example, when system initiated the switchover, this leaf + can be used to record the specific reason, e.g. due to critical + errors of the routing daemon in the primary role."; + } + } + + // identity statements + identity OPENCONFIG_HARDWARE_COMPONENT { + description + "Base identity for hardware related components in a managed + device. Derived identities are partially based on contents + of the IANA Entity MIB."; + reference + "IANA Entity MIB and RFC 6933"; + } + + identity OPENCONFIG_SOFTWARE_COMPONENT { + description + "Base identity for software-related components in a managed + device"; + } + + // hardware types + identity CHASSIS { + base OPENCONFIG_HARDWARE_COMPONENT; + description + "Chassis component, typically with multiple slots / shelves"; + } + + identity BACKPLANE { + base OPENCONFIG_HARDWARE_COMPONENT; + description + "Backplane component for aggregating traffic, typically + contained in a chassis component"; + } + + identity FABRIC { + base OPENCONFIG_HARDWARE_COMPONENT; + description + "Interconnect between ingress and egress ports on the + device (e.g., a crossbar switch)."; + } + + identity POWER_SUPPLY { + base OPENCONFIG_HARDWARE_COMPONENT; + description + "Component that is supplying power to the device"; + } + + identity FAN { + base OPENCONFIG_HARDWARE_COMPONENT; + description + "Cooling fan, or could be some other heat-reduction component"; + } + + identity SENSOR { + base OPENCONFIG_HARDWARE_COMPONENT; + description + "Physical sensor, e.g., a temperature sensor in a chassis"; + } + + identity FRU { + base OPENCONFIG_HARDWARE_COMPONENT; + description + "Replaceable hardware component that does not have a more + specific defined schema."; + } + + identity LINECARD { + base OPENCONFIG_HARDWARE_COMPONENT; + description + "Linecard component, typically inserted into a chassis slot"; + } + + identity CONTROLLER_CARD { + base OPENCONFIG_HARDWARE_COMPONENT; + description + "A type of linecard whose primary role is management or control + rather than data forwarding."; + } + + identity PORT { + base OPENCONFIG_HARDWARE_COMPONENT; + description + "Physical port, e.g., for attaching pluggables and networking + cables"; + } + + identity TRANSCEIVER { + base OPENCONFIG_HARDWARE_COMPONENT; + description + "Pluggable module present in a port"; + } + + identity CPU { + base OPENCONFIG_HARDWARE_COMPONENT; + description + "Processing unit, e.g., a management processor"; + } + + identity STORAGE { + base OPENCONFIG_HARDWARE_COMPONENT; + description + "A storage subsystem on the device (disk, SSD, etc.)"; + } + + identity INTEGRATED_CIRCUIT { + base OPENCONFIG_HARDWARE_COMPONENT; + description + "A special purpose processing unit, typically for traffic + switching/forwarding (e.g., switching ASIC, NPU, forwarding + chip, etc.)"; + } + + identity WIFI_ACCESS_POINT { + base OPENCONFIG_HARDWARE_COMPONENT; + description + "A device that attaches to a an Ethernet network and creates a wireless + local area network"; + } + + identity OPERATING_SYSTEM { + base OPENCONFIG_SOFTWARE_COMPONENT; + description + "Operating system running on a component"; + } + + identity OPERATING_SYSTEM_UPDATE { + base OPENCONFIG_SOFTWARE_COMPONENT; + description + "An operating system update - which should be a subcomponent + of the `OPERATING_SYSTEM` running on a component. An update is + defined to be a set of software changes that are atomically + installed (and uninstalled) together. Multiple updates may be + present for the Operating System. A system should not list all + installed software packages using this type -- but rather + updates that are bundled together as a single installable + item"; + } + + identity BIOS { + base OPENCONFIG_SOFTWARE_COMPONENT; + description + "Legacy BIOS or UEFI firmware interface responsible for + initializing hardware components and first stage boot loader."; + } + + identity BOOT_LOADER { + base OPENCONFIG_SOFTWARE_COMPONENT; + description + "Software layer responsible for loading and booting the + device OS or network OS."; + } + + identity SOFTWARE_MODULE { + base OPENCONFIG_SOFTWARE_COMPONENT; + description + "A base identity for software modules installed and/or + running on the device. Modules include user-space programs + and kernel modules that provide specific functionality. + A component with type SOFTWARE_MODULE should also have a + module type that indicates the specific type of software module"; + } + + identity COMPONENT_OPER_STATUS { + description + "Current operational status of a platform component"; + } + + identity ACTIVE { + base COMPONENT_OPER_STATUS; + description + "Component is enabled and active (i.e., up)"; + } + + identity INACTIVE { + base COMPONENT_OPER_STATUS; + description + "Component is enabled but inactive (i.e., down)"; + } + + identity DISABLED { + base COMPONENT_OPER_STATUS; + description + "Component is administratively disabled."; + } + + identity FEC_MODE_TYPE { + description + "Base identity for FEC operational modes."; + } + + identity FEC_ENABLED { + base FEC_MODE_TYPE; + description + "FEC is administratively enabled."; + } + + identity FEC_DISABLED { + base FEC_MODE_TYPE; + description + "FEC is administratively disabled."; + } + + identity FEC_AUTO { + base FEC_MODE_TYPE; + description + "System will determine whether to enable or disable + FEC on a transceiver."; + } + + identity FEC_STATUS_TYPE { + description + "Base identity for FEC operational statuses."; + } + + identity FEC_STATUS_LOCKED { + base FEC_STATUS_TYPE; + description + "FEC is operationally locked."; + } + + identity FEC_STATUS_UNLOCKED { + base FEC_STATUS_TYPE; + description + "FEC is operationally unlocked."; + } + + // typedef statements + typedef component-power-type { + type enumeration { + enum POWER_ENABLED { + description + "Enable power on the component"; + } + enum POWER_DISABLED { + description + "Disable power on the component"; + } + } + description + "A generic type reflecting whether a hardware component + is powered on or off"; + } + + identity COMPONENT_REBOOT_REASON { + description + "Base entity for component reboot reasons."; + } + + identity REBOOT_USER_INITIATED { + base COMPONENT_REBOOT_REASON; + description + "User initiated the reboot of the componenent."; + } + + identity REBOOT_POWER_FAILURE { + base COMPONENT_REBOOT_REASON; + description + "The component reboots due to power failure."; + } + + identity REBOOT_CRITICAL_ERROR { + base COMPONENT_REBOOT_REASON; + description + "The component reboots due to critical errors."; + } + + typedef component-redundant-role { + type enumeration { + enum PRIMARY { + description + "Component is acting the primary role."; + } + enum SECONDARY { + description + "Component is acting the secondary role."; + } + } + description + "A generic type reflecting the component's redundanty role. + For example, a device might have dual supervisors components + for redundant purpose, with one being the primary and the + other secondary."; + } + + typedef component-redundant-role-switchover-reason-trigger { + type enumeration { + enum USER_INITIATED { + description + "User initiated the switchover, e.g. via command line."; + } + enum SYSTEM_INITIATED { + description + "The system initiated the switchover, e.g. due to + critical errors in the component of the primar role."; + } + } + description + "Records how the role switchover is triggered."; + } +} diff --git a/ocdiff/testdata/yang/new/platform/openconfig-platform.yang b/ocdiff/testdata/yang/new/platform/openconfig-platform.yang new file mode 100644 index 0000000..843c2f7 --- /dev/null +++ b/ocdiff/testdata/yang/new/platform/openconfig-platform.yang @@ -0,0 +1,1205 @@ +module openconfig-platform { + + yang-version "1"; + + // namespace + namespace "http://openconfig.net/yang/platform"; + + prefix "oc-platform"; + + import openconfig-platform-types { prefix oc-platform-types; } + import openconfig-extensions { prefix oc-ext; } + import openconfig-yang-types { prefix oc-yang; } + import openconfig-types { prefix oc-types; } + + include openconfig-platform-common; + + // meta + organization "OpenConfig working group"; + + contact + "OpenConfig working group + www.openconfig.net"; + + description + "This module defines a data model for representing a system + component inventory, which can include hardware or software + elements arranged in an arbitrary structure. The primary + relationship supported by the model is containment, e.g., + components containing subcomponents. + + It is expected that this model reflects every field replacable + unit on the device at a minimum (i.e., additional information + may be supplied about non-replacable components). + + Every element in the inventory is termed a 'component' with each + component expected to have a unique name and type, and optionally + a unique system-assigned identifier and FRU number. The + uniqueness is guaranteed by the system within the device. + + Components may have properties defined by the system that are + modeled as a list of key-value pairs. These may or may not be + user-configurable. The model provides a flag for the system + to optionally indicate which properties are user configurable. + + Each component also has a list of 'subcomponents' which are + references to other components. Appearance in a list of + subcomponents indicates a containment relationship as described + above. For example, a linecard component may have a list of + references to port components that reside on the linecard. + + This schema is generic to allow devices to express their own + platform-specific structure. It may be augmented by additional + component type-specific schemas that provide a common structure + for well-known component types. In these cases, the system is + expected to populate the common component schema, and may + optionally also represent the component and its properties in the + generic structure. + + The properties for each component may include dynamic values, + e.g., in the 'state' part of the schema. For example, a CPU + component may report its utilization, temperature, or other + physical properties. The intent is to capture all platform- + specific physical data in one location, including inventory + (presence or absence of a component) and state (physical + attributes or status)."; + + oc-ext:openconfig-version "0.24.0"; + + revision "2023-07-13" { + description + "Refactor resource utilization threshold config into a separate grouping. + Update 'utilization resource' to 'resource utilization'."; + reference "0.24.0"; + } + + revision "2023-02-13" { + description + "Refactor resource utilization threshold config into a separate grouping. + Update 'utilization resource' to 'resource utilization'."; + reference "0.23.0"; + } + + revision "2022-12-20" { + description + "Add threshold and threshold-exceeded for resource usage."; + reference "0.22.0"; + } + + revision "2022-12-19" { + description + "Update last-high-watermark timestamp documentation."; + reference "0.21.1"; + } + + revision "2022-09-26" { + description + "Add state data for base-mac-address."; + reference "0.21.0"; + } + + revision "2022-08-31" { + description + "Add new state data for component CLEI code."; + reference "0.20.0"; + } + + revision "2022-07-28" { + description + "Add container for controller card component"; + reference "0.19.0"; + } + + revision "2022-07-11" { + description + "Add switchover ready"; + reference "0.18.0"; + } + + revision "2022-06-10" { + description + "Specify units and epoch for switchover and reboot times."; + reference "0.17.0"; + } + + revision "2022-04-21" { + description + "Add platform utilization."; + reference "0.16.0"; + } + + revision "2022-02-02" { + description + "Add new state data for component reboot and + switchover."; + reference "0.15.0"; + } + + revision "2021-08-13" { + description + "Add container for PCIe error statistics"; + reference "0.14.0"; + } + + revision "2021-01-18" { + description + "Add container for software module component"; + reference "0.13.0"; + } + + revision "2019-04-16" { + description + "Fix bug in parent path reference"; + reference "0.12.2"; + } + + revision "2018-11-21" { + description + "Add OpenConfig module metadata extensions."; + reference "0.12.1"; + } + + revision "2018-06-29" { + description + "Added location description for components"; + reference "0.12.0"; + } + + revision "2018-06-03" { + description + "Added parent reference, empty flag and preconfiguration + for components"; + reference "0.11.0"; + } + + revision "2018-04-20" { + description + "Added new per-component state data: mfg-date and removable"; + reference "0.10.0"; + } + + revision "2018-01-30" { + description + "Amended approach for modelling CPU - rather than having + a local CPU utilisation state variable, a component with + a CPU should create a subcomponent of type CPU to report + statistics."; + reference "0.9.0"; + } + + revision "2018-01-16" { + description + "Added new per-component common data; add temp alarm; + moved hardware-port reference to port model"; + reference "0.8.0"; + } + + revision "2017-12-14" { + description + "Added anchor containers for component data, added new + component types"; + reference "0.7.0"; + } + + revision "2017-08-16" { + description + "Added power state enumerated type"; + reference "0.6.0"; + } + + revision "2016-12-22" { + description + "Added temperature state variable to component"; + reference "0.5.0"; + } + + // OpenConfig specific extensions for module metadata. + oc-ext:regexp-posix; + oc-ext:catalog-organization "openconfig"; + oc-ext:origin "openconfig"; + + // grouping statements + + + grouping platform-component-properties-config { + description + "System-defined configuration data for component properties"; + + leaf name { + type string; + description + "System-supplied name of the property -- this is typically + non-configurable"; + } + + leaf value { + type union { + type string; + type boolean; + type int64; + type uint64; + type decimal64 { + fraction-digits 2; + } + } + description + "Property values can take on a variety of types. Signed and + unsigned integer types may be provided in smaller sizes, + e.g., int8, uint16, etc."; + } + } + + grouping platform-component-properties-state { + description + "Operational state data for component properties"; + + leaf configurable { + type boolean; + description + "Indication whether the property is user-configurable"; + } + } + + grouping platform-component-properties-top { + description + "Top-level grouping "; + + container properties { + description + "Enclosing container "; + + list property { + key "name"; + description + "List of system properties for the component"; + + leaf name { + type leafref { + path "../config/name"; + } + description + "Reference to the property name."; + } + + container config { + description + "Configuration data for each property"; + + uses platform-component-properties-config; + } + + container state { + + config false; + + description + "Operational state data for each property"; + + uses platform-component-properties-config; + uses platform-component-properties-state; + } + } + } + } + + grouping platform-subcomponent-ref-config { + description + "Configuration data for subcomponent references"; + + leaf name { + type leafref { + path "../../../../../component/config/name"; + } + description + "Reference to the name of the subcomponent"; + } + } + + grouping platform-subcomponent-ref-state { + description + "Operational state data for subcomponent references"; + + } + + grouping platform-subcomponent-ref-top { + description + "Top-level grouping for list of subcomponent references"; + + container subcomponents { + description + "Enclosing container for subcomponent references"; + + list subcomponent { + key "name"; + description + "List of subcomponent references"; + + leaf name { + type leafref { + path "../config/name"; + } + description + "Reference to the name list key"; + } + + container config { + description + "Configuration data for the subcomponent"; + + uses platform-subcomponent-ref-config; + } + + container state { + + config false; + + description + "Operational state data for the subcomponent"; + + uses platform-subcomponent-ref-config; + uses platform-subcomponent-ref-state; + } + } + } + } + + grouping platform-component-config { + description + "Configuration data for components"; + + leaf name { + type string; + description + "Device name for the component -- this may not be a + configurable parameter on many implementations. Where + component preconfiguration is supported, for example, + the component name may be configurable."; + } + } + + grouping platform-component-state { + description + "Operational state data for device components."; + + leaf type { + type union { + type identityref { + base oc-platform-types:OPENCONFIG_HARDWARE_COMPONENT; + } + type identityref { + base oc-platform-types:OPENCONFIG_SOFTWARE_COMPONENT; + } + } + description + "Type of component as identified by the system"; + } + + leaf id { + type string; + description + "Unique identifier assigned by the system for the + component"; + } + + leaf location { + type string; + description + "System-supplied description of the location of the + component within the system. This could be a bay position, + slot number, socket location, etc. For component types that + have an explicit slot-id attribute, such as linecards, the + system should populate the more specific slot-id."; + } + + leaf description { + type string; + description + "System-supplied description of the component"; + } + + leaf mfg-name { + type string; + description + "System-supplied identifier for the manufacturer of the + component. This data is particularly useful when a + component manufacturer is different than the overall + device vendor."; + } + + leaf mfg-date { + type oc-yang:date; + description + "System-supplied representation of the component's + manufacturing date."; + } + + leaf hardware-version { + type string; + description + "For hardware components, this is the hardware revision of + the component."; + } + + leaf firmware-version { + type string; + description + "For hardware components, this is the version of associated + firmware that is running on the component, if applicable."; + } + + leaf software-version { + type string; + description + "For software components such as operating system or other + software module, this is the version of the currently + running software."; + } + + leaf serial-no { + type string; + description + "System-assigned serial number of the component."; + } + + leaf part-no { + type string; + description + "System-assigned part number for the component. This should + be present in particular if the component is also an FRU + (field replaceable unit)"; + } + + leaf clei-code { + type string; + description + "Common Language Equipment Identifier (CLEI) code of the + component. This should be present in particular if the + component is also an FRU (field replaceable unit)"; + } + + leaf removable { + type boolean; + description + "If true, this component is removable or is a field + replaceable unit"; + } + + leaf oper-status { + type identityref { + base oc-platform-types:COMPONENT_OPER_STATUS; + } + description + "If applicable, this reports the current operational status + of the component."; + } + + leaf empty { + type boolean; + default false; + description + "The empty leaf may be used by the device to indicate that a + component position exists but is not populated. Using this + flag, it is possible for the management system to learn how + many positions are available (e.g., occupied vs. empty + linecard slots in a chassis)."; + } + + leaf parent { + type leafref { + path "../../../component/config/name"; + } + description + "Reference to the name of the parent component. Note that + this reference must be kept synchronized with the + corresponding subcomponent reference from the parent + component."; + } + + leaf redundant-role { + type oc-platform-types:component-redundant-role; + description + "For components that have redundant roles (e.g. two + supervisors in a device, one as primary the other as secondary), + this reports the role of the component."; + } + + container last-switchover-reason { + description + "For components that have redundant roles (e.g. two + supervisors in a device, one as primary the other as secondary), + this reports the reason of the last change of the + component's role."; + + uses oc-platform-types:component-redundant-role-switchover-reason; + } + + leaf last-switchover-time { + type oc-types:timeticks64; + units "nanoseconds"; + description + "For components that have redundant roles (e.g. two + supervisors in a device, one as primary the other as + secondary), this reports the time of the last change of + the component's role. The value is the timestamp in + nanoseconds relative to the Unix Epoch (Jan 1, 1970 00:00:00 UTC)."; + + } + + leaf last-reboot-reason { + type identityref { + base oc-platform-types:COMPONENT_REBOOT_REASON; + } + description + "This reports the reason of the last reboot of the component."; + } + + leaf last-reboot-time { + type oc-types:timeticks64; + units "nanoseconds"; + description + "This reports the time of the last reboot of the component. The + value is the timestamp in nanoseconds relative to the Unix Epoch + (Jan 1, 1970 00:00:00 UTC)."; + } + + leaf switchover-ready { + type boolean; + description + "For components that have redundant roles, this reports a value + that indicates if the component is ready to support failover. + + The components with a redundant-role should reflect the overall + system's switchover status. For example, two supervisors in a + device, one as primary and the other as secondary, should both + report the same value."; + } + + leaf base-mac-address { + type oc-yang:mac-address; + description + "This is a MAC address representing the root or primary MAC + address for a component. Components such as CHASSIS and + CONTROLLER_CARD are expected to provide a base-mac-address. The + base mac-address for CHASSIS and a PRIMARY CONTROLLER_CARD may + contain the same value."; + } + + } + + grouping platform-component-temp-alarm-state { + description + "Temperature alarm data for platform components"; + + // TODO(aashaikh): consider if these leaves could be in a + // reusable grouping (not temperature-specific); threshold + // may always need to be units specific. + + leaf alarm-status { + type boolean; + description + "A value of true indicates the alarm has been raised or + asserted. The value should be false when the alarm is + cleared."; + } + + leaf alarm-threshold { + type uint32; + description + "The threshold value that was crossed for this alarm."; + } + } + + grouping platform-component-power-state { + description + "Power-related operational state for device components."; + + leaf allocated-power { + type uint32; + units watts; + description + "Power allocated by the system for the component."; + } + + leaf used-power { + type uint32; + units watts; + description + "Actual power used by the component."; + } + } + + grouping platform-component-temp-state { + description + "Temperature state data for device components"; + + container temperature { + description + "Temperature in degrees Celsius of the component. Values include + the instantaneous, average, minimum, and maximum statistics. If + avg/min/max statistics are not supported, the target is expected + to just supply the instant value"; + + uses oc-platform-types:avg-min-max-instant-stats-precision1-celsius; + uses platform-component-temp-alarm-state; + } + } + + grouping platform-component-memory-state { + description + "Per-component memory statistics"; + + container memory { + description + "For components that have associated memory, these values + report information about available and utilized memory."; + + leaf available { + type uint64; + units bytes; + description + "The available memory physically installed, or logically + allocated to the component."; + } + + // TODO(aashaikh): consider if this needs to be a + // min/max/avg statistic + leaf utilized { + type uint64; + units bytes; + description + "The memory currently in use by processes running on + the component, not considering reserved memory that is + not available for use."; + } + } + } + + grouping pcie-uncorrectable-errors { + description + "PCIe uncorrectable error statistics."; + + leaf total-errors { + type oc-yang:counter64; + description + "Total number of uncorrectable errors detected by PCIe device + since the system booted, according to PCIe AER driver."; + } + + leaf undefined-errors { + type oc-yang:counter64; + description + "Number of undefined errors detected by PCIe device since the + system booted, according to PCIe AER driver."; + } + + leaf data-link-errors { + type oc-yang:counter64; + description + "Number of data-link errors detected by PCIe device since the + system booted, according to PCIe AER driver."; + } + + leaf surprise-down-errors { + type oc-yang:counter64; + description + "Number of unexpected link down errors detected by PCIe device + since the system booted, according to PCIe AER driver."; + } + + leaf poisoned-tlp-errors { + type oc-yang:counter64; + description + "Number of poisoned TLP errors detected by PCIe device since the + system booted, according to PCIe AER driver."; + } + + leaf flow-control-protocol-errors { + type oc-yang:counter64; + description + "Number of flow control protocol errors detected by PCIe device + since the system booted, according to PCIe AER driver."; + } + + leaf completion-timeout-errors { + type oc-yang:counter64; + description + "Number of completion timeout errors detected by PCIe device + since the system booted, according to PCIe AER driver."; + } + + leaf completion-abort-errors { + type oc-yang:counter64; + description + "Number of completion abort errors detected by PCIe device + since the system booted, according to PCIe AER driver."; + } + + leaf unexpected-completion-errors { + type oc-yang:counter64; + description + "Number of unexpected completion errors detected by PCIe device + since the system booted, according to PCIe AER driver."; + } + + leaf receiver-overflow-errors { + type oc-yang:counter64; + description + "Number of receiver overflow errors detected by PCIe device + since the system booted, according to PCIe AER driver."; + } + + leaf malformed-tlp-errors { + type oc-yang:counter64; + description + "Number of malformed TLP errors detected by PCIe device since the + system booted, according to PCIe AER driver."; + } + + leaf ecrc-errors { + type oc-yang:counter64; + description + "Number of ECRC errors detected by PCIe device since the system + booted, according to PCIe AER driver."; + } + + leaf unsupported-request-errors { + type oc-yang:counter64; + description + "Number of unsupported request errors detected by PCIe device + since the system booted, according to PCIe AER driver."; + } + + leaf acs-violation-errors { + type oc-yang:counter64; + description + "Number of access control errors detected by PCIe device since + the system booted, according to PCIe AER driver."; + } + + leaf internal-errors { + type oc-yang:counter64; + description + "Number of internal errors detected by PCIe device since the + system booted, according to PCIe AER driver."; + } + + leaf blocked-tlp-errors { + type oc-yang:counter64; + description + "Number of blocked TLP errors detected by PCIe device since + the system booted, according to PCIe AER driver."; + } + + leaf atomic-op-blocked-errors { + type oc-yang:counter64; + description + "Number of atomic operation blocked errors detected by PCIe + device since the system booted, according to PCIe AER driver."; + } + + leaf tlp-prefix-blocked-errors { + type oc-yang:counter64; + description + "Number of TLP prefix blocked errors detected by PCIe device + since the system booted, according to PCIe AER driver."; + } + } + + grouping pcie-correctable-errors { + description + "PCIe correctable error statistics."; + + leaf total-errors { + type oc-yang:counter64; + description + "Total number of correctable errors detected by PCIe device + since the system booted, according to PCIe AER driver."; + } + + leaf receiver-errors { + type oc-yang:counter64; + description + "Number of receiver errors detected by PCIe device since the + system booted, according to PCIe AER driver."; + } + + leaf bad-tlp-errors { + type oc-yang:counter64; + description + "Number of TLPs with bad LCRC detected by PCIe device since the + system booted, according to PCIe AER driver."; + } + + leaf bad-dllp-errors { + type oc-yang:counter64; + description + "Number of DLLPs with bad LCRC detected by PCIe device since the + system booted, according to PCIe AER driver."; + } + + leaf relay-rollover-errors { + type oc-yang:counter64; + description + "Number of relay rollover errors detected by PCIe device since the + system booted, according to PCIe AER driver."; + } + + leaf replay-timeout-errors { + type oc-yang:counter64; + description + "Number of replay timeout errors detected by PCIe device since the + system booted, according to PCIe AER driver."; + } + + leaf advisory-non-fatal-errors { + type oc-yang:counter64; + description + "Number of advisory non fatal errors detected by PCIe device since + the system booted, according to PCIe AER driver."; + } + + leaf internal-errors { + type oc-yang:counter64; + description + "Number of internal errors detected by PCIe device since the system + booted, according to PCIe AER driver."; + } + + leaf hdr-log-overflow-errors { + type oc-yang:counter64; + description + "Number of header log overflow errors detected by PCIe device since + the system booted, according to PCIe AER driver."; + } + } + + grouping platform-component-pcie-state { + description + "Per-component PCIe error statistics"; + + container pcie { + description + "Components that are connected to the system over the Peripheral + Component Interconnect Express (PCIe), report the fatal, non-fatal + and correctable PCIe error counts."; + + container fatal-errors { + description + "The count of the fatal PCIe errors."; + uses pcie-uncorrectable-errors; + } + + container non-fatal-errors { + description + "The count of the non-fatal PCIe errors."; + uses pcie-uncorrectable-errors; + } + + container correctable-errors { + description + "The count of the correctable PCIe errors."; + uses pcie-correctable-errors; + } + } + } + + grouping platform-anchors-top { + description + "This grouping is used to add containers for components that + are common across systems, but do not have a defined schema + within the openconfig-platform module. Containers should be + added to this grouping for components that are expected to + exist in multiple systems, with corresponding modules + augmenting the config/state containers directly."; + + container chassis { + description + "Data for chassis components"; + + container config { + description + "Configuration data for chassis components"; + } + + container state { + config false; + description + "Operational state data for chassis components"; + } + + uses platform-resource-utilization-top; + } + +// TODO(aashaikh): linecard container is already defined in +// openconfig-platform-linecard; will move to this module +// in future. + /* + container linecard { + description + "Data for linecard components"; + + container config { + description + "Configuration data for linecard components"; + } + + container state { + config false; + description + "Operational state data for linecard components"; + } + } + */ + + container port { + description + "Data for physical port components"; + + container config { + description + "Configuration data for physical port components"; + } + + container state { + config false; + description + "Operational state data for physical port components"; + } + } + +// TODO(aashaikh): transceiver container is already defined in +// openconfig-platform-transceiver; will move to this module +// in future. + /* + container transceiver { + description + "Data for transceiver components"; + + container config { + description + "Configuration data for transceiver components"; + } + + container state { + config false; + description + "Operational state data for transceiver components"; + } + } + */ + + container power-supply { + description + "Data for power supply components"; + + container config { + description + "Configuration data for power supply components"; + } + + container state { + config false; + description + "Operational state data for power supply components"; + } + } + + container fan { + description + "Data for fan components"; + + container config { + description + "Configuration data for fan components"; + } + + container state { + config false; + description + "Operational state data for fan components"; + } + } + + container fabric { + description + "Data for fabric components"; + + container config { + description + "Configuration data for fabric components"; + } + + container state { + config false; + description + "Operational state data for fabric components"; + } + } + + container storage { + description + "Data for storage components"; + + container config { + description + "Configuration data for storage components"; + } + + container state { + config false; + description + "Operational state data for storage components"; + } + } + + container cpu { + description + "Data for cpu components"; + + container config { + description + "Configuration data for cpu components"; + } + + container state { + config false; + description + "Operational state data for cpu components"; + } + } + + container integrated-circuit { + description + "Data for chip components, such as ASIC, NPUs, etc."; + + container config { + description + "Configuration data for chip components"; + } + + container state { + config false; + description + "Operational state data for chip components"; + } + + uses platform-resource-utilization-top; + } + + container backplane { + description + "Data for backplane components"; + + container config { + description + "Configuration data for backplane components"; + } + + container state { + config false; + description + "Operational state data for backplane components"; + } + } + + container software-module { + description + "Data for software module components, i.e., for components + with type=SOFTWARE_MODULE"; + + container config { + description + "Configuration data for software module components"; + } + + container state { + config false; + description + "Operational state data for software module components"; + } + } + + container controller-card { + description + "Data for controller card components, i.e., for components + with type=CONTROLLER_CARD"; + + container config { + description + "Configuration data for controller card components. Note that disabling + power to the primary supervisor should be rejected, and the operator is + required to perform a switchover first."; + } + + container state { + config false; + description + "Operational state data for controller card components"; + } + } + } + + grouping platform-component-top { + description + "Top-level grouping for components in the device inventory"; + + container components { + description + "Enclosing container for the components in the system."; + + list component { + key "name"; + description + "List of components, keyed by component name."; + + leaf name { + type leafref { + path "../config/name"; + } + description + "References the component name"; + } + + container config { + description + "Configuration data for each component"; + + uses platform-component-config; + } + + container state { + + config false; + + description + "Operational state data for each component"; + + uses platform-component-config; + uses platform-component-state; + uses platform-component-temp-state; + uses platform-component-memory-state; + uses platform-component-power-state; + uses platform-component-pcie-state { + when "./type = 'oc-platform-types:STORAGE' or " + + "'oc-platform-types:INTEGRATED_CIRCUIT' or " + + "'oc-platform-types:FRU'"; + } + } + + uses platform-component-properties-top; + uses platform-subcomponent-ref-top; + uses platform-anchors-top; + } + } + } + + + // data definition statements + + uses platform-component-top; + + + // augments + + +} diff --git a/ocdiff/testdata/yang/old/platform/.spec.yml b/ocdiff/testdata/yang/old/platform/.spec.yml new file mode 100644 index 0000000..59ffb1c --- /dev/null +++ b/ocdiff/testdata/yang/old/platform/.spec.yml @@ -0,0 +1,43 @@ +- name: openconfig-platform + docs: + - yang/platform/openconfig-platform.yang + - yang/platform/openconfig-platform-common.yang + - yang/platform/openconfig-platform-types.yang + - yang/platform/openconfig-platform-transceiver.yang + - yang/platform/openconfig-platform-linecard.yang + - yang/platform/openconfig-platform-port.yang + - yang/platform/openconfig-platform-psu.yang + - yang/platform/openconfig-platform-fan.yang + - yang/platform/openconfig-platform-cpu.yang + - yang/platform/openconfig-platform-ext.yang + - yang/platform/openconfig-platform-software.yang + - yang/platform/openconfig-platform-fabric.yang + - yang/platform/openconfig-platform-pipeline-counters.yang + - yang/platform/openconfig-platform-integrated-circuit.yang + - yang/platform/openconfig-platform-controller-card.yang + - yang/platform/openconfig-platform-healthz.yang + - yang/p4rt/openconfig-p4rt.yang + - yang/system/openconfig-alarms.yang + - yang/optical-transport/openconfig-terminal-device.yang + - yang/optical-transport/openconfig-transport-line-common.yang + build: + - yang/platform/openconfig-platform.yang + - yang/platform/openconfig-platform-common.yang + - yang/platform/openconfig-platform-transceiver.yang + - yang/platform/openconfig-platform-linecard.yang + - yang/platform/openconfig-platform-port.yang + - yang/platform/openconfig-platform-psu.yang + - yang/platform/openconfig-platform-fan.yang + - yang/platform/openconfig-platform-ext.yang + - yang/platform/openconfig-platform-cpu.yang + - yang/platform/openconfig-platform-software.yang + - yang/platform/openconfig-platform-fabric.yang + - yang/platform/openconfig-platform-pipeline-counters.yang + - yang/platform/openconfig-platform-integrated-circuit.yang + - yang/platform/openconfig-platform-controller-card.yang + - yang/platform/openconfig-platform-healthz.yang + - yang/p4rt/openconfig-p4rt.yang + - yang/system/openconfig-alarms.yang + - yang/optical-transport/openconfig-terminal-device.yang + - yang/optical-transport/openconfig-transport-line-common.yang + run-ci: true diff --git a/ocdiff/testdata/yang/old/platform/openconfig-platform-common.yang b/ocdiff/testdata/yang/old/platform/openconfig-platform-common.yang new file mode 100644 index 0000000..d019580 --- /dev/null +++ b/ocdiff/testdata/yang/old/platform/openconfig-platform-common.yang @@ -0,0 +1,240 @@ +submodule openconfig-platform-common { + + yang-version "1"; + + belongs-to openconfig-platform { + prefix "oc-platform"; + } + + import openconfig-platform-types { prefix oc-platform-types; } + import openconfig-extensions { prefix oc-ext; } + import openconfig-types { prefix oc-types; } + + organization "OpenConfig working group"; + + contact + "OpenConfig working group + www.openconfig.net"; + + description + "This modules contains common groupings that are used in multiple + components within the platform module."; + + oc-ext:openconfig-version "0.23.0"; + + revision "2023-02-13" { + description + "Refactor resource utilization threshold config into a separate grouping. + Update 'utilization resource' to 'resource utilization'."; + reference "0.23.0"; + } + + revision "2022-12-20" { + description + "Add threshold and threshold-exceeded for resource usage."; + reference "0.22.0"; + } + + revision "2022-12-19" { + description + "Update last-high-watermark timestamp documentation."; + reference "0.21.1"; + } + + revision "2022-09-26" { + description + "Add state data for base-mac-address."; + reference "0.21.0"; + } + + revision "2022-08-31" { + description + "Add new state data for component CLEI code."; + reference "0.20.0"; + } + + revision "2022-07-28" { + description + "Add grouping for component power management"; + reference "0.19.0"; + } + + revision "2022-07-11" { + description + "Add switchover ready"; + reference "0.18.0"; + } + + revision "2022-06-10" { + description + "Specify units and epoch for switchover and reboot times."; + reference "0.17.0"; + } + + revision "2022-04-21" { + description + "Add platform utilization."; + reference "0.16.0"; + } + + // extension statements + + // feature statements + + // identity statements + + // typedef statements + + // grouping statements + + grouping platform-resource-utilization-top { + description + "Top level grouping of platform resource utilization."; + + container utilization { + description + "Resource utilization of the component."; + + container resources { + description + "Enclosing container for the resources in this component."; + + list resource { + key "name"; + description + "List of resources, keyed by resource name."; + + leaf name { + type leafref { + path "../config/name"; + } + description + "References the resource name."; + } + + container config { + description + "Configuration data for each resource."; + + uses platform-resource-utilization-config; + } + + container state { + config false; + description + "Operational state data for each resource."; + + uses platform-resource-utilization-config; + uses platform-resource-utilization-state; + } + } + } + } + } + + grouping resource-utilization-threshold-common { + description + "Common threshold configuration model for resource utilization."; + leaf used-threshold-upper { + type oc-types:percentage; + description + "The used percentage value (used / (used + free) * 100) that + when crossed will set utilization-threshold-exceeded to 'true'."; + } + + leaf used-threshold-upper-clear { + type oc-types:percentage; + description + "The used percentage value (used / (used + free) * 100) that when + crossed will set utilization-threshold-exceeded to 'false'."; + } + } + + grouping platform-resource-utilization-config { + description + "Configuration data for resource utilization."; + + leaf name { + type string; + description + "Resource name within the component."; + } + + uses resource-utilization-threshold-common; + } + + grouping platform-resource-utilization-state { + description + "Operational state data for resource utilization."; + + leaf used { + type uint64; + description + "Number of entries currently in use for the resource."; + } + + leaf committed { + type uint64; + description + "Number of entries currently reserved for this resource. This is only + relevant to tables which allocate a block of resource for a given + feature."; + } + + leaf free { + type uint64; + description + "Number of entries available to use."; + } + + leaf max-limit { + type uint64; + description + "Maximum number of entries available for the resource. The value + is the theoretical maximum resource utilization possible."; + } + + leaf high-watermark { + type uint64; + description + "A watermark of highest number of entries used for this resource."; + } + + leaf last-high-watermark { + type oc-types:timeticks64; + description + "The timestamp when the high-watermark was last updated. The value + is the timestamp in nanoseconds relative to the Unix Epoch + (Jan 1, 1970 00:00:00 UTC)."; + } + + leaf used-threshold-upper-exceeded { + type boolean; + description + "This value is set to true when the used percentage value + (used / (used + free) * 100) has crossed the used-threshold-upper for this + resource and false when the used percentage value has crossed the configured + used-threshold-upper-clear value for this resource."; + } + } + + grouping component-power-management { + description + "Common grouping for managing component power"; + + leaf power-admin-state { + type oc-platform-types:component-power-type; + default POWER_ENABLED; + description + "Enable or disable power to the component"; + } + } + + // data definition statements + + // augment statements + + // rpc statements + + // notification statements +} diff --git a/ocdiff/testdata/yang/old/platform/openconfig-platform-controller-card.yang b/ocdiff/testdata/yang/old/platform/openconfig-platform-controller-card.yang new file mode 100644 index 0000000..1bea20f --- /dev/null +++ b/ocdiff/testdata/yang/old/platform/openconfig-platform-controller-card.yang @@ -0,0 +1,81 @@ +module openconfig-platform-controller-card { + + yang-version "1"; + + // namespace + namespace "http://openconfig.net/yang/platform/controller-card"; + + prefix "oc-ctrl-card"; + + import openconfig-platform { prefix oc-platform; } + import openconfig-extensions { prefix oc-ext; } + + + // meta + organization "OpenConfig working group"; + + contact + "OpenConfig working group + www.openconfig.net"; + + description + "This module defines data related to CONTROLLER_CARD components in + the openconfig-platform model"; + + oc-ext:openconfig-version "0.1.0"; + + revision "2022-07-28" { + description + "Initial revision"; + reference "0.1.0"; + } + + // OpenConfig specific extensions for module metadata. + oc-ext:catalog-organization "openconfig"; + oc-ext:origin "openconfig"; + + // extension statements + + // feature statements + + // identity statements + + // typedef statements + + // grouping statements + + grouping controller-card-config { + description + "Configuration data for controller card components"; + + uses oc-platform:component-power-management; + } + + // data definition statements + + // augment statements + + augment "/oc-platform:components/oc-platform:component/" + + "oc-platform:controller-card/oc-platform:config" { + description + "Adding controller card data to physical inventory. This subtree + is only valid when the type of the component is CONTROLLER_CARD."; + + uses controller-card-config; + } + + augment "/oc-platform:components/oc-platform:component/" + + "oc-platform:controller-card/oc-platform:state" { + description + "Adding controller card data to physical inventory. This subtree + is only valid when the type of the component is CONTROLLER_CARD."; + + uses controller-card-config; + } + + // rpc statements + + // notification statements + +} + diff --git a/ocdiff/testdata/yang/old/platform/openconfig-platform-cpu.yang b/ocdiff/testdata/yang/old/platform/openconfig-platform-cpu.yang new file mode 100644 index 0000000..4182c77 --- /dev/null +++ b/ocdiff/testdata/yang/old/platform/openconfig-platform-cpu.yang @@ -0,0 +1,72 @@ +module openconfig-platform-cpu { + + yang-version "1"; + + // namespace + namespace "http://openconfig.net/yang/platform/cpu"; + + prefix "oc-cpu"; + + import openconfig-platform { prefix oc-platform; } + import openconfig-types { prefix oc-types; } + import openconfig-extensions { prefix oc-ext; } + + + // meta + organization "OpenConfig working group"; + + contact + "OpenConfig working group + www.openconfig.net"; + + description + "This module defines data related to FAN components in the + OpenConfig platform model."; + + oc-ext:openconfig-version "0.1.1"; + + revision "2018-11-21" { + description + "Add OpenConfig module metadata extensions."; + reference "0.1.1"; + } + + revision "2018-01-30" { + description + "Initial revision"; + reference "0.1.0"; + } + + // OpenConfig specific extensions for module metadata. + oc-ext:regexp-posix; + oc-ext:catalog-organization "openconfig"; + oc-ext:origin "openconfig"; + + grouping component-cpu-utilization { + description + "Per-component CPU statistics"; + + container utilization { + description + "Statistics representing CPU utilization of the + component."; + + container state { + config false; + description + "Operational state variables relating to the utilization + of the CPU."; + + uses oc-types:avg-min-max-instant-stats-pct; + } + } + } + + augment "/oc-platform:components/oc-platform:component/" + + "oc-platform:cpu" { + description + "Adding CPU utilization data to component model"; + + uses component-cpu-utilization; + } +} diff --git a/ocdiff/testdata/yang/old/platform/openconfig-platform-ext.yang b/ocdiff/testdata/yang/old/platform/openconfig-platform-ext.yang new file mode 100644 index 0000000..2e95427 --- /dev/null +++ b/ocdiff/testdata/yang/old/platform/openconfig-platform-ext.yang @@ -0,0 +1,82 @@ +module openconfig-platform-ext { + + yang-version "1"; + + // namespace + namespace "http://openconfig.net/yang/platform/extension"; + + prefix "oc-platform-ext"; + + import openconfig-platform { prefix oc-platform; } + import openconfig-extensions { prefix oc-ext; } + + + // meta + organization "OpenConfig working group"; + + contact + "OpenConfig working group + www.openconfig.net"; + + description + "This module defines optional extensions to the OpenConfig + platform model."; + + oc-ext:openconfig-version "0.1.1"; + + revision "2018-11-21" { + description + "Add OpenConfig module metadata extensions."; + reference "0.1.1"; + } + + revision "2018-01-18" { + description + "Initial revision"; + reference "0.1.0"; + } + + // OpenConfig specific extensions for module metadata. + oc-ext:regexp-posix; + oc-ext:catalog-organization "openconfig"; + oc-ext:origin "openconfig"; + + // identity statements + + // typedef statements + + // grouping statements + + + grouping platform-component-ext-state { + description + "Operational state data for platform components"; + + leaf entity-id { + type uint32; + description + "A unique numeric identifier assigned by the system to the + component. This identifier may be used to represent the + corresponding SNMP Entity MIB identifier."; + } + } + + + // data definition statements + + // augment statements + + augment "/oc-platform:components/oc-platform:component/" + + "oc-platform:state" { + description + "Adding extension state data to components"; + + uses platform-component-ext-state; + } + + // rpc statements + + // notification statements + +} + diff --git a/ocdiff/testdata/yang/old/platform/openconfig-platform-fabric.yang b/ocdiff/testdata/yang/old/platform/openconfig-platform-fabric.yang new file mode 100644 index 0000000..95d106c --- /dev/null +++ b/ocdiff/testdata/yang/old/platform/openconfig-platform-fabric.yang @@ -0,0 +1,81 @@ +module openconfig-platform-fabric { + + yang-version "1"; + + // namespace + namespace "http://openconfig.net/yang/platform/fabric"; + + prefix "oc-fabric"; + + import openconfig-platform { prefix oc-platform; } + import openconfig-extensions { prefix oc-ext; } + + + // meta + organization "OpenConfig working group"; + + contact + "OpenConfig working group + www.openconfig.net"; + + description + "This module defines data related to FABRIC components in + the openconfig-platform model"; + + oc-ext:openconfig-version "0.1.0"; + + revision "2022-07-28" { + description + "Initial revision"; + reference "0.1.0"; + } + + // OpenConfig specific extensions for module metadata. + oc-ext:catalog-organization "openconfig"; + oc-ext:origin "openconfig"; + + // extension statements + + // feature statements + + // identity statements + + // typedef statements + + // grouping statements + + grouping fabric-config { + description + "Configuration data for fabric components"; + + uses oc-platform:component-power-management; + } + + // data definition statements + + // augment statements + + augment "/oc-platform:components/oc-platform:component/" + + "oc-platform:fabric/oc-platform:config" { + description + "Adding fabric data to physical inventory. This subtree + is only valid when the type of the component is FABRIC."; + + uses fabric-config; + } + + augment "/oc-platform:components/oc-platform:component/" + + "oc-platform:fabric/oc-platform:state" { + description + "Adding fabric data to physical inventory. This subtree + is only valid when the type of the component is FABRIC."; + + uses fabric-config; + } + + // rpc statements + + // notification statements + +} + diff --git a/ocdiff/testdata/yang/old/platform/openconfig-platform-fan.yang b/ocdiff/testdata/yang/old/platform/openconfig-platform-fan.yang new file mode 100644 index 0000000..cd4a381 --- /dev/null +++ b/ocdiff/testdata/yang/old/platform/openconfig-platform-fan.yang @@ -0,0 +1,76 @@ +module openconfig-platform-fan { + + yang-version "1"; + + // namespace + namespace "http://openconfig.net/yang/platform/fan"; + + prefix "oc-fan"; + + import openconfig-platform { prefix oc-platform; } + import openconfig-extensions { prefix oc-ext; } + + + // meta + organization "OpenConfig working group"; + + contact + "OpenConfig working group + www.openconfig.net"; + + description + "This module defines data related to FAN components in the + OpenConfig platform model."; + + oc-ext:openconfig-version "0.1.1"; + + revision "2018-11-21" { + description + "Add OpenConfig module metadata extensions."; + reference "0.1.1"; + } + + revision "2018-01-18" { + description + "Initial revision"; + reference "0.1.0"; + } + + // OpenConfig specific extensions for module metadata. + oc-ext:regexp-posix; + oc-ext:catalog-organization "openconfig"; + oc-ext:origin "openconfig"; + + // identity statements + + // typedef statements + + // grouping statements + + grouping fan-state { + description + "Operational state data for fan components"; + + leaf speed { + type uint32; + units rpm; + description + "Current (instantaneous) fan speed"; + } + } + + + // data definition statements + + // augment statements + + augment "/oc-platform:components/oc-platform:component/" + + "oc-platform:fan/oc-platform:state" { + description + "Adding fan data to component model"; + + uses fan-state; + } + +} + diff --git a/ocdiff/testdata/yang/old/platform/openconfig-platform-healthz.yang b/ocdiff/testdata/yang/old/platform/openconfig-platform-healthz.yang new file mode 100644 index 0000000..11e44d3 --- /dev/null +++ b/ocdiff/testdata/yang/old/platform/openconfig-platform-healthz.yang @@ -0,0 +1,137 @@ +module openconfig-platform-healthz { + + yang-version "1"; + + // namespace + namespace "http://openconfig.net/yang/platform/healthz"; + + prefix "oc-platform-healthz"; + + import openconfig-extensions { prefix oc-ext; } + import openconfig-types { prefix oc-types; } + import openconfig-platform { prefix oc-platform; } + + // meta + organization "OpenConfig working group"; + + contact + "OpenConfig working group + www.openconfig.net"; + + description + "This model defines health-related variables for components + within the openconfig-platform model (which defines the + the /components hierarchy). It is designed to be used in + conjunction with the gNOI Healthz service (see + https://github.com/openconfig/gnoi/blob/main/healthz/README.md). + + The health variables included in this model are streamed via + telemetry interfaces, where gNOI.Healthz is used to retrieve + further diagnostic and debugging informaton from a network + device."; + + oc-ext:openconfig-version "0.1.1"; + + revision "2023-04-11" { + description + "Clarification for healthz state transition and unhealthy-count leaf"; + reference "0.1.1"; + } + + revision "2023-01-23" { + description + "Initial healthz variable revision"; + reference "0.1.0"; + } + + + grouping platform-health-top { + description + "Grouping containing health-related parameters."; + + container healthz { + description + "The health of the component. The paramaters within this + container indicate the status of the component beyond whether + it is operationally up or down. When a signal is received + that a component is in an unhealthy state the gNOI.Healthz + service can be used to retrieve further diagnostic information + relating to the component. + + The contents of this directory relate only to the specific + component that it is associated with. In the case that child + components become unhealthy and this causes a parent component + to be unhealthy, the new unhealthy status should be reported at + both components, such that an interested system can take the + relevant actions (e.g., retrieve the Healthz output, or + apply mitigation actions)."; + reference + "https://github.com/openconfig/gnoi/tree/main/healthz"; + + container state { + config false; + description + "Operational state parameters relating to component health."; + uses platform-health-state; + } + } + } + + grouping platform-health-state { + description + "Operational state parameters relating to a platform component's + health."; + + leaf status { + type enumeration { + enum UNSPECIFIED { + description + "The component's health status has not yet been checked + by the system."; + } + + enum HEALTHY { + description + "The component is in a HEALTHY state, and is operating + within the expected parameters."; + } + + enum UNHEALTHY { + description + "The component is in a unhealthy state, it is not + performing the function expected of it."; + } + } + description + "The status of the component, indicating its current health."; + oc-ext:telemetry-on-change; + } + + leaf last-unhealthy { + type oc-types:timeticks64; + description + "The time at which the component as last observed to be unhealthy + represented as nanoseconds since the Unix epoch. Unhealthy is defined + as the component being in a state other than HEALTHY."; + oc-ext:telemetry-on-change; + } + + leaf unhealthy-count { + type uint64; + description + "The number of status checks that have determined this component + to be in an unhealthy state. This counter should be incremented + when the component transitions from the HEALTHY to any other + state such that the value reflects the number of times the + component has become unhealthy."; + oc-ext:telemetry-on-change; + } + } + + augment "/oc-platform:components/oc-platform:component" { + description + "Augment healthz information into the /components/component hierarchy."; + + uses platform-health-top; + } +} diff --git a/ocdiff/testdata/yang/old/platform/openconfig-platform-integrated-circuit.yang b/ocdiff/testdata/yang/old/platform/openconfig-platform-integrated-circuit.yang new file mode 100644 index 0000000..67fec32 --- /dev/null +++ b/ocdiff/testdata/yang/old/platform/openconfig-platform-integrated-circuit.yang @@ -0,0 +1,180 @@ +module openconfig-platform-integrated-circuit { + yang-version "1"; + + namespace "http://openconfig.net/yang/platform/integrated-circuit"; + + prefix "oc-ic"; + + import openconfig-platform { prefix oc-platform; } + import openconfig-extensions { prefix oc-ext; } + + organization "OpenConfig working group"; + contact + "OpenConfig working group + www.openconfig.net"; + + description + "This module defines extensions to the OpenConfig platform model + that apply to integrated circuit (INTEGRATED_CIRCUIT) components. + These components are generically forwarding NPUs or ASICs within + the system for which configuration or state is applicable."; + + oc-ext:openconfig-version "0.3.1"; + + revision "2022-04-20" { + description + "Remove unused import"; + reference "0.3.1"; + } + + revision "2021-08-09" { + description + "Amendments to the platform capacity model."; + reference "0.3.0"; + } + + revision "2021-07-08" { + description + "Adding integrated circuit memory parity error counters."; + reference "0.2.0"; + } + + revision "2021-06-21" { + description + "Fix typos in description statements."; + reference "0.1.2"; + } + + revision "2021-06-16" { + description + "Remove trailing whitespace."; + reference "0.1.1"; + } + + revision "2021-05-16" { + description + "Initial revision with platform capacity."; + reference "0.1.0"; + } + + oc-ext:catalog-organization "openconfig"; + oc-ext:origin "openconfig"; + + grouping backplane-facing-capacity-structural { + description + "Structural grouping for reporting on backplane-facing capacity of an integrated + circuit."; + + container backplane-facing-capacity { + description + "This container allows a particular INTEGRATED_CIRCUIT to report its + available backplane-facing bandwidth. Where an integrated circuit is connected + by one or more links to the system's backplane, the capacity is the total cross- + sectional bandwidth available from the input ports of the integrated circuit + across the fabric. The capacity should also reflect the operational status of + the links."; + + container state { + config false; + description + "Operational state parameters relating to backplane capacity."; + + uses backplane-capacity-state; + } + } + } + + grouping backplane-capacity-state { + description + "Operational state relating to backplane capacity."; + + leaf total { + type uint64; + units "bits per second"; + description + "Total backplane-facing capacity that is available in the presence + of no link failures or degradation."; + oc-ext:telemetry-on-change; + } + + leaf total-operational-capacity { + type uint64; + units "bits per second"; + description + "Total backplane-facing capacity that is currently available based + on the active links."; + oc-ext:telemetry-on-change; + } + + leaf consumed-capacity { + type uint64; + units "bits per second"; + description + "Backplane-facing capacity that is consumed by front-panel ports that are connected + to the integrated circuit and are operationally up."; + oc-ext:telemetry-on-change; + } + + leaf available-pct { + type uint16; + description + "Percentage of the total backplane-facing capacity that is currently available to the front + panel ports taking into account failures and/or degradation within the system. + + In the case that there is more backplane-facing capacity available than the front-panel + ports consume, this value may be greater than 100%."; + oc-ext:telemetry-on-change; + } + } + + grouping integrated-circuit-memory { + description + "Structural grouping for integrated circuit memory."; + + container memory { + description + "Container for integrated circuit memory."; + + container state { + config false; + description + "Operational state parameters relating to integrated circuit memory."; + + uses integrated-circuit-memory-state; + } + } + } + + grouping integrated-circuit-memory-state { + description + "Counters that correspond to parity errors in integrated circuit memory"; + + leaf corrected-parity-errors { + type uint64; + description + "Number of corrected parity errors. Single bit ECC errors can be + detected and corrected by most integrated circuits."; + } + + leaf uncorrected-parity-errors { + type uint64; + description + "Number of uncorrected parity errors. Multi-bit ECC errors can be + detected but cannot be corrected by most integrated circuits."; + } + + leaf total-parity-errors { + type uint64; + description + "Total number of parity errors. This includes both the corrected and + uncorrected parity errors."; + } + } + + augment "/oc-platform:components/oc-platform:component/oc-platform:integrated-circuit" { + description + "Augment integrated circuit components with backplane-facing capacity and memory errors."; + uses backplane-facing-capacity-structural; + uses integrated-circuit-memory; + } +} diff --git a/ocdiff/testdata/yang/old/platform/openconfig-platform-linecard.yang b/ocdiff/testdata/yang/old/platform/openconfig-platform-linecard.yang new file mode 100644 index 0000000..5710c9e --- /dev/null +++ b/ocdiff/testdata/yang/old/platform/openconfig-platform-linecard.yang @@ -0,0 +1,151 @@ +module openconfig-platform-linecard { + + yang-version "1"; + + // namespace + namespace "http://openconfig.net/yang/platform/linecard"; + + prefix "oc-linecard"; + + import openconfig-platform { prefix oc-platform; } + import openconfig-extensions { prefix oc-ext; } + + + // meta + organization "OpenConfig working group"; + + contact + "OpenConfig working group + www.openconfig.net"; + + description + "This module defines data related to LINECARD components in + the openconfig-platform model"; + + oc-ext:openconfig-version "1.1.0"; + + revision "2023-02-13" { + description + "Renamed platform-utilization-top to platform-resource-utilization-top."; + reference "1.1.0"; + } + + revision "2022-07-28" { + description + "Remove leaf power-admin-state and use a common definition + instead."; + reference "1.0.0"; + } + + revision "2022-04-21" { + description + "Add platform utilization to linecard."; + reference "0.2.0"; + } + + revision "2020-05-10" { + description + "Remove when statement that references read-only entity from + a read-write context."; + reference "0.1.2"; + } + + revision "2018-11-21" { + description + "Add OpenConfig module metadata extensions."; + reference "0.1.1"; + } + + revision "2017-08-03" { + description + "Initial revision"; + reference "0.1.0"; + } + + // OpenConfig specific extensions for module metadata. + oc-ext:regexp-posix; + oc-ext:catalog-organization "openconfig"; + oc-ext:origin "openconfig"; + + // extension statements + + // feature statements + + // identity statements + + // typedef statements + + // grouping statements + + grouping linecard-config { + description + "Configuration data for linecard components"; + + uses oc-platform:component-power-management; + } + + grouping linecard-state { + description + "Operational state data for linecard components"; + + leaf slot-id { + type string; + description + "Identifier for the slot or chassis position in which the + linecard is installed"; + } + + leaf colour { + type string; + description + "linecard colour"; + } + } + + grouping linecard-top { + description + "Top-level grouping for linecard data"; + + container linecard { + description + "Top-level container for linecard data"; + + container config { + description + "Configuration data for linecards"; + + uses linecard-config; + } + + container state { + + config false; + + description + "Operational state data for linecards"; + + uses linecard-config; + uses linecard-state; + } + uses oc-platform:platform-resource-utilization-top; + } + } + + // data definition statements + + // augment statements + + augment "/oc-platform:components/oc-platform:component" { + description + "Adding linecard data to physical inventory. This subtree + is only valid when the type of the component is LINECARD."; + + uses linecard-top; + } + + // rpc statements + + // notification statements + +} + diff --git a/ocdiff/testdata/yang/old/platform/openconfig-platform-pipeline-counters.yang b/ocdiff/testdata/yang/old/platform/openconfig-platform-pipeline-counters.yang new file mode 100644 index 0000000..e4bad82 --- /dev/null +++ b/ocdiff/testdata/yang/old/platform/openconfig-platform-pipeline-counters.yang @@ -0,0 +1,1341 @@ +module openconfig-platform-pipeline-counters { + + yang-version "1"; + + namespace "http://openconfig.net/yang/platform-pipeline-counters"; + prefix "oc-ppc"; + + import openconfig-yang-types { prefix oc-yang; } + import openconfig-types { prefix oc-types; } + import openconfig-extensions { prefix oc-ext; } + import openconfig-platform { prefix oc-platform; } + + organization + "OpenConfig working group"; + + contact + "OpenConfig working group + www.openconfig.net"; + + description + "Provide fine grain, per-Integrated Circuit (IC), telemetry data streams + that will identify the health, any packet drops, and any errors on the IC. + With this additional telemetry, the health of the IC, packet drops and + errors, can be explicitly monitored not only on a specific router, but also + on a specific IC on a specific router. The IC is divided into 5 platform + independent sub-blocks. + 1. IC Interface Subsystem + 2. Queueing Subsystem + 3. Lookup Subsystem + 4. Host Interface + 5. Fabric Interface. + +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + | | + | +---------------------------------------------------------------+ | + | | Integrated +---------------------------------------+ | | + | | Circuit | Host Interface | | | + | | +---------------------------------------+ | | + | | +------------+ | | + | | +-----------+ | Lookup | +-------------+ | | + | | | IC | | Subsystem | | Fabric | | | + | | | Interface | | | | Interface | | | + | | | Subsystem | +------------+ | | | | + | | +-----------+ +-------------+ +-------------+ | | + | | | Queueing | | | + | | | Subsystem | | | + | | +-------------+ | | + | | | | + | +---------------------------------------------------------------+ | + | | + +-------------------------------------------------------------------+ + Each IC implementation inside forwarding engines may have a different set of + counters. Some counters have different names but the same + functionality and can be grouped together. Most counters are different + between IC families and will have to be aggregated as generic counters. The + aggregation could mean either a specific IC counter needs to be mapped to + one of the values specified in this model, or it may require multiple IC + counters aggregated to produce one of the values in this model. + The following classes of counters will generalize the types of + statistics that are provided from each of the above 5 blocks. + A. Packet Counters + B. Drop Counters + C. Error Counters + The advantage of grouping all the packet counters for all 5 blocks, + all drop counters from all 5 blocks, and all error counters from all + 5 blocks, is to have the abililty to receive all drop counters from + all 5 blocks, for example, with one request."; + + oc-ext:openconfig-version "0.4.0"; + oc-ext:catalog-organization "openconfig"; + oc-ext:origin "openconfig"; + + revision "2023-02-03" { + description + "Add vendor-specific control-plane traffic queue counters"; + reference "0.4.0"; + } + + revision "2022-12-01" { + description + "Add uRPF aggregate drop counter."; + reference "0.3.1"; + } + + revision "2022-11-09" { + description + "Add container for vendor specific drop counters."; + reference "0.3.0"; + } + + revision "2022-01-19" { + description + "Fixed typo for aggregate field."; + reference "0.2.1"; + } + + revision "2021-10-16" { + description + "Update pipeline error counters to allow for multiple errors + per block."; + reference "0.2.0"; + } + + revision "2020-07-31" { + description + "Initial revision of platform pipeline counters."; + reference "0.1.0"; + } + + grouping platform-pipeline-top { + description + "Top-level structural grouping for platform pipeline + counters."; + + container pipeline-counters { + config false; + description + "Top-level container for the packet, drop, and error counters for the + five NPU sub-blocks."; + container packet { + description + "IC packet counters for all five NPU sub-blocks."; + container interface-block { + description + "The IC interface subsystem connects the IC to the external PHY or + MAC."; + + // We do not need a 'config' container here since there is no configurable state for a particular + // entity. + + container state { + description + "State and counters corresponding to the interface subsystem of + the IC."; + + uses pipeline-counters-packet-interface-block-state; + } + } + + container lookup-block { + description + "The IC lookup subsystem perform the next hop lookup of the packet + and other forwarding features such as firewall filters."; + + container state { + description + "State and counters corresponding to the lookup subsystem of the + IC."; + + uses pipeline-counters-packet-lookup-block-state; + } + } + + container queueing-block { + description + "The IC queueing subsystem buffers the packet while processing it + and queues the packet for delivery to the next stage"; + + container state { + description + "State and counters corresponding to the queueing subsystem of + the IC."; + + uses pipeline-counters-packet-queueing-block-state; + } + } + + container fabric-block { + description + "The IC fabric block subsystem connects the IC to the external + systems fabric subsystem"; + + container state { + description + "State and counters corresponding to the fabric subsystem of the + IC."; + + uses pipeline-counters-packet-fabric-block-state; + } + } + + container host-interface-block { + description + "The IC host interface block subsystem connects the IC to the + external systems host or control subsystem"; + + container state { + description + "State and counters corresponding to the host interface subsystem + of the IC."; + + uses pipeline-counters-packet-host-interface-block-state; + } + } + } + + container drop { + description + "IC drop counters for all five NPU sub-blocks."; + container state { + description + "State container for IC drop counters"; + + uses pipeline-drop-packet-state; + } + + + container interface-block { + description + "The IC interface subsystem connects the IC to the external PHY or + MAC."; + + // We do not need a 'config' container here since there is no configurable state for a particular + // entity. + + container state { + description + "Drop counters corresponding to the interface subsystem of the + IC."; + + uses pipeline-drop-packet-interface-block-state; + } + } + + container lookup-block { + description + "The IC lookup subsystem perform the next hop lookup of the packet + and other forwarding features such as firewall filters."; + + container state { + description + "Drop counters corresponding to the lookup subsystem of the IC."; + + uses pipeline-drop-packet-lookup-block-state; + } + } + + container queueing-block { + description + "The IC queueing subsystem buffers the packet while processing it + and queues the packet for delivery to the next stage"; + + container state { + description + "Drop counters corresponding to the queueing subsystem of the + IC."; + + uses pipeline-drop-packet-queueing-block-state; + } + } + + container fabric-block { + description + "The IC fabric block subsystem connects the IC to the external + systems fabric subsystem"; + + container state { + description + "Drop counters corresponding to the fabric subsystem of the IC."; + + uses pipeline-drop-packet-fabric-block-state; + } + } + + container host-interface-block { + description + "The IC host interface block subsystem connects the IC to the + external systems host or control subsystem"; + + container state { + description + "Drop counters corresponding to the host interface subsystem of + the IC."; + + uses pipeline-drop-packet-host-interface-block-state; + } + } + + uses pipeline-vendor-drop-packets; + } + + container errors { + description + "IC errors for all five NPU sub-blocks."; + container interface-block { + description + "The IC interface subsystem connects the IC to the external PHY or + MAC."; + + list interface-block-error { + key "name"; + description + "An individual error within the interface block. Each error counter + is uniquely identified by the name of the error."; + + leaf name { + type leafref { + path "../state/name"; + } + description + "Reference to the name of the error being described."; + } + + container state { + description + "Errors corresponding to the interface subsystem of the IC."; + + uses pipeline-errors-packet-interface-block-state; + } + } + } + + container lookup-block { + description + "The IC lookup subsystem perform the next hop lookup of the packet + and other forwarding features such as firewall filters."; + + list lookup-block-error { + key "name"; + description + "An individual error within the lookup block. Each error counter + is uniquely identified by the name of the error."; + + leaf name { + type leafref { + path "../state/name"; + } + description + "Reference to the name of the error being described."; + } + + container state { + description + "Errors corresponding to the lookup subsystem of the IC."; + + uses pipeline-errors-packet-lookup-block-state; + } + } + } + + container queueing-block { + description + "The IC queueing subsystem buffers the packet while processing it + and queues the packet for delivery to the next stage"; + + list queueing-block-error { + key "name"; + description + "An individual error within the queueing block. Each error counter + is uniquely identified by the name of the error."; + + leaf name { + type leafref { + path "../state/name"; + } + description + "Reference to the name of the error being described."; + } + + container state { + description + "Errors corresponding to the queueing subsystem of the IC."; + + uses pipeline-errors-packet-queueing-block-state; + } + } + } + + container fabric-block { + description + "The IC fabric block subsystem connects the IC to the external + systems fabric subsystem"; + + list fabric-block-error { + key "name"; + description + "An individual error within the fabric block. Each error counter + is uniquely identified by the name of the error."; + + leaf name { + type leafref { + path "../state/name"; + } + description + "Reference to the name of the error being described."; + } + + container state { + description + "Errors corresponding to the fabric subsystem of the IC."; + + uses pipeline-errors-packet-fabric-block-state; + } + } + } + + container host-interface-block { + description + "The IC host interface block subsystem connects the IC to the + external systems host or control subsystem"; + + list host-interface-error { + key "name"; + description + "An individual error within the host interface block. Each error + counter is uniquely identified by the name of the error."; + + leaf name { + type leafref { + path "../state/name"; + } + description + "Reference to the name of the error being described."; + } + + container state { + description + "Errors corresponding to the host interface subsystem of + the IC."; + + uses pipeline-errors-packet-host-interface-block-state; + } + } + } + } + + uses pipeline-control-plane-top; + } + } + + grouping pipeline-packets-common { + description + "A common set of packet counters that apply to multiple packet sections."; + + leaf in-packets { + type oc-yang:counter64; + description + "Incoming packets towards the integrated-circuit interface + subsystem block from the line interfaces or fabric."; + } + + leaf out-packets { + type oc-yang:counter64; + description + "Outgoing packets towards the line interfaces or fabric from the + integrated-circuit interface subsystem block."; + } + + leaf in-bytes { + type oc-yang:counter64; + description + "Incoming bytes towards the integrated-circuit interface + subsystem block from the line interfaces or fabric."; + } + + leaf out-bytes { + type oc-yang:counter64; + description + "Outgoing bytes towards the line interfaces or fabric from the + integrated-circuit interface subsystem block."; + } + } + + grouping pipeline-counters-common-high-low-packets { + description + "A common set of high and low priority packet counters that apply to + multiple packet sections."; + + leaf in-high-priority-packets { + type oc-yang:counter64; + description + "Incoming high priority packets towards the integrated-circuit + fabric subsystem block from the previous NPU sub block."; + } + + leaf out-high-priority-packets { + type oc-yang:counter64; + description + "Outgoing high priority packets towards the fabric from the + integrated-circuit fabric subsystem block."; + } + + leaf in-low-priority-packets { + type oc-yang:counter64; + description + "Incoming low priority packets towards the integrated-circuit fabric + subsystem block from the previous NPU sub block."; + } + + leaf out-low-priority-packets { + type oc-yang:counter64; + description + "Outgoing low priority packets towards the fabric from the + integrated-circuit fabric subsystem block."; + } + + } + + grouping pipeline-counters-packet-interface-block-state { + description + "Each counter will aggregate incoming and outgoing packets and bytes + that connect the IC to the external MAC or PHY."; + + uses pipeline-packets-common; + + } + + grouping pipeline-counters-packet-lookup-block-state { + description + "The IC lookup subsystem counters include total packets/bytes in/out of + the lookup subsystem and performance metrics for key functionality of this + subsystem such as lookup memory usage, nexthop memory usage, ACL, + and firewall usage"; + + leaf lookup-utilization { + type oc-types:percentage; + description + "The integrated-circuit lookup subsystem block utilization percentage."; + } + + uses pipeline-packets-common; + + leaf lookup-memory { + type uint64; + units bytes; + description + "The total amount of memory available in the lookup subsystem."; + } + + leaf lookup-memory-used { + type uint64; + units bytes; + description + "The amount of memory used in the lookup subsystem."; + } + + leaf nexthop-memory { + type uint64; + units bytes; + description + "The total amount of nexthop memory available in the lookup subsystem."; + } + + leaf nexthop-memory-used { + type uint64; + units bytes; + description + "The amount of nexthops memory used in the lookup subsystem."; + } + + leaf acl-memory-total-entries { + type uint64; + description + "Total firewall or ACL memory counter measured in entries."; + } + + leaf acl-memory-used-entries { + type uint64; + description + "Amount of used firewall or ACL memory counter measured in entries. + The number of used entries must include the entries + that are 'allocated but free' if the memory reaping algorithm makes + these entries practically unusable."; + } + + leaf acl-memory-total-bytes { + type uint64; + units bytes; + description + "Total firewall or ACL memory counter measured in bytes."; + } + + leaf acl-memory-used-bytes { + type uint64; + units bytes; + description + "Amount of used firewall or ACL memory counter measured in bytes. + The number of used bytes must include the bytes + that are 'allocated but free' if the memory reaping algorithm makes + these bytes practically unusable"; + } + + leaf fragment-total-pkts { + type oc-yang:counter64; + description + "Total number of fragments generated by the CPU."; + } + + } + + grouping pipeline-counters-packet-queueing-block-state { + description + "The IC queueing subsystem counters include packets/bytes in/out of the + queueing subsystem and performance metrics for key functionality of this + subsystem such as memory used and loopback counts."; + + uses pipeline-packets-common; + + leaf queue-memory { + type uint64; + units bytes; + description + "The total amount of memory available in the queue subsystem."; + } + + leaf queue-memory-used { + type uint64; + units bytes; + description + "The amount of memory used in the queue subsystem."; + } + + leaf loopback-packets { + type oc-yang:counter64; + description + "The number of packets in the loopback or re-circulate subsystem."; + } + + leaf loopback-bytes { + type uint64; + units bytes; + description + "The number of bytes in the loopback or re-circulate subsystem."; + } + + } + + grouping pipeline-counters-packet-fabric-block-state { + description + "The IC fabric subsystem counters include packets/cells in/out of the + fabric subsystem and performance metrics for key functionality of this + subsystem such as high and low priority packet counts."; + + leaf in-cells { + type oc-yang:counter64; + description + "Incoming cells towards the integrated-circuit fabric + subsystem block from the previous NPU sub block."; + } + + leaf out-cells { + type oc-yang:counter64; + description + "Outgoing cells towards the fabric from the + integrated-circuit fabric subsystem block."; + } + + uses pipeline-packets-common; + + leaf in-high-priority-cells { + type oc-yang:counter64; + description + "Incoming high priority cells towards the integrated-circuit fabric + subsystem block from the previous NPU sub block."; + } + + leaf out-high-priority-cells { + type oc-yang:counter64; + description + "Outgoing high priority cells towards the fabric from the + integrated-circuit fabric subsystem block."; + } + + leaf in-low-priority-cells { + type oc-yang:counter64; + description + "Incoming low priority cells towards the integrated-circuit fabric + subsystem block from the previous NPU sub block."; + } + + leaf out-low-priority-cells { + type oc-yang:counter64; + description + "Outgoing low priority cells towards the fabric from the + integrated-circuit fabric subsystem block."; + } + + uses pipeline-counters-common-high-low-packets; + + } + + grouping pipeline-counters-packet-host-interface-block-state { + description + "The IC host interface counters include packets/bytes in/out of the + host interface subsystem and performance metrics for key functionality + of this subsystem such as fragmented packet counts and hi/low priority + packet counts"; + + uses pipeline-packets-common; + + leaf fragment-punt-pkts{ + type oc-yang:counter64; + description + "The packets that were successfully punted to CPU due to egress MTU + exceeded."; + } + + uses pipeline-counters-common-high-low-packets; + + } + + grouping pipeline-drops-common { + description + "A common set of drop counters that apply to multiple drop sections."; + + leaf oversubscription { + type oc-yang:counter64; + description + "Number of packets dropped due to oversubscription of the + integrated-circuit subsystem block."; + } + } + + grouping pipeline-drops-common-high-low { + description + "A common set of drop counters for high and low priority."; + + leaf in-high-priority { + type oc-yang:counter64; + description + "Incoming high priority drops towards this integrated-circuit + subsystem block from the previous NPU sub-block or interface."; + } + + leaf out-high-priority { + type oc-yang:counter64; + description + "Outgoing high priority drops towards the fabric/interface from this + integrated-circuit subsystem block."; + } + + leaf in-low-priority { + type oc-yang:counter64; + description + "Incoming low priority drops towards this integrated-circuit + subsystem block from the previous NPU sub-block or interface."; + } + + leaf out-low-priority { + type oc-yang:counter64; + description + "Outgoing low priority drops towards the fabric/interface from this + integrated-circuit subsystem block."; + } + } + + grouping pipeline-drop-packet-interface-block-state { + description + "Each drop counter will aggregate incoming and outgoing packets, and + oversubscription drops that connect the IC to the external MAC or PHY."; + + uses pipeline-drops-common; + + leaf in-drops { + type oc-yang:counter64; + description + "Incoming drops towards the integrated-circuit interface + subsystem block from the interfaces due to any reason."; + } + + leaf out-drops { + type oc-yang:counter64; + description + "Outgoing drops towards the interfaces from the + integrated-circuit interface subsystem block due to any reason."; + } + + } + + grouping pipeline-drop-packet-lookup-block-state { + description + "The IC lookup subsystem drop counters track key functionality of this + subsystem such as Oversubscription, no-route, no-label, no-NH, invalid- + packets, forwarding-policy, incorrect-software, rate-limit, fragments, + and firewall drops"; + + uses pipeline-drops-common; + + leaf no-route { + type oc-yang:counter64; + description + "Packets dropped due to no FIB entry for this ipv4 or ipv6 lookup."; + } + + leaf no-label { + type oc-yang:counter64; + description + "Packets dropped due to no FIB entry for this MPLS label."; + } + + leaf no-nexthop { + type oc-yang:counter64; + description + "Packets dropped due to no nexthop information - either the nexthop is + not programmed, or there is an invalid nexthop, or there is no ARP + information so the nexthop is in invalid state."; + } + + leaf invalid-packet { + type oc-yang:counter64; + description + "Packets dropped due to invalid packet format for ipv4, ipv6, or MPLS."; + } + + leaf forwarding-policy { + type oc-yang:counter64; + description + "Packets dropped due to either a filter applied as part of a forwarding + policy or dropped due to a policy-based-routing policy lookup."; + } + + leaf incorrect-software-state { + type oc-yang:counter64; + description + "Packets dropped due to any incorrect or invalid software state of the + forwarding structures during lookup."; + } + + leaf rate-limit { + type oc-yang:counter64; + description + "Packets dropped due to rate limiters - either user configured rate + limiters or system rate limiters in the forwarding path."; + } + + leaf fragment-total-drops { + type oc-yang:counter64; + description + "Total number of packets dropped that could not be fragmented by NPU + due to DF bit."; + } + + leaf lookup-aggregate { + type oc-yang:counter64; + description + "Packets dropped due to aggregate lookup drop counters - this counter + is sometimes referred to as Normal Discards or + ENQ_DISCARDED_PACKET_COUNTER."; + } + + leaf acl-drops { + type oc-yang:counter64; + description + "Packets dropped due to firewall or acl terms."; + } + + } + + grouping pipeline-drop-packet-queueing-block-state { + description + "The IC queueing subsystem drop counters track key functionality of this + subsystem such as oversubscription, memory-limit, incorrect-state, and + loopback drops."; + + uses pipeline-drops-common; + + leaf memory-limit { + type oc-yang:counter64; + description + "Packets dropped due to running out of the queue memory."; + } + + leaf incorrect-state { + type oc-yang:counter64; + description + "Packets dropped due to hardware of software incorrect state of VOQs, + or fabric queues, or interface queues."; + } + + leaf lookup-queue { + type oc-yang:counter64; + description + "Packets dropped in either the lookup or recirculation path."; + } + + } + + grouping pipeline-drop-packet-fabric-block-state { + description + "The IC fabric subsystem drop counters track key functionality of this + subsystem such as oversubscription, lost-packets, high and low priority + packet drops."; + + uses pipeline-drops-common; + + leaf lost-packets { + type oc-yang:counter64; + description + "Fabric drops due to re-ordering, or due to packets arriving late, or + due to some loss in the fabric."; + } + + uses pipeline-drops-common-high-low; + + leaf fabric-aggregate { + type oc-yang:counter64; + description + "Aggregate of fabric-in and fabric-out drops."; + } + + } + + grouping pipeline-drop-packet-host-interface-block-state { + description + "The IC host interface drop counters track key funcitonality of this + subsystem such as oversubscription, rate-limit, fragment, and + hi/low priority drop counts"; + + uses pipeline-drops-common; + + leaf rate-limit { + type oc-yang:counter64; + description + "Packet drops due to the rate limit in the integrated-circuit host + subsystem block."; + } + + uses pipeline-drops-common-high-low; + + leaf fragment-punt { + type oc-yang:counter64; + description + "The packets that were failed to punt to CPU due to policing rate."; + } + + leaf host-aggregate { + type oc-yang:counter64; + description + "Aggregate of all the drops in the host path."; + } + + } + + grouping pipeline-errors-common { + description + "A common set of error counters that apply to multiple error sections."; + + leaf name { + type string; + description + "Name of the interrupt, hardware error, or software error in the NPU."; + } + + leaf count { + type uint64; + description + "Total count of errors of this type."; + } + + leaf threshold { + type uint64; + description + "Number of errors before a recovery action is automatically + taken by the system."; + } + + leaf-list action { + type enumeration { + enum LOG { + description + "Log a descriptive message."; + } + enum LINECARD_REBOOT { + description + "The line card is brought offline and then back online."; + } + enum LINECARD_OFFLINE { + description + "The line card is brought offline."; + } + enum NPU_RESET { + description + "The NPU is brought offline and then back online."; + } + enum NPU_OFFLINE { + description + "The NPU is brought offline."; + } + enum GET_DIAGNOSTIC_INFO { + description + "Diagnostic data is gathered at the time of the problem."; + } + enum ALARM { + description + "An Alarm is raised"; + } + } + description + "Error actions that are taken by the system - log, linecard reboot, + linecard offline, NPU reset, NPU offline, gather diagnostic data, + raise an alarm."; + } + + leaf active { + type boolean; + default false; + description + "The error is currently in an active state. When the system detects + that the specified threshold is exceeded, this value should be set to + true."; + oc-ext:telemetry-on-change; + } + + leaf level { + type enumeration { + enum FATAL { + description + "The Fatal error causes total packet loss"; + } + enum MAJOR { + description + "The Major error causes persistent packet loss"; + } + enum MINOR { + description + "The Minor error is an indication of some past problem, but now is + corrected"; + } + enum INFORMATIONAL { + description + "Some problem happened that is not packet loss affecting."; + } + } + description + "The severity of the error that is being recorded by the system. This + value can be used by a consumer to determine the action when this error + is recorded."; + } + } + + grouping pipeline-errors-packet-interface-block-state { + description + "Error counter will aggregate the errors that connect the IC to the + external MAC or PHY. Each error should contain the name, count, + last-occurrence, threshold, action, and severity level."; + + uses pipeline-errors-common; + + } + + grouping pipeline-errors-packet-lookup-block-state { + description + "The IC lookup subsystem error counters include the errors encountered by + the lookup subsystem. Each error should contain the name, count, + last-occurrence, threshold, action, and severity level."; + + uses pipeline-errors-common; + + } + + grouping pipeline-errors-packet-queueing-block-state { + description + "The IC queueing subsystem error counters include the errors encountered + by the queueing subsystem. Each error should contain the name, count, + last-occurrence, threshold, action, and severity level."; + + uses pipeline-errors-common; + + } + + grouping pipeline-errors-packet-fabric-block-state { + description + "The IC fabric subsystem error counters include the errors encountered by + the fabric subsystem. Each error should contain the name, count, + last-occurrence, threshold, action, and severity level."; + + uses pipeline-errors-common; + + } + + grouping pipeline-errors-packet-host-interface-block-state { + description + "The IC host interface error counters include the errors encountered by + the host interface subsystem. Each error should contain the name, count, + last-occurrence, threshold, action, and severity level."; + + uses pipeline-errors-common; + + } + + grouping pipeline-drop-packet-state { + description + "Grouping of pipeline drop packet state."; + + leaf adverse-aggregate { + type oc-yang:counter64; + description + "This captures the aggregation of all counters where the switch is + unexpectedly dropping packets. Occurrence of these drops on a stable + (no recent hardware or config changes) and otherwise healthy + switch needs further investigation."; + } + + leaf congestion-aggregate { + type oc-yang:counter64; + description + "This tracks the aggregation of all counters where the expected + conditions of packet drops due to internal congestion in some block of + the hardware that may not be visible in through other congestion + indicators like interface discards or queue drop counters."; + } + + leaf packet-processing-aggregate { + type oc-yang:counter64; + description + "This aggregation of counters represents the conditions in which + packets are dropped due to legitimate forwarding decisions (ACL drops, + No Route etc.)"; + } + + leaf urpf-aggregate { + type oc-yang:counter64; + description + "This aggregation of counters represents the conditions in which + packets are dropped due to failing uRPF lookup check. This counter + and the packet-processing-aggregate counter should be incremented + for each uRPF packet drop."; + } + + } + + grouping pipeline-vendor-drop-packets { + description + "Grouping for vendor specific drop packets"; + + container vendor { + description + "Counters within these containers are defined and augmented by vendors. + As each ASIC and vendor has different implementation and internal + parts where packets may be dropped at any point in time. Providing + specific hardware counters provides better visibility into traffic drop. + + The recommended usage of this container is to create an augment at + .../pipeline-counter/drop/vendor that contains additional vendor/platform + specific containers. + + e.g. + augment /components/component/integrated-circuit/pipeline-counter/drop/vendor { + container { + container { + uses pipeline-vendor-drop-containers; + } + } + }"; + + reference + "https://github.com/openconfig/public/tree/master/doc/vendor_counter_guide.md"; + } + } + + grouping pipeline-vendor-drop-containers { + description + "A utility grouping for vendors to insert when augmenting the vendor + drop counters container .../pipeline-counter/drop/vendor. + + Counters that cannot differentiate between adverse, congestion, and + packet-processing should still be exposed as a vendor-specific, + packet-processing counter."; + + reference + "https://github.com/openconfig/public/tree/master/doc/vendor_counter_guide.md"; + + container adverse { + description + "These counters capture where the switch is unexpectedly dropping + packets. Occurrence of these drops on a stable (no recent hardware + or config changes) and otherwise healthy switch needs further + investigation. + + The sum of all counters under this container should match the value in + .../pipeline-counters/drop/state/adverse-aggregate"; + + container state { + description + "State container for vendor specific adverse counters."; + } + } + + container congestion { + description + "These counters track expected conditions of packet drops due to + internal congestion in some block of the hardware that may not be + visible in through other congestion indicators like interface + discards or queue drop counters. + + The sum of all counters under this container should match the value in + .../pipeline-counters/drop/state/congestion-aggregate"; + + container state { + description + "State container for vendor specific congestion counters."; + } + } + + container packet-processing { + description + "These counters represent the conditions in which packets are dropped + due to legitimate forwarding decisions (ACL drops, No Route etc.) + + The sum of all counters under this container should match the value in + .../pipeline-counters/drop/state/packet-processing-aggregate"; + + container state { + description + "State container for vendor specific packet processing counters."; + } + } + } + + grouping control-plane-traffic-counters-state { + description + "Control plane traffic counter state grouping."; + + leaf queued-aggregate { + type oc-yang:counter64; + description + "This captures the aggregation of all counters where the switch has enqueued + traffic related to the control-plane."; + } + + leaf queued-bytes-aggregate { + type oc-yang:counter64; + description + "This captures the aggregation of all counters in bytes where the switch has + enqueued traffic related to the control-plane."; + } + + leaf dropped-aggregate { + type oc-yang:counter64; + description + "This captures the aggregation of all counters where the switch has dropped + traffic related to the control-plane."; + } + + leaf dropped-bytes-aggregate { + type oc-yang:counter64; + description + "This captures the aggregation of all counters in bytes where the switch has + dropped traffic related to the control-plane."; + } + } + + grouping control-plane-traffic-vendor-counters { + description + "A utility grouping for vendors to use when augmenting the vendor-specific + control-plane traffic container."; + + leaf queued { + type oc-yang:counter64; + description + "This counter counts the number of packets enqueued. + + This counter should contribute to the total aggregate of + .../pipeline-counters/control-plane-traffic/state/queued-aggregate."; + } + + leaf queued-bytes { + type oc-yang:counter64; + description + "This counter counts the number of bytes enqueued. + + This counter should contribute to the total aggregate of + .../pipeline-counters/control-plane-traffic/state/queued-bytes-aggregate."; + } + + leaf dropped { + type oc-yang:counter64; + description + "This counter counts the number of packets dropped. + + This counter should contribute to the total aggregate of + .../pipeline-counters/control-plane-traffic/state/dropped-aggregate."; + } + + leaf dropped-bytes { + type oc-yang:counter64; + description + "This counter counts the number of bytes dropped. + + This counter should contribute to the total aggregate of + .../pipeline-counters/control-plane-traffic/state/dropped-bytes-aggregate."; + } + } + + grouping pipeline-control-plane-top { + description + "Top-level structural grouping for control-plane traffic counters."; + + container control-plane-traffic { + description + "Counters that are related to traffic destined to the control-plane."; + + container state { + config false; + description + "State container for control-plane traffic counters."; + + uses control-plane-traffic-counters-state; + } + + container vendor { + description + "Counters within these containers are defined and augmented by vendors. + As each ASIC and vendor has different implementation and internal + parts where packets may be dropped at any point in time. Providing + vendor-specific counters provides better visibility into control-plane traffic. + + The recommended usage of this container is to create an augment at + .../pipeline-counter/control-plane-traffic/vendor that contains additional + vendor/platform specific containers. + + e.g. + augment /components/component/integrated-circuit/pipeline-counter/control-plane-traffic/vendor { + container { + container { + container state { + leaf counter-a { + uses control-plane-traffic-vendor-counters; + } + + leaf counter-b { + uses control-plane-traffic-vendor-counters; + } + } + } + } + }"; + + reference + "https://github.com/openconfig/public/tree/master/doc/vendor_counter_guide.md"; + } + } + } + + augment "/oc-platform:components/oc-platform:component/oc-platform:integrated-circuit" { + description + "Add operational state data that corresponds to sub-blocks of an integrated + circuit (NPU, ASIC) to the platform model."; + + uses platform-pipeline-top; + } +} diff --git a/ocdiff/testdata/yang/old/platform/openconfig-platform-port.yang b/ocdiff/testdata/yang/old/platform/openconfig-platform-port.yang new file mode 100644 index 0000000..42a1193 --- /dev/null +++ b/ocdiff/testdata/yang/old/platform/openconfig-platform-port.yang @@ -0,0 +1,300 @@ +module openconfig-platform-port { + + yang-version "1"; + + // namespace + namespace "http://openconfig.net/yang/platform/port"; + + prefix "oc-port"; + + // import some basic types + import openconfig-platform { prefix oc-platform; } + import openconfig-extensions { prefix oc-ext; } + + // meta + organization "OpenConfig working group"; + + contact + "OpenConfig working group + www.openconfig.net"; + + description + "This module defines data related to PORT components in the + openconfig-platform model"; + + oc-ext:openconfig-version "1.0.1"; + + revision "2023-03-22" { + description + "Clarify use of the interface-ref type."; + reference "1.0.1"; + } + + revision "2023-01-19" { + description + "Add clarification of the definition of a physical channel, and + example configurations."; + reference "1.0.0"; + } + + revision "2021-10-01" { + description + "Fix indentation for 'list group'"; + reference "0.4.2"; + } + + revision "2021-06-16" { + description + "Remove trailing whitespace"; + reference "0.4.1"; + } + + revision "2021-04-22" { + description + "Adding support for flexible port breakout."; + reference "0.4.0"; + } + + revision "2020-05-06" { + description + "Ensure that when statements in read-write contexts + reference only read-write leaves."; + reference "0.3.3"; + } + + revision "2018-11-21" { + description + "Add OpenConfig module metadata extensions."; + reference "0.3.2"; + } + + revision "2018-11-07" { + description + "Fixed error in when statement path"; + reference "0.3.1"; + } + + revision "2018-01-20" { + description + "Added augmentation for interface-to-port reference"; + reference "0.3.0"; + } + + revision "2017-11-17" { + description + "Corrected augmentation path for port data"; + reference "0.2.0"; + } + + revision "2016-10-24" { + description + "Initial revision"; + reference "0.1.0"; + } + + // OpenConfig specific extensions for module metadata. + oc-ext:regexp-posix; + oc-ext:catalog-organization "openconfig"; + oc-ext:origin "openconfig"; + + // extension statements + + // feature statements + + // identity statements + + // typedef statements + + // grouping statements + + grouping group-config { + description + "Configuration data for the breakout group."; + + leaf index { + type uint8; + description + "Each index specifies breakouts that are identical in + terms of speed and the number of physical channels."; + } + + leaf num-breakouts { + type uint8; + description + "Sets the number of interfaces using this breakout group."; + } + + leaf num-physical-channels { + type uint8; + description + "Sets the number of lanes or physical channels assigned + to the interfaces in this breakout group. This leaf need + not be set if there is only one breakout group where all + the interfaces are of equal speed and have equal number + of physical channels. + + The physical channels referred to by this leaf are + electrical channels towards the transceiver."; + } + } + + grouping group-state { + description + "Operational state data for the port breakout group."; + } + + grouping port-breakout-top { + description + "Top-level grouping for port breakout data."; + + container breakout-mode { + description + "Top-level container for port breakout-mode data."; + + container groups { + description + "Top level container for breakout groups data. + + When a device has the capability to break a port into + interfaces of different speeds and different number of + physical channels, it can breakout a 400G OSFP port with + 8 physical channels (with support for 25G NRZ, 50G PAM4 + and 100G PAM4) into mixed speed interfaces. Particularly, to + break out into two 100G ports with different modulation, and a 200G + port, a user must configure 1 interface with 2 physical channels + 1 interface with 4 physical channels and 1 interface with + 2 physical channels. With this configuration the interface in + 1st breakout group would use 50G PAM4 modulation, interface + in 2nd breakout group would use 25G NRZ modulation and the + interface in 3rd breakout group would use 100G PAM4 modulation + This configuration would result in 3 entries in the breakout + groups list. The example configuration for this case is shown below: + + { + \"groups\": { + \"group\": [ + { + \"config\": { + \"breakout-speed\": \"SPEED_100GB\", + \"index\": 0, + \"num-breakouts\": 1, + \"num-physical-channels\": 2 + }, + \"index\": 0 + }, + { + \"config\": { + \"breakout-speed\": \"SPEED_100GB\", + \"index\": 1, + \"num-breakouts\": 1, + \"num-physical-channels\": 4 + }, + \"index\": 1 + }, + { + \"config\": { + \"breakout-speed\": \"SPEED_200GB\", + \"index\": 2, + \"num-breakouts\": 1, + \"num-physical-channels\": 2 + }, + \"index\": 2 + } + ] + } + } + + When a device does not have the capability to break a port + into interfaces of different speeds and different number of + physical channels, in order to breakout a 400G OSFP port with + 8 physical channels into 50G breakout ports it would use 8 interfaces + with 1 physical channel each. This would result in 1 entry in the + breakout groups list. The example configuration for this case is + shown below: + + { + \"groups\": { + \"group\": [ + { + \"config\": { + \"breakout-speed\": \"SPEED_50GB\", + \"index\": 0, + \"num-breakouts\": 8, + \"num-physical-channels\": 1 + }, + \"index\": 0 + } + ] + } + } + + Similarly, if a 400G-DR4 interface (8 electrical channels at 50Gbps) + is to be broken out into 4 100Gbps ports, the following configuration + is used: + + { + \"groups\": { + \"group\": [ + { + \"config\": { + \"breakout-speed\": \"SPEED_100GB\", + \"index\": 0, + \"num-breakouts\": 4, + \"num-physical-channels\": 2 + }, + \"index\": 0 + } + ] + } + }"; + + list group { + key "index"; + description + "List of breakout groups."; + + leaf index { + type leafref { + path "../config/index"; + } + description + "Index of the breakout group entry in the breakout groups list."; + } + + container config { + description + "Configuration data for breakout group."; + uses group-config; + } + + container state { + config false; + description + "Operational state data for breakout group."; + + uses group-config; + uses group-state; + } + } + } + } + } + + // data definition statements + + // augment statements + + augment "/oc-platform:components/oc-platform:component/" + + "oc-platform:port" { + description + "Adding port breakout data to physical platform data. This subtree + is only valid when the type of the component is PORT."; + + uses port-breakout-top; + } + + // rpc statements + + // notification statements + +} diff --git a/ocdiff/testdata/yang/old/platform/openconfig-platform-psu.yang b/ocdiff/testdata/yang/old/platform/openconfig-platform-psu.yang new file mode 100644 index 0000000..02d6e96 --- /dev/null +++ b/ocdiff/testdata/yang/old/platform/openconfig-platform-psu.yang @@ -0,0 +1,146 @@ +module openconfig-platform-psu { + + yang-version "1"; + + // namespace + namespace "http://openconfig.net/yang/platform/psu"; + + prefix "oc-platform-psu"; + + // import some basic types + import openconfig-extensions { prefix oc-ext; } + import openconfig-types { prefix oc-types; } + import openconfig-platform { prefix oc-platform; } + + + // meta + organization "OpenConfig working group"; + + contact + "OpenConfig working group + www.openconfig.net"; + + description + "This module defines a schema for power supply components in + the OpenConfig platform model."; + + oc-ext:openconfig-version "0.2.1"; + + revision "2018-11-21" { + description + "Add OpenConfig module metadata extensions."; + reference "0.2.1"; + } + + revision "2018-01-16" { + description + "Changed admin state leaf name"; + reference "0.2.0"; + } + + revision "2017-12-21" { + description + "Initial revision"; + reference "0.1.0"; + } + + // OpenConfig specific extensions for module metadata. + oc-ext:regexp-posix; + oc-ext:catalog-organization "openconfig"; + oc-ext:origin "openconfig"; + + // identity statements + + // typedef statements + + // grouping statements + + grouping psu-config { + description + "Configuration data for power supply components"; + + leaf enabled { + type boolean; + default true; + description + "Adminsitrative control on the on/off state of the power + supply unit."; + } + } + + grouping psu-state { + description + "Operational state data for power supply components"; + + + // TODO(aashaikh): May need to convert some of these to + // interval statistics once decided on which leaves to include. + leaf capacity { + type oc-types:ieeefloat32; + units watts; + description + "Maximum power capacity of the power supply."; + } + + leaf input-current { + type oc-types:ieeefloat32; + units amps; + description + "The input current draw of the power supply."; + } + + leaf input-voltage { + type oc-types:ieeefloat32; + units volts; + description + "Input voltage to the power supply."; + } + + leaf output-current { + type oc-types:ieeefloat32; + units amps; + description + "The output current supplied by the power supply."; + } + + leaf output-voltage { + type oc-types:ieeefloat32; + units volts; + description + "Output voltage supplied by the power supply."; + } + + leaf output-power { + type oc-types:ieeefloat32; + units watts; + description + "Output power supplied by the power supply."; + } + } + + // data definition statements + + // augment statements + + augment "/oc-platform:components/oc-platform:component/" + + "oc-platform:power-supply/oc-platform:config" { + description + "Adds power supply data to component operational state."; + + uses psu-config; + } + + augment "/oc-platform:components/oc-platform:component/" + + "oc-platform:power-supply/oc-platform:state" { + description + "Adds power supply data to component operational state."; + + uses psu-config; + uses psu-state; + } + + + // rpc statements + + // notification statements +} \ No newline at end of file diff --git a/ocdiff/testdata/yang/old/platform/openconfig-platform-software.yang b/ocdiff/testdata/yang/old/platform/openconfig-platform-software.yang new file mode 100644 index 0000000..96fd456 --- /dev/null +++ b/ocdiff/testdata/yang/old/platform/openconfig-platform-software.yang @@ -0,0 +1,100 @@ +module openconfig-platform-software { + + yang-version "1"; + + // namespace + namespace "http://openconfig.net/yang/platform/software-module"; + + prefix "oc-sw-module"; + + import openconfig-platform { + prefix oc-platform; + } + + import openconfig-extensions { + prefix oc-ext; + } + + // meta + organization + "OpenConfig working group"; + + contact + "OpenConfig working group + www.openconfig.net"; + + description + "This module defines data related to software components in + the openconfig-platform model"; + + oc-ext:openconfig-version "0.1.1"; + + revision "2021-06-16" { + description + "Remove trailing whitespace"; + reference "0.1.1"; + } + + revision "2021-01-18" { + description + "Initial revision."; + reference "0.1.0"; + } + + // OpenConfig specific extensions for module metadata. + oc-ext:catalog-organization "openconfig"; + oc-ext:origin "openconfig"; + + // extension statements + // feature statements + // identity statements + identity SOFTWARE_MODULE_TYPE { + description + "Base identity for defining various types of software + modules."; + } + + identity USERSPACE_PACKAGE_BUNDLE { + base SOFTWARE_MODULE_TYPE; + description + "A collection of userspace software modules that are grouped, and + possibly versioned, together. A package bundle may have + subcomponents that represent individual elements in the bundle + and their properties."; + } + + identity USERSPACE_PACKAGE { + base SOFTWARE_MODULE_TYPE; + description + "An individual software package that runs in user space. The + package may be part of a package bundle."; + } + + // typedef statements + // grouping statements + grouping sw-module-state { + description + "Operational state data for software module components"; + + leaf module-type { + type identityref { + base SOFTWARE_MODULE_TYPE; + } + description + "Type of the software module"; + } + } + + // data definition statements + // augment statements + augment "/oc-platform:components/oc-platform:component/" + + "oc-platform:software-module/oc-platform:state" { + description + "Adding software module operational data to physical inventory. + This subtree is only valid when the type of the component is + SOFTWARE_MODULE."; + + uses sw-module-state; + } +} + diff --git a/ocdiff/testdata/yang/old/platform/openconfig-platform-types.yang b/ocdiff/testdata/yang/old/platform/openconfig-platform-types.yang new file mode 100644 index 0000000..d28881f --- /dev/null +++ b/ocdiff/testdata/yang/old/platform/openconfig-platform-types.yang @@ -0,0 +1,541 @@ +module openconfig-platform-types { + + yang-version "1"; + + // namespace + namespace "http://openconfig.net/yang/platform-types"; + + prefix "oc-platform-types"; + + import openconfig-types { prefix oc-types; } + import openconfig-extensions { prefix oc-ext; } + + // meta + organization + "OpenConfig working group"; + + contact + "OpenConfig working group + www.openconfig.net"; + + description + "This module defines data types (e.g., YANG identities) + to support the OpenConfig component inventory model."; + + oc-ext:openconfig-version "1.6.0"; + + revision "2023-06-27" { + description + "Add WIFI_ACCESS_POINT"; + reference "1.6.0"; + } + + revision "2022-07-28" { + description + "Add grouping for component power management"; + reference "1.5.0"; + } + + revision "2022-03-27" { + description + "Add identity for BIOS"; + reference "1.4.0"; + } + + revision "2022-02-02" { + description + "Add support for component reboot and switchover."; + reference "1.3.0"; + } + + revision "2021-07-29" { + description + "Add several avg-min-max-instant-stats groupings"; + reference "1.2.0"; + } + + revision "2021-01-18" { + description + "Add identity for software modules"; + reference "1.1.0"; + } + + revision "2019-06-03" { + description + "Add OpenConfig component operating system patch type."; + reference "1.0.0"; + } + + revision "2018-11-21" { + description + "Add OpenConfig module metadata extensions."; + reference "0.10.1"; + } + + revision "2018-11-16" { + description + "Added FEC_MODE_TYPE and FEC_STATUS_TYPE"; + reference "0.10.0"; + } + + revision "2018-05-05" { + description + "Added min-max-time to + avg-min-max-instant-stats-precision1-celsius, + added new CONTROLLER_CARD identity"; + reference "0.9.0"; + } + + revision "2018-01-16" { + description + "Added new per-component common data; add temp alarm"; + reference "0.8.0"; + } + + revision "2017-12-14" { + description + "Added anchor containers for component data, added new + component types"; + reference "0.7.0"; + } + + revision "2017-08-16" { + description + "Added power state enumerated type"; + reference "0.6.0"; + } + + revision "2016-12-22" { + description + "Added temperature state variable to component"; + reference "0.5.0"; + } + + // OpenConfig specific extensions for module metadata. + oc-ext:regexp-posix; + oc-ext:catalog-organization "openconfig"; + oc-ext:origin "openconfig"; + + // grouping statements + grouping avg-min-max-instant-stats-precision1-celsius { + description + "Common grouping for recording temperature values in + Celsius with 1 decimal precision. Values include the + instantaneous, average, minimum, and maximum statistics"; + + leaf instant { + type decimal64 { + fraction-digits 1; + } + units celsius; + description + "The instantaneous value of the statistic."; + } + + leaf avg { + type decimal64 { + fraction-digits 1; + } + units celsius; + description + "The arithmetic mean value of the statistic over the + sampling period."; + } + + leaf min { + type decimal64 { + fraction-digits 1; + } + units celsius; + description + "The minimum value of the statistic over the sampling + period"; + } + + leaf max { + type decimal64 { + fraction-digits 1; + } + units celsius; + description + "The maximum value of the statistic over the sampling + period"; + } + + uses oc-types:stat-interval-state; + uses oc-types:min-max-time; + } + + grouping avg-min-max-instant-stats-precision2-volts { + description + "Common grouping for recording voltage values in + volts with 2 decimal precision. Values include the + instantaneous, average, minimum, and maximum statistics. + If supported by the device, the time interval over which + the statistics are computed, and the times at which the + minimum and maximum values occurred, are also reported."; + + leaf instant { + type decimal64 { + fraction-digits 2; + } + units volts; + description + "The instantaneous value of the statistic."; + } + + leaf avg { + type decimal64 { + fraction-digits 2; + } + units volts; + description + "The arithmetic mean value of the statistic over the + sampling period."; + } + + leaf min { + type decimal64 { + fraction-digits 2; + } + units volts; + description + "The minimum value of the statistic over the sampling + period"; + } + + leaf max { + type decimal64 { + fraction-digits 2; + } + units volts; + description + "The maximum value of the statistic over the sampling + period"; + } + + uses oc-types:stat-interval-state; + uses oc-types:min-max-time; + } + + grouping component-redundant-role-switchover-reason { + description + "Common grouping for recording the reason of a component's + redundant role switchover. For example two supervisors in + a device, one as primary the other as secondary, switchover + can happen in different scenarios, e.g. user requested, + system error, priority contention, etc."; + + leaf trigger { + type component-redundant-role-switchover-reason-trigger; + description + "Records the generic triggers, e.g. user or system + initiated the switchover."; + } + + leaf details { + type string; + description + "Records detailed description of why the switchover happens. + For example, when system initiated the switchover, this leaf + can be used to record the specific reason, e.g. due to critical + errors of the routing daemon in the primary role."; + } + } + + // identity statements + identity OPENCONFIG_HARDWARE_COMPONENT { + description + "Base identity for hardware related components in a managed + device. Derived identities are partially based on contents + of the IANA Entity MIB."; + reference + "IANA Entity MIB and RFC 6933"; + } + + identity OPENCONFIG_SOFTWARE_COMPONENT { + description + "Base identity for software-related components in a managed + device"; + } + + // hardware types + identity CHASSIS { + base OPENCONFIG_HARDWARE_COMPONENT; + description + "Chassis component, typically with multiple slots / shelves"; + } + + identity BACKPLANE { + base OPENCONFIG_HARDWARE_COMPONENT; + description + "Backplane component for aggregating traffic, typically + contained in a chassis component"; + } + + identity FABRIC { + base OPENCONFIG_HARDWARE_COMPONENT; + description + "Interconnect between ingress and egress ports on the + device (e.g., a crossbar switch)."; + } + + identity POWER_SUPPLY { + base OPENCONFIG_HARDWARE_COMPONENT; + description + "Component that is supplying power to the device"; + } + + identity FAN { + base OPENCONFIG_HARDWARE_COMPONENT; + description + "Cooling fan, or could be some other heat-reduction component"; + } + + identity SENSOR { + base OPENCONFIG_HARDWARE_COMPONENT; + description + "Physical sensor, e.g., a temperature sensor in a chassis"; + } + + identity FRU { + base OPENCONFIG_HARDWARE_COMPONENT; + description + "Replaceable hardware component that does not have a more + specific defined schema."; + } + + identity LINECARD { + base OPENCONFIG_HARDWARE_COMPONENT; + description + "Linecard component, typically inserted into a chassis slot"; + } + + identity CONTROLLER_CARD { + base OPENCONFIG_HARDWARE_COMPONENT; + description + "A type of linecard whose primary role is management or control + rather than data forwarding."; + } + + identity PORT { + base OPENCONFIG_HARDWARE_COMPONENT; + description + "Physical port, e.g., for attaching pluggables and networking + cables"; + } + + identity TRANSCEIVER { + base OPENCONFIG_HARDWARE_COMPONENT; + description + "Pluggable module present in a port"; + } + + identity CPU { + base OPENCONFIG_HARDWARE_COMPONENT; + description + "Processing unit, e.g., a management processor"; + } + + identity STORAGE { + base OPENCONFIG_HARDWARE_COMPONENT; + description + "A storage subsystem on the device (disk, SSD, etc.)"; + } + + identity INTEGRATED_CIRCUIT { + base OPENCONFIG_HARDWARE_COMPONENT; + description + "A special purpose processing unit, typically for traffic + switching/forwarding (e.g., switching ASIC, NPU, forwarding + chip, etc.)"; + } + + identity WIFI_ACCESS_POINT { + base OPENCONFIG_HARDWARE_COMPONENT; + description + "A device that attaches to a an Ethernet network and creates a wireless + local area network"; + } + + identity OPERATING_SYSTEM { + base OPENCONFIG_SOFTWARE_COMPONENT; + description + "Operating system running on a component"; + } + + identity OPERATING_SYSTEM_UPDATE { + base OPENCONFIG_SOFTWARE_COMPONENT; + description + "An operating system update - which should be a subcomponent + of the `OPERATING_SYSTEM` running on a component. An update is + defined to be a set of software changes that are atomically + installed (and uninstalled) together. Multiple updates may be + present for the Operating System. A system should not list all + installed software packages using this type -- but rather + updates that are bundled together as a single installable + item"; + } + + identity BIOS { + base OPENCONFIG_SOFTWARE_COMPONENT; + description + "Legacy BIOS or UEFI firmware interface responsible for + initializing hardware components and first stage boot loader."; + } + + identity BOOT_LOADER { + base OPENCONFIG_SOFTWARE_COMPONENT; + description + "Software layer responsible for loading and booting the + device OS or network OS."; + } + + identity SOFTWARE_MODULE { + base OPENCONFIG_SOFTWARE_COMPONENT; + description + "A base identity for software modules installed and/or + running on the device. Modules include user-space programs + and kernel modules that provide specific functionality. + A component with type SOFTWARE_MODULE should also have a + module type that indicates the specific type of software module"; + } + + identity COMPONENT_OPER_STATUS { + description + "Current operational status of a platform component"; + } + + identity ACTIVE { + base COMPONENT_OPER_STATUS; + description + "Component is enabled and active (i.e., up)"; + } + + identity INACTIVE { + base COMPONENT_OPER_STATUS; + description + "Component is enabled but inactive (i.e., down)"; + } + + identity DISABLED { + base COMPONENT_OPER_STATUS; + description + "Component is administratively disabled."; + } + + identity FEC_MODE_TYPE { + description + "Base identity for FEC operational modes."; + } + + identity FEC_ENABLED { + base FEC_MODE_TYPE; + description + "FEC is administratively enabled."; + } + + identity FEC_DISABLED { + base FEC_MODE_TYPE; + description + "FEC is administratively disabled."; + } + + identity FEC_AUTO { + base FEC_MODE_TYPE; + description + "System will determine whether to enable or disable + FEC on a transceiver."; + } + + identity FEC_STATUS_TYPE { + description + "Base identity for FEC operational statuses."; + } + + identity FEC_STATUS_LOCKED { + base FEC_STATUS_TYPE; + description + "FEC is operationally locked."; + } + + identity FEC_STATUS_UNLOCKED { + base FEC_STATUS_TYPE; + description + "FEC is operationally unlocked."; + } + + // typedef statements + typedef component-power-type { + type enumeration { + enum POWER_ENABLED { + description + "Enable power on the component"; + } + enum POWER_DISABLED { + description + "Disable power on the component"; + } + } + description + "A generic type reflecting whether a hardware component + is powered on or off"; + } + + identity COMPONENT_REBOOT_REASON { + description + "Base entity for component reboot reasons."; + } + + identity REBOOT_USER_INITIATED { + base COMPONENT_REBOOT_REASON; + description + "User initiated the reboot of the componenent."; + } + + identity REBOOT_POWER_FAILURE { + base COMPONENT_REBOOT_REASON; + description + "The component reboots due to power failure."; + } + + identity REBOOT_CRITICAL_ERROR { + base COMPONENT_REBOOT_REASON; + description + "The component reboots due to critical errors."; + } + + typedef component-redundant-role { + type enumeration { + enum PRIMARY { + description + "Component is acting the primary role."; + } + enum SECONDARY { + description + "Component is acting the secondary role."; + } + } + description + "A generic type reflecting the component's redundanty role. + For example, a device might have dual supervisors components + for redundant purpose, with one being the primary and the + other secondary."; + } + + typedef component-redundant-role-switchover-reason-trigger { + type enumeration { + enum USER_INITIATED { + description + "User initiated the switchover, e.g. via command line."; + } + enum SYSTEM_INITIATED { + description + "The system initiated the switchover, e.g. due to + critical errors in the component of the primar role."; + } + } + description + "Records how the role switchover is triggered."; + } +} diff --git a/ocdiff/testdata/yang/old/platform/openconfig-platform.yang b/ocdiff/testdata/yang/old/platform/openconfig-platform.yang new file mode 100644 index 0000000..9c82540 --- /dev/null +++ b/ocdiff/testdata/yang/old/platform/openconfig-platform.yang @@ -0,0 +1,1198 @@ +module openconfig-platform { + + yang-version "1"; + + // namespace + namespace "http://openconfig.net/yang/platform"; + + prefix "oc-platform"; + + import openconfig-platform-types { prefix oc-platform-types; } + import openconfig-extensions { prefix oc-ext; } + import openconfig-yang-types { prefix oc-yang; } + import openconfig-types { prefix oc-types; } + + include openconfig-platform-common; + + // meta + organization "OpenConfig working group"; + + contact + "OpenConfig working group + www.openconfig.net"; + + description + "This module defines a data model for representing a system + component inventory, which can include hardware or software + elements arranged in an arbitrary structure. The primary + relationship supported by the model is containment, e.g., + components containing subcomponents. + + It is expected that this model reflects every field replacable + unit on the device at a minimum (i.e., additional information + may be supplied about non-replacable components). + + Every element in the inventory is termed a 'component' with each + component expected to have a unique name and type, and optionally + a unique system-assigned identifier and FRU number. The + uniqueness is guaranteed by the system within the device. + + Components may have properties defined by the system that are + modeled as a list of key-value pairs. These may or may not be + user-configurable. The model provides a flag for the system + to optionally indicate which properties are user configurable. + + Each component also has a list of 'subcomponents' which are + references to other components. Appearance in a list of + subcomponents indicates a containment relationship as described + above. For example, a linecard component may have a list of + references to port components that reside on the linecard. + + This schema is generic to allow devices to express their own + platform-specific structure. It may be augmented by additional + component type-specific schemas that provide a common structure + for well-known component types. In these cases, the system is + expected to populate the common component schema, and may + optionally also represent the component and its properties in the + generic structure. + + The properties for each component may include dynamic values, + e.g., in the 'state' part of the schema. For example, a CPU + component may report its utilization, temperature, or other + physical properties. The intent is to capture all platform- + specific physical data in one location, including inventory + (presence or absence of a component) and state (physical + attributes or status)."; + + oc-ext:openconfig-version "0.23.0"; + + revision "2023-02-13" { + description + "Refactor resource utilization threshold config into a separate grouping. + Update 'utilization resource' to 'resource utilization'."; + reference "0.23.0"; + } + + revision "2022-12-20" { + description + "Add threshold and threshold-exceeded for resource usage."; + reference "0.22.0"; + } + + revision "2022-12-19" { + description + "Update last-high-watermark timestamp documentation."; + reference "0.21.1"; + } + + revision "2022-09-26" { + description + "Add state data for base-mac-address."; + reference "0.21.0"; + } + + revision "2022-08-31" { + description + "Add new state data for component CLEI code."; + reference "0.20.0"; + } + + revision "2022-07-28" { + description + "Add container for controller card component"; + reference "0.19.0"; + } + + revision "2022-07-11" { + description + "Add switchover ready"; + reference "0.18.0"; + } + + revision "2022-06-10" { + description + "Specify units and epoch for switchover and reboot times."; + reference "0.17.0"; + } + + revision "2022-04-21" { + description + "Add platform utilization."; + reference "0.16.0"; + } + + revision "2022-02-02" { + description + "Add new state data for component reboot and + switchover."; + reference "0.15.0"; + } + + revision "2021-08-13" { + description + "Add container for PCIe error statistics"; + reference "0.14.0"; + } + + revision "2021-01-18" { + description + "Add container for software module component"; + reference "0.13.0"; + } + + revision "2019-04-16" { + description + "Fix bug in parent path reference"; + reference "0.12.2"; + } + + revision "2018-11-21" { + description + "Add OpenConfig module metadata extensions."; + reference "0.12.1"; + } + + revision "2018-06-29" { + description + "Added location description for components"; + reference "0.12.0"; + } + + revision "2018-06-03" { + description + "Added parent reference, empty flag and preconfiguration + for components"; + reference "0.11.0"; + } + + revision "2018-04-20" { + description + "Added new per-component state data: mfg-date and removable"; + reference "0.10.0"; + } + + revision "2018-01-30" { + description + "Amended approach for modelling CPU - rather than having + a local CPU utilisation state variable, a component with + a CPU should create a subcomponent of type CPU to report + statistics."; + reference "0.9.0"; + } + + revision "2018-01-16" { + description + "Added new per-component common data; add temp alarm; + moved hardware-port reference to port model"; + reference "0.8.0"; + } + + revision "2017-12-14" { + description + "Added anchor containers for component data, added new + component types"; + reference "0.7.0"; + } + + revision "2017-08-16" { + description + "Added power state enumerated type"; + reference "0.6.0"; + } + + revision "2016-12-22" { + description + "Added temperature state variable to component"; + reference "0.5.0"; + } + + // OpenConfig specific extensions for module metadata. + oc-ext:regexp-posix; + oc-ext:catalog-organization "openconfig"; + oc-ext:origin "openconfig"; + + // grouping statements + + + grouping platform-component-properties-config { + description + "System-defined configuration data for component properties"; + + leaf name { + type string; + description + "System-supplied name of the property -- this is typically + non-configurable"; + } + + leaf value { + type union { + type string; + type boolean; + type int64; + type uint64; + type decimal64 { + fraction-digits 2; + } + } + description + "Property values can take on a variety of types. Signed and + unsigned integer types may be provided in smaller sizes, + e.g., int8, uint16, etc."; + } + } + + grouping platform-component-properties-state { + description + "Operational state data for component properties"; + + leaf configurable { + type boolean; + description + "Indication whether the property is user-configurable"; + } + } + + grouping platform-component-properties-top { + description + "Top-level grouping "; + + container properties { + description + "Enclosing container "; + + list property { + key "name"; + description + "List of system properties for the component"; + + leaf name { + type leafref { + path "../config/name"; + } + description + "Reference to the property name."; + } + + container config { + description + "Configuration data for each property"; + + uses platform-component-properties-config; + } + + container state { + + config false; + + description + "Operational state data for each property"; + + uses platform-component-properties-config; + uses platform-component-properties-state; + } + } + } + } + + grouping platform-subcomponent-ref-config { + description + "Configuration data for subcomponent references"; + + leaf name { + type leafref { + path "../../../../../component/config/name"; + } + description + "Reference to the name of the subcomponent"; + } + } + + grouping platform-subcomponent-ref-state { + description + "Operational state data for subcomponent references"; + + } + + grouping platform-subcomponent-ref-top { + description + "Top-level grouping for list of subcomponent references"; + + container subcomponents { + description + "Enclosing container for subcomponent references"; + + list subcomponent { + key "name"; + description + "List of subcomponent references"; + + leaf name { + type leafref { + path "../config/name"; + } + description + "Reference to the name list key"; + } + + container config { + description + "Configuration data for the subcomponent"; + + uses platform-subcomponent-ref-config; + } + + container state { + + config false; + + description + "Operational state data for the subcomponent"; + + uses platform-subcomponent-ref-config; + uses platform-subcomponent-ref-state; + } + } + } + } + + grouping platform-component-config { + description + "Configuration data for components"; + + leaf name { + type string; + description + "Device name for the component -- this may not be a + configurable parameter on many implementations. Where + component preconfiguration is supported, for example, + the component name may be configurable."; + } + } + + grouping platform-component-state { + description + "Operational state data for device components."; + + leaf type { + type union { + type identityref { + base oc-platform-types:OPENCONFIG_HARDWARE_COMPONENT; + } + type identityref { + base oc-platform-types:OPENCONFIG_SOFTWARE_COMPONENT; + } + } + description + "Type of component as identified by the system"; + } + + leaf id { + type string; + description + "Unique identifier assigned by the system for the + component"; + } + + leaf location { + type string; + description + "System-supplied description of the location of the + component within the system. This could be a bay position, + slot number, socket location, etc. For component types that + have an explicit slot-id attribute, such as linecards, the + system should populate the more specific slot-id."; + } + + leaf description { + type string; + description + "System-supplied description of the component"; + } + + leaf mfg-name { + type string; + description + "System-supplied identifier for the manufacturer of the + component. This data is particularly useful when a + component manufacturer is different than the overall + device vendor."; + } + + leaf mfg-date { + type oc-yang:date; + description + "System-supplied representation of the component's + manufacturing date."; + } + + leaf hardware-version { + type string; + description + "For hardware components, this is the hardware revision of + the component."; + } + + leaf firmware-version { + type string; + description + "For hardware components, this is the version of associated + firmware that is running on the component, if applicable."; + } + + leaf software-version { + type string; + description + "For software components such as operating system or other + software module, this is the version of the currently + running software."; + } + + leaf serial-no { + type string; + description + "System-assigned serial number of the component."; + } + + leaf part-no { + type string; + description + "System-assigned part number for the component. This should + be present in particular if the component is also an FRU + (field replaceable unit)"; + } + + leaf clei-code { + type string; + description + "Common Language Equipment Identifier (CLEI) code of the + component. This should be present in particular if the + component is also an FRU (field replaceable unit)"; + } + + leaf removable { + type boolean; + description + "If true, this component is removable or is a field + replaceable unit"; + } + + leaf oper-status { + type identityref { + base oc-platform-types:COMPONENT_OPER_STATUS; + } + description + "If applicable, this reports the current operational status + of the component."; + } + + leaf empty { + type boolean; + default false; + description + "The empty leaf may be used by the device to indicate that a + component position exists but is not populated. Using this + flag, it is possible for the management system to learn how + many positions are available (e.g., occupied vs. empty + linecard slots in a chassis)."; + } + + leaf parent { + type leafref { + path "../../../component/config/name"; + } + description + "Reference to the name of the parent component. Note that + this reference must be kept synchronized with the + corresponding subcomponent reference from the parent + component."; + } + + leaf redundant-role { + type oc-platform-types:component-redundant-role; + description + "For components that have redundant roles (e.g. two + supervisors in a device, one as primary the other as secondary), + this reports the role of the component."; + } + + container last-switchover-reason { + description + "For components that have redundant roles (e.g. two + supervisors in a device, one as primary the other as secondary), + this reports the reason of the last change of the + component's role."; + + uses oc-platform-types:component-redundant-role-switchover-reason; + } + + leaf last-switchover-time { + type oc-types:timeticks64; + units "nanoseconds"; + description + "For components that have redundant roles (e.g. two + supervisors in a device, one as primary the other as + secondary), this reports the time of the last change of + the component's role. The value is the timestamp in + nanoseconds relative to the Unix Epoch (Jan 1, 1970 00:00:00 UTC)."; + + } + + leaf last-reboot-reason { + type identityref { + base oc-platform-types:COMPONENT_REBOOT_REASON; + } + description + "This reports the reason of the last reboot of the component."; + } + + leaf last-reboot-time { + type oc-types:timeticks64; + units "nanoseconds"; + description + "This reports the time of the last reboot of the component. The + value is the timestamp in nanoseconds relative to the Unix Epoch + (Jan 1, 1970 00:00:00 UTC)."; + } + + leaf switchover-ready { + type boolean; + description + "For components that have redundant roles, this reports a value + that indicates if the component is ready to support failover. + + The components with a redundant-role should reflect the overall + system's switchover status. For example, two supervisors in a + device, one as primary and the other as secondary, should both + report the same value."; + } + + leaf base-mac-address { + type oc-yang:mac-address; + description + "This is a MAC address representing the root or primary MAC + address for a component. Components such as CHASSIS and + CONTROLLER_CARD are expected to provide a base-mac-address. The + base mac-address for CHASSIS and a PRIMARY CONTROLLER_CARD may + contain the same value."; + } + + } + + grouping platform-component-temp-alarm-state { + description + "Temperature alarm data for platform components"; + + // TODO(aashaikh): consider if these leaves could be in a + // reusable grouping (not temperature-specific); threshold + // may always need to be units specific. + + leaf alarm-status { + type boolean; + description + "A value of true indicates the alarm has been raised or + asserted. The value should be false when the alarm is + cleared."; + } + + leaf alarm-threshold { + type uint32; + description + "The threshold value that was crossed for this alarm."; + } + } + + grouping platform-component-power-state { + description + "Power-related operational state for device components."; + + leaf allocated-power { + type uint32; + units watts; + description + "Power allocated by the system for the component."; + } + + leaf used-power { + type uint32; + units watts; + description + "Actual power used by the component."; + } + } + + grouping platform-component-temp-state { + description + "Temperature state data for device components"; + + container temperature { + description + "Temperature in degrees Celsius of the component. Values include + the instantaneous, average, minimum, and maximum statistics. If + avg/min/max statistics are not supported, the target is expected + to just supply the instant value"; + + uses oc-platform-types:avg-min-max-instant-stats-precision1-celsius; + uses platform-component-temp-alarm-state; + } + } + + grouping platform-component-memory-state { + description + "Per-component memory statistics"; + + container memory { + description + "For components that have associated memory, these values + report information about available and utilized memory."; + + leaf available { + type uint64; + units bytes; + description + "The available memory physically installed, or logically + allocated to the component."; + } + + // TODO(aashaikh): consider if this needs to be a + // min/max/avg statistic + leaf utilized { + type uint64; + units bytes; + description + "The memory currently in use by processes running on + the component, not considering reserved memory that is + not available for use."; + } + } + } + + grouping pcie-uncorrectable-errors { + description + "PCIe uncorrectable error statistics."; + + leaf total-errors { + type oc-yang:counter64; + description + "Total number of uncorrectable errors detected by PCIe device + since the system booted, according to PCIe AER driver."; + } + + leaf undefined-errors { + type oc-yang:counter64; + description + "Number of undefined errors detected by PCIe device since the + system booted, according to PCIe AER driver."; + } + + leaf data-link-errors { + type oc-yang:counter64; + description + "Number of data-link errors detected by PCIe device since the + system booted, according to PCIe AER driver."; + } + + leaf surprise-down-errors { + type oc-yang:counter64; + description + "Number of unexpected link down errors detected by PCIe device + since the system booted, according to PCIe AER driver."; + } + + leaf poisoned-tlp-errors { + type oc-yang:counter64; + description + "Number of poisoned TLP errors detected by PCIe device since the + system booted, according to PCIe AER driver."; + } + + leaf flow-control-protocol-errors { + type oc-yang:counter64; + description + "Number of flow control protocol errors detected by PCIe device + since the system booted, according to PCIe AER driver."; + } + + leaf completion-timeout-errors { + type oc-yang:counter64; + description + "Number of completion timeout errors detected by PCIe device + since the system booted, according to PCIe AER driver."; + } + + leaf completion-abort-errors { + type oc-yang:counter64; + description + "Number of completion abort errors detected by PCIe device + since the system booted, according to PCIe AER driver."; + } + + leaf unexpected-completion-errors { + type oc-yang:counter64; + description + "Number of unexpected completion errors detected by PCIe device + since the system booted, according to PCIe AER driver."; + } + + leaf receiver-overflow-errors { + type oc-yang:counter64; + description + "Number of receiver overflow errors detected by PCIe device + since the system booted, according to PCIe AER driver."; + } + + leaf malformed-tlp-errors { + type oc-yang:counter64; + description + "Number of malformed TLP errors detected by PCIe device since the + system booted, according to PCIe AER driver."; + } + + leaf ecrc-errors { + type oc-yang:counter64; + description + "Number of ECRC errors detected by PCIe device since the system + booted, according to PCIe AER driver."; + } + + leaf unsupported-request-errors { + type oc-yang:counter64; + description + "Number of unsupported request errors detected by PCIe device + since the system booted, according to PCIe AER driver."; + } + + leaf acs-violation-errors { + type oc-yang:counter64; + description + "Number of access control errors detected by PCIe device since + the system booted, according to PCIe AER driver."; + } + + leaf internal-errors { + type oc-yang:counter64; + description + "Number of internal errors detected by PCIe device since the + system booted, according to PCIe AER driver."; + } + + leaf blocked-tlp-errors { + type oc-yang:counter64; + description + "Number of blocked TLP errors detected by PCIe device since + the system booted, according to PCIe AER driver."; + } + + leaf atomic-op-blocked-errors { + type oc-yang:counter64; + description + "Number of atomic operation blocked errors detected by PCIe + device since the system booted, according to PCIe AER driver."; + } + + leaf tlp-prefix-blocked-errors { + type oc-yang:counter64; + description + "Number of TLP prefix blocked errors detected by PCIe device + since the system booted, according to PCIe AER driver."; + } + } + + grouping pcie-correctable-errors { + description + "PCIe correctable error statistics."; + + leaf total-errors { + type oc-yang:counter64; + description + "Total number of correctable errors detected by PCIe device + since the system booted, according to PCIe AER driver."; + } + + leaf receiver-errors { + type oc-yang:counter64; + description + "Number of receiver errors detected by PCIe device since the + system booted, according to PCIe AER driver."; + } + + leaf bad-tlp-errors { + type oc-yang:counter64; + description + "Number of TLPs with bad LCRC detected by PCIe device since the + system booted, according to PCIe AER driver."; + } + + leaf bad-dllp-errors { + type oc-yang:counter64; + description + "Number of DLLPs with bad LCRC detected by PCIe device since the + system booted, according to PCIe AER driver."; + } + + leaf relay-rollover-errors { + type oc-yang:counter64; + description + "Number of relay rollover errors detected by PCIe device since the + system booted, according to PCIe AER driver."; + } + + leaf replay-timeout-errors { + type oc-yang:counter64; + description + "Number of replay timeout errors detected by PCIe device since the + system booted, according to PCIe AER driver."; + } + + leaf advisory-non-fatal-errors { + type oc-yang:counter64; + description + "Number of advisory non fatal errors detected by PCIe device since + the system booted, according to PCIe AER driver."; + } + + leaf internal-errors { + type oc-yang:counter64; + description + "Number of internal errors detected by PCIe device since the system + booted, according to PCIe AER driver."; + } + + leaf hdr-log-overflow-errors { + type oc-yang:counter64; + description + "Number of header log overflow errors detected by PCIe device since + the system booted, according to PCIe AER driver."; + } + } + + grouping platform-component-pcie-state { + description + "Per-component PCIe error statistics"; + + container pcie { + description + "Components that are connected to the system over the Peripheral + Component Interconnect Express (PCIe), report the fatal, non-fatal + and correctable PCIe error counts."; + + container fatal-errors { + description + "The count of the fatal PCIe errors."; + uses pcie-uncorrectable-errors; + } + + container non-fatal-errors { + description + "The count of the non-fatal PCIe errors."; + uses pcie-uncorrectable-errors; + } + + container correctable-errors { + description + "The count of the correctable PCIe errors."; + uses pcie-correctable-errors; + } + } + } + + grouping platform-anchors-top { + description + "This grouping is used to add containers for components that + are common across systems, but do not have a defined schema + within the openconfig-platform module. Containers should be + added to this grouping for components that are expected to + exist in multiple systems, with corresponding modules + augmenting the config/state containers directly."; + + container chassis { + description + "Data for chassis components"; + + container config { + description + "Configuration data for chassis components"; + } + + container state { + config false; + description + "Operational state data for chassis components"; + } + + uses platform-resource-utilization-top; + } + +// TODO(aashaikh): linecard container is already defined in +// openconfig-platform-linecard; will move to this module +// in future. + /* + container linecard { + description + "Data for linecard components"; + + container config { + description + "Configuration data for linecard components"; + } + + container state { + config false; + description + "Operational state data for linecard components"; + } + } + */ + + container port { + description + "Data for physical port components"; + + container config { + description + "Configuration data for physical port components"; + } + + container state { + config false; + description + "Operational state data for physical port components"; + } + } + +// TODO(aashaikh): transceiver container is already defined in +// openconfig-platform-transceiver; will move to this module +// in future. + /* + container transceiver { + description + "Data for transceiver components"; + + container config { + description + "Configuration data for transceiver components"; + } + + container state { + config false; + description + "Operational state data for transceiver components"; + } + } + */ + + container power-supply { + description + "Data for power supply components"; + + container config { + description + "Configuration data for power supply components"; + } + + container state { + config false; + description + "Operational state data for power supply components"; + } + } + + container fan { + description + "Data for fan components"; + + container config { + description + "Configuration data for fan components"; + } + + container state { + config false; + description + "Operational state data for fan components"; + } + } + + container fabric { + description + "Data for fabric components"; + + container config { + description + "Configuration data for fabric components"; + } + + container state { + config false; + description + "Operational state data for fabric components"; + } + } + + container storage { + description + "Data for storage components"; + + container config { + description + "Configuration data for storage components"; + } + + container state { + config false; + description + "Operational state data for storage components"; + } + } + + container cpu { + description + "Data for cpu components"; + + container config { + description + "Configuration data for cpu components"; + } + + container state { + config false; + description + "Operational state data for cpu components"; + } + } + + container integrated-circuit { + description + "Data for chip components, such as ASIC, NPUs, etc."; + + container config { + description + "Configuration data for chip components"; + } + + container state { + config false; + description + "Operational state data for chip components"; + } + + uses platform-resource-utilization-top; + } + + container backplane { + description + "Data for backplane components"; + + container config { + description + "Configuration data for backplane components"; + } + + container state { + config false; + description + "Operational state data for backplane components"; + } + } + + container software-module { + description + "Data for software module components, i.e., for components + with type=SOFTWARE_MODULE"; + + container config { + description + "Configuration data for software module components"; + } + + container state { + config false; + description + "Operational state data for software module components"; + } + } + + container controller-card { + description + "Data for controller card components, i.e., for components + with type=CONTROLLER_CARD"; + + container config { + description + "Configuration data for controller card components. Note that disabling + power to the primary supervisor should be rejected, and the operator is + required to perform a switchover first."; + } + + container state { + config false; + description + "Operational state data for controller card components"; + } + } + } + + grouping platform-component-top { + description + "Top-level grouping for components in the device inventory"; + + container components { + description + "Enclosing container for the components in the system."; + + list component { + key "name"; + description + "List of components, keyed by component name."; + + leaf name { + type leafref { + path "../config/name"; + } + description + "References the component name"; + } + + container config { + description + "Configuration data for each component"; + + uses platform-component-config; + } + + container state { + + config false; + + description + "Operational state data for each component"; + + uses platform-component-config; + uses platform-component-state; + uses platform-component-temp-state; + uses platform-component-memory-state; + uses platform-component-power-state; + uses platform-component-pcie-state { + when "./type = 'oc-platform-types:STORAGE' or " + + "'oc-platform-types:INTEGRATED_CIRCUIT' or " + + "'oc-platform-types:FRU'"; + } + } + + uses platform-component-properties-top; + uses platform-subcomponent-ref-top; + uses platform-anchors-top; + } + } + } + + + // data definition statements + + uses platform-component-top; + + + // augments + + +} From 2eb7f8aee009d1b7aa366d7757c6cac0468b94f7 Mon Sep 17 00:00:00 2001 From: wenovus Date: Thu, 3 Aug 2023 16:46:59 -0700 Subject: [PATCH 12/15] Fix CLI --- cmd/check.go | 19 ++++++--- openconfig-ci/README.md | 7 ++++ {ocdiff => openconfig-ci/ocdiff}/ocdiff.go | 4 +- .../ocdiff}/ocdiff_test.go | 20 +++------- .../ocdiff}/testdata/disallowed-incompats.txt | 0 .../github-comment-disallowed-incompats.txt | 0 .../ocdiff}/testdata/github-comment.txt | 0 .../ocdiff}/testdata/no-options.txt | 0 .../yang/incl/openconfig-extensions.yang | 0 .../testdata/yang/incl/types/.spec.yml | 0 .../incl/types/openconfig-inet-types.yang | 0 .../yang/incl/types/openconfig-types.yang | 0 .../incl/types/openconfig-yang-types.yang | 0 .../testdata/yang/new/platform/.spec.yml | 0 .../platform/openconfig-platform-common.yang | 0 .../openconfig-platform-controller-card.yang | 0 .../new/platform/openconfig-platform-cpu.yang | 0 .../new/platform/openconfig-platform-ext.yang | 0 .../platform/openconfig-platform-fabric.yang | 0 .../new/platform/openconfig-platform-fan.yang | 0 .../platform/openconfig-platform-healthz.yang | 0 ...penconfig-platform-integrated-circuit.yang | 0 .../openconfig-platform-linecard.yang | 0 ...openconfig-platform-pipeline-counters.yang | 0 .../platform/openconfig-platform-port.yang | 0 .../new/platform/openconfig-platform-psu.yang | 0 .../openconfig-platform-software.yang | 0 .../platform/openconfig-platform-types.yang | 0 .../new/platform/openconfig-platform.yang | 0 .../testdata/yang/old/platform/.spec.yml | 0 .../platform/openconfig-platform-common.yang | 0 .../openconfig-platform-controller-card.yang | 0 .../old/platform/openconfig-platform-cpu.yang | 0 .../old/platform/openconfig-platform-ext.yang | 0 .../platform/openconfig-platform-fabric.yang | 0 .../old/platform/openconfig-platform-fan.yang | 0 .../platform/openconfig-platform-healthz.yang | 0 ...penconfig-platform-integrated-circuit.yang | 0 .../openconfig-platform-linecard.yang | 0 ...openconfig-platform-pipeline-counters.yang | 0 .../platform/openconfig-platform-port.yang | 0 .../old/platform/openconfig-platform-psu.yang | 0 .../openconfig-platform-software.yang | 0 .../platform/openconfig-platform-types.yang | 0 .../old/platform/openconfig-platform.yang | 0 yangutil/yangutil.go | 39 +++++++++++++++++++ 46 files changed, 67 insertions(+), 22 deletions(-) create mode 100644 openconfig-ci/README.md rename {ocdiff => openconfig-ci/ocdiff}/ocdiff.go (98%) rename {ocdiff => openconfig-ci/ocdiff}/ocdiff_test.go (83%) rename {ocdiff => openconfig-ci/ocdiff}/testdata/disallowed-incompats.txt (100%) rename {ocdiff => openconfig-ci/ocdiff}/testdata/github-comment-disallowed-incompats.txt (100%) rename {ocdiff => openconfig-ci/ocdiff}/testdata/github-comment.txt (100%) rename {ocdiff => openconfig-ci/ocdiff}/testdata/no-options.txt (100%) rename {ocdiff => openconfig-ci/ocdiff}/testdata/yang/incl/openconfig-extensions.yang (100%) rename {ocdiff => openconfig-ci/ocdiff}/testdata/yang/incl/types/.spec.yml (100%) rename {ocdiff => openconfig-ci/ocdiff}/testdata/yang/incl/types/openconfig-inet-types.yang (100%) rename {ocdiff => openconfig-ci/ocdiff}/testdata/yang/incl/types/openconfig-types.yang (100%) rename {ocdiff => openconfig-ci/ocdiff}/testdata/yang/incl/types/openconfig-yang-types.yang (100%) rename {ocdiff => openconfig-ci/ocdiff}/testdata/yang/new/platform/.spec.yml (100%) rename {ocdiff => openconfig-ci/ocdiff}/testdata/yang/new/platform/openconfig-platform-common.yang (100%) rename {ocdiff => openconfig-ci/ocdiff}/testdata/yang/new/platform/openconfig-platform-controller-card.yang (100%) rename {ocdiff => openconfig-ci/ocdiff}/testdata/yang/new/platform/openconfig-platform-cpu.yang (100%) rename {ocdiff => openconfig-ci/ocdiff}/testdata/yang/new/platform/openconfig-platform-ext.yang (100%) rename {ocdiff => openconfig-ci/ocdiff}/testdata/yang/new/platform/openconfig-platform-fabric.yang (100%) rename {ocdiff => openconfig-ci/ocdiff}/testdata/yang/new/platform/openconfig-platform-fan.yang (100%) rename {ocdiff => openconfig-ci/ocdiff}/testdata/yang/new/platform/openconfig-platform-healthz.yang (100%) rename {ocdiff => openconfig-ci/ocdiff}/testdata/yang/new/platform/openconfig-platform-integrated-circuit.yang (100%) rename {ocdiff => openconfig-ci/ocdiff}/testdata/yang/new/platform/openconfig-platform-linecard.yang (100%) rename {ocdiff => openconfig-ci/ocdiff}/testdata/yang/new/platform/openconfig-platform-pipeline-counters.yang (100%) rename {ocdiff => openconfig-ci/ocdiff}/testdata/yang/new/platform/openconfig-platform-port.yang (100%) rename {ocdiff => openconfig-ci/ocdiff}/testdata/yang/new/platform/openconfig-platform-psu.yang (100%) rename {ocdiff => openconfig-ci/ocdiff}/testdata/yang/new/platform/openconfig-platform-software.yang (100%) rename {ocdiff => openconfig-ci/ocdiff}/testdata/yang/new/platform/openconfig-platform-types.yang (100%) rename {ocdiff => openconfig-ci/ocdiff}/testdata/yang/new/platform/openconfig-platform.yang (100%) rename {ocdiff => openconfig-ci/ocdiff}/testdata/yang/old/platform/.spec.yml (100%) rename {ocdiff => openconfig-ci/ocdiff}/testdata/yang/old/platform/openconfig-platform-common.yang (100%) rename {ocdiff => openconfig-ci/ocdiff}/testdata/yang/old/platform/openconfig-platform-controller-card.yang (100%) rename {ocdiff => openconfig-ci/ocdiff}/testdata/yang/old/platform/openconfig-platform-cpu.yang (100%) rename {ocdiff => openconfig-ci/ocdiff}/testdata/yang/old/platform/openconfig-platform-ext.yang (100%) rename {ocdiff => openconfig-ci/ocdiff}/testdata/yang/old/platform/openconfig-platform-fabric.yang (100%) rename {ocdiff => openconfig-ci/ocdiff}/testdata/yang/old/platform/openconfig-platform-fan.yang (100%) rename {ocdiff => openconfig-ci/ocdiff}/testdata/yang/old/platform/openconfig-platform-healthz.yang (100%) rename {ocdiff => openconfig-ci/ocdiff}/testdata/yang/old/platform/openconfig-platform-integrated-circuit.yang (100%) rename {ocdiff => openconfig-ci/ocdiff}/testdata/yang/old/platform/openconfig-platform-linecard.yang (100%) rename {ocdiff => openconfig-ci/ocdiff}/testdata/yang/old/platform/openconfig-platform-pipeline-counters.yang (100%) rename {ocdiff => openconfig-ci/ocdiff}/testdata/yang/old/platform/openconfig-platform-port.yang (100%) rename {ocdiff => openconfig-ci/ocdiff}/testdata/yang/old/platform/openconfig-platform-psu.yang (100%) rename {ocdiff => openconfig-ci/ocdiff}/testdata/yang/old/platform/openconfig-platform-software.yang (100%) rename {ocdiff => openconfig-ci/ocdiff}/testdata/yang/old/platform/openconfig-platform-types.yang (100%) rename {ocdiff => openconfig-ci/ocdiff}/testdata/yang/old/platform/openconfig-platform.yang (100%) create mode 100644 yangutil/yangutil.go diff --git a/cmd/check.go b/cmd/check.go index f971129..ca99487 100644 --- a/cmd/check.go +++ b/cmd/check.go @@ -18,7 +18,8 @@ import ( "fmt" "os" - "github.com/openconfig/models-ci/ocdiff" + "github.com/openconfig/models-ci/openconfig-ci/ocdiff" + "github.com/openconfig/models-ci/yangutil" "github.com/spf13/cobra" "github.com/spf13/viper" ) @@ -36,7 +37,15 @@ This application is a tool to generate the needed files to quickly create a Cobra application.`, RunE: func(cmd *cobra.Command, args []string) error { viper.BindPFlags(cmd.Flags()) - report, err := ocdiff.NewDiffReport(viper.GetStringSlice("oldp"), viper.GetStringSlice("newp"), viper.GetStringSlice("oldfiles"), viper.GetStringSlice("newfiles")) + oldfiles, err := yangutil.GetAllYANGFiles(viper.GetString("oldroot")) + if err != nil { + return fmt.Errorf("error while finding YANG files from the old root: %v", err) + } + newfiles, err := yangutil.GetAllYANGFiles(viper.GetString("newroot")) + if err != nil { + return fmt.Errorf("error while finding YANG files from the new root: %v", err) + } + report, err := ocdiff.NewDiffReport(viper.GetStringSlice("oldp"), viper.GetStringSlice("newp"), oldfiles, newfiles) if err != nil { return err } @@ -64,8 +73,8 @@ func init() { checkCmd.Flags().StringSlice("oldp", []string{}, "search path for old set of YANG files") checkCmd.Flags().StringSlice("newp", []string{}, "search path for new set of YANG files") - checkCmd.Flags().StringSlice("oldfiles", []string{}, "comma-separated list of old YANG files") - checkCmd.Flags().StringSlice("newfiles", []string{}, "comma-separated list of new YANG files") - checkCmd.Flags().Bool("disallowed-incompats", false, "only show disallowed (per semver.org) backwards-incompatible changes. Note that the backwards-incompatible checks are not exhausive.") + checkCmd.Flags().StringP("oldroot", "o", "", "Root directory of old OpenConfig YANG files") + checkCmd.Flags().StringP("newroot", "n", "", "Root directory of new OpenConfig YANG files") + checkCmd.Flags().Bool("disallowed-incompats", false, "only show disallowed (per semver.org) backward-incompatible changes. Note that the backward-incompatible checks are not exhausive.") checkCmd.Flags().Bool("github-comment", false, "Show output suitable for posting in a GitHub comment.") } diff --git a/openconfig-ci/README.md b/openconfig-ci/README.md new file mode 100644 index 0000000..5bb801a --- /dev/null +++ b/openconfig-ci/README.md @@ -0,0 +1,7 @@ +``` +go install github.com/openconfig/models-ci/openconfig-ci@latest + +git clone github.com/openconfig/models-ci +cd $GOPATH/src/github.com/openconfig/models-ci/openconfig-ci +openconfig-ci diff --oldp ocdiff/testdata/yang/incl --newp ocdiff/testdata/yang/incl --oldroot ocdiff/testdata/yang/old --newroot ocdiff/testdata/yang/new +``` diff --git a/ocdiff/ocdiff.go b/openconfig-ci/ocdiff/ocdiff.go similarity index 98% rename from ocdiff/ocdiff.go rename to openconfig-ci/ocdiff/ocdiff.go index b3d14a9..9bb61ab 100644 --- a/ocdiff/ocdiff.go +++ b/openconfig-ci/ocdiff/ocdiff.go @@ -12,8 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// ocdiff checks for backwards-compatibility between two sets of YANG -// files. +// ocdiff produces a report between two sets of OpenConfig YANG files. package ocdiff import ( @@ -104,6 +103,7 @@ type reportOptions struct { githubComment bool } +// Report outputs a report on the diff between the two sets of OpenConfig YANG files. func (r *DiffReport) Report(options ...Option) string { opts := resolveOpts(options) r.Sort() diff --git a/ocdiff/ocdiff_test.go b/openconfig-ci/ocdiff/ocdiff_test.go similarity index 83% rename from ocdiff/ocdiff_test.go rename to openconfig-ci/ocdiff/ocdiff_test.go index e3eb311..a7590ea 100644 --- a/ocdiff/ocdiff_test.go +++ b/openconfig-ci/ocdiff/ocdiff_test.go @@ -17,28 +17,18 @@ package ocdiff import ( "flag" "os" - "path/filepath" "testing" + "github.com/openconfig/models-ci/yangutil" "github.com/openconfig/ygot/testutil" ) var updateGolden = flag.Bool("update_golden", false, "Update golden files") -func getAllYANGFiles(t *testing.T, path string) []string { +func getAllYANGFilesTest(t *testing.T, path string) []string { t.Helper() - var files []string - if err := filepath.Walk(path, - func(path string, info os.FileInfo, err error) error { - if err != nil { - return err - } - if filepath.Ext(info.Name()) == ".yang" { - files = append(files, path) - } - return nil - }, - ); err != nil { + files, err := yangutil.GetAllYANGFiles(path) + if err != nil { t.Fatal(err) } return files @@ -75,7 +65,7 @@ func TestDiffReport(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - report, err := NewDiffReport([]string{"testdata/yang/incl"}, []string{"testdata/yang/incl"}, getAllYANGFiles(t, "testdata/yang/old"), getAllYANGFiles(t, "testdata/yang/new")) + report, err := NewDiffReport([]string{"testdata/yang/incl"}, []string{"testdata/yang/incl"}, getAllYANGFilesTest(t, "testdata/yang/old"), getAllYANGFilesTest(t, "testdata/yang/new")) if err != nil { t.Fatal(err) } diff --git a/ocdiff/testdata/disallowed-incompats.txt b/openconfig-ci/ocdiff/testdata/disallowed-incompats.txt similarity index 100% rename from ocdiff/testdata/disallowed-incompats.txt rename to openconfig-ci/ocdiff/testdata/disallowed-incompats.txt diff --git a/ocdiff/testdata/github-comment-disallowed-incompats.txt b/openconfig-ci/ocdiff/testdata/github-comment-disallowed-incompats.txt similarity index 100% rename from ocdiff/testdata/github-comment-disallowed-incompats.txt rename to openconfig-ci/ocdiff/testdata/github-comment-disallowed-incompats.txt diff --git a/ocdiff/testdata/github-comment.txt b/openconfig-ci/ocdiff/testdata/github-comment.txt similarity index 100% rename from ocdiff/testdata/github-comment.txt rename to openconfig-ci/ocdiff/testdata/github-comment.txt diff --git a/ocdiff/testdata/no-options.txt b/openconfig-ci/ocdiff/testdata/no-options.txt similarity index 100% rename from ocdiff/testdata/no-options.txt rename to openconfig-ci/ocdiff/testdata/no-options.txt diff --git a/ocdiff/testdata/yang/incl/openconfig-extensions.yang b/openconfig-ci/ocdiff/testdata/yang/incl/openconfig-extensions.yang similarity index 100% rename from ocdiff/testdata/yang/incl/openconfig-extensions.yang rename to openconfig-ci/ocdiff/testdata/yang/incl/openconfig-extensions.yang diff --git a/ocdiff/testdata/yang/incl/types/.spec.yml b/openconfig-ci/ocdiff/testdata/yang/incl/types/.spec.yml similarity index 100% rename from ocdiff/testdata/yang/incl/types/.spec.yml rename to openconfig-ci/ocdiff/testdata/yang/incl/types/.spec.yml diff --git a/ocdiff/testdata/yang/incl/types/openconfig-inet-types.yang b/openconfig-ci/ocdiff/testdata/yang/incl/types/openconfig-inet-types.yang similarity index 100% rename from ocdiff/testdata/yang/incl/types/openconfig-inet-types.yang rename to openconfig-ci/ocdiff/testdata/yang/incl/types/openconfig-inet-types.yang diff --git a/ocdiff/testdata/yang/incl/types/openconfig-types.yang b/openconfig-ci/ocdiff/testdata/yang/incl/types/openconfig-types.yang similarity index 100% rename from ocdiff/testdata/yang/incl/types/openconfig-types.yang rename to openconfig-ci/ocdiff/testdata/yang/incl/types/openconfig-types.yang diff --git a/ocdiff/testdata/yang/incl/types/openconfig-yang-types.yang b/openconfig-ci/ocdiff/testdata/yang/incl/types/openconfig-yang-types.yang similarity index 100% rename from ocdiff/testdata/yang/incl/types/openconfig-yang-types.yang rename to openconfig-ci/ocdiff/testdata/yang/incl/types/openconfig-yang-types.yang diff --git a/ocdiff/testdata/yang/new/platform/.spec.yml b/openconfig-ci/ocdiff/testdata/yang/new/platform/.spec.yml similarity index 100% rename from ocdiff/testdata/yang/new/platform/.spec.yml rename to openconfig-ci/ocdiff/testdata/yang/new/platform/.spec.yml diff --git a/ocdiff/testdata/yang/new/platform/openconfig-platform-common.yang b/openconfig-ci/ocdiff/testdata/yang/new/platform/openconfig-platform-common.yang similarity index 100% rename from ocdiff/testdata/yang/new/platform/openconfig-platform-common.yang rename to openconfig-ci/ocdiff/testdata/yang/new/platform/openconfig-platform-common.yang diff --git a/ocdiff/testdata/yang/new/platform/openconfig-platform-controller-card.yang b/openconfig-ci/ocdiff/testdata/yang/new/platform/openconfig-platform-controller-card.yang similarity index 100% rename from ocdiff/testdata/yang/new/platform/openconfig-platform-controller-card.yang rename to openconfig-ci/ocdiff/testdata/yang/new/platform/openconfig-platform-controller-card.yang diff --git a/ocdiff/testdata/yang/new/platform/openconfig-platform-cpu.yang b/openconfig-ci/ocdiff/testdata/yang/new/platform/openconfig-platform-cpu.yang similarity index 100% rename from ocdiff/testdata/yang/new/platform/openconfig-platform-cpu.yang rename to openconfig-ci/ocdiff/testdata/yang/new/platform/openconfig-platform-cpu.yang diff --git a/ocdiff/testdata/yang/new/platform/openconfig-platform-ext.yang b/openconfig-ci/ocdiff/testdata/yang/new/platform/openconfig-platform-ext.yang similarity index 100% rename from ocdiff/testdata/yang/new/platform/openconfig-platform-ext.yang rename to openconfig-ci/ocdiff/testdata/yang/new/platform/openconfig-platform-ext.yang diff --git a/ocdiff/testdata/yang/new/platform/openconfig-platform-fabric.yang b/openconfig-ci/ocdiff/testdata/yang/new/platform/openconfig-platform-fabric.yang similarity index 100% rename from ocdiff/testdata/yang/new/platform/openconfig-platform-fabric.yang rename to openconfig-ci/ocdiff/testdata/yang/new/platform/openconfig-platform-fabric.yang diff --git a/ocdiff/testdata/yang/new/platform/openconfig-platform-fan.yang b/openconfig-ci/ocdiff/testdata/yang/new/platform/openconfig-platform-fan.yang similarity index 100% rename from ocdiff/testdata/yang/new/platform/openconfig-platform-fan.yang rename to openconfig-ci/ocdiff/testdata/yang/new/platform/openconfig-platform-fan.yang diff --git a/ocdiff/testdata/yang/new/platform/openconfig-platform-healthz.yang b/openconfig-ci/ocdiff/testdata/yang/new/platform/openconfig-platform-healthz.yang similarity index 100% rename from ocdiff/testdata/yang/new/platform/openconfig-platform-healthz.yang rename to openconfig-ci/ocdiff/testdata/yang/new/platform/openconfig-platform-healthz.yang diff --git a/ocdiff/testdata/yang/new/platform/openconfig-platform-integrated-circuit.yang b/openconfig-ci/ocdiff/testdata/yang/new/platform/openconfig-platform-integrated-circuit.yang similarity index 100% rename from ocdiff/testdata/yang/new/platform/openconfig-platform-integrated-circuit.yang rename to openconfig-ci/ocdiff/testdata/yang/new/platform/openconfig-platform-integrated-circuit.yang diff --git a/ocdiff/testdata/yang/new/platform/openconfig-platform-linecard.yang b/openconfig-ci/ocdiff/testdata/yang/new/platform/openconfig-platform-linecard.yang similarity index 100% rename from ocdiff/testdata/yang/new/platform/openconfig-platform-linecard.yang rename to openconfig-ci/ocdiff/testdata/yang/new/platform/openconfig-platform-linecard.yang diff --git a/ocdiff/testdata/yang/new/platform/openconfig-platform-pipeline-counters.yang b/openconfig-ci/ocdiff/testdata/yang/new/platform/openconfig-platform-pipeline-counters.yang similarity index 100% rename from ocdiff/testdata/yang/new/platform/openconfig-platform-pipeline-counters.yang rename to openconfig-ci/ocdiff/testdata/yang/new/platform/openconfig-platform-pipeline-counters.yang diff --git a/ocdiff/testdata/yang/new/platform/openconfig-platform-port.yang b/openconfig-ci/ocdiff/testdata/yang/new/platform/openconfig-platform-port.yang similarity index 100% rename from ocdiff/testdata/yang/new/platform/openconfig-platform-port.yang rename to openconfig-ci/ocdiff/testdata/yang/new/platform/openconfig-platform-port.yang diff --git a/ocdiff/testdata/yang/new/platform/openconfig-platform-psu.yang b/openconfig-ci/ocdiff/testdata/yang/new/platform/openconfig-platform-psu.yang similarity index 100% rename from ocdiff/testdata/yang/new/platform/openconfig-platform-psu.yang rename to openconfig-ci/ocdiff/testdata/yang/new/platform/openconfig-platform-psu.yang diff --git a/ocdiff/testdata/yang/new/platform/openconfig-platform-software.yang b/openconfig-ci/ocdiff/testdata/yang/new/platform/openconfig-platform-software.yang similarity index 100% rename from ocdiff/testdata/yang/new/platform/openconfig-platform-software.yang rename to openconfig-ci/ocdiff/testdata/yang/new/platform/openconfig-platform-software.yang diff --git a/ocdiff/testdata/yang/new/platform/openconfig-platform-types.yang b/openconfig-ci/ocdiff/testdata/yang/new/platform/openconfig-platform-types.yang similarity index 100% rename from ocdiff/testdata/yang/new/platform/openconfig-platform-types.yang rename to openconfig-ci/ocdiff/testdata/yang/new/platform/openconfig-platform-types.yang diff --git a/ocdiff/testdata/yang/new/platform/openconfig-platform.yang b/openconfig-ci/ocdiff/testdata/yang/new/platform/openconfig-platform.yang similarity index 100% rename from ocdiff/testdata/yang/new/platform/openconfig-platform.yang rename to openconfig-ci/ocdiff/testdata/yang/new/platform/openconfig-platform.yang diff --git a/ocdiff/testdata/yang/old/platform/.spec.yml b/openconfig-ci/ocdiff/testdata/yang/old/platform/.spec.yml similarity index 100% rename from ocdiff/testdata/yang/old/platform/.spec.yml rename to openconfig-ci/ocdiff/testdata/yang/old/platform/.spec.yml diff --git a/ocdiff/testdata/yang/old/platform/openconfig-platform-common.yang b/openconfig-ci/ocdiff/testdata/yang/old/platform/openconfig-platform-common.yang similarity index 100% rename from ocdiff/testdata/yang/old/platform/openconfig-platform-common.yang rename to openconfig-ci/ocdiff/testdata/yang/old/platform/openconfig-platform-common.yang diff --git a/ocdiff/testdata/yang/old/platform/openconfig-platform-controller-card.yang b/openconfig-ci/ocdiff/testdata/yang/old/platform/openconfig-platform-controller-card.yang similarity index 100% rename from ocdiff/testdata/yang/old/platform/openconfig-platform-controller-card.yang rename to openconfig-ci/ocdiff/testdata/yang/old/platform/openconfig-platform-controller-card.yang diff --git a/ocdiff/testdata/yang/old/platform/openconfig-platform-cpu.yang b/openconfig-ci/ocdiff/testdata/yang/old/platform/openconfig-platform-cpu.yang similarity index 100% rename from ocdiff/testdata/yang/old/platform/openconfig-platform-cpu.yang rename to openconfig-ci/ocdiff/testdata/yang/old/platform/openconfig-platform-cpu.yang diff --git a/ocdiff/testdata/yang/old/platform/openconfig-platform-ext.yang b/openconfig-ci/ocdiff/testdata/yang/old/platform/openconfig-platform-ext.yang similarity index 100% rename from ocdiff/testdata/yang/old/platform/openconfig-platform-ext.yang rename to openconfig-ci/ocdiff/testdata/yang/old/platform/openconfig-platform-ext.yang diff --git a/ocdiff/testdata/yang/old/platform/openconfig-platform-fabric.yang b/openconfig-ci/ocdiff/testdata/yang/old/platform/openconfig-platform-fabric.yang similarity index 100% rename from ocdiff/testdata/yang/old/platform/openconfig-platform-fabric.yang rename to openconfig-ci/ocdiff/testdata/yang/old/platform/openconfig-platform-fabric.yang diff --git a/ocdiff/testdata/yang/old/platform/openconfig-platform-fan.yang b/openconfig-ci/ocdiff/testdata/yang/old/platform/openconfig-platform-fan.yang similarity index 100% rename from ocdiff/testdata/yang/old/platform/openconfig-platform-fan.yang rename to openconfig-ci/ocdiff/testdata/yang/old/platform/openconfig-platform-fan.yang diff --git a/ocdiff/testdata/yang/old/platform/openconfig-platform-healthz.yang b/openconfig-ci/ocdiff/testdata/yang/old/platform/openconfig-platform-healthz.yang similarity index 100% rename from ocdiff/testdata/yang/old/platform/openconfig-platform-healthz.yang rename to openconfig-ci/ocdiff/testdata/yang/old/platform/openconfig-platform-healthz.yang diff --git a/ocdiff/testdata/yang/old/platform/openconfig-platform-integrated-circuit.yang b/openconfig-ci/ocdiff/testdata/yang/old/platform/openconfig-platform-integrated-circuit.yang similarity index 100% rename from ocdiff/testdata/yang/old/platform/openconfig-platform-integrated-circuit.yang rename to openconfig-ci/ocdiff/testdata/yang/old/platform/openconfig-platform-integrated-circuit.yang diff --git a/ocdiff/testdata/yang/old/platform/openconfig-platform-linecard.yang b/openconfig-ci/ocdiff/testdata/yang/old/platform/openconfig-platform-linecard.yang similarity index 100% rename from ocdiff/testdata/yang/old/platform/openconfig-platform-linecard.yang rename to openconfig-ci/ocdiff/testdata/yang/old/platform/openconfig-platform-linecard.yang diff --git a/ocdiff/testdata/yang/old/platform/openconfig-platform-pipeline-counters.yang b/openconfig-ci/ocdiff/testdata/yang/old/platform/openconfig-platform-pipeline-counters.yang similarity index 100% rename from ocdiff/testdata/yang/old/platform/openconfig-platform-pipeline-counters.yang rename to openconfig-ci/ocdiff/testdata/yang/old/platform/openconfig-platform-pipeline-counters.yang diff --git a/ocdiff/testdata/yang/old/platform/openconfig-platform-port.yang b/openconfig-ci/ocdiff/testdata/yang/old/platform/openconfig-platform-port.yang similarity index 100% rename from ocdiff/testdata/yang/old/platform/openconfig-platform-port.yang rename to openconfig-ci/ocdiff/testdata/yang/old/platform/openconfig-platform-port.yang diff --git a/ocdiff/testdata/yang/old/platform/openconfig-platform-psu.yang b/openconfig-ci/ocdiff/testdata/yang/old/platform/openconfig-platform-psu.yang similarity index 100% rename from ocdiff/testdata/yang/old/platform/openconfig-platform-psu.yang rename to openconfig-ci/ocdiff/testdata/yang/old/platform/openconfig-platform-psu.yang diff --git a/ocdiff/testdata/yang/old/platform/openconfig-platform-software.yang b/openconfig-ci/ocdiff/testdata/yang/old/platform/openconfig-platform-software.yang similarity index 100% rename from ocdiff/testdata/yang/old/platform/openconfig-platform-software.yang rename to openconfig-ci/ocdiff/testdata/yang/old/platform/openconfig-platform-software.yang diff --git a/ocdiff/testdata/yang/old/platform/openconfig-platform-types.yang b/openconfig-ci/ocdiff/testdata/yang/old/platform/openconfig-platform-types.yang similarity index 100% rename from ocdiff/testdata/yang/old/platform/openconfig-platform-types.yang rename to openconfig-ci/ocdiff/testdata/yang/old/platform/openconfig-platform-types.yang diff --git a/ocdiff/testdata/yang/old/platform/openconfig-platform.yang b/openconfig-ci/ocdiff/testdata/yang/old/platform/openconfig-platform.yang similarity index 100% rename from ocdiff/testdata/yang/old/platform/openconfig-platform.yang rename to openconfig-ci/ocdiff/testdata/yang/old/platform/openconfig-platform.yang diff --git a/yangutil/yangutil.go b/yangutil/yangutil.go new file mode 100644 index 0000000..7deb81b --- /dev/null +++ b/yangutil/yangutil.go @@ -0,0 +1,39 @@ +// Copyright 2023 Google Inc. +// +// 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. + +// yangutil contains utilities related to YANG. +package yangutil + +import ( + "os" + "path/filepath" +) + +func GetAllYANGFiles(path string) ([]string, error) { + var files []string + if err := filepath.Walk(path, + func(path string, info os.FileInfo, err error) error { + if err != nil { + return err + } + if filepath.Ext(info.Name()) == ".yang" { + files = append(files, path) + } + return nil + }, + ); err != nil { + return nil, err + } + return files, nil +} From 88da8da36026ef5a9c433d4d83b489b509472e04 Mon Sep 17 00:00:00 2001 From: wenovus Date: Thu, 3 Aug 2023 16:48:13 -0700 Subject: [PATCH 13/15] bash comment --- openconfig-ci/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openconfig-ci/README.md b/openconfig-ci/README.md index 5bb801a..5d3cc19 100644 --- a/openconfig-ci/README.md +++ b/openconfig-ci/README.md @@ -1,4 +1,4 @@ -``` +```bash go install github.com/openconfig/models-ci/openconfig-ci@latest git clone github.com/openconfig/models-ci From 5ef41fc9a1991c16f2864e6f2e1c63dad720dfe7 Mon Sep 17 00:00:00 2001 From: wenovus Date: Thu, 3 Aug 2023 17:06:23 -0700 Subject: [PATCH 14/15] Fix up comments and descs --- cmd/check.go | 30 ++++++++++++++---------------- cmd/root.go | 28 +++++++++++++++++----------- 2 files changed, 31 insertions(+), 27 deletions(-) diff --git a/cmd/check.go b/cmd/check.go index ca99487..a355b87 100644 --- a/cmd/check.go +++ b/cmd/check.go @@ -24,17 +24,15 @@ import ( "github.com/spf13/viper" ) -// checkCmd represents the check command -// FIXME(wenbli): Update comments. -var checkCmd = &cobra.Command{ +// diffCmd represents the diff command, which diffs two sets of OpenConfig YANG +// files. +var diffCmd = &cobra.Command{ Use: "diff", - Short: "A brief description of your command", - Long: `A longer description that spans multiple lines and likely contains examples -and usage of using your command. For example: + Short: "Diff between two sets of OpenConfig YANG files", + Long: `Use this command to find what's different between two commits of openconfig/public: -Cobra is a CLI library for Go that empowers applications. -This application is a tool to generate the needed files -to quickly create a Cobra application.`, +openconfig-ci diff --oldp public_old/third_party --newp public_new/third_party --oldroot public_old/release --newroot public_new/release +`, RunE: func(cmd *cobra.Command, args []string) error { viper.BindPFlags(cmd.Flags()) oldfiles, err := yangutil.GetAllYANGFiles(viper.GetString("oldroot")) @@ -69,12 +67,12 @@ to quickly create a Cobra application.`, } func init() { - rootCmd.AddCommand(checkCmd) + rootCmd.AddCommand(diffCmd) - checkCmd.Flags().StringSlice("oldp", []string{}, "search path for old set of YANG files") - checkCmd.Flags().StringSlice("newp", []string{}, "search path for new set of YANG files") - checkCmd.Flags().StringP("oldroot", "o", "", "Root directory of old OpenConfig YANG files") - checkCmd.Flags().StringP("newroot", "n", "", "Root directory of new OpenConfig YANG files") - checkCmd.Flags().Bool("disallowed-incompats", false, "only show disallowed (per semver.org) backward-incompatible changes. Note that the backward-incompatible checks are not exhausive.") - checkCmd.Flags().Bool("github-comment", false, "Show output suitable for posting in a GitHub comment.") + diffCmd.Flags().StringSlice("oldp", []string{}, "search path for old set of YANG files") + diffCmd.Flags().StringSlice("newp", []string{}, "search path for new set of YANG files") + diffCmd.Flags().StringP("oldroot", "o", "", "Root directory of old OpenConfig YANG files") + diffCmd.Flags().StringP("newroot", "n", "", "Root directory of new OpenConfig YANG files") + diffCmd.Flags().Bool("disallowed-incompats", false, "only show disallowed (per semver.org) backward-incompatible changes. Note that the backward-incompatible checks are not exhausive.") + diffCmd.Flags().Bool("github-comment", false, "Show output suitable for posting in a GitHub comment.") } diff --git a/cmd/root.go b/cmd/root.go index 03a8f3f..f6d8d3a 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -1,6 +1,17 @@ -/* -Copyright © 2023 Google Inc. -*/ +// Copyright 2023 Google Inc. +// +// 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 cmd import ( @@ -15,14 +26,9 @@ var cfgFile string // rootCmd represents the base command when called without any subcommands var rootCmd = &cobra.Command{ - Use: "openconfig-models-ci", - Short: "A brief description of your application", - Long: `A longer description that spans multiple lines and likely contains -examples and usage of using your application. For example: - -Cobra is a CLI library for Go that empowers applications. -This application is a tool to generate the needed files -to quickly create a Cobra application.`, + Use: "openconfig-ci", + Short: "OpenConfig Models Continuous Integration CLI", + Long: `Explore the subcommands.`, // Uncomment the following line if your bare application // has an action associated with it: // Run: func(cmd *cobra.Command, args []string) { }, From 09a47825bfb64bcfdcae6381af3013d884e53bfb Mon Sep 17 00:00:00 2001 From: wenovus Date: Fri, 4 Aug 2023 10:00:24 -0700 Subject: [PATCH 15/15] Improve readme --- openconfig-ci/README.md | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/openconfig-ci/README.md b/openconfig-ci/README.md index 5d3cc19..a703f1c 100644 --- a/openconfig-ci/README.md +++ b/openconfig-ci/README.md @@ -1,7 +1,31 @@ +## Install + ```bash go install github.com/openconfig/models-ci/openconfig-ci@latest +``` -git clone github.com/openconfig/models-ci -cd $GOPATH/src/github.com/openconfig/models-ci/openconfig-ci -openconfig-ci diff --oldp ocdiff/testdata/yang/incl --newp ocdiff/testdata/yang/incl --oldroot ocdiff/testdata/yang/old --newroot ocdiff/testdata/yang/new +## Usage + +``` +$ git clone github.com/openconfig/models-ci +$ cd $GOPATH/src/github.com/openconfig/models-ci/openconfig-ci +$ openconfig-ci diff --oldp ocdiff/testdata/yang/incl --newp ocdiff/testdata/yang/incl --oldroot ocdiff/testdata/yang/old --newroot ocdiff/testdata/yang/new +leaf deleted: /openconfig-platform/components/component/chassis/utilization/resources/resource/state/max-limit ("openconfig-platform": openconfig-version 0.23.0 -> 0.24.0) +leaf deleted: /openconfig-platform/components/component/integrated-circuit/utilization/resources/resource/state/max-limit ("openconfig-platform": openconfig-version 0.23.0 -> 0.24.0) +leaf deleted: /openconfig-platform/components/component/linecard/state/slot-id ("openconfig-platform-linecard": openconfig-version 1.1.0 -> 1.2.0) +leaf deleted: /openconfig-platform/components/component/linecard/utilization/resources/resource/state/max-limit ("openconfig-platform": openconfig-version 0.23.0 -> 0.24.0) +leaf deleted: /openconfig-platform/components/component/port/breakout-mode/groups/group/config/num-breakouts ("openconfig-platform-port": openconfig-version 1.0.1 -> 2.0.0) +leaf deleted: /openconfig-platform/components/component/port/breakout-mode/groups/group/state/num-breakouts ("openconfig-platform-port": openconfig-version 1.0.1 -> 2.0.0) +leaf updated: /openconfig-platform/components/component/chassis/utilization/resources/resource/state/used: type changed from uint64 to uint32 ("openconfig-platform": openconfig-version 0.23.0 -> 0.24.0) +leaf updated: /openconfig-platform/components/component/integrated-circuit/utilization/resources/resource/state/used: type changed from uint64 to uint32 ("openconfig-platform": openconfig-version 0.23.0 -> 0.24.0) +leaf updated: /openconfig-platform/components/component/linecard/state/colour: type changed from string to binary ("openconfig-platform-linecard": openconfig-version 1.1.0 -> 1.2.0) +leaf updated: /openconfig-platform/components/component/linecard/utilization/resources/resource/state/used: type changed from uint64 to uint32 ("openconfig-platform": openconfig-version 0.23.0 -> 0.24.0) +leaf updated: /openconfig-platform/components/component/port/breakout-mode/groups/group/config/num-physical-channels: type changed from uint8 to uint16 ("openconfig-platform-port": openconfig-version 1.0.1 -> 2.0.0) +leaf updated: /openconfig-platform/components/component/port/breakout-mode/groups/group/state/num-physical-channels: type changed from uint8 to uint16 ("openconfig-platform-port": openconfig-version 1.0.1 -> 2.0.0) +leaf added: /openconfig-platform/components/component/chassis/utilization/resources/resource/state/total ("openconfig-platform": openconfig-version 0.23.0 -> 0.24.0) +leaf added: /openconfig-platform/components/component/integrated-circuit/utilization/resources/resource/state/total ("openconfig-platform": openconfig-version 0.23.0 -> 0.24.0) +leaf added: /openconfig-platform/components/component/linecard/state/slot-identifier ("openconfig-platform-linecard": openconfig-version 1.1.0 -> 1.2.0) +leaf added: /openconfig-platform/components/component/linecard/utilization/resources/resource/state/total ("openconfig-platform": openconfig-version 0.23.0 -> 0.24.0) +leaf added: /openconfig-platform/components/component/port/breakout-mode/groups/group/config/break-num ("openconfig-platform-port": openconfig-version 1.0.1 -> 2.0.0) +leaf added: /openconfig-platform/components/component/port/breakout-mode/groups/group/state/break-num ("openconfig-platform-port": openconfig-version 1.0.1 -> 2.0.0) ```