secret: add support for value change events

Emit an event whenever a secret value changes

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
Daniel P. Berrange 2017-01-05 13:51:07 +00:00
parent d6398c869c
commit 42241208d9
10 changed files with 190 additions and 1 deletions

View File

@ -1528,8 +1528,37 @@ remoteRelaySecretEventLifecycle(virConnectPtr conn,
return 0;
}
static int
remoteRelaySecretEventValueChanged(virConnectPtr conn,
virSecretPtr secret,
void *opaque)
{
daemonClientEventCallbackPtr callback = opaque;
remote_secret_event_value_changed_msg data;
if (callback->callbackID < 0 ||
!remoteRelaySecretEventCheckACL(callback->client, conn, secret))
return -1;
VIR_DEBUG("Relaying node secret value changed callback %d",
callback->callbackID);
/* build return data */
memset(&data, 0, sizeof(data));
make_nonnull_secret(&data.secret, secret);
data.callbackID = callback->callbackID;
remoteDispatchObjectEventSend(callback->client, remoteProgram,
REMOTE_PROC_SECRET_EVENT_VALUE_CHANGED,
(xdrproc_t)xdr_remote_secret_event_value_changed_msg,
&data);
return 0;
}
static virConnectSecretEventGenericCallback secretEventCallbacks[] = {
VIR_SECRET_EVENT_CALLBACK(remoteRelaySecretEventLifecycle),
VIR_SECRET_EVENT_CALLBACK(remoteRelaySecretEventValueChanged),
};
verify(ARRAY_CARDINALITY(secretEventCallbacks) == VIR_SECRET_EVENT_ID_LAST);

View File

@ -763,6 +763,18 @@ mySecretEventCallback(virConnectPtr conn ATTRIBUTE_UNUSED,
}
static int
mySecretEventValueChanged(virConnectPtr conn ATTRIBUTE_UNUSED,
virSecretPtr secret,
void *opaque ATTRIBUTE_UNUSED)
{
char uuid[VIR_UUID_STRING_BUFLEN];
virSecretGetUUIDString(secret, uuid);
printf("%s EVENT: Secret %s\n", __func__, uuid);
return 0;
}
static void
eventTypedParamsPrint(virTypedParameterPtr params,
int nparams)
@ -1085,6 +1097,7 @@ struct secretEventData {
struct secretEventData secretEvents[] = {
SECRET_EVENT(VIR_SECRET_EVENT_ID_LIFECYCLE, mySecretEventCallback),
SECRET_EVENT(VIR_SECRET_EVENT_ID_VALUE_CHANGED, mySecretEventValueChanged),
};
/* make sure that the events are kept in sync */

View File

@ -127,6 +127,7 @@ int virSecretFree (virSecretPtr secret);
*/
typedef enum {
VIR_SECRET_EVENT_ID_LIFECYCLE = 0, /* virConnectSecretEventLifecycleCallback */
VIR_SECRET_EVENT_ID_VALUE_CHANGED = 1, /* virConnectSecretEventGenericCallback */
# ifdef VIR_ENUM_SENTINELS
VIR_SECRET_EVENT_ID_LAST

View File

@ -48,10 +48,19 @@ struct _virSecretEventLifecycle {
typedef struct _virSecretEventLifecycle virSecretEventLifecycle;
typedef virSecretEventLifecycle *virSecretEventLifecyclePtr;
struct _virSecretEventValueChanged {
virSecretEvent parent;
bool dummy;
};
typedef struct _virSecretEventValueChanged virSecretEventValueChanged;
typedef virSecretEventValueChanged *virSecretEventValueChangedPtr;
static virClassPtr virSecretEventClass;
static virClassPtr virSecretEventLifecycleClass;
static virClassPtr virSecretEventValueChangedClass;
static void virSecretEventDispose(void *obj);
static void virSecretEventLifecycleDispose(void *obj);
static void virSecretEventValueChangedDispose(void *obj);
static int
virSecretEventsOnceInit(void)
@ -68,6 +77,12 @@ virSecretEventsOnceInit(void)
sizeof(virSecretEventLifecycle),
virSecretEventLifecycleDispose)))
return -1;
if (!(virSecretEventValueChangedClass =
virClassNew(virSecretEventClass,
"virSecretEventValueChanged",
sizeof(virSecretEventValueChanged),
virSecretEventValueChangedDispose)))
return -1;
return 0;
}
@ -89,6 +104,14 @@ virSecretEventLifecycleDispose(void *obj)
}
static void
virSecretEventValueChangedDispose(void *obj)
{
virSecretEventValueChangedPtr event = obj;
VIR_DEBUG("obj=%p", event);
}
static void
virSecretEventDispatchDefaultFunc(virConnectPtr conn,
virObjectEventPtr event,
@ -116,6 +139,13 @@ virSecretEventDispatchDefaultFunc(virConnectPtr conn,
goto cleanup;
}
case VIR_SECRET_EVENT_ID_VALUE_CHANGED:
{
((virConnectSecretEventGenericCallback)cb)(conn, secret,
cbopaque);
goto cleanup;
}
case VIR_SECRET_EVENT_ID_LAST:
break;
}
@ -250,3 +280,32 @@ virSecretEventLifecycleNew(const unsigned char *uuid,
return (virObjectEventPtr)event;
}
/**
* virSecretEventValueChangedNew:
* @uuid: UUID of the secret object the event describes
*
* Create a new secret lifecycle event.
*/
virObjectEventPtr
virSecretEventValueChangedNew(const unsigned char *uuid,
int usage_type,
const char *usage_id)
{
virSecretEventValueChangedPtr event;
char uuidstr[VIR_UUID_STRING_BUFLEN];
if (virSecretEventsInitialize() < 0)
return NULL;
virUUIDFormat(uuid, uuidstr);
VIR_DEBUG("Event %s %d %s", uuidstr, usage_type, usage_id);
if (!(event = virObjectEventNew(virSecretEventValueChangedClass,
virSecretEventDispatchDefaultFunc,
VIR_SECRET_EVENT_ID_VALUE_CHANGED,
usage_type, usage_id, uuid, uuidstr)))
return NULL;
return (virObjectEventPtr)event;
}

