github.com/coreos/mantle@v0.13.0/platform/machine/do/flight.go (about) 1 // Copyright 2017 CoreOS, Inc. 2 // Copyright 2018 Red Hat 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 16 package do 17 18 import ( 19 "context" 20 21 "github.com/coreos/pkg/capnslog" 22 23 ctplatform "github.com/coreos/container-linux-config-transpiler/config/platform" 24 "github.com/coreos/mantle/platform" 25 "github.com/coreos/mantle/platform/api/do" 26 ) 27 28 const ( 29 Platform platform.Name = "do" 30 ) 31 32 var ( 33 plog = capnslog.NewPackageLogger("github.com/coreos/mantle", "platform/machine/do") 34 ) 35 36 type flight struct { 37 *platform.BaseFlight 38 api *do.API 39 sshKeyID int 40 fakeSSHKeyID int 41 } 42 43 func NewFlight(opts *do.Options) (platform.Flight, error) { 44 api, err := do.New(opts) 45 if err != nil { 46 return nil, err 47 } 48 49 bf, err := platform.NewBaseFlight(opts.Options, Platform, ctplatform.DO) 50 if err != nil { 51 return nil, err 52 } 53 54 df := &flight{ 55 BaseFlight: bf, 56 api: api, 57 } 58 59 keys, err := df.Keys() 60 if err != nil { 61 df.Destroy() 62 return nil, err 63 } 64 df.sshKeyID, err = df.api.AddKey(context.TODO(), df.Name(), keys[0].String()) 65 if err != nil { 66 df.Destroy() 67 return nil, err 68 } 69 70 // The DO API requires us to provide an SSH key for Container Linux 71 // droplets. Create one that can never authenticate. 72 key, err := platform.GenerateFakeKey() 73 if err != nil { 74 df.Destroy() 75 return nil, err 76 } 77 df.fakeSSHKeyID, err = df.api.AddKey(context.TODO(), df.Name()+"-fake", key) 78 if err != nil { 79 df.Destroy() 80 return nil, err 81 } 82 83 return df, nil 84 } 85 86 func (df *flight) NewCluster(rconf *platform.RuntimeConfig) (platform.Cluster, error) { 87 bc, err := platform.NewBaseCluster(df.BaseFlight, rconf) 88 if err != nil { 89 return nil, err 90 } 91 92 dc := &cluster{ 93 BaseCluster: bc, 94 flight: df, 95 } 96 if !rconf.NoSSHKeyInMetadata { 97 dc.sshKeyID = df.sshKeyID 98 } else { 99 // The DO API requires us to provide an SSH key for 100 // Container Linux droplets. Provide one that can never 101 // authenticate. 102 dc.sshKeyID = df.fakeSSHKeyID 103 } 104 105 df.AddCluster(dc) 106 107 return dc, nil 108 } 109 110 func (df *flight) Destroy() { 111 for _, keyID := range []int{df.sshKeyID, df.fakeSSHKeyID} { 112 if keyID == 0 { 113 continue 114 } 115 if err := df.api.DeleteKey(context.TODO(), keyID); err != nil { 116 plog.Errorf("Error deleting key %v: %v", keyID, err) 117 } 118 } 119 120 df.BaseFlight.Destroy() 121 }