github.com/wallyworld/juju@v0.0.0-20161013125918-6cf1bc9d917a/core/description/sshhostkey.go (about) 1 // Copyright 2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package description 5 6 import ( 7 "github.com/juju/errors" 8 "github.com/juju/schema" 9 ) 10 11 type sshHostKeys struct { 12 Version int `yaml:"version"` 13 SSHHostKeys_ []*sshHostKey `yaml:"ssh-host-keys"` 14 } 15 16 type sshHostKey struct { 17 MachineID_ string `yaml:"machine-id"` 18 Keys_ []string `yaml:"keys"` 19 } 20 21 // MachineID implements SSHHostKey. 22 func (i *sshHostKey) MachineID() string { 23 return i.MachineID_ 24 } 25 26 // Keys implements SSHHostKey. 27 func (i *sshHostKey) Keys() []string { 28 return i.Keys_ 29 } 30 31 // SSHHostKeyArgs is an argument struct used to create a 32 // new internal sshHostKey type that supports the SSHHostKey interface. 33 type SSHHostKeyArgs struct { 34 MachineID string 35 Keys []string 36 } 37 38 func newSSHHostKey(args SSHHostKeyArgs) *sshHostKey { 39 return &sshHostKey{ 40 MachineID_: args.MachineID, 41 Keys_: args.Keys, 42 } 43 } 44 45 func importSSHHostKeys(source map[string]interface{}) ([]*sshHostKey, error) { 46 checker := versionedChecker("ssh-host-keys") 47 coerced, err := checker.Coerce(source, nil) 48 if err != nil { 49 return nil, errors.Annotatef(err, "ssh-host-keys version schema check failed") 50 } 51 valid := coerced.(map[string]interface{}) 52 53 version := int(valid["version"].(int64)) 54 importFunc, ok := sshHostKeyDeserializationFuncs[version] 55 if !ok { 56 return nil, errors.NotValidf("version %d", version) 57 } 58 sourceList := valid["ssh-host-keys"].([]interface{}) 59 return importSSHHostKeyList(sourceList, importFunc) 60 } 61 62 func importSSHHostKeyList(sourceList []interface{}, importFunc sshHostKeyDeserializationFunc) ([]*sshHostKey, error) { 63 result := make([]*sshHostKey, 0, len(sourceList)) 64 for i, value := range sourceList { 65 source, ok := value.(map[string]interface{}) 66 if !ok { 67 return nil, errors.Errorf("unexpected value for ssh-host-key %d, %T", i, value) 68 } 69 sshHostKey, err := importFunc(source) 70 if err != nil { 71 return nil, errors.Annotatef(err, "ssh-host-key %d", i) 72 } 73 result = append(result, sshHostKey) 74 } 75 return result, nil 76 } 77 78 type sshHostKeyDeserializationFunc func(map[string]interface{}) (*sshHostKey, error) 79 80 var sshHostKeyDeserializationFuncs = map[int]sshHostKeyDeserializationFunc{ 81 1: importSSHHostKeyV1, 82 } 83 84 func importSSHHostKeyV1(source map[string]interface{}) (*sshHostKey, error) { 85 fields := schema.Fields{ 86 "machine-id": schema.String(), 87 "keys": schema.List(schema.String()), 88 } 89 // Some values don't have to be there. 90 defaults := schema.Defaults{} 91 checker := schema.FieldMap(fields, defaults) 92 93 coerced, err := checker.Coerce(source, nil) 94 if err != nil { 95 return nil, errors.Annotatef(err, "sshhostkey v1 schema check failed") 96 } 97 valid := coerced.(map[string]interface{}) 98 keysInterface := valid["keys"].([]interface{}) 99 keys := make([]string, len(keysInterface)) 100 for i, d := range keysInterface { 101 keys[i] = d.(string) 102 } 103 return &sshHostKey{ 104 MachineID_: valid["machine-id"].(string), 105 Keys_: keys, 106 }, nil 107 }