func importConstraintsV1(source map[string]interface{}) (*constraints, error) { fields := schema.Fields{ "architecture": schema.String(), "container": schema.String(), "cpu-cores": schema.Uint(), "cpu-power": schema.Uint(), "instance-type": schema.String(), "memory": schema.Uint(), "root-disk": schema.Uint(), "spaces": schema.List(schema.String()), "tags": schema.List(schema.String()), } // Some values don't have to be there. defaults := schema.Defaults{ "architecture": "", "container": "", "cpu-cores": uint64(0), "cpu-power": uint64(0), "instance-type": "", "memory": uint64(0), "root-disk": uint64(0), "spaces": schema.Omit, "tags": schema.Omit, } checker := schema.FieldMap(fields, defaults) coerced, err := checker.Coerce(source, nil) if err != nil { return nil, errors.Annotatef(err, "constraints v1 schema check failed") } valid := coerced.(map[string]interface{}) // From here we know that the map returned from the schema coercion // contains fields of the right type. return &constraints{ Version: 1, Architecture_: valid["architecture"].(string), Container_: valid["container"].(string), CpuCores_: valid["cpu-cores"].(uint64), CpuPower_: valid["cpu-power"].(uint64), InstanceType_: valid["instance-type"].(string), Memory_: valid["memory"].(uint64), RootDisk_: valid["root-disk"].(uint64), Spaces_: convertToStringSlice(valid["spaces"]), Tags_: convertToStringSlice(valid["tags"]), }, nil }
func blockdevice_2_0(source map[string]interface{}) (*blockdevice, error) { fields := schema.Fields{ "resource_uri": schema.String(), "id": schema.ForceInt(), "name": schema.String(), "model": schema.String(), "path": schema.String(), "used_for": schema.String(), "tags": schema.List(schema.String()), "block_size": schema.ForceUint(), "used_size": schema.ForceUint(), "size": schema.ForceUint(), "partitions": schema.List(schema.StringMap(schema.Any())), } checker := schema.FieldMap(fields, nil) coerced, err := checker.Coerce(source, nil) if err != nil { return nil, WrapWithDeserializationError(err, "blockdevice 2.0 schema check failed") } valid := coerced.(map[string]interface{}) // From here we know that the map returned from the schema coercion // contains fields of the right type. partitions, err := readPartitionList(valid["partitions"].([]interface{}), partition_2_0) if err != nil { return nil, errors.Trace(err) } result := &blockdevice{ resourceURI: valid["resource_uri"].(string), id: valid["id"].(int), name: valid["name"].(string), model: valid["model"].(string), path: valid["path"].(string), usedFor: valid["used_for"].(string), tags: convertToStringSlice(valid["tags"]), blockSize: valid["block_size"].(uint64), usedSize: valid["used_size"].(uint64), size: valid["size"].(uint64), partitions: partitions, } return result, nil }
func space_2_0(source map[string]interface{}) (*space, error) { fields := schema.Fields{ "resource_uri": schema.String(), "id": schema.ForceInt(), "name": schema.String(), "subnets": schema.List(schema.StringMap(schema.Any())), } checker := schema.FieldMap(fields, nil) // no defaults coerced, err := checker.Coerce(source, nil) if err != nil { return nil, errors.Annotatef(err, "space 2.0 schema check failed") } valid := coerced.(map[string]interface{}) // From here we know that the map returned from the schema coercion // contains fields of the right type. subnets, err := readSubnetList(valid["subnets"].([]interface{}), subnet_2_0) if err != nil { return nil, errors.Trace(err) } result := &space{ resourceURI: valid["resource_uri"].(string), id: valid["id"].(int), name: valid["name"].(string), subnets: subnets, } return result, nil }
func importStorageV1(source map[string]interface{}) (*storage, error) { fields := schema.Fields{ "id": schema.String(), "kind": schema.String(), "owner": schema.String(), "name": schema.String(), "attachments": schema.List(schema.String()), } // Normally a list would have defaults, but in this case storage // should always have at least one attachment. checker := schema.FieldMap(fields, nil) // no defaults coerced, err := checker.Coerce(source, nil) if err != nil { return nil, errors.Annotatef(err, "storage v1 schema check failed") } valid := coerced.(map[string]interface{}) // From here we know that the map returned from the schema coercion // contains fields of the right type. result := &storage{ ID_: valid["id"].(string), Kind_: valid["kind"].(string), Owner_: valid["owner"].(string), Name_: valid["name"].(string), Attachments_: convertToStringSlice(valid["attachments"]), } return result, nil }
func (c *controller) readAPIVersion(apiVersion version.Number) (set.Strings, version.Number, error) { parsed, err := c.get("version") if err != nil { return nil, apiVersion, errors.Trace(err) } // As we care about other fields, add them. fields := schema.Fields{ "capabilities": schema.List(schema.String()), } checker := schema.FieldMap(fields, nil) // no defaults coerced, err := checker.Coerce(parsed, nil) if err != nil { return nil, apiVersion, WrapWithDeserializationError(err, "version response") } // For now, we don't append any subversion, but as it becomes used, we // should parse and check. valid := coerced.(map[string]interface{}) // From here we know that the map returned from the schema coercion // contains fields of the right type. capabilities := set.NewStrings() capabilityValues := valid["capabilities"].([]interface{}) for _, value := range capabilityValues { capabilities.Add(value.(string)) } return capabilities, apiVersion, nil }
func importPayloadV1(source map[string]interface{}) (*payload, error) { fields := schema.Fields{ "name": schema.String(), "type": schema.String(), "raw-id": schema.String(), "state": schema.String(), "labels": schema.List(schema.String()), } // Some values don't have to be there. defaults := schema.Defaults{ "labels": schema.Omit, } checker := schema.FieldMap(fields, defaults) coerced, err := checker.Coerce(source, nil) if err != nil { return nil, errors.Annotatef(err, "payload v1 schema check failed") } valid := coerced.(map[string]interface{}) return &payload{ Name_: valid["name"].(string), Type_: valid["type"].(string), RawID_: valid["raw-id"].(string), State_: valid["state"].(string), Labels_: convertToStringSlice(valid["labels"]), }, nil }
func device_2_0(source map[string]interface{}) (*device, error) { fields := schema.Fields{ "resource_uri": schema.String(), "system_id": schema.String(), "hostname": schema.String(), "fqdn": schema.String(), "parent": schema.String(), "owner": schema.String(), "ip_addresses": schema.List(schema.String()), "interface_set": schema.List(schema.StringMap(schema.Any())), "zone": schema.StringMap(schema.Any()), } checker := schema.FieldMap(fields, nil) // no defaults coerced, err := checker.Coerce(source, nil) if err != nil { return nil, WrapWithDeserializationError(err, "device 2.0 schema check failed") } valid := coerced.(map[string]interface{}) // From here we know that the map returned from the schema coercion // contains fields of the right type. interfaceSet, err := readInterfaceList(valid["interface_set"].([]interface{}), interface_2_0) if err != nil { return nil, errors.Trace(err) } zone, err := zone_2_0(valid["zone"].(map[string]interface{})) if err != nil { return nil, errors.Trace(err) } result := &device{ resourceURI: valid["resource_uri"].(string), systemID: valid["system_id"].(string), hostname: valid["hostname"].(string), fqdn: valid["fqdn"].(string), parent: valid["parent"].(string), owner: valid["owner"].(string), ipAddresses: convertToStringSlice(valid["ip_addresses"]), interfaceSet: interfaceSet, zone: zone, } return result, nil }
func versionedChecker(name string) schema.Checker { fields := schema.Fields{ "version": schema.Int(), } if name != "" { fields[name] = schema.List(schema.StringMap(schema.Any())) } return schema.FieldMap(fields, nil) // no defaults }
func readMachines(controllerVersion version.Number, source interface{}) ([]*machine, error) { readFunc, err := getMachineDeserializationFunc(controllerVersion) if err != nil { return nil, errors.Trace(err) } checker := schema.List(schema.StringMap(schema.Any())) coerced, err := checker.Coerce(source, nil) if err != nil { return nil, WrapWithDeserializationError(err, "machine base schema check failed") } valid := coerced.([]interface{}) return readMachineList(valid, readFunc) }
func importBlockDeviceV1(source map[string]interface{}) (*blockdevice, error) { fields := schema.Fields{ "name": schema.String(), "links": schema.List(schema.String()), "label": schema.String(), "uuid": schema.String(), "hardware-id": schema.String(), "bus-address": schema.String(), "size": schema.ForceUint(), "fs-type": schema.String(), "in-use": schema.Bool(), "mount-point": schema.String(), } defaults := schema.Defaults{ "links": schema.Omit, "label": "", "uuid": "", "hardware-id": "", "bus-address": "", "fs-type": "", "mount-point": "", } checker := schema.FieldMap(fields, defaults) coerced, err := checker.Coerce(source, nil) if err != nil { return nil, errors.Annotatef(err, "block device v1 schema check failed") } valid := coerced.(map[string]interface{}) // From here we know that the map returned from the schema coercion // contains fields of the right type. result := &blockdevice{ Name_: valid["name"].(string), Links_: convertToStringSlice(valid["links"]), Label_: valid["label"].(string), UUID_: valid["uuid"].(string), HardwareID_: valid["hardware-id"].(string), BusAddress_: valid["bus-address"].(string), Size_: valid["size"].(uint64), FilesystemType_: valid["fs-type"].(string), InUse_: valid["in-use"].(bool), MountPoint_: valid["mount-point"].(string), } return result, nil }
func (s *S) TestList(c *gc.C) { s.sch = schema.List(schema.Int()) out, err := s.sch.Coerce([]int8{1, 2}, aPath) c.Assert(err, gc.IsNil) c.Assert(out, gc.DeepEquals, []interface{}{int64(1), int64(2)}) out, err = s.sch.Coerce(42, aPath) c.Assert(out, gc.IsNil) c.Assert(err, gc.ErrorMatches, "<path>: expected list, got int\\(42\\)") out, err = s.sch.Coerce(nil, aPath) c.Assert(out, gc.IsNil) c.Assert(err, gc.ErrorMatches, "<path>: expected list, got nothing") out, err = s.sch.Coerce([]interface{}{1, true}, aPath) c.Assert(out, gc.IsNil) c.Assert(err, gc.ErrorMatches, `<path>\[1\]: expected int, got bool\(true\)`) }
func subnet_2_0(source map[string]interface{}) (*subnet, error) { fields := schema.Fields{ "resource_uri": schema.String(), "id": schema.ForceInt(), "name": schema.String(), "space": schema.String(), "gateway_ip": schema.OneOf(schema.Nil(""), schema.String()), "cidr": schema.String(), "vlan": schema.StringMap(schema.Any()), "dns_servers": schema.OneOf(schema.Nil(""), schema.List(schema.String())), } checker := schema.FieldMap(fields, nil) // no defaults coerced, err := checker.Coerce(source, nil) if err != nil { return nil, errors.Annotatef(err, "subnet 2.0 schema check failed") } valid := coerced.(map[string]interface{}) // From here we know that the map returned from the schema coercion // contains fields of the right type. vlan, err := vlan_2_0(valid["vlan"].(map[string]interface{})) if err != nil { return nil, errors.Trace(err) } // Since the gateway_ip is optional, we use the two part cast assignment. If // the cast fails, then we get the default value we care about, which is the // empty string. gateway, _ := valid["gateway_ip"].(string) result := &subnet{ resourceURI: valid["resource_uri"].(string), id: valid["id"].(int), name: valid["name"].(string), space: valid["space"].(string), vlan: vlan, gateway: gateway, cidr: valid["cidr"].(string), dnsServers: convertToStringSlice(valid["dns_servers"]), } return result, nil }
func readBootResources(controllerVersion version.Number, source interface{}) ([]*bootResource, error) { checker := schema.List(schema.StringMap(schema.Any())) coerced, err := checker.Coerce(source, nil) if err != nil { return nil, WrapWithDeserializationError(err, "boot resource base schema check failed") } valid := coerced.([]interface{}) var deserialisationVersion version.Number for v := range bootResourceDeserializationFuncs { if v.Compare(deserialisationVersion) > 0 && v.Compare(controllerVersion) <= 0 { deserialisationVersion = v } } if deserialisationVersion == version.Zero { return nil, NewUnsupportedVersionError("no boot resource read func for version %s", controllerVersion) } readFunc := bootResourceDeserializationFuncs[deserialisationVersion] return readBootResourceList(valid, readFunc) }
func readVLANs(controllerVersion version.Number, source interface{}) ([]*vlan, error) { checker := schema.List(schema.StringMap(schema.Any())) coerced, err := checker.Coerce(source, nil) if err != nil { return nil, errors.Annotatef(err, "vlan base schema check failed") } valid := coerced.([]interface{}) var deserialisationVersion version.Number for v := range vlanDeserializationFuncs { if v.Compare(deserialisationVersion) > 0 && v.Compare(controllerVersion) <= 0 { deserialisationVersion = v } } if deserialisationVersion == version.Zero { return nil, errors.Errorf("no vlan read func for version %s", controllerVersion) } readFunc := vlanDeserializationFuncs[deserialisationVersion] return readVLANList(valid, readFunc) }
func importSSHHostKeyV1(source map[string]interface{}) (*sshHostKey, error) { fields := schema.Fields{ "machine-id": schema.String(), "keys": schema.List(schema.String()), } // Some values don't have to be there. defaults := schema.Defaults{} checker := schema.FieldMap(fields, defaults) coerced, err := checker.Coerce(source, nil) if err != nil { return nil, errors.Annotatef(err, "sshhostkey v1 schema check failed") } valid := coerced.(map[string]interface{}) keysInterface := valid["keys"].([]interface{}) keys := make([]string, len(keysInterface)) for i, d := range keysInterface { keys[i] = d.(string) } return &sshHostKey{ MachineID_: valid["machine-id"].(string), Keys_: keys, }, nil }
func fabric_2_0(source map[string]interface{}) (*fabric, error) { fields := schema.Fields{ "resource_uri": schema.String(), "id": schema.ForceInt(), "name": schema.String(), "class_type": schema.OneOf(schema.Nil(""), schema.String()), "vlans": schema.List(schema.StringMap(schema.Any())), } checker := schema.FieldMap(fields, nil) // no defaults coerced, err := checker.Coerce(source, nil) if err != nil { return nil, errors.Annotatef(err, "fabric 2.0 schema check failed") } valid := coerced.(map[string]interface{}) // From here we know that the map returned from the schema coercion // contains fields of the right type. vlans, err := readVLANList(valid["vlans"].([]interface{}), vlan_2_0) if err != nil { return nil, errors.Trace(err) } // Since the class_type is optional, we use the two part cast assignment. If // the cast fails, then we get the default value we care about, which is the // empty string. classType, _ := valid["class_type"].(string) result := &fabric{ resourceURI: valid["resource_uri"].(string), id: valid["id"].(int), name: valid["name"].(string), classType: classType, vlans: vlans, } return result, nil }
func machine_2_0(source map[string]interface{}) (*machine, error) { fields := schema.Fields{ "resource_uri": schema.String(), "system_id": schema.String(), "hostname": schema.String(), "fqdn": schema.String(), "tag_names": schema.List(schema.String()), "osystem": schema.String(), "distro_series": schema.String(), "architecture": schema.String(), "memory": schema.ForceInt(), "cpu_count": schema.ForceInt(), "ip_addresses": schema.List(schema.String()), "power_state": schema.String(), "status_name": schema.String(), "status_message": schema.String(), "boot_interface": schema.StringMap(schema.Any()), "interface_set": schema.List(schema.StringMap(schema.Any())), "zone": schema.StringMap(schema.Any()), "physicalblockdevice_set": schema.List(schema.StringMap(schema.Any())), "blockdevice_set": schema.List(schema.StringMap(schema.Any())), } checker := schema.FieldMap(fields, nil) // no defaults coerced, err := checker.Coerce(source, nil) if err != nil { return nil, WrapWithDeserializationError(err, "machine 2.0 schema check failed") } valid := coerced.(map[string]interface{}) // From here we know that the map returned from the schema coercion // contains fields of the right type. bootInterface, err := interface_2_0(valid["boot_interface"].(map[string]interface{})) if err != nil { return nil, errors.Trace(err) } interfaceSet, err := readInterfaceList(valid["interface_set"].([]interface{}), interface_2_0) if err != nil { return nil, errors.Trace(err) } zone, err := zone_2_0(valid["zone"].(map[string]interface{})) if err != nil { return nil, errors.Trace(err) } physicalBlockDevices, err := readBlockDeviceList(valid["physicalblockdevice_set"].([]interface{}), blockdevice_2_0) if err != nil { return nil, errors.Trace(err) } blockDevices, err := readBlockDeviceList(valid["blockdevice_set"].([]interface{}), blockdevice_2_0) if err != nil { return nil, errors.Trace(err) } result := &machine{ resourceURI: valid["resource_uri"].(string), systemID: valid["system_id"].(string), hostname: valid["hostname"].(string), fqdn: valid["fqdn"].(string), tags: convertToStringSlice(valid["tag_names"]), operatingSystem: valid["osystem"].(string), distroSeries: valid["distro_series"].(string), architecture: valid["architecture"].(string), memory: valid["memory"].(int), cpuCount: valid["cpu_count"].(int), ipAddresses: convertToStringSlice(valid["ip_addresses"]), powerState: valid["power_state"].(string), statusName: valid["status_name"].(string), statusMessage: valid["status_message"].(string), bootInterface: bootInterface, interfaceSet: interfaceSet, zone: zone, physicalBlockDevices: physicalBlockDevices, blockDevices: blockDevices, } return result, nil }
func importUnitV1(source map[string]interface{}) (*unit, error) { fields := schema.Fields{ "name": schema.String(), "machine": schema.String(), "agent-status": schema.StringMap(schema.Any()), "agent-status-history": schema.StringMap(schema.Any()), "workload-status": schema.StringMap(schema.Any()), "workload-status-history": schema.StringMap(schema.Any()), "principal": schema.String(), "subordinates": schema.List(schema.String()), "password-hash": schema.String(), "tools": schema.StringMap(schema.Any()), "meter-status-code": schema.String(), "meter-status-info": schema.String(), } defaults := schema.Defaults{ "principal": "", "subordinates": schema.Omit, "meter-status-code": "", "meter-status-info": "", } addAnnotationSchema(fields, defaults) addConstraintsSchema(fields, defaults) checker := schema.FieldMap(fields, defaults) coerced, err := checker.Coerce(source, nil) if err != nil { return nil, errors.Annotatef(err, "unit v1 schema check failed") } valid := coerced.(map[string]interface{}) // From here we know that the map returned from the schema coercion // contains fields of the right type. result := &unit{ Name_: valid["name"].(string), Machine_: valid["machine"].(string), Principal_: valid["principal"].(string), PasswordHash_: valid["password-hash"].(string), MeterStatusCode_: valid["meter-status-code"].(string), MeterStatusInfo_: valid["meter-status-info"].(string), WorkloadStatusHistory_: newStatusHistory(), AgentStatusHistory_: newStatusHistory(), } result.importAnnotations(valid) workloadHistory := valid["workload-status-history"].(map[string]interface{}) if err := importStatusHistory(&result.WorkloadStatusHistory_, workloadHistory); err != nil { return nil, errors.Trace(err) } agentHistory := valid["agent-status-history"].(map[string]interface{}) if err := importStatusHistory(&result.AgentStatusHistory_, agentHistory); err != nil { return nil, errors.Trace(err) } if constraintsMap, ok := valid["constraints"]; ok { constraints, err := importConstraints(constraintsMap.(map[string]interface{})) if err != nil { return nil, errors.Trace(err) } result.Constraints_ = constraints } result.Subordinates_ = convertToStringSlice(valid["subordinates"]) // Tools and status are required, so we expect them to be there. tools, err := importAgentTools(valid["tools"].(map[string]interface{})) if err != nil { return nil, errors.Trace(err) } result.Tools_ = tools agentStatus, err := importStatus(valid["agent-status"].(map[string]interface{})) if err != nil { return nil, errors.Trace(err) } result.AgentStatus_ = agentStatus workloadStatus, err := importStatus(valid["workload-status"].(map[string]interface{})) if err != nil { return nil, errors.Trace(err) } result.WorkloadStatus_ = workloadStatus return result, nil }
if err != nil { return v, err } for _, allow := range c.vals { if allow == v { return v, nil } } return nil, fmt.Errorf("%sexpected one of %v, got %#v", pathPrefix(path), c.vals, v) } type attrsC struct{} var ( attrMapChecker = schema.Map(schema.String(), schema.String()) attrSliceChecker = schema.List(schema.String()) ) func (c attrsC) Coerce(v interface{}, path []string) (interface{}, error) { // TODO consider allowing only the map variant. switch reflect.TypeOf(v).Kind() { case reflect.String: s, err := schema.String().Coerce(v, path) if err != nil { return nil, errors.Mask(err) } result, err := keyvalues.Parse(strings.Fields(s.(string)), true) if err != nil { return nil, fmt.Errorf("%s%v", pathPrefix(path), err) } return result, nil
"scope": string(ScopeGlobal), "optional": false, }, ) var charmSchema = schema.FieldMap( schema.Fields{ "name": schema.String(), "summary": schema.String(), "description": schema.String(), "peers": schema.StringMap(ifaceExpander(int64(1))), "provides": schema.StringMap(ifaceExpander(nil)), "requires": schema.StringMap(ifaceExpander(int64(1))), "revision": schema.Int(), // Obsolete "format": schema.Int(), "subordinate": schema.Bool(), "categories": schema.List(schema.String()), "series": schema.String(), }, schema.Defaults{ "provides": schema.Omit, "requires": schema.Omit, "peers": schema.Omit, "revision": schema.Omit, "format": 1, "subordinate": schema.Omit, "categories": schema.Omit, "series": schema.Omit, }, )
func importMachineV1(source map[string]interface{}) (*machine, error) { fields := schema.Fields{ "id": schema.String(), "nonce": schema.String(), "password-hash": schema.String(), "placement": schema.String(), "instance": schema.StringMap(schema.Any()), "series": schema.String(), "container-type": schema.String(), "jobs": schema.List(schema.String()), "status": schema.StringMap(schema.Any()), "supported-containers": schema.List(schema.String()), "tools": schema.StringMap(schema.Any()), "containers": schema.List(schema.StringMap(schema.Any())), "opened-ports": schema.StringMap(schema.Any()), "provider-addresses": schema.List(schema.StringMap(schema.Any())), "machine-addresses": schema.List(schema.StringMap(schema.Any())), "preferred-public-address": schema.StringMap(schema.Any()), "preferred-private-address": schema.StringMap(schema.Any()), "block-devices": schema.StringMap(schema.Any()), } defaults := schema.Defaults{ "placement": "", "container-type": "", // Even though we are expecting instance data for every machine, // it isn't strictly necessary, so we allow it to not exist here. "instance": schema.Omit, "supported-containers": schema.Omit, "opened-ports": schema.Omit, "block-devices": schema.Omit, "provider-addresses": schema.Omit, "machine-addresses": schema.Omit, "preferred-public-address": schema.Omit, "preferred-private-address": schema.Omit, } addAnnotationSchema(fields, defaults) addConstraintsSchema(fields, defaults) addStatusHistorySchema(fields) checker := schema.FieldMap(fields, defaults) coerced, err := checker.Coerce(source, nil) if err != nil { return nil, errors.Annotatef(err, "machine v1 schema check failed") } valid := coerced.(map[string]interface{}) // From here we know that the map returned from the schema coercion // contains fields of the right type. result := &machine{ Id_: valid["id"].(string), Nonce_: valid["nonce"].(string), PasswordHash_: valid["password-hash"].(string), Placement_: valid["placement"].(string), Series_: valid["series"].(string), ContainerType_: valid["container-type"].(string), StatusHistory_: newStatusHistory(), Jobs_: convertToStringSlice(valid["jobs"]), } result.importAnnotations(valid) if err := result.importStatusHistory(valid); err != nil { return nil, errors.Trace(err) } if constraintsMap, ok := valid["constraints"]; ok { constraints, err := importConstraints(constraintsMap.(map[string]interface{})) if err != nil { return nil, errors.Trace(err) } result.Constraints_ = constraints } if supported, ok := valid["supported-containers"]; ok { supportedList := supported.([]interface{}) s := make([]string, len(supportedList)) for i, containerType := range supportedList { s[i] = containerType.(string) } result.SupportedContainers_ = &s } if instanceMap, ok := valid["instance"]; ok { instance, err := importCloudInstance(instanceMap.(map[string]interface{})) if err != nil { return nil, errors.Trace(err) } result.Instance_ = instance } if blockDeviceMap, ok := valid["block-devices"]; ok { devices, err := importBlockDevices(blockDeviceMap.(map[string]interface{})) if err != nil { return nil, errors.Trace(err) } result.setBlockDevices(devices) } else { result.setBlockDevices(nil) } // Tools and status are required, so we expect them to be there. tools, err := importAgentTools(valid["tools"].(map[string]interface{})) if err != nil { return nil, errors.Trace(err) } result.Tools_ = tools status, err := importStatus(valid["status"].(map[string]interface{})) if err != nil { return nil, errors.Trace(err) } result.Status_ = status if addresses, ok := valid["provider-addresses"]; ok { providerAddresses, err := importAddresses(addresses.([]interface{})) if err != nil { return nil, errors.Trace(err) } result.ProviderAddresses_ = providerAddresses } if addresses, ok := valid["machine-addresses"]; ok { machineAddresses, err := importAddresses(addresses.([]interface{})) if err != nil { return nil, errors.Trace(err) } result.MachineAddresses_ = machineAddresses } if address, ok := valid["preferred-public-address"]; ok { publicAddress, err := importAddress(address.(map[string]interface{})) if err != nil { return nil, errors.Trace(err) } result.PreferredPublicAddress_ = publicAddress } if address, ok := valid["preferred-private-address"]; ok { privateAddress, err := importAddress(address.(map[string]interface{})) if err != nil { return nil, errors.Trace(err) } result.PreferredPrivateAddress_ = privateAddress } machineList := valid["containers"].([]interface{}) machines, err := importMachineList(machineList, importMachineV1) if err != nil { return nil, errors.Annotatef(err, "containers") } result.Containers_ = machines if portsMap, ok := valid["opened-ports"]; ok { portsList, err := importOpenedPorts(portsMap.(map[string]interface{})) if err != nil { return nil, errors.Trace(err) } result.setOpenedPorts(portsList) } return result, nil }
} // StorageProvider implements storage.ProviderRegistry. func (*maasEnviron) StorageProvider(t storage.ProviderType) (storage.Provider, error) { if t == maasStorageProviderType { return maasStorageProvider{}, nil } return nil, errors.NotFoundf("storage provider %q", t) } // maasStorageProvider allows volumes to be specified when a node is acquired. type maasStorageProvider struct{} var storageConfigFields = schema.Fields{ tagsAttribute: schema.OneOf( schema.List(schema.String()), schema.String(), ), } var storageConfigChecker = schema.FieldMap( storageConfigFields, schema.Defaults{ tagsAttribute: schema.Omit, }, ) type storageConfig struct { tags []string }