seems to work, needs tests and a lot of cleanup
This commit is contained in:
parent
f880187573
commit
ef3c344868
@ -60,7 +60,7 @@ func NewKubeletServerCertificateManager(kubeClient clientset.Interface, kubeCfg
|
|||||||
Subsystem: metrics.KubeletSubsystem,
|
Subsystem: metrics.KubeletSubsystem,
|
||||||
Name: "server_expiration_renew_errors",
|
Name: "server_expiration_renew_errors",
|
||||||
Help: "Counter of certificate renewal errors.",
|
Help: "Counter of certificate renewal errors.",
|
||||||
StabilityLevel: compbasemetrics.ALPHA,
|
StabilityLevel: compbasemetrics.STABLE,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
legacyregistry.MustRegister(certificateRenewFailure)
|
legacyregistry.MustRegister(certificateRenewFailure)
|
||||||
|
@ -20,6 +20,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/token"
|
"go/token"
|
||||||
|
"os"
|
||||||
"sort"
|
"sort"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@ -182,7 +183,24 @@ func (c *metricDecoder) decodeOpts(expr ast.Expr) (metric, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return m, err
|
return m, err
|
||||||
}
|
}
|
||||||
|
case *ast.SelectorExpr:
|
||||||
|
packageName := fmt.Sprintf("%v", v.X)
|
||||||
|
|
||||||
|
variableExpr, found := c.variables[packageName + "." + v.Sel.Name]
|
||||||
|
if !found {
|
||||||
|
return m, newDecodeErrorf(expr, errBadVariableAttribute)
|
||||||
|
}
|
||||||
|
bl, ok := variableExpr.(*ast.BasicLit)
|
||||||
|
if !ok {
|
||||||
|
return m, newDecodeErrorf(expr, errNonStringAttribute)
|
||||||
|
}
|
||||||
|
value, err = stringValue(bl)
|
||||||
|
if err != nil {
|
||||||
|
return m, err
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
fmt.Fprintf(os.Stdout, "key %s is type %T from Default\n", key, v)
|
||||||
return m, newDecodeErrorf(expr, errNonStringAttribute)
|
return m, newDecodeErrorf(expr, errNonStringAttribute)
|
||||||
}
|
}
|
||||||
switch key {
|
switch key {
|
||||||
|
@ -28,7 +28,7 @@ const (
|
|||||||
errStabilityLevel = "StabilityLevel should be passed STABLE, ALPHA or removed"
|
errStabilityLevel = "StabilityLevel should be passed STABLE, ALPHA or removed"
|
||||||
errStableSummary = "Stable summary metric is not supported"
|
errStableSummary = "Stable summary metric is not supported"
|
||||||
errInvalidNewMetricCall = "Invalid new metric call, please ensure code compiles"
|
errInvalidNewMetricCall = "Invalid new metric call, please ensure code compiles"
|
||||||
errNonStringAttribute = "Non string attribute it not supported"
|
errNonStringAttribute = "Non string attribute is not supported"
|
||||||
errBadVariableAttribute = "Metric attribute was not correctly set. Please use only global consts in same file"
|
errBadVariableAttribute = "Metric attribute was not correctly set. Please use only global consts in same file"
|
||||||
errFieldNotSupported = "Field %s is not supported"
|
errFieldNotSupported = "Field %s is not supported"
|
||||||
errBuckets = "Buckets should be set to list of floats, result from function call of prometheus.LinearBuckets or prometheus.ExponentialBuckets"
|
errBuckets = "Buckets should be set to list of floats, result from function call of prometheus.LinearBuckets or prometheus.ExponentialBuckets"
|
||||||
|
@ -23,6 +23,7 @@ import (
|
|||||||
"go/ast"
|
"go/ast"
|
||||||
"go/parser"
|
"go/parser"
|
||||||
"go/token"
|
"go/token"
|
||||||
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"sort"
|
"sort"
|
||||||
@ -124,6 +125,11 @@ func searchFileForStableMetrics(filename string, src interface{}) ([]metric, []e
|
|||||||
}
|
}
|
||||||
variables := globalVariableDeclarations(tree)
|
variables := globalVariableDeclarations(tree)
|
||||||
|
|
||||||
|
variables, err = importedGlobalVariableDeclaration(variables, tree.Imports)
|
||||||
|
if err != nil {
|
||||||
|
return []metric{}, addFileInformationToErrors([]error{err}, fileset)
|
||||||
|
}
|
||||||
|
|
||||||
stableMetricsFunctionCalls, errors := findStableMetricDeclaration(tree, metricsImportName)
|
stableMetricsFunctionCalls, errors := findStableMetricDeclaration(tree, metricsImportName)
|
||||||
metrics, es := decodeMetricCalls(stableMetricsFunctionCalls, metricsImportName, variables)
|
metrics, es := decodeMetricCalls(stableMetricsFunctionCalls, metricsImportName, variables)
|
||||||
errors = append(errors, es...)
|
errors = append(errors, es...)
|
||||||
@ -173,3 +179,100 @@ func globalVariableDeclarations(tree *ast.File) map[string]ast.Expr {
|
|||||||
}
|
}
|
||||||
return consts
|
return consts
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func importedGlobalVariableDeclaration(localVariables map[string]ast.Expr, imports []*ast.ImportSpec) (map[string]ast.Expr, error) {
|
||||||
|
// to test the import will be rooted at GOPATH, so probably import will be something like /test/instrumentation/testpackage
|
||||||
|
|
||||||
|
// env gets
|
||||||
|
//GOMODCACHE := os.Getenv("GOMODCACHE")
|
||||||
|
GOROOT := os.Getenv("GOROOT")
|
||||||
|
GOOS := os.Getenv("GOOS")
|
||||||
|
KUBE_ROOT := os.Getenv("KUBE_ROOT")
|
||||||
|
KUBE_URL_ROOT := "k8s.io/kubernetes"
|
||||||
|
KUBE_ROOT_INTERNAL := strings.Replace(KUBE_ROOT, KUBE_URL_ROOT, "", 1) // k8s/k8s refs need this stripped
|
||||||
|
|
||||||
|
for _, im := range imports {
|
||||||
|
// get imported label
|
||||||
|
importAlias := "unknown"
|
||||||
|
if im.Name == nil {
|
||||||
|
pathSegments := strings.Split(im.Path.Value, "/")
|
||||||
|
importAlias = strings.Trim(pathSegments[len(pathSegments)-1], "\"")
|
||||||
|
} else {
|
||||||
|
importAlias = im.Name.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse directory path
|
||||||
|
pathPrefix := "unknown"
|
||||||
|
if strings.Contains(im.Path.Value, KUBE_URL_ROOT) {
|
||||||
|
// search k/k local checkout
|
||||||
|
pathPrefix = KUBE_ROOT_INTERNAL
|
||||||
|
} else if strings.Contains(im.Path.Value, "k8s.io/") {
|
||||||
|
// search k/k/staging local checkout
|
||||||
|
pathPrefix = KUBE_ROOT + string(os.PathSeparator) + "staging" + string(os.PathSeparator) + "src" //KUBE_ROOT + string(os.PathSeparator) + "vendor" //
|
||||||
|
} else if strings.Contains(im.Path.Value, ".") {
|
||||||
|
// not stdlib -> prefix with GOMODCACHE
|
||||||
|
// pathPrefix = KUBE_ROOT + string(os.PathSeparator) + "vendor"
|
||||||
|
|
||||||
|
// this requires implementing SIV, skip for now
|
||||||
|
continue
|
||||||
|
} else {
|
||||||
|
// stdlib -> prefix with GOROOT
|
||||||
|
pathPrefix = GOROOT + string(os.PathSeparator) + "src"
|
||||||
|
} // ToDo: support non go mod
|
||||||
|
importDirectory := pathPrefix + string(os.PathSeparator) + strings.Trim(im.Path.Value, "\"")
|
||||||
|
|
||||||
|
files, err := ioutil.ReadDir(importDirectory)
|
||||||
|
if err != nil {
|
||||||
|
//fmt.Fprintf(os.Stderr, "failed to read import path directory %s with error %w, skipping\n", importDirectory, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, file := range files {
|
||||||
|
if file.IsDir() {
|
||||||
|
// do not grab constants from subpackages
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.Contains(file.Name(), "_test") {
|
||||||
|
// do not parse test files
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
if !strings.HasSuffix(file.Name(), ".go") {
|
||||||
|
// not a go code file, do not attempt to parse
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
fileset := token.NewFileSet()
|
||||||
|
tree, err := parser.ParseFile(fileset, importDirectory+string(os.PathSeparator)+file.Name(), nil, parser.AllErrors)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to parse path %s with error %w", im.Path.Value, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// pass parsed filepath into globalVariableDeclarations
|
||||||
|
variables := globalVariableDeclarations(tree)
|
||||||
|
|
||||||
|
// add returned map into supplied map and prepend import label to all keys
|
||||||
|
for k, v := range variables {
|
||||||
|
importK := importAlias + "." + k
|
||||||
|
if _, ok := localVariables[importK]; !ok {
|
||||||
|
localVariables[importK] = v
|
||||||
|
} else {
|
||||||
|
// cross-platform file that gets included in the correct OS build via OS build tags
|
||||||
|
// use whatever matches GOOS
|
||||||
|
|
||||||
|
if strings.Contains(file.Name(), GOOS) {
|
||||||
|
// assume at some point we will find the correct OS version of this file
|
||||||
|
// if we are running on an OS that does not have an OS specific file for something then we will include a constant we shouldn't
|
||||||
|
// TODO: should we include/exclude based on the build tags?
|
||||||
|
localVariables[importK] = v
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return localVariables, nil
|
||||||
|
}
|
||||||
|
@ -58,7 +58,7 @@ reset=$(tput sgr0)
|
|||||||
kube::validate::stablemetrics() {
|
kube::validate::stablemetrics() {
|
||||||
stability_check_setup
|
stability_check_setup
|
||||||
temp_file=$(mktemp)
|
temp_file=$(mktemp)
|
||||||
doValidate=$(find_files_to_check | grep -E ".*.go" | grep -v ".*_test.go" | sort | xargs -L 200 go run "test/instrumentation/main.go" "test/instrumentation/decode_metric.go" "test/instrumentation/find_stable_metric.go" "test/instrumentation/error.go" "test/instrumentation/metric.go" -- 1>"${temp_file}")
|
doValidate=$(find_files_to_check | grep -E ".*.go" | grep -v ".*_test.go" | sort | KUBE_ROOT=${KUBE_ROOT} xargs -L 200 go run "test/instrumentation/main.go" "test/instrumentation/decode_metric.go" "test/instrumentation/find_stable_metric.go" "test/instrumentation/error.go" "test/instrumentation/metric.go" -- 1>"${temp_file}")
|
||||||
|
|
||||||
if $doValidate; then
|
if $doValidate; then
|
||||||
echo -e "${green}Diffing test/instrumentation/testdata/stable-metrics-list.yaml\n${reset}"
|
echo -e "${green}Diffing test/instrumentation/testdata/stable-metrics-list.yaml\n${reset}"
|
||||||
|
Loading…
Reference in New Issue
Block a user