1 /*
2  * virsh-completer-network.c: virsh completer callbacks related to networks
3  *
4  * Copyright (C) 2019 Red Hat, Inc.
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library.  If not, see
18  * <http://www.gnu.org/licenses/>.
19  */
20 
21 #include <config.h>
22 
23 #include "virsh-completer-network.h"
24 #include "virsh-util.h"
25 #include "viralloc.h"
26 #include "virsh-network.h"
27 #include "virsh.h"
28 #include "virstring.h"
29 
30 char **
virshNetworkNameCompleter(vshControl * ctl,const vshCmd * cmd G_GNUC_UNUSED,unsigned int flags)31 virshNetworkNameCompleter(vshControl *ctl,
32                           const vshCmd *cmd G_GNUC_UNUSED,
33                           unsigned int flags)
34 {
35     virshControl *priv = ctl->privData;
36     virNetworkPtr *nets = NULL;
37     int nnets = 0;
38     size_t i = 0;
39     char **ret = NULL;
40     g_auto(GStrv) tmp = NULL;
41 
42     virCheckFlags(VIR_CONNECT_LIST_NETWORKS_INACTIVE |
43                   VIR_CONNECT_LIST_NETWORKS_ACTIVE |
44                   VIR_CONNECT_LIST_NETWORKS_PERSISTENT,
45                   NULL);
46 
47     if (!priv->conn || virConnectIsAlive(priv->conn) <= 0)
48         return NULL;
49 
50     if ((nnets = virConnectListAllNetworks(priv->conn, &nets, flags)) < 0)
51         return NULL;
52 
53     tmp = g_new0(char *, nnets + 1);
54 
55     for (i = 0; i < nnets; i++) {
56         const char *name = virNetworkGetName(nets[i]);
57 
58         tmp[i] = g_strdup(name);
59     }
60 
61     ret = g_steal_pointer(&tmp);
62 
63     for (i = 0; i < nnets; i++)
64         virshNetworkFree(nets[i]);
65     g_free(nets);
66     return ret;
67 }
68 
69 
70 char **
virshNetworkEventNameCompleter(vshControl * ctl G_GNUC_UNUSED,const vshCmd * cmd G_GNUC_UNUSED,unsigned int flags)71 virshNetworkEventNameCompleter(vshControl *ctl G_GNUC_UNUSED,
72                                const vshCmd *cmd G_GNUC_UNUSED,
73                                unsigned int flags)
74 {
75     size_t i = 0;
76     g_auto(GStrv) tmp = NULL;
77 
78     virCheckFlags(0, NULL);
79 
80     tmp = g_new0(char *, VIR_NETWORK_EVENT_ID_LAST + 1);
81 
82     for (i = 0; i < VIR_NETWORK_EVENT_ID_LAST; i++)
83         tmp[i] = g_strdup(virshNetworkEventCallbacks[i].name);
84 
85     return g_steal_pointer(&tmp);
86 }
87 
88 
89 char **
virshNetworkPortUUIDCompleter(vshControl * ctl,const vshCmd * cmd G_GNUC_UNUSED,unsigned int flags)90 virshNetworkPortUUIDCompleter(vshControl *ctl,
91                               const vshCmd *cmd G_GNUC_UNUSED,
92                               unsigned int flags)
93 {
94     virshControl *priv = ctl->privData;
95     virNetworkPtr net = NULL;
96     virNetworkPortPtr *ports = NULL;
97     int nports = 0;
98     size_t i = 0;
99     char **ret = NULL;
100 
101     virCheckFlags(0, NULL);
102 
103     if (!priv->conn || virConnectIsAlive(priv->conn) <= 0)
104         return NULL;
105 
106     if (!(net = virshCommandOptNetwork(ctl, cmd, NULL)))
107         return NULL;
108 
109     if ((nports = virNetworkListAllPorts(net, &ports, flags)) < 0)
110         return NULL;
111 
112     ret = g_new0(char *, nports + 1);
113 
114     for (i = 0; i < nports; i++) {
115         char uuid[VIR_UUID_STRING_BUFLEN];
116 
117         if (virNetworkPortGetUUIDString(ports[i], uuid) < 0)
118             goto error;
119 
120         ret[i] = g_strdup(uuid);
121 
122         virNetworkPortFree(ports[i]);
123     }
124     g_free(ports);
125 
126     return ret;
127 
128  error:
129     for (; i < nports; i++)
130         virNetworkPortFree(ports[i]);
131     g_free(ports);
132     for (i = 0; i < nports; i++)
133         g_free(ret[i]);
134     g_free(ret);
135     return NULL;
136 }
137 
138 
139 char **
virshNetworkUUIDCompleter(vshControl * ctl,const vshCmd * cmd G_GNUC_UNUSED,unsigned int flags)140 virshNetworkUUIDCompleter(vshControl *ctl,
141                           const vshCmd *cmd G_GNUC_UNUSED,
142                           unsigned int flags)
143 {
144     virshControl *priv = ctl->privData;
145     virNetworkPtr *nets = NULL;
146     int nnets = 0;
147     size_t i = 0;
148     char **ret = NULL;
149     g_auto(GStrv) tmp = NULL;
150 
151     virCheckFlags(0, NULL);
152 
153     if (!priv->conn || virConnectIsAlive(priv->conn) <= 0)
154         return NULL;
155 
156     if ((nnets = virConnectListAllNetworks(priv->conn, &nets, flags)) < 0)
157         return NULL;
158 
159     tmp = g_new0(char *, nnets + 1);
160 
161     for (i = 0; i < nnets; i++) {
162         char uuid[VIR_UUID_STRING_BUFLEN];
163 
164         if (virNetworkGetUUIDString(nets[i], uuid) < 0)
165             goto cleanup;
166 
167         tmp[i] = g_strdup(uuid);
168     }
169 
170     ret = g_steal_pointer(&tmp);
171 
172  cleanup:
173     for (i = 0; i < nnets; i++)
174         virshNetworkFree(nets[i]);
175     g_free(nets);
176     return ret;
177 }
178 
179 
180 char **
virshNetworkDhcpMacCompleter(vshControl * ctl,const vshCmd * cmd,unsigned int flags)181 virshNetworkDhcpMacCompleter(vshControl *ctl,
182                              const vshCmd *cmd,
183                              unsigned int flags)
184 {
185     virshControl *priv = ctl->privData;
186     virNetworkDHCPLeasePtr *leases = NULL;
187     g_autoptr(virshNetwork) network = NULL;
188     int nleases;
189     size_t i = 0;
190     char **ret = NULL;
191     g_auto(GStrv) tmp = NULL;
192 
193     virCheckFlags(0, NULL);
194 
195     if (!priv->conn || virConnectIsAlive(priv->conn) <= 0)
196         return NULL;
197 
198     if (!(network = virshCommandOptNetwork(ctl, cmd, NULL)))
199         return NULL;
200 
201     if ((nleases = virNetworkGetDHCPLeases(network, NULL, &leases, flags)) < 0)
202         goto cleanup;
203 
204     tmp = g_new0(char *, nleases + 1);
205 
206     for (i = 0; i < nleases; i++) {
207         virNetworkDHCPLeasePtr lease = leases[i];
208         tmp[i] = g_strdup(lease->mac);
209     }
210 
211     ret = g_steal_pointer(&tmp);
212 
213  cleanup:
214     if (leases) {
215         for (i = 0; i < nleases; i++)
216             virNetworkDHCPLeaseFree(leases[i]);
217         VIR_FREE(leases);
218     }
219     return ret;
220 }
221