From 358831c18fcf2937f4bf85a55fa0c8bdc802d817 Mon Sep 17 00:00:00 2001
From: John Estabrook <jestabro@vyos.io>
Date: Wed, 1 Dec 2021 13:14:07 -0600
Subject: graphql: T3993: define add/delete system image request

---
 src/services/api/graphql/graphql/directives.py     | 11 +++++++-
 src/services/api/graphql/graphql/mutations.py      | 10 ++++++++
 .../api/graphql/graphql/schema/image.graphql       | 29 ++++++++++++++++++++++
 .../api/graphql/graphql/schema/schema.graphql      |  3 +++
 src/services/api/graphql/recipes/session.py        | 29 +++++++++++++++++++++-
 5 files changed, 80 insertions(+), 2 deletions(-)
 create mode 100644 src/services/api/graphql/graphql/schema/image.graphql

(limited to 'src/services/api')

diff --git a/src/services/api/graphql/graphql/directives.py b/src/services/api/graphql/graphql/directives.py
index 4bc31c6b5..10bc522db 100644
--- a/src/services/api/graphql/graphql/directives.py
+++ b/src/services/api/graphql/graphql/directives.py
@@ -48,7 +48,16 @@ class ShowDirective(VyosDirective):
         super().visit_field_definition(field, object_type,
                                        make_resolver=make_show_resolver)
 
+class ImageDirective(VyosDirective):
+    """
+    Class providing implementation of 'image' directive in schema.
+    """
+    def visit_field_definition(self, field, object_type):
+        super().visit_field_definition(field, object_type,
+                                       make_resolver=make_image_resolver)
+
 directives_dict = {"configure": ConfigureDirective,
                    "showconfig": ShowConfigDirective,
                    "configfile": ConfigFileDirective,
-                   "show": ShowDirective}
+                   "show": ShowDirective,
+                   "image": ImageDirective}
diff --git a/src/services/api/graphql/graphql/mutations.py b/src/services/api/graphql/graphql/mutations.py
index 0ba2cd4bb..8e5aab56d 100644
--- a/src/services/api/graphql/graphql/mutations.py
+++ b/src/services/api/graphql/graphql/mutations.py
@@ -87,3 +87,13 @@ def make_config_file_resolver(mutation_name):
 def make_show_resolver(mutation_name):
     class_name = mutation_name
     return make_resolver(mutation_name, class_name, 'show')
+
+def make_image_resolver(mutation_name):
+    if 'Add' in mutation_name:
+        class_name = mutation_name.replace('Add', '', 1)
+        return make_resolver(mutation_name, class_name, 'add')
+    elif 'Delete' in mutation_name:
+        class_name = mutation_name.replace('Delete', '', 1)
+        return make_resolver(mutation_name, class_name, 'delete')
+    else:
+        raise Exception
diff --git a/src/services/api/graphql/graphql/schema/image.graphql b/src/services/api/graphql/graphql/schema/image.graphql
new file mode 100644
index 000000000..7d1b4f9d0
--- /dev/null
+++ b/src/services/api/graphql/graphql/schema/image.graphql
@@ -0,0 +1,29 @@
+input AddSystemImageInput {
+    location: String!
+}
+
+type AddSystemImage {
+    location: String
+    result: String
+}
+
+type AddSystemImageResult {
+    data: AddSystemImage
+    success: Boolean!
+    errors: [String]
+}
+
+input DeleteSystemImageInput {
+    name: String!
+}
+
+type DeleteSystemImage {
+    name: String
+    result: String
+}
+
+type DeleteSystemImageResult {
+    data: DeleteSystemImage
+    success: Boolean!
+    errors: [String]
+}
diff --git a/src/services/api/graphql/graphql/schema/schema.graphql b/src/services/api/graphql/graphql/schema/schema.graphql
index 375b88cc5..c6899bee6 100644
--- a/src/services/api/graphql/graphql/schema/schema.graphql
+++ b/src/services/api/graphql/graphql/schema/schema.graphql
@@ -11,6 +11,7 @@ directive @configure on FIELD_DEFINITION
 directive @configfile on FIELD_DEFINITION
 directive @show on FIELD_DEFINITION
 directive @showconfig on FIELD_DEFINITION
+directive @image on FIELD_DEFINITION
 
 type Mutation {
     CreateDhcpServer(data: DhcpServerConfigInput) : CreateDhcpServerResult @configure
@@ -22,4 +23,6 @@ type Mutation {
     LoadConfigFile(data: LoadConfigFileInput) : LoadConfigFileResult @configfile
     Show(data: ShowInput) : ShowResult @show
     ShowConfig(data: ShowConfigInput) : ShowConfigResult @showconfig
+    AddSystemImage(data: AddSystemImageInput) : AddSystemImageResult @image
+    DeleteSystemImage(data: DeleteSystemImageInput) : DeleteSystemImageResult @image
 }
diff --git a/src/services/api/graphql/recipes/session.py b/src/services/api/graphql/recipes/session.py
index f8c072b39..5ece78ee6 100644
--- a/src/services/api/graphql/recipes/session.py
+++ b/src/services/api/graphql/recipes/session.py
@@ -7,7 +7,12 @@ from vyos.config import Config
 from vyos.configtree import ConfigTree
 from vyos.template import render
 
-class Session(object):
+class Session:
+    """
+    Wrapper for calling configsession functions based on GraphQL requests.
+    Non-nullable fields in the respective schema allow avoiding a key check
+    in 'data'.
+    """
     def __init__(self, session, data):
         self._session = session
         self._data = data
@@ -94,3 +99,25 @@ class Session(object):
             raise error
 
         return out
+
+    def add(self):
+        session = self._session
+        data = self._data
+
+        try:
+            res = session.install_image(data['location'])
+        except Exception as error:
+            raise error
+
+        return res
+
+    def delete(self):
+        session = self._session
+        data = self._data
+
+        try:
+            res = session.remove_image(data['name'])
+        except Exception as error:
+            raise error
+
+        return res
-- 
cgit v1.2.3