summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/rest.c243
-rw-r--r--src/rest.h2
-rw-r--r--src/schema.c35
3 files changed, 280 insertions, 0 deletions
diff --git a/src/rest.c b/src/rest.c
index 32cf757..8563fd2 100644
--- a/src/rest.c
+++ b/src/rest.c
@@ -3895,6 +3895,230 @@ static int og_cmd_delete_image(json_t *element, struct og_msg_params *params)
return 0;
}
+struct og_scope_image {
+ struct list_head list;
+ uint32_t id;
+};
+
+static void og_scope_image_list_free(struct list_head *scope_list)
+{
+ struct og_scope_image *scope, *next;
+
+ list_for_each_entry_safe(scope, next, scope_list, list) {
+ list_del(&scope->list);
+ free(scope);
+ }
+}
+
+static int og_json_parse_scope_image_list(json_t *element, struct list_head *scope_list)
+{
+ struct og_scope_image *scope;
+ unsigned int i;
+ json_t *k;
+
+ if (json_typeof(element) != JSON_ARRAY)
+ return -1;
+
+ for (i = 0; i < json_array_size(element); i++) {
+ k = json_array_get(element, i);
+ if (json_typeof(k) != JSON_INTEGER)
+ goto err_out;
+
+ scope = calloc(1, sizeof(struct og_scope_image));
+ if (!scope)
+ goto err_out;
+
+ scope->id = json_integer_value(k);
+
+ list_add_tail(&scope->list, scope_list);
+ }
+
+ return 0;
+err_out:
+ og_scope_image_list_free(scope_list);
+ return -1;
+}
+
+enum {
+ OG_ATTR_IMAGE_ID = (1 << 0),
+ OG_ATTR_IMAGE_SCOPE_ID = (1 << 0),
+};
+
+static int og_cmd_image_scope_update(json_t *element, struct og_msg_params *params)
+{
+ struct og_scope_image *scope;
+ LIST_HEAD(scope_list);
+ struct og_dbi *dbi;
+ const char *msglog;
+ uint32_t image_id;
+ dbi_result result;
+ const char *key;
+ json_t *value;
+ int err = 0;
+
+ if (json_typeof(element) != JSON_OBJECT)
+ return -1;
+
+ json_object_foreach(element, key, value) {
+ if (!strcmp(key, "image")) {
+ err = og_json_parse_uint(value, &image_id);
+ params->flags |= OG_ATTR_IMAGE_ID;
+ } else if (!strcmp(key, "scopes")) {
+ err = og_json_parse_scope_image_list(value, &scope_list);
+ if (err >= 0 && !list_empty(&scope_list))
+ params->flags |= OG_ATTR_IMAGE_SCOPE_ID;
+ }
+
+ if (err < 0)
+ return err;
+ }
+
+ if (!og_msg_params_validate(params, OG_ATTR_IMAGE_ID |
+ OG_ATTR_IMAGE_SCOPE_ID)) {
+ og_scope_image_list_free(&scope_list);
+ return -1;
+ }
+
+ dbi = og_dbi_open(&ogconfig.db);
+ if (!dbi) {
+ syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
+ __func__, __LINE__);
+ og_scope_image_list_free(&scope_list);
+ return -1;
+ }
+
+ result = dbi_conn_queryf(dbi->conn,
+ "DELETE FROM image_scope WHERE image_id=%d",
+ image_id);
+ if (!result) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ goto err_out;
+ }
+ dbi_result_free(result);
+
+ list_for_each_entry(scope, &scope_list, list) {
+ result = dbi_conn_queryf(dbi->conn,
+ "INSERT INTO image_scope (image_id, scope_id) "
+ "VALUES (%d, %d)", image_id, scope->id);
+ if (!result) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ goto err_out;
+ }
+ dbi_result_free(result);
+ }
+
+ og_dbi_close(dbi);
+
+ og_scope_image_list_free(&scope_list);
+
+ return 0;
+
+err_out:
+ og_scope_image_list_free(&scope_list);
+ og_dbi_close(dbi);
+
+ return -1;
+}
+
+static json_t *og_json_image_scope(struct og_dbi *dbi, uint32_t image_id)
+{
+ json_t *scope_image, *scope_array;
+ const char *msglog;
+ uint32_t scope_id;
+ dbi_result result;
+
+ result = dbi_conn_queryf(dbi->conn,
+ "SELECT scope_id FROM image_scope WHERE image_id = '%u'", image_id);
+ if (!result) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_ERR, "failed to query database (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ return NULL;
+ }
+
+ scope_image = json_object();
+ if (!scope_image) {
+ dbi_result_free(result);
+ return NULL;
+ }
+
+ json_object_set_new(scope_image, "id", json_integer(image_id));
+
+ scope_array = json_array();
+ if (!scope_array) {
+ json_decref(scope_image);
+ dbi_result_free(result);
+ return NULL;
+ }
+
+ while (dbi_result_next_row(result)) {
+ scope_id = dbi_result_get_uint(result, "scope_id");
+ json_array_append_new(scope_array, json_integer(scope_id));
+ }
+ dbi_result_free(result);
+
+ json_object_set_new(scope_image, "scopes", scope_array);
+
+ return scope_image;
+}
+
+static int og_cmd_image_scope_list(json_t *element,
+ struct og_msg_params *params,
+ char *buffer_reply)
+{
+ struct og_buffer og_buffer = {
+ .data = buffer_reply
+ };
+ json_t *value, *scope_image;
+ struct og_dbi *dbi;
+ uint32_t image_id;
+ const char *key;
+ int err = 0;
+
+ if (json_typeof(element) != JSON_OBJECT)
+ return -1;
+
+ json_object_foreach(element, key, value) {
+ if (!strcmp(key, "image")) {
+ err = og_json_parse_uint(value, &image_id);
+ params->flags |= OG_ATTR_IMAGE_ID;
+ }
+
+ if (err < 0)
+ return err;
+ }
+
+ if (!og_msg_params_validate(params, OG_ATTR_IMAGE_ID))
+ return -1;
+
+ dbi = og_dbi_open(&ogconfig.db);
+ if (!dbi) {
+ syslog(LOG_ERR, "cannot open connection database (%s:%d)\n",
+ __func__, __LINE__);
+ return -1;
+ }
+
+ scope_image = og_json_image_scope(dbi, image_id);
+
+ og_dbi_close(dbi);
+
+ if (!scope_image)
+ return -1;
+
+ if (json_dump_callback(scope_image, og_json_dump_clients, &og_buffer, 0)) {
+ json_decref(scope_image);
+ return -1;
+ }
+
+ json_decref(scope_image);
+
+ return 0;
+}
+
static int og_dbi_client_cache_get(struct og_dbi *dbi, json_t *clients, const char *ip)
{
const char *img_name, *msglog, *img_checksum;
@@ -7934,6 +8158,7 @@ struct {
[OG_URI_IMAGE_UPDATE] = { "image/update" },
[OG_URI_IMAGE_RESTORE] = { "image/restore", },
[OG_URI_IMAGE_DELETE] = { "image/delete", },
+ [OG_URI_IMAGE_RESTRICT] = { "image/restrict", },
[OG_URI_CACHE_LIST] = { "cache/list", },
[OG_URI_CACHE_DELETE] = { "cache/delete", },
[OG_URI_PART_SETUP] = { "setup", },
@@ -8530,6 +8755,24 @@ int og_client_state_process_payload_rest(struct og_client *cli)
goto err_process_rest_payload;
}
err = og_cmd_delete_image(root, &params);
+ } else if (!strncmp(cmd, "image/restrict", strlen("image/restrict"))) {
+ if (!root) {
+ err = og_client_bad_request(cli);
+ goto err_process_rest_payload;
+ }
+
+ switch (method) {
+ case OG_METHOD_GET:
+ err = og_cmd_image_scope_list(root, &params, buf_reply);
+ break;
+ case OG_METHOD_POST:
+ err = og_cmd_image_scope_update(root, &params);
+ break;
+ default:
+ err = og_client_method_not_found(cli);
+ goto err_process_rest_payload;
+ }
+
} else if (!strncmp(cmd, "cache/list", strlen("cache/list"))) {
if (method != OG_METHOD_GET) {
err = og_client_method_not_found(cli);
diff --git a/src/rest.h b/src/rest.h
index f70af75..61169fe 100644
--- a/src/rest.h
+++ b/src/rest.h
@@ -37,6 +37,7 @@ enum og_cmd_type {
OG_CMD_IMAGE_CREATE,
OG_CMD_IMAGE_UPDATE,
OG_CMD_IMAGE_RESTORE,
+ OG_CMD_IMAGE_RESTRICT,
OG_CMD_SETUP,
OG_CMD_RUN_SCHEDULE,
OG_CMD_IMAGES,
@@ -124,6 +125,7 @@ enum og_rest_uri {
OG_URI_IMAGE_UPDATE,
OG_URI_IMAGE_RESTORE,
OG_URI_IMAGE_DELETE,
+ OG_URI_IMAGE_RESTRICT,
OG_URI_CACHE_LIST,
OG_URI_CACHE_DELETE,
OG_URI_PART_SETUP,
diff --git a/src/schema.c b/src/schema.c
index 002fd56..7390e27 100644
--- a/src/schema.c
+++ b/src/schema.c
@@ -335,6 +335,40 @@ static int og_dbi_schema_v7(struct og_dbi *dbi)
return 0;
}
+static int og_dbi_schema_v8(struct og_dbi *dbi)
+{
+ const char *msglog;
+ dbi_result result;
+
+ syslog(LOG_DEBUG, "Creating table image_scope\n");
+ result = dbi_conn_query(dbi->conn, "CREATE TABLE `image_scope` ("
+ "`id` int NOT NULL AUTO_INCREMENT,"
+ "`image_id` int NOT NULL,"
+ "`scope_id` int NOT NULL,"
+ "PRIMARY KEY (`id`),"
+ "FOREIGN KEY (`image_id`) REFERENCES `imagenes` (`idimagen`) ON DELETE CASCADE,"
+ "FOREIGN KEY (`scope_id`) REFERENCES `centros` (`idcentro`) ON DELETE CASCADE"
+ ") AUTO_INCREMENT=1;");
+ if (!result) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_INFO, "Error when creating image_scope (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ return -1;
+ }
+ dbi_result_free(result);
+
+ result = dbi_conn_query(dbi->conn, "UPDATE version SET version = 8");
+ if (!result) {
+ dbi_conn_error(dbi->conn, &msglog);
+ syslog(LOG_INFO, "Could not update version row (%s:%d) %s\n",
+ __func__, __LINE__, msglog);
+ return -1;
+ }
+ dbi_result_free(result);
+
+ return 0;
+}
+
static struct og_schema_version {
int version;
int (*update)(struct og_dbi *dbi);
@@ -346,6 +380,7 @@ static struct og_schema_version {
{ .version = 5, .update = og_dbi_schema_v5 },
{ .version = 6, .update = og_dbi_schema_v6 },
{ .version = 7, .update = og_dbi_schema_v7, },
+ { .version = 8, .update = og_dbi_schema_v8, },
{ 0, NULL },
};