func parseAllocateConstraintsResponse(source interface{}, machine *machine) (ConstraintMatches, error) { var empty ConstraintMatches matchFields := schema.Fields{ "storage": schema.StringMap(schema.ForceInt()), "interfaces": schema.StringMap(schema.ForceInt()), } matchDefaults := schema.Defaults{ "storage": schema.Omit, "interfaces": schema.Omit, } fields := schema.Fields{ "constraints_by_type": schema.FieldMap(matchFields, matchDefaults), } checker := schema.FieldMap(fields, nil) // no defaults coerced, err := checker.Coerce(source, nil) if err != nil { return empty, WrapWithDeserializationError(err, "allocation constraints response schema check failed") } valid := coerced.(map[string]interface{}) constraintsMap := valid["constraints_by_type"].(map[string]interface{}) result := ConstraintMatches{ Interfaces: make(map[string]Interface), Storage: make(map[string]BlockDevice), } if interfaceMatches, found := constraintsMap["interfaces"]; found { for label, value := range interfaceMatches.(map[string]interface{}) { id := value.(int) iface := machine.Interface(id) if iface == nil { return empty, NewDeserializationError("constraint match interface %q: %d does not match an interface for the machine", label, id) } result.Interfaces[label] = iface } } if storageMatches, found := constraintsMap["storage"]; found { for label, value := range storageMatches.(map[string]interface{}) { id := value.(int) blockDevice := machine.PhysicalBlockDevice(id) if blockDevice == nil { return empty, NewDeserializationError("constraint match storage %q: %d does not match a physical block device for the machine", label, id) } result.Storage[label] = blockDevice } } return result, nil }
func bootResource_2_0(source map[string]interface{}) (*bootResource, error) { fields := schema.Fields{ "resource_uri": schema.String(), "id": schema.ForceInt(), "name": schema.String(), "type": schema.String(), "architecture": schema.String(), "subarches": schema.String(), "kflavor": schema.String(), } checker := schema.FieldMap(fields, nil) // no defaults coerced, err := checker.Coerce(source, nil) if err != nil { return nil, WrapWithDeserializationError(err, "boot resource 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. result := &bootResource{ resourceURI: valid["resource_uri"].(string), id: valid["id"].(int), name: valid["name"].(string), type_: valid["type"].(string), architecture: valid["architecture"].(string), subArches: valid["subarches"].(string), kernelFlavor: valid["kflavor"].(string), } 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 vlan_2_0(source map[string]interface{}) (*vlan, error) { fields := schema.Fields{ "id": schema.ForceInt(), "resource_uri": schema.String(), "name": schema.OneOf(schema.Nil(""), schema.String()), "fabric": schema.String(), "vid": schema.ForceInt(), "mtu": schema.ForceInt(), "dhcp_on": schema.Bool(), // racks are not always set. "primary_rack": schema.OneOf(schema.Nil(""), schema.String()), "secondary_rack": schema.OneOf(schema.Nil(""), schema.String()), } checker := schema.FieldMap(fields, nil) coerced, err := checker.Coerce(source, nil) if err != nil { return nil, errors.Annotatef(err, "vlan 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. // Since the primary and secondary racks are optional, we use the two // part cast assignment. If the case fails, then we get the default value // we care about, which is the empty string. primary_rack, _ := valid["primary_rack"].(string) secondary_rack, _ := valid["secondary_rack"].(string) name, _ := valid["name"].(string) result := &vlan{ resourceURI: valid["resource_uri"].(string), id: valid["id"].(int), name: name, fabric: valid["fabric"].(string), vid: valid["vid"].(int), mtu: valid["mtu"].(int), dhcp: valid["dhcp_on"].(bool), primaryRack: primary_rack, secondaryRack: secondary_rack, } return result, 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 (s *S) TestForceInt(c *gc.C) { s.sch = schema.ForceInt() out, err := s.sch.Coerce(42, aPath) c.Assert(err, gc.IsNil) c.Assert(out, gc.Equals, int(42)) out, err = s.sch.Coerce("42", aPath) c.Assert(err, gc.IsNil) c.Assert(out, gc.Equals, int(42)) out, err = s.sch.Coerce("42.66", aPath) c.Assert(err, gc.IsNil) c.Assert(out, gc.Equals, int(42)) out, err = s.sch.Coerce(int8(42), aPath) c.Assert(err, gc.IsNil) c.Assert(out, gc.Equals, int(42)) out, err = s.sch.Coerce(float32(42), aPath) c.Assert(err, gc.IsNil) c.Assert(out, gc.Equals, int(42)) out, err = s.sch.Coerce(float64(42), aPath) c.Assert(err, gc.IsNil) c.Assert(out, gc.Equals, int(42)) out, err = s.sch.Coerce(42.66, aPath) c.Assert(err, gc.IsNil) c.Assert(out, gc.Equals, int(42)) // If an out of range value is provided, that value is truncated, // generating unexpected results, but no error is raised. out, err = s.sch.Coerce(float64(math.MaxInt64+1), aPath) c.Assert(err, gc.IsNil) out, err = s.sch.Coerce(true, aPath) c.Assert(out, gc.IsNil) c.Assert(err, gc.ErrorMatches, `<path>: expected number, got bool\(true\)`) out, err = s.sch.Coerce(nil, aPath) c.Assert(out, gc.IsNil) c.Assert(err, gc.ErrorMatches, "<path>: expected number, got nothing") }
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 partition_2_0(source map[string]interface{}) (*partition, error) { fields := schema.Fields{ "resource_uri": schema.String(), "id": schema.ForceInt(), "path": schema.String(), "uuid": schema.String(), "used_for": schema.String(), "size": schema.ForceUint(), "filesystem": schema.OneOf(schema.Nil(""), schema.StringMap(schema.Any())), } checker := schema.FieldMap(fields, nil) coerced, err := checker.Coerce(source, nil) if err != nil { return nil, WrapWithDeserializationError(err, "partition 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. var filesystem *filesystem if fsSource := valid["filesystem"]; fsSource != nil { filesystem, err = filesystem2_0(fsSource.(map[string]interface{})) if err != nil { return nil, errors.Trace(err) } } result := &partition{ resourceURI: valid["resource_uri"].(string), id: valid["id"].(int), path: valid["path"].(string), uuid: valid["uuid"].(string), usedFor: valid["used_for"].(string), size: valid["size"].(uint64), filesystem: filesystem, } return result, nil }
func (s *configSuite) TestSecretAttrsAreStrings(c *gc.C) { for i, field := range configSecretFields { c.Logf("test %d: %s", i, field) attrs := validAttrs().Merge(testing.Attrs{field: 0}) if v, ok := configFields[field]; ok { configFields[field] = schema.ForceInt() defer func(c schema.Checker) { configFields[field] = c }(v) } else { c.Errorf("secrect field %s not found in configFields", field) continue } testConfig := newConfig(c, attrs) sa, err := providerInstance.SecretAttrs(testConfig) c.Check(sa, gc.IsNil) c.Check(err, gc.ErrorMatches, "secret .* field must have a string value; got .*") } }
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 }
if uuid, ok := c[ControllerUUIDKey].(string); ok && !utils.IsValidUUIDString(uuid) { return errors.Errorf("controller-uuid: expected UUID, got string(%q)", uuid) } return nil } // GenerateControllerCertAndKey makes sure that the config has a CACert and // CAPrivateKey, generates and returns new certificate and key. func GenerateControllerCertAndKey(caCert, caKey string, hostAddresses []string) (string, string, error) { return cert.NewDefaultServer(caCert, caKey, hostAddresses) } var configChecker = schema.FieldMap(schema.Fields{ AuditingEnabled: schema.Bool(), APIPort: schema.ForceInt(), StatePort: schema.ForceInt(), IdentityURL: schema.String(), IdentityPublicKey: schema.String(), SetNUMAControlPolicyKey: schema.Bool(), AutocertURLKey: schema.String(), AutocertDNSNameKey: schema.String(), AllowModelAccessKey: schema.Bool(), }, schema.Defaults{ APIPort: DefaultAPIPort, AuditingEnabled: DefaultAuditingEnabled, StatePort: DefaultStatePort, IdentityURL: schema.Omit, IdentityPublicKey: schema.Omit, SetNUMAControlPolicyKey: DefaultNUMAControlPolicy, AutocertURLKey: schema.Omit,
// ebsProvider creates volume sources which use AWS EBS volumes. type ebsProvider struct{} var _ storage.Provider = (*ebsProvider)(nil) var ebsConfigFields = schema.Fields{ EBS_VolumeType: schema.OneOf( schema.Const(volumeTypeMagnetic), schema.Const(volumeTypeSsd), schema.Const(volumeTypeProvisionedIops), schema.Const(volumeTypeStandard), schema.Const(volumeTypeGp2), schema.Const(volumeTypeIo1), ), EBS_IOPS: schema.ForceInt(), EBS_Encrypted: schema.Bool(), } var ebsConfigChecker = schema.FieldMap( ebsConfigFields, schema.Defaults{ EBS_VolumeType: volumeTypeMagnetic, EBS_IOPS: schema.Omit, EBS_Encrypted: false, }, ) type ebsConfig struct { volumeType string iops int
// FieldType describes the type of an attribute value. type FieldType string // The following constants are the possible type values. const ( Tstring FieldType = "string" Tbool FieldType = "bool" Tint FieldType = "int" Tattrs FieldType = "attrs" ) var checkers = map[FieldType]schema.Checker{ Tstring: schema.String(), Tbool: schema.Bool(), Tint: schema.ForceInt(), Tattrs: attrsC{}, } // Alternative possibilities to ValidationSchema to bear in mind for // the future: // func (s Fields) Checker() schema.Checker // func (s Fields) Validate(value map[string]interface{}) (v map[string] interface{}, extra []string, err error) // ValidationSchema returns values suitable for passing to // schema.FieldMap to create a schema.Checker that will validate the given fields. // It will return an error if the fields are invalid. // // The Defaults return value will contain entries for all non-mandatory // attributes set to schema.Omit. It is the responsibility of the // client to set any actual default values as required.
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 }
import ( "fmt" "github.com/juju/schema" "github.com/juju/juju/environs/config" ) const defaultStoragePort = 8040 var ( configFields = schema.Fields{ "bootstrap-host": schema.String(), "bootstrap-user": schema.String(), "storage-listen-ip": schema.String(), "storage-port": schema.ForceInt(), "storage-auth-key": schema.String(), "use-sshstorage": schema.Bool(), } configDefaults = schema.Defaults{ "bootstrap-user": "", "storage-listen-ip": "", "storage-port": defaultStoragePort, "use-sshstorage": true, } ) type environConfig struct { *config.Config attrs map[string]interface{} }
"default-series": schema.String(), "tools-metadata-url": schema.String(), "image-metadata-url": schema.String(), "image-stream": schema.String(), "authorized-keys": schema.String(), "authorized-keys-path": schema.String(), "firewall-mode": schema.String(), "agent-version": schema.String(), "development": schema.Bool(), "admin-secret": schema.String(), "ca-cert": schema.String(), "ca-cert-path": schema.String(), "ca-private-key": schema.String(), "ca-private-key-path": schema.String(), "ssl-hostname-verification": schema.Bool(), "state-port": schema.ForceInt(), "api-port": schema.ForceInt(), "syslog-port": schema.ForceInt(), "rsyslog-ca-cert": schema.String(), "logging-config": schema.String(), "charm-store-auth": schema.String(), "provisioner-safe-mode": schema.Bool(), "http-proxy": schema.String(), "https-proxy": schema.String(), "ftp-proxy": schema.String(), "no-proxy": schema.String(), "apt-http-proxy": schema.String(), "apt-https-proxy": schema.String(), "apt-ftp-proxy": schema.String(), "bootstrap-timeout": schema.ForceInt(), "bootstrap-retry-delay": schema.ForceInt(),
} data, err := ioutil.ReadFile(absPath) if err != nil { return "", userSpecified, errors.Annotatef(err, "%q not set, and could not read from %q", key, path) } if len(data) == 0 { return "", userSpecified, errors.Errorf("file %q is empty", path) } return string(data), userSpecified, nil } var configChecker = schema.FieldMap(schema.Fields{ AdminSecretKey: schema.String(), CACertKey: schema.String(), CACertKey + "-path": schema.String(), CAPrivateKeyKey: schema.String(), CAPrivateKeyKey + "-path": schema.String(), BootstrapTimeoutKey: schema.ForceInt(), BootstrapRetryDelayKey: schema.ForceInt(), BootstrapAddressesDelayKey: schema.ForceInt(), }, schema.Defaults{ AdminSecretKey: schema.Omit, CACertKey: schema.Omit, CACertKey + "-path": schema.Omit, CAPrivateKeyKey: schema.Omit, CAPrivateKeyKey + "-path": schema.Omit, BootstrapTimeoutKey: DefaultBootstrapSSHTimeout, BootstrapRetryDelayKey: DefaultBootstrapSSHRetryDelay, BootstrapAddressesDelayKey: DefaultBootstrapSSHAddressesDelay, })