View File

@ -57,5 +57,9 @@ virSecretEventLifecycleNew(const unsigned char *uuid,
const char *usage_id,
int type,
int detail);
virObjectEventPtr
virSecretEventValueChangedNew(const unsigned char *uuid,
int usage_type,
const char *usage_id);
#endif

View File

@ -845,6 +845,7 @@ virSecretUsageTypeToString;
# conf/secret_event.h
virSecretEventLifecycleNew;
virSecretEventStateRegisterID;
virSecretEventValueChangedNew;
# conf/snapshot_conf.h

View File

@ -390,6 +390,11 @@ remoteSecretBuildEventLifecycle(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
virNetClientPtr client ATTRIBUTE_UNUSED,
void *evdata, void *opaque);
static void
remoteSecretBuildEventValueChanged(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
virNetClientPtr client ATTRIBUTE_UNUSED,
void *evdata, void *opaque);
static void
remoteConnectNotifyEventConnectionClosed(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
virNetClientPtr client ATTRIBUTE_UNUSED,
@ -593,6 +598,10 @@ static virNetClientProgramEvent remoteEvents[] = {
remoteSecretBuildEventLifecycle,
sizeof(remote_secret_event_lifecycle_msg),
(xdrproc_t)xdr_remote_secret_event_lifecycle_msg },
{ REMOTE_PROC_SECRET_EVENT_VALUE_CHANGED,
remoteSecretBuildEventValueChanged,
sizeof(remote_secret_event_value_changed_msg),
(xdrproc_t)xdr_remote_secret_event_value_changed_msg },
};
static void
@ -5516,6 +5525,27 @@ remoteSecretBuildEventLifecycle(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
remoteEventQueue(priv, event, msg->callbackID);
}
static void
remoteSecretBuildEventValueChanged(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
virNetClientPtr client ATTRIBUTE_UNUSED,
void *evdata, void *opaque)
{
virConnectPtr conn = opaque;
struct private_data *priv = conn->privateData;
remote_secret_event_value_changed_msg *msg = evdata;
virSecretPtr secret;
virObjectEventPtr event = NULL;
secret = get_nonnull_secret(conn, msg->secret);
if (!secret)
return;
event = virSecretEventValueChangedNew(secret->uuid, secret->usageType, secret->usageID);
virObjectUnref(secret);
remoteEventQueue(priv, event, msg->callbackID);
}
static void
remoteDomainBuildQemuMonitorEvent(virNetClientProgramPtr prog ATTRIBUTE_UNUSED,
virNetClientPtr client ATTRIBUTE_UNUSED,

View File

@ -3381,6 +3381,11 @@ struct remote_secret_event_lifecycle_msg {
int detail;
};
struct remote_secret_event_value_changed_msg {
int callbackID;
remote_nonnull_secret secret;
};
/*----- Protocol. -----*/
/* Define the program number, protocol version and procedure numbers here. */
@ -6007,6 +6012,12 @@ enum remote_procedure {
* @generate: both
* @acl: none
*/
REMOTE_PROC_SECRET_EVENT_LIFECYCLE = 382
REMOTE_PROC_SECRET_EVENT_LIFECYCLE = 382,
/**
* @generate: both
* @acl: none
*/
REMOTE_PROC_SECRET_EVENT_VALUE_CHANGED = 383
};

View File

@ -327,6 +327,7 @@ secretSetValue(virSecretPtr obj,
int ret = -1;
virSecretObjPtr secret;
virSecretDefPtr def;
virObjectEventPtr event = NULL;
virCheckFlags(0, -1);
@ -343,10 +344,15 @@ secretSetValue(virSecretPtr obj,
if (virSecretObjSetValue(secret, value, value_size) < 0)
goto cleanup;
event = virSecretEventValueChangedNew(def->uuid,
def->usage_type,
def->usage_id);
ret = 0;
cleanup:
virSecretObjEndAPI(&secret);
if (event)
virObjectEventStateQueue(driver->secretEventState, event);
return ret;
}

View File

@ -614,9 +614,44 @@ vshEventLifecyclePrint(virConnectPtr conn ATTRIBUTE_UNUSED,
vshEventDone(data->ctl);
}
static void
vshEventGenericPrint(virConnectPtr conn ATTRIBUTE_UNUSED,
virSecretPtr secret,
void *opaque)
{
virshSecretEventData *data = opaque;
char uuid[VIR_UUID_STRING_BUFLEN];
if (!data->loop && data->count)
return;
virSecretGetUUIDString(secret, uuid);
if (data->timestamp) {
char timestamp[VIR_TIME_STRING_BUFLEN];
if (virTimeStringNowRaw(timestamp) < 0)
timestamp[0] = '\0';
vshPrint(data->ctl, _("%s: event '%s' for secret %s\n"),
timestamp,
data->cb->name,
uuid);
} else {
vshPrint(data->ctl, _("event '%s' for secret %s\n"),
data->cb->name,
uuid);
}
data->count++;
if (!data->loop)
vshEventDone(data->ctl);
}
static vshEventCallback vshEventCallbacks[] = {
{ "lifecycle",
VIR_SECRET_EVENT_CALLBACK(vshEventLifecyclePrint), },
{ "value-changed", vshEventGenericPrint, },
};
static const vshCmdInfo info_secret_event[] = {