github.com/snyk/vervet/v3@v3.7.0/resource_versions.go (about)

     1  package vervet
     2  
     3  import (
     4  	"fmt"
     5  	"sort"
     6  
     7  	"github.com/getkin/kin-openapi/openapi3"
     8  )
     9  
    10  type resourceVersionsSlice []*ResourceVersions
    11  
    12  func (s resourceVersionsSlice) validate() error {
    13  	for _, v := range s.versions() {
    14  		resourcePaths := map[string]string{}
    15  		for _, eps := range s {
    16  			ep, err := eps.At(v.String())
    17  			if err == ErrNoMatchingVersion {
    18  				continue
    19  			} else if err != nil {
    20  				return fmt.Errorf("validation failed: %w", err)
    21  			}
    22  			for path := range ep.Paths {
    23  				if conflict, ok := resourcePaths[path]; ok {
    24  					return fmt.Errorf("conflict: %q %q", conflict, ep.sourcePrefix)
    25  				}
    26  				resourcePaths[path] = ep.sourcePrefix
    27  			}
    28  		}
    29  	}
    30  	return nil
    31  }
    32  
    33  func (s resourceVersionsSlice) versions() VersionSlice {
    34  	vset := map[Version]bool{}
    35  	for _, eps := range s {
    36  		for i := range eps.versions {
    37  			vset[eps.versions[i].Version] = true
    38  		}
    39  	}
    40  	var versions VersionSlice
    41  	for v := range vset {
    42  		versions = append(versions, v)
    43  	}
    44  	sort.Sort(versions)
    45  	return versions
    46  }
    47  
    48  func (s resourceVersionsSlice) at(v Version) (*openapi3.T, error) {
    49  	var result *openapi3.T
    50  	for _, eps := range s {
    51  		ep, err := eps.At(v.String())
    52  		if err == ErrNoMatchingVersion {
    53  			continue
    54  		} else if err != nil {
    55  			return nil, err
    56  		}
    57  		if result == nil {
    58  			// Assign a clean copy of the contents of the first resource to the
    59  			// resulting spec. Marshaling is used to ensure that references in
    60  			// the source resource are dropped from the result, which could be
    61  			// modified on subsequent merges.
    62  			buf, err := ep.T.MarshalJSON()
    63  			if err != nil {
    64  				return nil, err
    65  			}
    66  			result = &openapi3.T{}
    67  			err = result.UnmarshalJSON(buf)
    68  			if err != nil {
    69  				return nil, err
    70  			}
    71  		}
    72  		Merge(result, ep.T, false)
    73  	}
    74  	if result == nil {
    75  		return nil, ErrNoMatchingVersion
    76  	}
    77  	// Remove the API stability extension from the merged OpenAPI spec, this
    78  	// extension is only applicable to individual resource version specs.
    79  	delete(result.ExtensionProps.Extensions, ExtSnykApiStability)
    80  	return result, nil
    81  }