GetLxcInterfaces retrieves network interface information for an LXC container.
(vm *VM)
| 157 | |
| 158 | // GetLxcInterfaces retrieves network interface information for an LXC container. |
| 159 | func (c *Client) GetLxcInterfaces(vm *VM) ([]NetworkInterface, error) { |
| 160 | if vm.Type != VMTypeLXC || vm.Status != VMStatusRunning { |
| 161 | return nil, fmt.Errorf("network interface endpoint not applicable for this guest type or status") |
| 162 | } |
| 163 | |
| 164 | var apiResponse map[string]interface{} |
| 165 | |
| 166 | endpoint := fmt.Sprintf("/nodes/%s/lxc/%d/interfaces", vm.Node, vm.ID) |
| 167 | |
| 168 | if err := c.GetWithCache(endpoint, &apiResponse, VMDataTTL); err != nil { |
| 169 | // Based on previous handling, API might return 500 if feature not available or container stopped. |
| 170 | // Treat this as "no interfaces found" rather than a hard error for GetVmStatus. |
| 171 | c.logger.Debug("Failed to get LXC interfaces for VM %d on node %s (may be expected): %v", vm.ID, vm.Node, err) |
| 172 | |
| 173 | return nil, nil |
| 174 | } |
| 175 | |
| 176 | responseData, ok := apiResponse["data"].([]interface{}) |
| 177 | if !ok { |
| 178 | // It's possible this specific endpoint returns the array directly without a "data" wrapper. |
| 179 | // Let's try to type assert apiResponse itself to []interface{}. This is unusual for Proxmox API. |
| 180 | // config.DebugLog("LXC interfaces: 'data' key not found or not an array. Full response: %+v", apiResponse) |
| 181 | // This part is tricky. If the user-provided example `[{"hwaddr":...}]` is accurate for the *entire* response body, |
| 182 | // then `c.Get` which expects `*map[string]interface{}` will fail to unmarshal it directly. |
| 183 | // The user's confidence in `c.Get` working suggests the API *does* conform, or their example was just the *value* of the "data" field. |
| 184 | // For now, assuming the standard `{"data": [...]}` structure based on other working code. |
| 185 | // If it still fails, this is where the GetRaw approach or direct HTTP call would be needed if the endpoint is truly different. |
| 186 | return nil, fmt.Errorf("unexpected response format for LXC interfaces: 'data' field missing or not an array. VM: %d, Node: %s", vm.ID, vm.Node) |
| 187 | } |
| 188 | |
| 189 | var interfaces []NetworkInterface |
| 190 | |
| 191 | for _, ifaceDataItem := range responseData { |
| 192 | ifaceMap, ok := ifaceDataItem.(map[string]interface{}) |
| 193 | if !ok { |
| 194 | c.logger.Debug("LXC interface item is not a map[string]interface{}: %+v", ifaceDataItem) |
| 195 | |
| 196 | continue |
| 197 | } |
| 198 | |
| 199 | netInterface := NetworkInterface{} |
| 200 | if name, ok := ifaceMap["name"].(string); ok { |
| 201 | netInterface.Name = name |
| 202 | netInterface.IsLoopback = (name == "lo") |
| 203 | } |
| 204 | |
| 205 | if hwaddr, ok := ifaceMap["hwaddr"].(string); ok { |
| 206 | netInterface.MACAddress = hwaddr |
| 207 | } |
| 208 | |
| 209 | var ipAddresses []IPAddress |
| 210 | |
| 211 | if inet, ok := ifaceMap["inet"].(string); ok { |
| 212 | if ip, valid := parseIPCIDR(inet, IPTypeIPv4); valid { |
| 213 | ipAddresses = append(ipAddresses, ip) |
| 214 | } |
| 215 | } |
| 216 |
no test coverage detected