mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-05 14:38:09 +02:00
nmcli: improve setting connection.secondaries property
- check if the values being set are existing connections - also allow specifying connections by names, translating them transparently to UUIDs. - nmcli-specific section for 'describe' command added (We use a global nm_cli variable in nmc_property_connection_set_secondaries())
This commit is contained in:
parent
ab0c37d042
commit
645f0204f9
5 changed files with 130 additions and 69 deletions
|
|
@ -951,3 +951,69 @@ nmc_team_check_config (const char *config, char **out_config, GError **error)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* nmc_find_connection:
|
||||
* @list: list of NMConnections to search in
|
||||
* @filter_type: "id", "uuid", "path" or %NULL
|
||||
* @filter_val: connection to find (connection name, UUID or path)
|
||||
* @start: where to start in @list. The location is updated so that the function
|
||||
* can be called multiple times (for connections with the same name).
|
||||
*
|
||||
* Find a connection in @list according to @filter_val. @filter_type determines
|
||||
* what property is used for comparison. When @filter_type is NULL, compare
|
||||
* @filter_val against all types. Otherwise, only compare against the specified
|
||||
* type. If 'path' filter type is specified, comparison against numeric index
|
||||
* (in addition to the whole path) is allowed.
|
||||
*
|
||||
* Returns: found connection, or %NULL
|
||||
*/
|
||||
NMConnection *
|
||||
nmc_find_connection (GSList *list,
|
||||
const char *filter_type,
|
||||
const char *filter_val,
|
||||
GSList **start)
|
||||
{
|
||||
NMConnection *connection;
|
||||
NMConnection *found = NULL;
|
||||
GSList *iterator;
|
||||
const char *id;
|
||||
const char *uuid;
|
||||
const char *path, *path_num;
|
||||
|
||||
iterator = (start && *start) ? *start : list;
|
||||
while (iterator) {
|
||||
connection = NM_CONNECTION (iterator->data);
|
||||
|
||||
id = nm_connection_get_id (connection);
|
||||
uuid = nm_connection_get_uuid (connection);
|
||||
path = nm_connection_get_path (connection);
|
||||
path_num = path ? strrchr (path, '/') + 1 : NULL;
|
||||
|
||||
/* When filter_type is NULL, compare connection ID (filter_val)
|
||||
* against all types. Otherwise, only compare against the specific
|
||||
* type. If 'path' filter type is specified, comparison against
|
||||
* numeric index (in addition to the whole path) is allowed.
|
||||
*/
|
||||
if ( ( (!filter_type || strcmp (filter_type, "id") == 0)
|
||||
&& strcmp (filter_val, id) == 0)
|
||||
|| ( (!filter_type || strcmp (filter_type, "uuid") == 0)
|
||||
&& strcmp (filter_val, uuid) == 0)
|
||||
|| ( (!filter_type || strcmp (filter_type, "path") == 0)
|
||||
&& (g_strcmp0 (filter_val, path) == 0 || (filter_type && g_strcmp0 (filter_val, path_num) == 0)))) {
|
||||
if (!start)
|
||||
return connection;
|
||||
if (found) {
|
||||
*start = iterator;
|
||||
return found;
|
||||
}
|
||||
found = connection;
|
||||
}
|
||||
|
||||
iterator = g_slist_next (iterator);
|
||||
}
|
||||
|
||||
if (start)
|
||||
*start = NULL;
|
||||
return found;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* (C) Copyright 2012 - 2013 Red Hat, Inc.
|
||||
* (C) Copyright 2012 - 2014 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef NMC_COMMON_H
|
||||
|
|
@ -54,4 +54,9 @@ nmc_vlan_parse_priority_maps (const char *priority_map,
|
|||
const char *nmc_bond_validate_mode (const char *mode, GError **error);
|
||||
gboolean nmc_team_check_config (const char *config, char **out_config, GError **error);
|
||||
|
||||
NMConnection *nmc_find_connection (GSList *list,
|
||||
const char *filter_type,
|
||||
const char *filter_val,
|
||||
GSList **start);
|
||||
|
||||
#endif /* NMC_COMMON_H */
|
||||
|
|
|
|||
|
|
@ -702,56 +702,6 @@ nmc_connection_profile_details (NMConnection *connection, NmCli *nmc)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static NMConnection *
|
||||
find_connection (GSList *list,
|
||||
const char *filter_type,
|
||||
const char *filter_val,
|
||||
GSList **start)
|
||||
{
|
||||
NMConnection *connection;
|
||||
NMConnection *found = NULL;
|
||||
GSList *iterator;
|
||||
const char *id;
|
||||
const char *uuid;
|
||||
const char *path, *path_num;
|
||||
|
||||
iterator = (start && *start) ? *start : list;
|
||||
while (iterator) {
|
||||
connection = NM_CONNECTION (iterator->data);
|
||||
|
||||
id = nm_connection_get_id (connection);
|
||||
uuid = nm_connection_get_uuid (connection);
|
||||
path = nm_connection_get_path (connection);
|
||||
path_num = path ? strrchr (path, '/') + 1 : NULL;
|
||||
|
||||
/* When filter_type is NULL, compare connection ID (filter_val)
|
||||
* against all types. Otherwise, only compare against the specific
|
||||
* type. If 'path' filter type is specified, comparison against
|
||||
* numeric index (in addition to the whole path) is allowed.
|
||||
*/
|
||||
if ( ( (!filter_type || strcmp (filter_type, "id") == 0)
|
||||
&& strcmp (filter_val, id) == 0)
|
||||
|| ( (!filter_type || strcmp (filter_type, "uuid") == 0)
|
||||
&& strcmp (filter_val, uuid) == 0)
|
||||
|| ( (!filter_type || strcmp (filter_type, "path") == 0)
|
||||
&& (g_strcmp0 (filter_val, path) == 0 || (filter_type && g_strcmp0 (filter_val, path_num) == 0)))) {
|
||||
if (!start)
|
||||
return connection;
|
||||
if (found) {
|
||||
*start = iterator;
|
||||
return found;
|
||||
}
|
||||
found = connection;
|
||||
}
|
||||
|
||||
iterator = g_slist_next (iterator);
|
||||
}
|
||||
|
||||
if (start)
|
||||
*start = NULL;
|
||||
return found;
|
||||
}
|
||||
|
||||
static NMActiveConnection *
|
||||
find_active_connection (const GPtrArray *active_cons,
|
||||
const GSList *cons,
|
||||
|
|
@ -1405,7 +1355,7 @@ do_connections_show (NmCli *nmc, gboolean active_only, int argc, char **argv)
|
|||
}
|
||||
|
||||
/* Find connection by id, uuid, path or apath */
|
||||
con = find_connection (nmc->system_connections, selector, *argv, &pos);
|
||||
con = nmc_find_connection (nmc->system_connections, selector, *argv, &pos);
|
||||
if (!con) {
|
||||
acon = find_active_connection (active_cons, nmc->system_connections, selector, *argv, NULL);
|
||||
if (acon)
|
||||
|
|
@ -2012,7 +1962,7 @@ do_connection_up (NmCli *nmc, int argc, char **argv)
|
|||
}
|
||||
|
||||
if (name)
|
||||
connection = find_connection (nmc->system_connections, selector, name, NULL);
|
||||
connection = nmc_find_connection (nmc->system_connections, selector, name, NULL);
|
||||
|
||||
while (argc > 0) {
|
||||
if (strcmp (*argv, "ifname") == 0) {
|
||||
|
|
@ -7812,7 +7762,7 @@ do_connection_edit (NmCli *nmc, int argc, char **argv)
|
|||
/* Existing connection */
|
||||
NMConnection *found_con;
|
||||
|
||||
found_con = find_connection (nmc->system_connections, selector, con, NULL);
|
||||
found_con = nmc_find_connection (nmc->system_connections, selector, con, NULL);
|
||||
if (!found_con) {
|
||||
g_string_printf (nmc->return_text, _("Error: Unknown connection '%s'."), con);
|
||||
nmc->return_value = NMC_RESULT_ERROR_NOT_FOUND;
|
||||
|
|
@ -8002,7 +7952,7 @@ do_connection_modify (NmCli *nmc,
|
|||
nmc->return_value = NMC_RESULT_ERROR_USER_INPUT;
|
||||
goto finish;
|
||||
}
|
||||
connection = find_connection (nmc->system_connections, selector, name, NULL);
|
||||
connection = nmc_find_connection (nmc->system_connections, selector, name, NULL);
|
||||
if (!connection) {
|
||||
g_string_printf (nmc->return_text, _("Error: Unknown connection '%s'."), name);
|
||||
nmc->return_value = NMC_RESULT_ERROR_NOT_FOUND;
|
||||
|
|
@ -8218,7 +8168,7 @@ do_connection_delete (NmCli *nmc, int argc, char **argv)
|
|||
}
|
||||
}
|
||||
|
||||
connection = find_connection (nmc->system_connections, selector, *arg_ptr, &pos);
|
||||
connection = nmc_find_connection (nmc->system_connections, selector, *arg_ptr, &pos);
|
||||
if (!connection) {
|
||||
if (nmc->print_output != NMC_PRINT_TERSE)
|
||||
printf (_("Error: unknown connection: %s\n"), *arg_ptr);
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* (C) Copyright 2010 - 2012 Red Hat, Inc.
|
||||
* (C) Copyright 2010 - 2014 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
/* Generated configuration file */
|
||||
|
|
@ -47,6 +47,10 @@
|
|||
# define NMCLI_VERSION VERSION
|
||||
#endif
|
||||
|
||||
/* Global NmCli object */
|
||||
// FIXME: Currently, we pass NmCli over in most APIs, but we might refactor
|
||||
// that and use the global variable directly instead.
|
||||
NmCli nm_cli;
|
||||
|
||||
typedef struct {
|
||||
NmCli *nmc;
|
||||
|
|
@ -406,8 +410,7 @@ start (gpointer data)
|
|||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
NmCli nmc;
|
||||
ArgsInfo args_info = { &nmc, argc, argv };
|
||||
ArgsInfo args_info = { &nm_cli, argc, argv };
|
||||
|
||||
/* Set up unix signal handling */
|
||||
if (!setup_signals ())
|
||||
|
|
@ -425,19 +428,19 @@ main (int argc, char *argv[])
|
|||
|
||||
g_type_init ();
|
||||
|
||||
nmc_init (&nmc);
|
||||
nmc_init (&nm_cli);
|
||||
g_idle_add (start, &args_info);
|
||||
|
||||
loop = g_main_loop_new (NULL, FALSE); /* create main loop */
|
||||
g_main_loop_run (loop); /* run main loop */
|
||||
|
||||
/* Print result descripting text */
|
||||
if (nmc.return_value != NMC_RESULT_SUCCESS) {
|
||||
fprintf (stderr, "%s\n", nmc.return_text->str);
|
||||
if (nm_cli.return_value != NMC_RESULT_SUCCESS) {
|
||||
fprintf (stderr, "%s\n", nm_cli.return_text->str);
|
||||
}
|
||||
|
||||
g_main_loop_unref (loop);
|
||||
nmc_cleanup (&nmc);
|
||||
nmc_cleanup (&nm_cli);
|
||||
|
||||
return nmc.return_value;
|
||||
return nm_cli.return_value;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1587,6 +1587,13 @@ typedef struct {
|
|||
NmcPropertyOut2InFunc out2in_func; /* func converting property values from output to input format */
|
||||
} NmcPropertyFuncs;
|
||||
|
||||
/*
|
||||
* We need NmCli in some _set_property functions, and they aren't passed NmCli.
|
||||
* So use the global variable.
|
||||
*/
|
||||
/* Global variable defined in nmcli.c */
|
||||
extern NmCli nm_cli;
|
||||
|
||||
NMSetting *
|
||||
nmc_setting_new_for_name (const char *name)
|
||||
{
|
||||
|
|
@ -2446,15 +2453,34 @@ DEFINE_ALLOWED_VAL_FUNC (nmc_property_con_allowed_slave_type, con_valid_slave_ty
|
|||
static gboolean
|
||||
nmc_property_connection_set_secondaries (NMSetting *setting, const char *prop, const char *val, GError **error)
|
||||
{
|
||||
char **strv = NULL;
|
||||
NMConnection *con;
|
||||
char **strv = NULL, **iter;
|
||||
guint i = 0;
|
||||
|
||||
g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
|
||||
|
||||
strv = nmc_strsplit_set (val, " \t,", 0);
|
||||
if (!verify_string_list (strv, prop, nm_utils_is_uuid, error)) {
|
||||
g_strfreev (strv);
|
||||
return FALSE;
|
||||
for (iter = strv; iter && *iter; iter++) {
|
||||
if (**iter == '\0')
|
||||
continue;
|
||||
|
||||
if (nm_utils_is_uuid (*iter)) {
|
||||
con = nmc_find_connection (nm_cli.system_connections,
|
||||
"uuid", *iter, NULL);
|
||||
if (!con)
|
||||
printf (_("Warning: %s is not an UUID of any existing connection profile\n"), *iter);
|
||||
} else {
|
||||
con = nmc_find_connection (nm_cli.system_connections,
|
||||
"id", *iter, NULL);
|
||||
if (!con) {
|
||||
g_set_error (error, 1, 0, _("'%s' is not a name of any exiting profile"), *iter);
|
||||
g_strfreev (strv);
|
||||
return FALSE;
|
||||
}
|
||||
/* translate id to uuid */
|
||||
g_free (*iter);
|
||||
*iter = g_strdup (nm_connection_get_uuid (con));
|
||||
}
|
||||
}
|
||||
|
||||
while (strv && strv[i])
|
||||
|
|
@ -2489,6 +2515,17 @@ DEFINE_REMOVER_INDEX_OR_VALUE (nmc_property_connection_remove_secondaries,
|
|||
nm_setting_connection_remove_secondary,
|
||||
_validate_and_remove_connection_secondary)
|
||||
|
||||
static const char *
|
||||
nmc_property_connection_describe_secondaries (NMSetting *setting, const char *prop)
|
||||
{
|
||||
return _("Enter secondary connections that should be activated when this connection is\n"
|
||||
"activated. Connections can be specified either by UUID or ID (name). nmcli\n"
|
||||
"transparently translates names to UUIDs. Note that NetworkManager only supports\n"
|
||||
"VPNs as secondary connections at the moment.\n"
|
||||
"The items can be separated by commas or spaces.\n\n"
|
||||
"Example: private-openvpn, fe6ba5d8-c2fc-4aae-b2e3-97efddd8d9a7\n");
|
||||
}
|
||||
|
||||
/* --- NM_SETTING_802_1X_SETTING_NAME property setter functions --- */
|
||||
#define DEFINE_SETTER_STR_LIST(def_func, set_func) \
|
||||
static gboolean \
|
||||
|
|
@ -5051,7 +5088,7 @@ nmc_properties_init (void)
|
|||
nmc_property_connection_get_secondaries,
|
||||
nmc_property_connection_set_secondaries,
|
||||
nmc_property_connection_remove_secondaries,
|
||||
NULL,
|
||||
nmc_property_connection_describe_secondaries,
|
||||
NULL,
|
||||
NULL);
|
||||
nmc_add_prop_funcs (GLUE (CONNECTION, GATEWAY_PING_TIMEOUT),
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue