github.com/zntrio/harp/v2@v2.0.9/pkg/bundle/ruleset/bundle.go (about)

     1  // Licensed to Elasticsearch B.V. under one or more contributor
     2  // license agreements. See the NOTICE file distributed with
     3  // this work for additional information regarding copyright
     4  // ownership. Elasticsearch B.V. licenses this file to you under
     5  // the Apache License, Version 2.0 (the "License"); you may
     6  // not use this file except in compliance with the License.
     7  // You may obtain a copy of the License at
     8  //
     9  //     http://www.apache.org/licenses/LICENSE-2.0
    10  //
    11  // Unless required by applicable law or agreed to in writing,
    12  // software distributed under the License is distributed on an
    13  // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    14  // KIND, either express or implied.  See the License for the
    15  // specific language governing permissions and limitations
    16  // under the License.
    17  
    18  package ruleset
    19  
    20  import (
    21  	"encoding/base64"
    22  	"errors"
    23  	"fmt"
    24  
    25  	bundlev1 "github.com/zntrio/harp/v2/api/gen/go/harp/bundle/v1"
    26  	"github.com/zntrio/harp/v2/pkg/bundle"
    27  )
    28  
    29  // FromBundle crawls secret structure to generate a linter ruleset.
    30  func FromBundle(b *bundlev1.Bundle) (*bundlev1.RuleSet, error) {
    31  	// Check arguments
    32  	if b == nil {
    33  		return nil, errors.New("unable to process nil bundle")
    34  	}
    35  	if len(b.Packages) == 0 {
    36  		return nil, errors.New("unable to generate rule from an empty bundle")
    37  	}
    38  
    39  	// Retrieve MTR
    40  	root, _, err := bundle.Tree(b)
    41  	if err != nil {
    42  		return nil, fmt.Errorf("unable to compute bundle identifier: %w", err)
    43  	}
    44  
    45  	// Encode MTR as Base64
    46  	b64Root := base64.RawURLEncoding.EncodeToString(root.Root())
    47  
    48  	// Create ruleset
    49  	rs := &bundlev1.RuleSet{
    50  		ApiVersion: "harp.elastic.co/v1",
    51  		Kind:       "RuleSet",
    52  		Meta: &bundlev1.RuleSetMeta{
    53  			Name:        b64Root,
    54  			Description: "Generated from bundle content",
    55  		},
    56  		Spec: &bundlev1.RuleSetSpec{
    57  			Rules: []*bundlev1.Rule{},
    58  		},
    59  	}
    60  
    61  	// Iterate over bundle package
    62  	ruleIdx := 1
    63  	for _, p := range b.Packages {
    64  		if p == nil || p.Secrets == nil || len(p.Secrets.Data) == 0 {
    65  			// Skip invalid package
    66  			continue
    67  		}
    68  
    69  		// Prepare a rule
    70  		r := &bundlev1.Rule{
    71  			Name:        fmt.Sprintf("LINT-%s-%d", b64Root[:6], ruleIdx),
    72  			Path:        p.Name,
    73  			Constraints: []string{},
    74  		}
    75  
    76  		// Process each secret
    77  		for _, s := range p.Secrets.Data {
    78  			r.Constraints = append(r.Constraints, fmt.Sprintf(`p.has_secret(%q)`, s.Key))
    79  		}
    80  
    81  		// Add the rules
    82  		rs.Spec.Rules = append(rs.Spec.Rules, r)
    83  		ruleIdx++
    84  	}
    85  
    86  	// No error
    87  	return rs, nil
    88  }