|
| 1 | +package main |
| 2 | + |
| 3 | +import ( |
| 4 | + "os" |
| 5 | + |
| 6 | + "gopkg.in/yaml.v3" |
| 7 | +) |
| 8 | + |
| 9 | +// Config contains a map of the specification for all entities (resources), |
| 10 | +// for which the code for the data source should be generated. |
| 11 | +// The key of the map is the `name` of the resource, e.g. `network`. |
| 12 | +// The key MUST be singular and in snake case, e.g. `network_forward`. |
| 13 | +type Config map[string]*Entity |
| 14 | + |
| 15 | +type Entity struct { |
| 16 | + // Additional description about the resource. This is added to the |
| 17 | + // introduction section of resource in the documentation. |
| 18 | + Description string `yaml:"description"` |
| 19 | + |
| 20 | + // Content for the optinal notes section at the end of the data source |
| 21 | + // documention. |
| 22 | + Notes string `yaml:"notes"` |
| 23 | + |
| 24 | + // Name of the package, this data source belongs to. |
| 25 | + // This also defines the path of the package in `internal/`. |
| 26 | + PackageName string `yaml:"package-name"` |
| 27 | + |
| 28 | + // Name property of the resource. If not set, this defaults to `name`. |
| 29 | + // But some entities do not have a `name` property and therefore an other |
| 30 | + // property is name defining. |
| 31 | + ObjectNamePropertyName string `yaml:"object-name-property-name"` |
| 32 | + |
| 33 | + // Default value used in the documentation for the name defining property. |
| 34 | + // Defaults to: `default`. |
| 35 | + ObjectNamePropertyDefaultValue string `yaml:"object-name-property-default-value"` |
| 36 | + |
| 37 | + // Method of the Incus client to get the resource, e.g. `GetNetwork`. |
| 38 | + // |
| 39 | + // E.g. from https://github.com/lxc/incus/blob/3da8fcd06c4f7ee3cb9388127e6071244db7ac8f/client/incus_networks.go#L104 |
| 40 | + IncusGetMethod string `yaml:"incus-get-method"` |
| 41 | + |
| 42 | + // Name of the parent entity, if any. |
| 43 | + // Resources like network forwards have a parent, in this case a network. |
| 44 | + // If this is the case, the name of the parent needs to be specidied. |
| 45 | + ParentName string `yaml:"parent"` |
| 46 | + |
| 47 | + // If a resource has no project attribute. |
| 48 | + // Most resources do have a project attribute. If this is not the case, |
| 49 | + // `has-no-project` needs to be set to `true`. |
| 50 | + HasNoProject bool `yaml:"has-no-project"` |
| 51 | + |
| 52 | + // If a resource has no status attribute. |
| 53 | + // Most resources do have a status attribute. If this is not the case, |
| 54 | + // `has-no-status` needs to be set to `true`. |
| 55 | + HasNoStatus bool `yaml:"has-no-status"` |
| 56 | + |
| 57 | + // If a resource has a location, mutual exclusive with has-locations. |
| 58 | + // Some resources are location aware. If this is the case for a resource, |
| 59 | + // `has-location` needs to be set to `true`. |
| 60 | + HasLocation bool `yaml:"has-location"` |
| 61 | + |
| 62 | + // If a resource has multiple locations, mutual exclusive with has-location. |
| 63 | + // Some resources can be assigned to multiple locations. If this is the case |
| 64 | + // for a resource, `has-locations` needs to be set to `true`. |
| 65 | + HasLocations bool `yaml:"has-locations"` |
| 66 | + |
| 67 | + // Name in snake case of an extra ID attribute, which is specific to the |
| 68 | + // respective resource type. |
| 69 | + // As of now, the only resource requiring an extra ID defining attribute is |
| 70 | + // storage volume, where the `type` is also part of the ID. |
| 71 | + ExtraIDAttribute ExtraAttribute `yaml:"extra-id-attribute"` |
| 72 | + |
| 73 | + // List of extra attributes, which are specific to the respective resource type. |
| 74 | + // |
| 75 | + // See definition of type ExtraAttribute for details. |
| 76 | + // |
| 77 | + // The following attributes are handled automatically be the code generator |
| 78 | + // and must therefore not be listed in `extra-attributes`: |
| 79 | + // |
| 80 | + // * `name` (or if the resource does not have a `name` attribute, the attribute referenced in `object-name-property-name`) |
| 81 | + // * The attributes mentioned in `extra-id-attribute`, if any |
| 82 | + // * `parent` (if `parent` is not empty) |
| 83 | + // * `project` |
| 84 | + // * `target` |
| 85 | + // * `remote` |
| 86 | + // * `description` |
| 87 | + // * `config` |
| 88 | + // * `status` (if `has-no-status` is not set to `true`) |
| 89 | + // * `location` (if `has-location` is set to `true`) |
| 90 | + // * `locations` (if `has-locations` is set to `true`) |
| 91 | + ExtraAttributes []ExtraAttribute `yaml:"extra-attributes"` |
| 92 | + |
| 93 | + // Map of additional description added to the documentation for the |
| 94 | + // automatically handled attributes (see list above). |
| 95 | + // Is added to the documentation "as-is", may contain markdown. |
| 96 | + ExtraDescriptions map[string]string `yaml:"extra-descriptions"` |
| 97 | +} |
| 98 | + |
| 99 | +// ExtraAttribute contains the specification for an attribute of a resource. |
| 100 | +type ExtraAttribute struct { |
| 101 | + // Name of the attribute in snake case, e.g. `type`. |
| 102 | + Name string `yaml:"name"` |
| 103 | + |
| 104 | + // Data type of the attribute, e.g. `string`. |
| 105 | + // Supported types are (mapping directly to the corresponding types from Terraform): |
| 106 | + // |
| 107 | + // * `bool` |
| 108 | + // * `list` |
| 109 | + // * `map` |
| 110 | + // * `object` |
| 111 | + // * `string` |
| 112 | + // |
| 113 | + // Additionally, the following special types are supported: |
| 114 | + // (the internal types are recognizable by the leading `_`) |
| 115 | + // |
| 116 | + // * `_device`: represents devices as used in instances and profiles. On the |
| 117 | + // API, these are represented as map[string]map[string]string, |
| 118 | + // which is mapped to a set of blocks of device information |
| 119 | + // consisting of name, type and properties. |
| 120 | + // This is a special type with the names and the logic hard |
| 121 | + // coded. With this, it can only be used to represent devices. |
| 122 | + Type string `yaml:"type"` |
| 123 | + |
| 124 | + // If the `type` is `list` or `map`, `element-type` defines the Terraform type |
| 125 | + // of the elements contained in the list or map. |
| 126 | + // Supported types for list are: |
| 127 | + // |
| 128 | + // * `bool` |
| 129 | + // * `list` |
| 130 | + // * `map` |
| 131 | + // * `object` |
| 132 | + // * `string` |
| 133 | + // |
| 134 | + // Supported types for `map`: |
| 135 | + // |
| 136 | + // * `bool` |
| 137 | + // * `list` |
| 138 | + // * `object` |
| 139 | + // * `string` |
| 140 | + // |
| 141 | + // Be aware, that nesting of map in map is not supported by Terraform. |
| 142 | + ElementType *ExtraAttribute `yaml:"element-type"` |
| 143 | + |
| 144 | + // If the `type` or the `element-type` is `object`, the type of the attribtues of |
| 145 | + // the object need to be defined. This is a list, listing each possible attribute of |
| 146 | + // the object. |
| 147 | + AttrTypes []*ExtraAttribute `yaml:"attr-types"` |
| 148 | + |
| 149 | + // Description of the extra attribute. This is added to the documentation. |
| 150 | + Description string `yaml:"description"` |
| 151 | +} |
| 152 | + |
| 153 | +func (c *Config) LoadConfig(path string) error { |
| 154 | + contents, err := os.ReadFile(path) |
| 155 | + if err != nil { |
| 156 | + return err |
| 157 | + } |
| 158 | + |
| 159 | + return yaml.Unmarshal(contents, c) |
| 160 | +} |
0 commit comments