github.com/Prakhar-Agarwal-byte/moby@v0.0.0-20231027092010-a14e3e8ab87e/libnetwork/drivers/windows/windows_store.go (about) 1 //go:build windows 2 3 package windows 4 5 import ( 6 "context" 7 "encoding/json" 8 "fmt" 9 "net" 10 11 "github.com/containerd/log" 12 "github.com/Prakhar-Agarwal-byte/moby/libnetwork/datastore" 13 "github.com/Prakhar-Agarwal-byte/moby/libnetwork/discoverapi" 14 "github.com/Prakhar-Agarwal-byte/moby/libnetwork/netlabel" 15 "github.com/Prakhar-Agarwal-byte/moby/libnetwork/scope" 16 "github.com/Prakhar-Agarwal-byte/moby/libnetwork/types" 17 ) 18 19 const ( 20 windowsPrefix = "windows" 21 windowsEndpointPrefix = "windows-endpoint" 22 ) 23 24 func (d *driver) initStore(option map[string]interface{}) error { 25 if data, ok := option[netlabel.LocalKVClient]; ok { 26 var err error 27 dsc, ok := data.(discoverapi.DatastoreConfigData) 28 if !ok { 29 return types.InternalErrorf("incorrect data in datastore configuration: %v", data) 30 } 31 d.store, err = datastore.FromConfig(dsc) 32 if err != nil { 33 return types.InternalErrorf("windows driver failed to initialize data store: %v", err) 34 } 35 36 err = d.populateNetworks() 37 if err != nil { 38 return err 39 } 40 41 err = d.populateEndpoints() 42 if err != nil { 43 return err 44 } 45 } 46 47 return nil 48 } 49 50 func (d *driver) populateNetworks() error { 51 kvol, err := d.store.List(datastore.Key(windowsPrefix), &networkConfiguration{Type: d.name}) 52 if err != nil && err != datastore.ErrKeyNotFound { 53 return fmt.Errorf("failed to get windows network configurations from store: %v", err) 54 } 55 56 // It's normal for network configuration state to be empty. Just return. 57 if err == datastore.ErrKeyNotFound { 58 return nil 59 } 60 61 for _, kvo := range kvol { 62 ncfg := kvo.(*networkConfiguration) 63 if ncfg.Type != d.name { 64 continue 65 } 66 d.createNetwork(ncfg) 67 log.G(context.TODO()).Debugf("Network %v (%.7s) restored", d.name, ncfg.ID) 68 } 69 70 return nil 71 } 72 73 func (d *driver) populateEndpoints() error { 74 kvol, err := d.store.List(datastore.Key(windowsEndpointPrefix), &hnsEndpoint{Type: d.name}) 75 if err != nil && err != datastore.ErrKeyNotFound { 76 return fmt.Errorf("failed to get endpoints from store: %v", err) 77 } 78 79 if err == datastore.ErrKeyNotFound { 80 return nil 81 } 82 83 for _, kvo := range kvol { 84 ep := kvo.(*hnsEndpoint) 85 if ep.Type != d.name { 86 continue 87 } 88 n, ok := d.networks[ep.nid] 89 if !ok { 90 log.G(context.TODO()).Debugf("Network (%.7s) not found for restored endpoint (%.7s)", ep.nid, ep.id) 91 log.G(context.TODO()).Debugf("Deleting stale endpoint (%.7s) from store", ep.id) 92 if err := d.storeDelete(ep); err != nil { 93 log.G(context.TODO()).Debugf("Failed to delete stale endpoint (%.7s) from store", ep.id) 94 } 95 continue 96 } 97 n.endpoints[ep.id] = ep 98 log.G(context.TODO()).Debugf("Endpoint (%.7s) restored to network (%.7s)", ep.id, ep.nid) 99 } 100 101 return nil 102 } 103 104 func (d *driver) storeUpdate(kvObject datastore.KVObject) error { 105 if d.store == nil { 106 log.G(context.TODO()).Warnf("store not initialized. kv object %s is not added to the store", datastore.Key(kvObject.Key()...)) 107 return nil 108 } 109 110 if err := d.store.PutObjectAtomic(kvObject); err != nil { 111 return fmt.Errorf("failed to update store for object type %T: %v", kvObject, err) 112 } 113 114 return nil 115 } 116 117 func (d *driver) storeDelete(kvObject datastore.KVObject) error { 118 if d.store == nil { 119 log.G(context.TODO()).Debugf("store not initialized. kv object %s is not deleted from store", datastore.Key(kvObject.Key()...)) 120 return nil 121 } 122 123 retry: 124 if err := d.store.DeleteObjectAtomic(kvObject); err != nil { 125 if err == datastore.ErrKeyModified { 126 if err := d.store.GetObject(datastore.Key(kvObject.Key()...), kvObject); err != nil { 127 return fmt.Errorf("could not update the kvobject to latest when trying to delete: %v", err) 128 } 129 goto retry 130 } 131 return err 132 } 133 134 return nil 135 } 136 137 func (ncfg *networkConfiguration) MarshalJSON() ([]byte, error) { 138 nMap := make(map[string]interface{}) 139 140 nMap["ID"] = ncfg.ID 141 nMap["Type"] = ncfg.Type 142 nMap["Name"] = ncfg.Name 143 nMap["HnsID"] = ncfg.HnsID 144 nMap["VLAN"] = ncfg.VLAN 145 nMap["VSID"] = ncfg.VSID 146 nMap["DNSServers"] = ncfg.DNSServers 147 nMap["DNSSuffix"] = ncfg.DNSSuffix 148 nMap["SourceMac"] = ncfg.SourceMac 149 nMap["NetworkAdapterName"] = ncfg.NetworkAdapterName 150 151 return json.Marshal(nMap) 152 } 153 154 func (ncfg *networkConfiguration) UnmarshalJSON(b []byte) error { 155 var ( 156 err error 157 nMap map[string]interface{} 158 ) 159 160 if err = json.Unmarshal(b, &nMap); err != nil { 161 return err 162 } 163 164 ncfg.ID = nMap["ID"].(string) 165 ncfg.Type = nMap["Type"].(string) 166 ncfg.Name = nMap["Name"].(string) 167 ncfg.HnsID = nMap["HnsID"].(string) 168 ncfg.VLAN = uint(nMap["VLAN"].(float64)) 169 ncfg.VSID = uint(nMap["VSID"].(float64)) 170 ncfg.DNSServers = nMap["DNSServers"].(string) 171 ncfg.DNSSuffix = nMap["DNSSuffix"].(string) 172 ncfg.SourceMac = nMap["SourceMac"].(string) 173 ncfg.NetworkAdapterName = nMap["NetworkAdapterName"].(string) 174 return nil 175 } 176 177 func (ncfg *networkConfiguration) Key() []string { 178 return []string{windowsPrefix + ncfg.Type, ncfg.ID} 179 } 180 181 func (ncfg *networkConfiguration) KeyPrefix() []string { 182 return []string{windowsPrefix + ncfg.Type} 183 } 184 185 func (ncfg *networkConfiguration) Value() []byte { 186 b, err := json.Marshal(ncfg) 187 if err != nil { 188 return nil 189 } 190 return b 191 } 192 193 func (ncfg *networkConfiguration) SetValue(value []byte) error { 194 return json.Unmarshal(value, ncfg) 195 } 196 197 func (ncfg *networkConfiguration) Index() uint64 { 198 return ncfg.dbIndex 199 } 200 201 func (ncfg *networkConfiguration) SetIndex(index uint64) { 202 ncfg.dbIndex = index 203 ncfg.dbExists = true 204 } 205 206 func (ncfg *networkConfiguration) Exists() bool { 207 return ncfg.dbExists 208 } 209 210 func (ncfg *networkConfiguration) Skip() bool { 211 return false 212 } 213 214 func (ncfg *networkConfiguration) New() datastore.KVObject { 215 return &networkConfiguration{Type: ncfg.Type} 216 } 217 218 func (ncfg *networkConfiguration) CopyTo(o datastore.KVObject) error { 219 dstNcfg := o.(*networkConfiguration) 220 *dstNcfg = *ncfg 221 return nil 222 } 223 224 func (ncfg *networkConfiguration) DataScope() string { 225 return scope.Local 226 } 227 228 func (ep *hnsEndpoint) MarshalJSON() ([]byte, error) { 229 epMap := make(map[string]interface{}) 230 epMap["id"] = ep.id 231 epMap["nid"] = ep.nid 232 epMap["Type"] = ep.Type 233 epMap["profileID"] = ep.profileID 234 epMap["MacAddress"] = ep.macAddress.String() 235 if ep.addr.IP != nil { 236 epMap["Addr"] = ep.addr.String() 237 } 238 if ep.gateway != nil { 239 epMap["gateway"] = ep.gateway.String() 240 } 241 epMap["epOption"] = ep.epOption 242 epMap["epConnectivity"] = ep.epConnectivity 243 epMap["PortMapping"] = ep.portMapping 244 245 return json.Marshal(epMap) 246 } 247 248 func (ep *hnsEndpoint) UnmarshalJSON(b []byte) error { 249 var ( 250 err error 251 epMap map[string]interface{} 252 ) 253 254 if err = json.Unmarshal(b, &epMap); err != nil { 255 return fmt.Errorf("Failed to unmarshal to endpoint: %v", err) 256 } 257 if v, ok := epMap["MacAddress"]; ok { 258 if ep.macAddress, err = net.ParseMAC(v.(string)); err != nil { 259 return types.InternalErrorf("failed to decode endpoint MAC address (%s) after json unmarshal: %v", v.(string), err) 260 } 261 } 262 if v, ok := epMap["Addr"]; ok { 263 if ep.addr, err = types.ParseCIDR(v.(string)); err != nil { 264 log.G(context.TODO()).Warnf("failed to decode endpoint IPv4 address (%s) after json unmarshal: %v", v.(string), err) 265 } 266 } 267 if v, ok := epMap["gateway"]; ok { 268 ep.gateway = net.ParseIP(v.(string)) 269 } 270 ep.id = epMap["id"].(string) 271 ep.Type = epMap["Type"].(string) 272 ep.nid = epMap["nid"].(string) 273 ep.profileID = epMap["profileID"].(string) 274 d, _ := json.Marshal(epMap["epOption"]) 275 if err := json.Unmarshal(d, &ep.epOption); err != nil { 276 log.G(context.TODO()).Warnf("Failed to decode endpoint container config %v", err) 277 } 278 d, _ = json.Marshal(epMap["epConnectivity"]) 279 if err := json.Unmarshal(d, &ep.epConnectivity); err != nil { 280 log.G(context.TODO()).Warnf("Failed to decode endpoint external connectivity configuration %v", err) 281 } 282 d, _ = json.Marshal(epMap["PortMapping"]) 283 if err := json.Unmarshal(d, &ep.portMapping); err != nil { 284 log.G(context.TODO()).Warnf("Failed to decode endpoint port mapping %v", err) 285 } 286 287 return nil 288 } 289 290 func (ep *hnsEndpoint) Key() []string { 291 return []string{windowsEndpointPrefix + ep.Type, ep.id} 292 } 293 294 func (ep *hnsEndpoint) KeyPrefix() []string { 295 return []string{windowsEndpointPrefix + ep.Type} 296 } 297 298 func (ep *hnsEndpoint) Value() []byte { 299 b, err := json.Marshal(ep) 300 if err != nil { 301 return nil 302 } 303 return b 304 } 305 306 func (ep *hnsEndpoint) SetValue(value []byte) error { 307 return json.Unmarshal(value, ep) 308 } 309 310 func (ep *hnsEndpoint) Index() uint64 { 311 return ep.dbIndex 312 } 313 314 func (ep *hnsEndpoint) SetIndex(index uint64) { 315 ep.dbIndex = index 316 ep.dbExists = true 317 } 318 319 func (ep *hnsEndpoint) Exists() bool { 320 return ep.dbExists 321 } 322 323 func (ep *hnsEndpoint) Skip() bool { 324 return false 325 } 326 327 func (ep *hnsEndpoint) New() datastore.KVObject { 328 return &hnsEndpoint{Type: ep.Type} 329 } 330 331 func (ep *hnsEndpoint) CopyTo(o datastore.KVObject) error { 332 dstEp := o.(*hnsEndpoint) 333 *dstEp = *ep 334 return nil 335 } 336 337 func (ep *hnsEndpoint) DataScope() string { 338 return scope.Local 339 }