github.com/snyk/vervet/v4@v4.27.2/internal/generator/resources.go (about) 1 package generator 2 3 import ( 4 "path/filepath" 5 6 "github.com/getkin/kin-openapi/openapi3" 7 8 "github.com/snyk/vervet/v4" 9 "github.com/snyk/vervet/v4/config" 10 "github.com/snyk/vervet/v4/internal/compiler" 11 ) 12 13 // ResourceKey uniquely identifies an API resource. 14 type ResourceKey struct { 15 API string 16 Resource string 17 Path string 18 } 19 20 // ResourceMap defines a mapping from API resource identity to its versions. 21 type ResourceMap map[ResourceKey]*vervet.ResourceVersions 22 23 // OperationMap defines a mapping from operation name to all versions 24 // of that operation within a resource. 25 type OperationMap map[string][]OperationVersion 26 27 // OperationVersion represents a version of an operation within a collection of 28 // resource versions. 29 type OperationVersion struct { 30 *vervet.ResourceVersion 31 Path string 32 Method string 33 Operation *openapi3.Operation 34 } 35 36 // MapResourceOperations returns a mapping from operation ID to all versions of that 37 // operation. 38 func MapResourceOperations(resourceVersions *vervet.ResourceVersions) (OperationMap, error) { 39 result := OperationMap{} 40 versions := resourceVersions.Versions() 41 for i := range versions { 42 r, err := resourceVersions.At(versions[i].String()) 43 if err != nil { 44 return nil, err 45 } 46 for path, pathItem := range r.Document.Paths { 47 ops := MapPathOperations(pathItem) 48 for method, op := range ops { 49 opVersion := OperationVersion{ 50 ResourceVersion: r, 51 Path: path, 52 Method: method, 53 Operation: op, 54 } 55 result[op.OperationID] = append(result[op.OperationID], opVersion) 56 } 57 } 58 } 59 return result, nil 60 } 61 62 // MapPathOperations returns a mapping from HTTP method to *openapi3.Operation 63 // for a given *openapi3.PathItem. 64 func MapPathOperations(p *openapi3.PathItem) map[string]*openapi3.Operation { 65 result := map[string]*openapi3.Operation{} 66 if p.Connect != nil { 67 result["connect"] = p.Connect 68 } 69 if p.Delete != nil { 70 result["delete"] = p.Delete 71 } 72 if p.Get != nil { 73 result["get"] = p.Get 74 } 75 if p.Head != nil { 76 result["head"] = p.Head 77 } 78 if p.Options != nil { 79 result["options"] = p.Options 80 } 81 if p.Patch != nil { 82 result["patch"] = p.Patch 83 } 84 if p.Post != nil { 85 result["post"] = p.Post 86 } 87 if p.Put != nil { 88 result["put"] = p.Put 89 } 90 if p.Trace != nil { 91 result["trace"] = p.Trace 92 } 93 return result 94 } 95 96 // MapResources returns a mapping of all resources managed within a Vervet 97 // project. 98 func MapResources(proj *config.Project) (ResourceMap, error) { 99 resources := ResourceMap{} 100 for apiName, apiConfig := range proj.APIs { 101 for _, rcConfig := range apiConfig.Resources { 102 specFiles, err := compiler.ResourceSpecFiles(rcConfig) 103 if err != nil { 104 return nil, err 105 } 106 for i := range specFiles { 107 versionDir := filepath.Dir(specFiles[i]) 108 resourceDir := filepath.Dir(versionDir) 109 resourceKey := ResourceKey{API: apiName, Resource: filepath.Base(resourceDir), Path: resourceDir} 110 if _, ok := resources[resourceKey]; !ok { 111 rcVersions, err := vervet.LoadResourceVersions(resourceDir) 112 if err != nil { 113 return nil, err 114 } 115 resources[resourceKey] = rcVersions 116 } 117 } 118 } 119 } 120 return resources, nil 121 }