/* * This file is part of the libvirt-go-module project * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * * Copyright (c) 2013 Alex Zorin * Copyright (C) 2016 Red Hat, Inc. * */ package libvirt /* #cgo !libvirt_dlopen pkg-config: libvirt #cgo libvirt_dlopen LDFLAGS: -ldl #cgo libvirt_dlopen CFLAGS: -DLIBVIRT_DLOPEN #include #include "libvirt_generated.h" */ import "C" import ( "fmt" "reflect" "time" "unsafe" ) type IPAddrType int const ( IP_ADDR_TYPE_IPV4 = IPAddrType(C.VIR_IP_ADDR_TYPE_IPV4) IP_ADDR_TYPE_IPV6 = IPAddrType(C.VIR_IP_ADDR_TYPE_IPV6) ) type NetworkXMLFlags uint const ( NETWORK_XML_INACTIVE = NetworkXMLFlags(C.VIR_NETWORK_XML_INACTIVE) ) type NetworkCreateFlags uint const ( NETWORK_CREATE_VALIDATE = NetworkCreateFlags(C.VIR_NETWORK_CREATE_VALIDATE) ) type NetworkDefineFlags uint const ( NETWORK_DEFINE_VALIDATE = NetworkDefineFlags(C.VIR_NETWORK_DEFINE_VALIDATE) ) type NetworkUpdateCommand int const ( NETWORK_UPDATE_COMMAND_NONE = NetworkUpdateCommand(C.VIR_NETWORK_UPDATE_COMMAND_NONE) NETWORK_UPDATE_COMMAND_MODIFY = NetworkUpdateCommand(C.VIR_NETWORK_UPDATE_COMMAND_MODIFY) NETWORK_UPDATE_COMMAND_DELETE = NetworkUpdateCommand(C.VIR_NETWORK_UPDATE_COMMAND_DELETE) NETWORK_UPDATE_COMMAND_ADD_LAST = NetworkUpdateCommand(C.VIR_NETWORK_UPDATE_COMMAND_ADD_LAST) NETWORK_UPDATE_COMMAND_ADD_FIRST = NetworkUpdateCommand(C.VIR_NETWORK_UPDATE_COMMAND_ADD_FIRST) ) type NetworkUpdateSection int const ( NETWORK_SECTION_NONE = NetworkUpdateSection(C.VIR_NETWORK_SECTION_NONE) NETWORK_SECTION_BRIDGE = NetworkUpdateSection(C.VIR_NETWORK_SECTION_BRIDGE) NETWORK_SECTION_DOMAIN = NetworkUpdateSection(C.VIR_NETWORK_SECTION_DOMAIN) NETWORK_SECTION_IP = NetworkUpdateSection(C.VIR_NETWORK_SECTION_IP) NETWORK_SECTION_IP_DHCP_HOST = NetworkUpdateSection(C.VIR_NETWORK_SECTION_IP_DHCP_HOST) NETWORK_SECTION_IP_DHCP_RANGE = NetworkUpdateSection(C.VIR_NETWORK_SECTION_IP_DHCP_RANGE) NETWORK_SECTION_FORWARD = NetworkUpdateSection(C.VIR_NETWORK_SECTION_FORWARD) NETWORK_SECTION_FORWARD_INTERFACE = NetworkUpdateSection(C.VIR_NETWORK_SECTION_FORWARD_INTERFACE) NETWORK_SECTION_FORWARD_PF = NetworkUpdateSection(C.VIR_NETWORK_SECTION_FORWARD_PF) NETWORK_SECTION_PORTGROUP = NetworkUpdateSection(C.VIR_NETWORK_SECTION_PORTGROUP) NETWORK_SECTION_DNS_HOST = NetworkUpdateSection(C.VIR_NETWORK_SECTION_DNS_HOST) NETWORK_SECTION_DNS_TXT = NetworkUpdateSection(C.VIR_NETWORK_SECTION_DNS_TXT) NETWORK_SECTION_DNS_SRV = NetworkUpdateSection(C.VIR_NETWORK_SECTION_DNS_SRV) ) type NetworkUpdateFlags uint const ( NETWORK_UPDATE_AFFECT_CURRENT = NetworkUpdateFlags(C.VIR_NETWORK_UPDATE_AFFECT_CURRENT) NETWORK_UPDATE_AFFECT_LIVE = NetworkUpdateFlags(C.VIR_NETWORK_UPDATE_AFFECT_LIVE) NETWORK_UPDATE_AFFECT_CONFIG = NetworkUpdateFlags(C.VIR_NETWORK_UPDATE_AFFECT_CONFIG) ) type NetworkEventLifecycleType int const ( NETWORK_EVENT_DEFINED = NetworkEventLifecycleType(C.VIR_NETWORK_EVENT_DEFINED) NETWORK_EVENT_UNDEFINED = NetworkEventLifecycleType(C.VIR_NETWORK_EVENT_UNDEFINED) NETWORK_EVENT_STARTED = NetworkEventLifecycleType(C.VIR_NETWORK_EVENT_STARTED) NETWORK_EVENT_STOPPED = NetworkEventLifecycleType(C.VIR_NETWORK_EVENT_STOPPED) ) type NetworkEventID int const ( NETWORK_EVENT_ID_LIFECYCLE = NetworkEventID(C.VIR_NETWORK_EVENT_ID_LIFECYCLE) NETWORK_EVENT_ID_METADATA_CHANGE = NetworkEventID(C.VIR_NETWORK_EVENT_ID_METADATA_CHANGE) ) type NetworkMetadataType int const ( NETWORK_METADATA_DESCRIPTION = NetworkMetadataType(C.VIR_NETWORK_METADATA_DESCRIPTION) NETWORK_METADATA_TITLE = NetworkMetadataType(C.VIR_NETWORK_METADATA_TITLE) NETWORK_METADATA_ELEMENT = NetworkMetadataType(C.VIR_NETWORK_METADATA_ELEMENT) ) type Network struct { ptr C.virNetworkPtr } type NetworkDHCPLease struct { Iface string ExpiryTime time.Time Type IPAddrType Mac string Iaid string IPaddr string Prefix uint Hostname string Clientid string } // See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetworkFree func (n *Network) Free() error { var err C.virError ret := C.virNetworkFreeWrapper(n.ptr, &err) if ret == -1 { return makeError(&err) } return nil } // See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetworkRef func (c *Network) Ref() error { var err C.virError ret := C.virNetworkRefWrapper(c.ptr, &err) if ret == -1 { return makeError(&err) } return nil } // See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetworkCreate func (n *Network) Create() error { var err C.virError result := C.virNetworkCreateWrapper(n.ptr, &err) if result == -1 { return makeError(&err) } return nil } // See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetworkDestroy func (n *Network) Destroy() error { var err C.virError result := C.virNetworkDestroyWrapper(n.ptr, &err) if result == -1 { return makeError(&err) } return nil } // See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetworkIsActive func (n *Network) IsActive() (bool, error) { var err C.virError result := C.virNetworkIsActiveWrapper(n.ptr, &err) if result == -1 { return false, makeError(&err) } if result == 1 { return true, nil } return false, nil } // See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetworkIsPersistent func (n *Network) IsPersistent() (bool, error) { var err C.virError result := C.virNetworkIsPersistentWrapper(n.ptr, &err) if result == -1 { return false, makeError(&err) } if result == 1 { return true, nil } return false, nil } // See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetworkGetAutostart func (n *Network) GetAutostart() (bool, error) { var out C.int var err C.virError result := C.virNetworkGetAutostartWrapper(n.ptr, (*C.int)(unsafe.Pointer(&out)), &err) if result == -1 { return false, makeError(&err) } switch out { case 1: return true, nil default: return false, nil } } // See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetworkSetAutostart func (n *Network) SetAutostart(autostart bool) error { var cAutostart C.int switch autostart { case true: cAutostart = 1 default: cAutostart = 0 } var err C.virError result := C.virNetworkSetAutostartWrapper(n.ptr, cAutostart, &err) if result == -1 { return makeError(&err) } return nil } // See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetworkGetName func (n *Network) GetName() (string, error) { var err C.virError name := C.virNetworkGetNameWrapper(n.ptr, &err) if name == nil { return "", makeError(&err) } return C.GoString(name), nil } // See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetworkGetUUID func (n *Network) GetUUID() ([]byte, error) { var cUuid [C.VIR_UUID_BUFLEN](byte) cuidPtr := unsafe.Pointer(&cUuid) var err C.virError result := C.virNetworkGetUUIDWrapper(n.ptr, (*C.uchar)(cuidPtr), &err) if result != 0 { return []byte{}, makeError(&err) } return C.GoBytes(cuidPtr, C.VIR_UUID_BUFLEN), nil } // See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetworkGetUUIDString func (n *Network) GetUUIDString() (string, error) { var cUuid [C.VIR_UUID_STRING_BUFLEN](C.char) cuidPtr := unsafe.Pointer(&cUuid) var err C.virError result := C.virNetworkGetUUIDStringWrapper(n.ptr, (*C.char)(cuidPtr), &err) if result != 0 { return "", makeError(&err) } return C.GoString((*C.char)(cuidPtr)), nil } // See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetworkGetBridgeName func (n *Network) GetBridgeName() (string, error) { var err C.virError result := C.virNetworkGetBridgeNameWrapper(n.ptr, &err) if result == nil { return "", makeError(&err) } bridge := C.GoString(result) C.free(unsafe.Pointer(result)) return bridge, nil } // See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetworkGetXMLDesc func (n *Network) GetXMLDesc(flags NetworkXMLFlags) (string, error) { var err C.virError result := C.virNetworkGetXMLDescWrapper(n.ptr, C.uint(flags), &err) if result == nil { return "", makeError(&err) } xml := C.GoString(result) C.free(unsafe.Pointer(result)) return xml, nil } // See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetworkUndefine func (n *Network) Undefine() error { var err C.virError result := C.virNetworkUndefineWrapper(n.ptr, &err) if result == -1 { return makeError(&err) } return nil } // See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetworkUpdate func (n *Network) Update(cmd NetworkUpdateCommand, section NetworkUpdateSection, parentIndex int, xml string, flags NetworkUpdateFlags) error { cxml := C.CString(xml) defer C.free(unsafe.Pointer(cxml)) var err C.virError result := C.virNetworkUpdateWrapper(n.ptr, C.uint(cmd), C.uint(section), C.int(parentIndex), cxml, C.uint(flags), &err) if result == -1 { return makeError(&err) } return nil } // See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetworkGetDHCPLeases func (n *Network) GetDHCPLeases() ([]NetworkDHCPLease, error) { var cLeases *C.virNetworkDHCPLeasePtr var err C.virError numLeases := C.virNetworkGetDHCPLeasesWrapper(n.ptr, nil, (**C.virNetworkDHCPLeasePtr)(&cLeases), C.uint(0), &err) if numLeases == -1 { return nil, makeError(&err) } hdr := reflect.SliceHeader{ Data: uintptr(unsafe.Pointer(cLeases)), Len: int(numLeases), Cap: int(numLeases), } var leases []NetworkDHCPLease slice := *(*[]C.virNetworkDHCPLeasePtr)(unsafe.Pointer(&hdr)) for _, clease := range slice { leases = append(leases, NetworkDHCPLease{ Iface: C.GoString(clease.iface), ExpiryTime: time.Unix(int64(clease.expirytime), 0), Type: IPAddrType(clease._type), Mac: C.GoString(clease.mac), Iaid: C.GoString(clease.iaid), IPaddr: C.GoString(clease.ipaddr), Prefix: uint(clease.prefix), Hostname: C.GoString(clease.hostname), Clientid: C.GoString(clease.clientid), }) C.virNetworkDHCPLeaseFreeWrapper(clease) } C.free(unsafe.Pointer(cLeases)) return leases, nil } // See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetworkPortLookupByUUIDString func (n *Network) LookupNetworkPortByUUIDString(uuid string) (*NetworkPort, error) { cUuid := C.CString(uuid) defer C.free(unsafe.Pointer(cUuid)) var err C.virError ptr := C.virNetworkPortLookupByUUIDStringWrapper(n.ptr, cUuid, &err) if ptr == nil { return nil, makeError(&err) } return &NetworkPort{ptr: ptr}, nil } // See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetworkPortLookupByUUID func (n *Network) LookupNetworkPortByUUID(uuid []byte) (*NetworkPort, error) { if len(uuid) != C.VIR_UUID_BUFLEN { return nil, fmt.Errorf("UUID must be exactly %d bytes in size", int(C.VIR_UUID_BUFLEN)) } cUuid := make([]C.uchar, C.VIR_UUID_BUFLEN) for i := 0; i < C.VIR_UUID_BUFLEN; i++ { cUuid[i] = C.uchar(uuid[i]) } var err C.virError ptr := C.virNetworkPortLookupByUUIDWrapper(n.ptr, &cUuid[0], &err) if ptr == nil { return nil, makeError(&err) } return &NetworkPort{ptr: ptr}, nil } // See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetworkPortCreateXML func (n *Network) PortCreateXML(xmlConfig string, flags uint32) (*NetworkPort, error) { cXml := C.CString(string(xmlConfig)) defer C.free(unsafe.Pointer(cXml)) var err C.virError ptr := C.virNetworkPortCreateXMLWrapper(n.ptr, cXml, C.uint(flags), &err) if ptr == nil { return nil, makeError(&err) } return &NetworkPort{ptr: ptr}, nil } // See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetworkListAllPorts func (n *Network) ListAllPorts(flags uint32) ([]NetworkPort, error) { var cList *C.virNetworkPortPtr var err C.virError numPorts := C.virNetworkListAllPortsWrapper(n.ptr, (**C.virNetworkPortPtr)(&cList), C.uint(flags), &err) if numPorts == -1 { return []NetworkPort{}, makeError(&err) } hdr := reflect.SliceHeader{ Data: uintptr(unsafe.Pointer(cList)), Len: int(numPorts), Cap: int(numPorts), } var ports []NetworkPort slice := *(*[]C.virNetworkPortPtr)(unsafe.Pointer(&hdr)) for _, ptr := range slice { ports = append(ports, NetworkPort{ptr}) } C.free(unsafe.Pointer(cList)) return ports, nil } // See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetworkGetMetadata func (n *Network) GetMetadata(metadataType NetworkMetadataType, uri string, flags NetworkUpdateFlags) (string, error) { var cUri *C.char if uri != "" { cUri = C.CString(uri) defer C.free(unsafe.Pointer(cUri)) } var err C.virError result := C.virNetworkGetMetadataWrapper(n.ptr, C.int(metadataType), cUri, C.uint(flags), &err) if result == nil { return "", makeError(&err) } defer C.free(unsafe.Pointer(result)) return C.GoString(result), nil } // See also https://libvirt.org/html/libvirt-libvirt-network.html#virNetworkSetMetadata func (n *Network) SetMetadata(metadataType NetworkMetadataType, metaDataCont, uriKey, uri string, flags NetworkUpdateFlags) error { var cMetaDataCont *C.char var cUriKey *C.char var cUri *C.char if metaDataCont != "" { cMetaDataCont = C.CString(metaDataCont) defer C.free(unsafe.Pointer(cMetaDataCont)) } if metadataType == NETWORK_METADATA_ELEMENT { if uriKey != "" { cUriKey = C.CString(uriKey) defer C.free(unsafe.Pointer(cUriKey)) } cUri = C.CString(uri) defer C.free(unsafe.Pointer(cUri)) } var err C.virError result := C.virNetworkSetMetadataWrapper(n.ptr, C.int(metadataType), cMetaDataCont, cUriKey, cUri, C.uint(flags), &err) if result == -1 { return makeError(&err) } return nil }