go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/featureflags.go (about) 1 // Copyright (c) Mondoo, Inc. 2 // SPDX-License-Identifier: BUSL-1.1 3 4 // 5 // In this file we introduce feature flags. They help us activate optional 6 // features on requests. 7 // 8 // Features can only be activated, never deactivated. Features are efficiently encoded. 9 // They are introduced at a given version and destined to be removed at a later version. 10 // Please mark them accordingly. Feature flags are short term contextual information. 11 // 12 // Example usage: 13 // 14 // features := []Feature{ MassResolver, LiveQueries } 15 // 16 // features.IsActive( MassResolver ) // true 17 // 18 19 package cnquery 20 21 //go:generate go run golang.org/x/tools/cmd/stringer -type=Feature 22 23 import ( 24 "bytes" 25 "context" 26 "encoding/base64" 27 ) 28 29 const ( 30 // For all features, use this format: 31 // desc: A description of this feature and what it does... 32 // start: vX.x (the version when it ix introduced) 33 // end: vZ.0 (the version when this flag will be removed) 34 35 // Feature flags: 36 37 // MassQueries feature flag 38 // desc: Resolve similar queries the same way. If 100 assets have the same 39 // dependent queries and overrides, they create the same resolved 40 // plan. Cannot be used with old resolver at the same time for asset. 41 // start: v3.x, available at v4.x, default at v5.x 42 // end: v6.0 => default now, no need to set it anymore 43 MassQueries Feature = iota + 1 44 45 // PiperCode feature flag 46 // desc: Allows MQL to use variable references across blocks. Fully changes 47 // the compiled code. 48 // start: v5.x 49 // end: v7.0 => default now, no need to set it anymore 50 PiperCode 51 52 // BoolAssertions feature flag 53 // desc: Only boolean results are checked when evaluating a query for success 54 // 55 // start: v6.x 56 // end: v8.0 57 BoolAssertions 58 59 // K8sNodeDiscovery feature flag 60 // desc: Enables discovery of Kubernetes cluster nodes as individual assets 61 // 62 // start: v6.12 63 // end: unknown 64 K8sNodeDiscovery 65 66 // MQLAssetContext feature flag 67 // 68 // start: v7.0 69 // end: v8.0 70 MQLAssetContext 71 72 // ErrorsAsFailures feature flag 73 // desc: Errors are treated as failures 74 // See https://www.notion.so/mondoo/Errors-and-Scoring-5dc554348aad4118a1dbf35123368329 75 // start: v8.x 76 // end: v9.0 77 ErrorsAsFailures 78 ) 79 80 // FeaturesValue is a map from feature name to feature flag 81 var FeaturesValue = map[string]Feature{ 82 MassQueries.String(): MassQueries, 83 PiperCode.String(): PiperCode, 84 BoolAssertions.String(): BoolAssertions, 85 MQLAssetContext.String(): MQLAssetContext, 86 ErrorsAsFailures.String(): ErrorsAsFailures, 87 } 88 89 // DefaultFeatures are a set of default flags that are active 90 var DefaultFeatures = Features{ 91 byte(MassQueries), 92 byte(PiperCode), 93 } 94 95 // Features is a collection of activated features 96 type Features []byte 97 98 // Feature is a simple feature flag 99 type Feature byte 100 101 // IsActive returns true if the given feature has been requested in this list 102 func (f Features) IsActive(feature Feature) bool { 103 return bytes.IndexByte(f, byte(feature)) != -1 104 } 105 106 // Encode a set of features to base64 107 func (f Features) Encode() string { 108 return base64.StdEncoding.EncodeToString(f) 109 } 110 111 // DecodeFeatures that were previously encoded 112 func DecodeFeatures(s string) (Features, error) { 113 data, err := base64.StdEncoding.DecodeString(s) 114 return Features(data), err 115 } 116 117 type featureContextID struct{} 118 119 // SetFeatures to a given context 120 func SetFeatures(ctx context.Context, fts Features) context.Context { 121 return context.WithValue(ctx, featureContextID{}, fts) 122 } 123 124 // GetFeatures from a given context 125 func GetFeatures(ctx context.Context) Features { 126 f, ok := ctx.Value(featureContextID{}).(Features) 127 if !ok { 128 // nothing stored, assume empty features 129 return Features{} 130 } 131 return f 132 }