cli: move pre-check for setting connection:secondaries out of nm-meta-setting-desc.c

This check requires additional information about the environment, that
is about the present connections in NMClient.

"nm-meta-setting-desc.c" should be independent from the libnm D-Bus
cache, hence move this code to "settings.c".
This commit is contained in:
Thomas Haller 2017-03-30 17:26:17 +02:00
parent 2379af7e36
commit cecee19b2b
2 changed files with 104 additions and 72 deletions

View file

@ -530,6 +530,64 @@ nmc_setting_custom_init (NMSetting *setting)
/*****************************************************************************/
static gboolean
_set_fcn_precheck_connection_secondaries (const char *value,
char **value_coerced,
GError **error)
{
const GPtrArray *connections;
NMConnection *con;
gs_strfreev char **strv = NULL;
char **iter;
gboolean modified;
strv = nmc_strsplit_set (value, " \t,", 0);
if (!strv)
return TRUE;
connections = nm_client_get_connections (nm_cli.client);
for (iter = strv; *iter; iter++) {
if (nm_utils_is_uuid (*iter)) {
con = nmc_find_connection (connections, "uuid", *iter, NULL, FALSE);
if (!con){
g_print (_("Warning: %s is not an UUID of any existing connection profile\n"),
*iter);
} else {
/* Currenly NM only supports VPN connections as secondaries */
if (!nm_connection_is_type (con, NM_SETTING_VPN_SETTING_NAME)) {
g_set_error (error, 1, 0, _("'%s' is not a VPN connection profile"), *iter);
return FALSE;
}
}
} else {
con = nmc_find_connection (connections, "id", *iter, NULL, FALSE);
if (!con) {
g_set_error (error, 1, 0, _("'%s' is not a name of any exiting profile"), *iter);
return FALSE;
}
/* Currenly NM only supports VPN connections as secondaries */
if (!nm_connection_is_type (con, NM_SETTING_VPN_SETTING_NAME)) {
g_set_error (error, 1, 0, _("'%s' is not a VPN connection profile"), *iter);
return FALSE;
}
/* translate id to uuid */
g_free (*iter);
*iter = g_strdup (nm_connection_get_uuid (con));
modified = TRUE;
}
}
if (modified)
*value_coerced = g_strjoinv (" ", strv);
return TRUE;
}
/*****************************************************************************/
static void
_env_warn_fcn_handle (const NMMetaEnvironment *environment,
gpointer environment_user_data,
@ -609,6 +667,22 @@ nmc_setting_get_property_parsable (NMSetting *setting, const char *prop, GError
return get_property_val (setting, prop, NM_META_ACCESSOR_GET_TYPE_PARSABLE, TRUE, error);
}
static gboolean
_set_fcn_call (const NMMetaSettingInfoEditor *setting_info,
const NMMetaPropertyInfo *property_info,
NMSetting *setting,
const char *value,
GError **error)
{
return property_info->property_type->set_fcn (&meta_environment,
NULL,
setting_info,
property_info,
setting,
value,
error);
}
/*
* Generic function for setting property value.
*
@ -638,13 +712,29 @@ nmc_setting_set_property (NMSetting *setting, const char *prop, const char *valu
/* Traditionally, the "name" property was not handled here.
* For the moment, skip it from get_property_val(). */
} else if (property_info->property_type->set_fcn) {
return property_info->property_type->set_fcn (&meta_environment,
NULL,
setting_info,
property_info,
setting,
value,
error);
switch (setting_info->general->meta_type) {
case NM_META_SETTING_TYPE_CONNECTION:
if (nm_streq (property_info->property_name, NM_SETTING_CONNECTION_SECONDARIES)) {
gs_free char *value_coerced = NULL;
if (!_set_fcn_precheck_connection_secondaries (value, &value_coerced, error))
return FALSE;
return _set_fcn_call (setting_info,
property_info,
setting,
value_coerced ?: value,
error);
}
break;
default:
break;
}
return _set_fcn_call (setting_info,
property_info,
setting,
value,
error);
}
}

View file

@ -27,29 +27,12 @@
#include "nm-common-macros.h"
#include "nm-utils/nm-enum-utils.h"
#include "NetworkManager.h"
#include "nm-vpn-helpers.h"
#include "nm-client-utils.h"
/*****************************************************************************/
/* FIXME: don't include headers from nmcli. And move all uses of NMClient out
* of there. */
/* FIXME: don't directly print any warnings. Instead, add a hook mechanism to notify
* the caller about warnings, error or whatever.
*/
#include "nmcli.h"
NMConnection *
nmc_find_connection (const GPtrArray *connections,
const char *filter_type,
const char *filter_val,
int *start,
gboolean complete);
/*****************************************************************************/
static gboolean validate_int (NMSetting *setting, const char* prop, gint val, GError **error);
static gboolean validate_uint (NMSetting *setting, const char* prop, guint val, GError **error);
static gboolean validate_int64 (NMSetting *setting, const char* prop, gint64 val, GError **error);
@ -2230,57 +2213,16 @@ _set_fcn_connection_master (ARGS_SET_FCN)
static gboolean
_set_fcn_connection_secondaries (ARGS_SET_FCN)
{
const GPtrArray *connections;
NMConnection *con;
char **strv = NULL, **iter;
guint i = 0;
gs_strfreev char **strv = NULL;
char **iter;
connections = nm_client_get_connections (nm_cli.client);
strv = nmc_strsplit_set (value, " \t,", 0);
for (iter = strv; iter && *iter; iter++) {
if (**iter == '\0')
continue;
if (nm_utils_is_uuid (*iter)) {
con = nmc_find_connection (connections, "uuid", *iter, NULL, FALSE);
if (!con){
_env_warn_fcn (environment, environment_user_data,
NM_META_ENV_WARN_LEVEL_WARN,
N_ ("%s is not an UUID of any existing connection profile"),
*iter);
} else {
/* Currenly NM only supports VPN connections as secondaries */
if (!nm_connection_is_type (con, NM_SETTING_VPN_SETTING_NAME)) {
g_set_error (error, 1, 0, _("'%s' is not a VPN connection profile"), *iter);
g_strfreev (strv);
return FALSE;
}
}
} else {
con = nmc_find_connection (connections, "id", *iter, NULL, FALSE);
if (!con) {
g_set_error (error, 1, 0, _("'%s' is not a name of any exiting profile"), *iter);
g_strfreev (strv);
return FALSE;
}
/* Currenly NM only supports VPN connections as secondaries */
if (!nm_connection_is_type (con, NM_SETTING_VPN_SETTING_NAME)) {
g_set_error (error, 1, 0, _("'%s' is not a VPN connection profile"), *iter);
g_strfreev (strv);
return FALSE;
}
/* translate id to uuid */
g_free (*iter);
*iter = g_strdup (nm_connection_get_uuid (con));
if (strv) {
for (iter = strv; *iter; iter++) {
if (**iter)
nm_setting_connection_add_secondary (NM_SETTING_CONNECTION (setting), *iter);
}
}
while (strv && strv[i])
nm_setting_connection_add_secondary (NM_SETTING_CONNECTION (setting), strv[i++]);
g_strfreev (strv);
return TRUE;
}