From ca3c79923b2abb9ef25976228219215505502c74 Mon Sep 17 00:00:00 2001 From: Jaime Melis Date: Sun, 10 Feb 2019 17:52:45 +0100 Subject: [PATCH 1/8] Add resources query It also pluralizes the top-level queries. --- assets/schema.yml | 20 +++++++---- src/db.ts | 66 +++++++++++++++++++++++++++++++----- src/schema.ts | 26 +++++++++++--- test/schemas/cluster.test.ts | 4 +-- test/server.test.ts | 2 +- 5 files changed, 95 insertions(+), 23 deletions(-) diff --git a/assets/schema.yml b/assets/schema.yml index cc825db..795a0b5 100644 --- a/assets/schema.yml +++ b/assets/schema.yml @@ -1,3 +1,10 @@ +- name: Resource + version: '1' + fields: + - { name: path, type: string, isRequired: true} + - { name: content, type: string, isRequired: true} + - { name: sha256sum, type: string, isRequired: true} + - name: VaultSecret version: '1' fields: @@ -180,9 +187,10 @@ - name: Query fields: - - { name: user, type: User, isList: true, datafileSchema: /access/user-1.yml } - - { name: bot, type: Bot, isList: true, datafileSchema: /access/bot-1.yml } - - { name: role, type: Role, isList: true, datafileSchema: /access/role-1.yml } - - { name: cluster, type: Cluster, isList: true, datafileSchema: /openshift/cluster-1.yml } - - { name: quay_org, type: QuayOrg, isList: true, datafileSchema: /dependencies/quay-org-1.yml } - - { name: app, type: App, isList: true, datafileSchema: /app-sre/app-1.yml } + - { name: users, type: User, isList: true, datafileSchema: /access/user-1.yml } + - { name: bots, type: Bot, isList: true, datafileSchema: /access/bot-1.yml } + - { name: roles, type: Role, isList: true, datafileSchema: /access/role-1.yml } + - { name: clusters, type: Cluster, isList: true, datafileSchema: /openshift/cluster-1.yml } + - { name: quay_orgs, type: QuayOrg, isList: true, datafileSchema: /dependencies/quay-org-1.yml } + - { name: apps, type: App, isList: true, datafileSchema: /app-sre/app-1.yml } + - { name: resources, type: Resource, isResource: true, isRequired: true, isList: true } diff --git a/src/db.ts b/src/db.ts index 986ffca..ca0933f 100644 --- a/src/db.ts +++ b/src/db.ts @@ -11,12 +11,23 @@ interface IDatafile { path: string; } +interface IResource { + path: string; + content: string; + sha256sum: string; +} + interface IDatafilesDict { [key: string]: any; } +interface IResourcesDict { + [key: string]: any; +} + // module variables let datafiles: IDatafilesDict = new Map(); +let resources: IResourcesDict = new Map(); let sha256sum: string = ''; // utils @@ -27,16 +38,11 @@ const getRefExpr = (ref: string): string => { return m ? m[0] : ''; }; -// filters -export function getDatafilesBySchema(schema: string): IDatafile[] { - return Object.values(datafiles).filter((d: any) => d.$schema === schema); -} - export function resolveRef(itemRef: any) { const path = getRefPath(itemRef.$ref); const expr = getRefExpr(itemRef.$ref); - const datafile: any = datafiles[path]; + const datafile: any = datafiles.get(path); if (typeof (datafile) === 'undefined') { console.log(`Error retrieving datafile '${path}'.`); @@ -51,6 +57,20 @@ export function resolveRef(itemRef: any) { return resolvedData; } +// filters +export function getDatafilesBySchema(schema: string): IDatafile[] { + return Object.values(datafiles).filter((d: any) => d.$schema === schema); +} + +export function getResource(path: string): IResource { + return resources[path]; +} + +export function getResources(): IResource[] { + return Object.values(resources); +} + +// loader function validateDatafile(d: any) { const datafilePath: any = d[0]; const datafileData: any = d[1]; @@ -64,17 +84,33 @@ function validateDatafile(d: any) { !('$schema' in datafileData)) { throw new Error('Invalid datafileData object'); } +} + +function validateResource(d: any) { + const resourcePath: string = d[0]; + const resourceData: IResource = d[1]; + if (typeof (resourcePath) !== 'string') { + throw new Error('Expecting string for resourcePath'); + } + + if (typeof (resourceData) !== 'object' || + Object.keys(resourceData).length === 0 || + !('path' in resourceData) || + !('content' in resourceData) || + !('sha256sum' in resourceData)) { + throw new Error('Invalid datafileData object'); + } } // datafile Loading functions function loadUnpack(raw: string) { const dbDatafilesNew: any = {}; - - const bundle = JSON.parse(raw); + const dbResourcesNew: any = {}; const sha256hex = forgeMd.sha256.create().update(raw).digest().toHex(); + const bundle = JSON.parse(raw); - Object.entries(bundle).forEach((d) => { + Object.entries(bundle.data).forEach((d) => { validateDatafile(d); const datafilePath: string = d[0]; @@ -85,7 +121,19 @@ function loadUnpack(raw: string) { dbDatafilesNew[datafilePath] = datafileData; }); + Object.entries(bundle.resources).forEach((d) => { + validateResource(d); + + const resourcePath: string = d[0]; + const resourceData: any = d[1]; + + resourceData.path = resourcePath; + + dbResourcesNew[resourcePath] = resourceData; + }); + datafiles = dbDatafilesNew; + resources = dbResourcesNew; sha256sum = sha256hex; console.log(`End datafile reload: ${new Date()}`); diff --git a/src/schema.ts b/src/schema.ts index 1885f2f..862d788 100644 --- a/src/schema.ts +++ b/src/schema.ts @@ -132,18 +132,25 @@ const createSchemaType = function (schemaTypes: any, interfaceTypes: any, conf: fieldDef['type'] = t; - // schema if (fieldInfo.datafileSchema) { + // schema fieldDef['resolve'] = () => db.getDatafilesBySchema(fieldInfo.datafileSchema); - } - - // synthetic - if (fieldInfo.synthetic) { + } else if (fieldInfo.synthetic) { + // synthetic fieldDef['resolve'] = (root: any) => resolveSyntheticField( root, fieldInfo.synthetic.schema, fieldInfo.synthetic.subAttr, ); + } else if (fieldInfo.isResource) { + // resource + fieldDef['args'] = { path: { type: GraphQLString } }; + fieldDef['resolve'] = (root: any, args: any) => { + if (args.path) { + return [db.getResource(args.path)]; + } + return db.getResources(); + }; } // return @@ -197,6 +204,15 @@ const jsonType = new GraphQLScalarType({ serialize: JSON.stringify, }); +const resourceType = new GraphQLObjectType({ + name: 'Resource_v1', + fields: { + sha256sum: { type: new GraphQLNonNull(GraphQLString) }, + path: { type: new GraphQLNonNull(GraphQLString) }, + content: { type: new GraphQLNonNull(GraphQLString) }, + }, +}); + export function generateAppSchema(path: string): GraphQLSchema { const schemaData = yaml.safeLoad(fs.readFileSync(path, 'utf8')); diff --git a/test/schemas/cluster.test.ts b/test/schemas/cluster.test.ts index 2fe3434..611a86b 100644 --- a/test/schemas/cluster.test.ts +++ b/test/schemas/cluster.test.ts @@ -7,7 +7,7 @@ import chaiHttp = require('chai-http'); chai.use(chaiHttp); const should = chai.should(); -describe('cluster', () => { +describe('clusters', () => { before(() => { db.loadFromFile('test/schemas/cluster.data.json'); }); @@ -15,7 +15,7 @@ describe('cluster', () => { it('serves a basic graphql query', (done) => { chai.request(server) .get('/graphql') - .query({ query: '{ cluster { name } }' }) + .query({ query: '{ clusters { name } }' }) .end((err, res) => { res.should.have.status(200); res.body.data.cluster[0].name.should.equal('example cluster'); diff --git a/test/server.test.ts b/test/server.test.ts index 464ae09..8bb5a2d 100644 --- a/test/server.test.ts +++ b/test/server.test.ts @@ -50,7 +50,7 @@ describe('server', () => { it('resolves object refs', (done) => { const query = `{ - app { + apps { quayRepos { org { name From 44efed40949c9da1bcd023457caf67a80d67f0e5 Mon Sep 17 00:00:00 2001 From: Jaime Melis Date: Tue, 12 Feb 2019 10:49:59 +0100 Subject: [PATCH 2/8] Create new namespace resource type --- assets/schemas/openshift/cluster-1.yml | 13 --- assets/schemas/openshift/namespace-1.yml | 120 +++++++++++++++++++++++ 2 files changed, 120 insertions(+), 13 deletions(-) create mode 100644 assets/schemas/openshift/namespace-1.yml diff --git a/assets/schemas/openshift/cluster-1.yml b/assets/schemas/openshift/cluster-1.yml index 1d68f92..64d2bee 100644 --- a/assets/schemas/openshift/cluster-1.yml +++ b/assets/schemas/openshift/cluster-1.yml @@ -20,19 +20,6 @@ properties: "$ref": "/common-1.json#/definitions/vaultSecret" description: type: string - managedRoles: - type: array - items: - type: object - additionalProperties: false - properties: - namespace: - type: string - role: - type: string - required: - - namespace - - role required: - "$schema" - labels diff --git a/assets/schemas/openshift/namespace-1.yml b/assets/schemas/openshift/namespace-1.yml new file mode 100644 index 0000000..b7802ea --- /dev/null +++ b/assets/schemas/openshift/namespace-1.yml @@ -0,0 +1,120 @@ +--- +"$schema": /metaschema-1.json +version: '1.0' +type: object + +additionalProperties: false +properties: + "$schema": + type: string + enum: + - /openshift/namespace-1.yml + labels: + "$ref": "/common-1.json#/definitions/labels" + name: + type: string + description: + type: string + cluster: + "$ref": "/common-1.json#/definitions/crossref" + "$schemaRef": "/openshift/cluster-1.yml" + managedRoles: + type: array + items: + type: string + enum: + - view + - edit + - admin + managedResourceTypes: + type: array + items: + type: string + # oc api-resources --verbs=list --no-headers | awk '{print $NF} | sort -u' + enum: + - Alertmanager + - APIService + - AppliedClusterResourceQuota + - BrokerTemplateInstance + - Build + - BuildConfig + - CatalogSource + - CertificateSigningRequest + - ClusterNetwork + - ClusterResourceQuota + - ClusterRole + - ClusterRoleBinding + - ClusterServiceVersion + - ComponentStatus + - ConfigMap + - ControllerRevision + - CronJob + - CustomResourceDefinition + - DaemonSet + - Deployment + - DeploymentConfig + - EgressNetworkPolicy + - Endpoints + - Event + - Group + - HorizontalPodAutoscaler + - HostSubnet + - Identity + - Image + - ImageStream + - ImageStreamTag + - Ingress + - InstallPlan + - Job + - LimitRange + - MutatingWebhookConfiguration + - Namespace + - NetNamespace + - NetworkPolicy + - Node + - NodeMetrics + - OAuthAccessToken + - OAuthAuthorizeToken + - OAuthClient + - OAuthClientAuthorization + - OperatorGroup + - PackageManifest + - PersistentVolume + - PersistentVolumeClaim + - Pod + - PodDisruptionBudget + - PodMetrics + - PodSecurityPolicy + - PodTemplate + - PriorityClass + - Project + - ProjectRequest + - Prometheus + - PrometheusRule + - RangeAllocation + - ReplicaSet + - ReplicationController + - ResourceQuota + - Role + - RoleBinding + - RoleBindingRestriction + - Route + - Secret + - SecurityContextConstraints + - Service + - ServiceAccount + - ServiceMonitor + - StatefulSet + - StorageClass + - Subscription + - Template + - TemplateInstance + - User + - ValidatingWebhookConfiguration + - VolumeAttachment +required: +- "$schema" +- labels +- name +- description +- cluster From e53d2283f3d45395d734c7893ac5a71fb962a477 Mon Sep 17 00:00:00 2001 From: Jaime Melis Date: Tue, 12 Feb 2019 11:03:59 +0100 Subject: [PATCH 3/8] typo --- assets/schemas/openshift/namespace-1.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/schemas/openshift/namespace-1.yml b/assets/schemas/openshift/namespace-1.yml index b7802ea..2162ec7 100644 --- a/assets/schemas/openshift/namespace-1.yml +++ b/assets/schemas/openshift/namespace-1.yml @@ -30,7 +30,7 @@ properties: type: array items: type: string - # oc api-resources --verbs=list --no-headers | awk '{print $NF} | sort -u' + # oc api-resources --verbs=list --no-headers | awk '{print $NF}' | sort -u enum: - Alertmanager - APIService From 8d9c8a0756d93c9177cf7b9d48661ab9639ec098 Mon Sep 17 00:00:00 2001 From: Jaime Melis Date: Thu, 14 Feb 2019 10:21:43 +0100 Subject: [PATCH 4/8] WIP --- assets/schema.yml | 45 +++++++++++++++++++++++++++----- assets/schemas/app-sre/app-1.yml | 32 +++++++++++++++++++++++ src/db.ts | 2 +- src/schema.ts | 2 ++ 4 files changed, 73 insertions(+), 8 deletions(-) diff --git a/assets/schema.yml b/assets/schema.yml index 795a0b5..549d6a0 100644 --- a/assets/schema.yml +++ b/assets/schema.yml @@ -23,12 +23,6 @@ - { name: managedTeams, type: string, isList: true, isRequired: true } - { name: automationToken, type: VaultSecret } -- name: ClusterManagedRole - version: '1' - fields: - - { name: namespace, type: string, isRequired: true } - - { name: role, type: string, isRequired: true } - - name: Cluster version: '1' fields: @@ -39,7 +33,18 @@ - { name: description, type: string, isRequired: true } - { name: serverUrl, type: string, isRequired: true } - { name: automationToken, type: VaultSecret } - - { name: managedRoles, type: ClusterManagedRole, isList: true } + +- name: Namespace + version: '1' + fields: + - { name: schema, type: string, isRequired: true } + - { name: path, type: string, isRequired: true } + - { name: labels, type: json } + - { name: name, type: string, isRequired: true } + - { name: description, type: string, isRequired: true } + - { name: cluster, type: Cluster, isRequired: true } + - { name: managedRoles, type: string, isList: true} + - { name: managedResourceTypes, type: string, isList: true} - name: AppServiceOwner version: '1' @@ -77,6 +82,30 @@ - { name: org, type: QuayOrg, isRequired: true } - { name: items, type: AppQuayReposItems, isRequired: true, isList: true } +- name: AppOpenshiftResourcesResource + version: '1' + isInterface: true + interfaceResolve: + strategy: fieldMap + field: provider + fieldMap: + resource: AppOpenshiftResourcesResourceResource + fields: + - { name: provider, type: string, isRequired: true } + +- name: AppOpenshiftResourcesResourceResource + version: '1' + interface: AppOpenshiftResourcesResource + fields: + - { name: provider, type: string, isRequired: true } + - { name: path, type: string, isRequired: true } + +- name: AppOpenshiftResources + version: '1' + fields: + - { name: resource, type: AppOpenshiftResourcesResource, isRequired: true, isInterface: true} + - { name: namespace, type: Namespace, isRequired: true} + - name: App version: '1' fields: @@ -87,6 +116,7 @@ - { name: serviceOwner, type: AppServiceOwner, isRequired: true } - { name: dependencies, type: AppDependencies, isList: true } - { name: quayRepos, type: AppQuayRepos, isList: true } + - { name: openshiftResources, type: AppOpenshiftResources, isList: true } - name: Permission version: '1' @@ -191,6 +221,7 @@ - { name: bots, type: Bot, isList: true, datafileSchema: /access/bot-1.yml } - { name: roles, type: Role, isList: true, datafileSchema: /access/role-1.yml } - { name: clusters, type: Cluster, isList: true, datafileSchema: /openshift/cluster-1.yml } + - { name: namespaces, type: Namespace, isList: true, datafileSchema: /openshift/namespace-1.yml } - { name: quay_orgs, type: QuayOrg, isList: true, datafileSchema: /dependencies/quay-org-1.yml } - { name: apps, type: App, isList: true, datafileSchema: /app-sre/app-1.yml } - { name: resources, type: Resource, isResource: true, isRequired: true, isList: true } diff --git a/assets/schemas/app-sre/app-1.yml b/assets/schemas/app-sre/app-1.yml index 2e4e604..17ce8be 100644 --- a/assets/schemas/app-sre/app-1.yml +++ b/assets/schemas/app-sre/app-1.yml @@ -81,6 +81,38 @@ properties: - SLA - dependencyFailureImpact + openshiftResources: + type: array + items: + type: object + additionalProperties: false + properties: + resource: + type: object + properties: + provider: + type: string + oneOf: + - additionalProperties: false + properties: + provider: + type: string + enum: + - resource + path: + type: string + required: + - provider + - path + required: + - provider + namespace: + "$ref": "/common-1.json#/definitions/crossref" + "$schemaRef": "/openshift/namespace-1.yml" + required: + - resource + - namespace + quayRepos: type: array items: diff --git a/src/db.ts b/src/db.ts index ca0933f..b1cbc05 100644 --- a/src/db.ts +++ b/src/db.ts @@ -42,7 +42,7 @@ export function resolveRef(itemRef: any) { const path = getRefPath(itemRef.$ref); const expr = getRefExpr(itemRef.$ref); - const datafile: any = datafiles.get(path); + const datafile: any = datafiles[path]; if (typeof (datafile) === 'undefined') { console.log(`Error retrieving datafile '${path}'.`); diff --git a/src/schema.ts b/src/schema.ts index 862d788..fe2dafa 100644 --- a/src/schema.ts +++ b/src/schema.ts @@ -219,7 +219,9 @@ export function generateAppSchema(path: string): GraphQLSchema { const schemaTypes: any = {}; const interfaceTypes: any = {}; + schemaData.map((t: any) => createSchemaType(schemaTypes, interfaceTypes, t)); + console.log(interfaceTypes); return new GraphQLSchema({ types: Object.values(schemaTypes), From da6d99bbb71b47ccba868ed90e48156b595fe621 Mon Sep 17 00:00:00 2001 From: Jaime Melis Date: Fri, 15 Feb 2019 13:11:13 +0100 Subject: [PATCH 5/8] move openshiftResources to namespace --- assets/schema.yml | 45 ++++------ assets/schemas/app-sre/app-1.yml | 32 ------- assets/schemas/openshift/namespace-1.yml | 109 +++++++---------------- 3 files changed, 49 insertions(+), 137 deletions(-) diff --git a/assets/schema.yml b/assets/schema.yml index 549d6a0..e2451cf 100644 --- a/assets/schema.yml +++ b/assets/schema.yml @@ -34,6 +34,24 @@ - { name: serverUrl, type: string, isRequired: true } - { name: automationToken, type: VaultSecret } +- name: NamespaceOpenshiftResource + version: '1' + isInterface: true + interfaceResolve: + strategy: fieldMap + field: provider + fieldMap: + resource: NamespaceOpenshiftResourceResource + fields: + - { name: provider, type: string, isRequired: true } + +- name: NamespaceOpenshiftResourceResource + version: '1' + interface: NamespaceOpenshiftResource + fields: + - { name: provider, type: string, isRequired: true } + - { name: path, type: string, isRequired: true } + - name: Namespace version: '1' fields: @@ -45,6 +63,7 @@ - { name: cluster, type: Cluster, isRequired: true } - { name: managedRoles, type: string, isList: true} - { name: managedResourceTypes, type: string, isList: true} + - { name: openshiftResources, type: NamespaceOpenshiftResource, isList: true, isInterface: true} - name: AppServiceOwner version: '1' @@ -82,30 +101,6 @@ - { name: org, type: QuayOrg, isRequired: true } - { name: items, type: AppQuayReposItems, isRequired: true, isList: true } -- name: AppOpenshiftResourcesResource - version: '1' - isInterface: true - interfaceResolve: - strategy: fieldMap - field: provider - fieldMap: - resource: AppOpenshiftResourcesResourceResource - fields: - - { name: provider, type: string, isRequired: true } - -- name: AppOpenshiftResourcesResourceResource - version: '1' - interface: AppOpenshiftResourcesResource - fields: - - { name: provider, type: string, isRequired: true } - - { name: path, type: string, isRequired: true } - -- name: AppOpenshiftResources - version: '1' - fields: - - { name: resource, type: AppOpenshiftResourcesResource, isRequired: true, isInterface: true} - - { name: namespace, type: Namespace, isRequired: true} - - name: App version: '1' fields: @@ -116,7 +111,6 @@ - { name: serviceOwner, type: AppServiceOwner, isRequired: true } - { name: dependencies, type: AppDependencies, isList: true } - { name: quayRepos, type: AppQuayRepos, isList: true } - - { name: openshiftResources, type: AppOpenshiftResources, isList: true } - name: Permission version: '1' @@ -224,4 +218,3 @@ - { name: namespaces, type: Namespace, isList: true, datafileSchema: /openshift/namespace-1.yml } - { name: quay_orgs, type: QuayOrg, isList: true, datafileSchema: /dependencies/quay-org-1.yml } - { name: apps, type: App, isList: true, datafileSchema: /app-sre/app-1.yml } - - { name: resources, type: Resource, isResource: true, isRequired: true, isList: true } diff --git a/assets/schemas/app-sre/app-1.yml b/assets/schemas/app-sre/app-1.yml index 17ce8be..2e4e604 100644 --- a/assets/schemas/app-sre/app-1.yml +++ b/assets/schemas/app-sre/app-1.yml @@ -81,38 +81,6 @@ properties: - SLA - dependencyFailureImpact - openshiftResources: - type: array - items: - type: object - additionalProperties: false - properties: - resource: - type: object - properties: - provider: - type: string - oneOf: - - additionalProperties: false - properties: - provider: - type: string - enum: - - resource - path: - type: string - required: - - provider - - path - required: - - provider - namespace: - "$ref": "/common-1.json#/definitions/crossref" - "$schemaRef": "/openshift/namespace-1.yml" - required: - - resource - - namespace - quayRepos: type: array items: diff --git a/assets/schemas/openshift/namespace-1.yml b/assets/schemas/openshift/namespace-1.yml index 2162ec7..9201856 100644 --- a/assets/schemas/openshift/namespace-1.yml +++ b/assets/schemas/openshift/namespace-1.yml @@ -9,15 +9,20 @@ properties: type: string enum: - /openshift/namespace-1.yml + labels: "$ref": "/common-1.json#/definitions/labels" + name: type: string + description: type: string + cluster: "$ref": "/common-1.json#/definitions/crossref" "$schemaRef": "/openshift/cluster-1.yml" + managedRoles: type: array items: @@ -26,92 +31,38 @@ properties: - view - edit - admin + managedResourceTypes: type: array items: type: string + # For the moment we want to limit this list. + # A complete list can be obtained from here: # oc api-resources --verbs=list --no-headers | awk '{print $NF}' | sort -u enum: - - Alertmanager - - APIService - - AppliedClusterResourceQuota - - BrokerTemplateInstance - - Build - - BuildConfig - - CatalogSource - - CertificateSigningRequest - - ClusterNetwork - - ClusterResourceQuota - - ClusterRole - - ClusterRoleBinding - - ClusterServiceVersion - - ComponentStatus - ConfigMap - - ControllerRevision - - CronJob - - CustomResourceDefinition - - DaemonSet - - Deployment - - DeploymentConfig - - EgressNetworkPolicy - - Endpoints - - Event - - Group - - HorizontalPodAutoscaler - - HostSubnet - - Identity - - Image - - ImageStream - - ImageStreamTag - - Ingress - - InstallPlan - - Job - - LimitRange - - MutatingWebhookConfiguration - - Namespace - - NetNamespace - - NetworkPolicy - - Node - - NodeMetrics - - OAuthAccessToken - - OAuthAuthorizeToken - - OAuthClient - - OAuthClientAuthorization - - OperatorGroup - - PackageManifest - - PersistentVolume - - PersistentVolumeClaim - - Pod - - PodDisruptionBudget - - PodMetrics - - PodSecurityPolicy - - PodTemplate - - PriorityClass - - Project - - ProjectRequest - - Prometheus - - PrometheusRule - - RangeAllocation - - ReplicaSet - - ReplicationController - - ResourceQuota - - Role - - RoleBinding - - RoleBindingRestriction - - Route - - Secret - - SecurityContextConstraints - - Service - - ServiceAccount - - ServiceMonitor - - StatefulSet - - StorageClass - - Subscription - - Template - - TemplateInstance - - User - - ValidatingWebhookConfiguration - - VolumeAttachment + + openshiftResources: + type: array + items: + type: object + properties: + provider: + type: string + oneOf: + - additionalProperties: false + properties: + provider: + type: string + enum: + - resource + path: + type: string + required: + - path + required: + - provider + required: - "$schema" - labels From 2c4264344a898e26eaded8b5802ca07f83b5b6b4 Mon Sep 17 00:00:00 2001 From: Jaime Melis Date: Tue, 19 Feb 2019 18:43:03 +0100 Subject: [PATCH 6/8] fix resources --- assets/schema.yml | 1 + src/schema.ts | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/assets/schema.yml b/assets/schema.yml index e2451cf..ea73f63 100644 --- a/assets/schema.yml +++ b/assets/schema.yml @@ -218,3 +218,4 @@ - { name: namespaces, type: Namespace, isList: true, datafileSchema: /openshift/namespace-1.yml } - { name: quay_orgs, type: QuayOrg, isList: true, datafileSchema: /dependencies/quay-org-1.yml } - { name: apps, type: App, isList: true, datafileSchema: /app-sre/app-1.yml } + - { name: resources, type: Resource, isResource: true, isRequired: true, isList: true } diff --git a/src/schema.ts b/src/schema.ts index fe2dafa..862d788 100644 --- a/src/schema.ts +++ b/src/schema.ts @@ -219,9 +219,7 @@ export function generateAppSchema(path: string): GraphQLSchema { const schemaTypes: any = {}; const interfaceTypes: any = {}; - schemaData.map((t: any) => createSchemaType(schemaTypes, interfaceTypes, t)); - console.log(interfaceTypes); return new GraphQLSchema({ types: Object.values(schemaTypes), From 6066f5763b16c2547f0a28c9f85b46f50b259e63 Mon Sep 17 00:00:00 2001 From: Jaime Melis Date: Wed, 20 Feb 2019 13:27:06 +0100 Subject: [PATCH 7/8] fix tests --- test/schemas/cluster.data.json | 15 +++--- test/schemas/cluster.test.ts | 2 +- test/server.data.json | 97 ++++++++++++++++++---------------- test/server.test.ts | 6 +-- 4 files changed, 63 insertions(+), 57 deletions(-) diff --git a/test/schemas/cluster.data.json b/test/schemas/cluster.data.json index 838bc98..3e68cc6 100644 --- a/test/schemas/cluster.data.json +++ b/test/schemas/cluster.data.json @@ -1,9 +1,12 @@ { - "/cluster.yml": { - "name": "example cluster", - "labels": {}, - "serverUrl": "https://example.com", - "$schema": "/openshift/cluster-1.yml", - "description": "example cluster" + "resources": {}, + "data": { + "/cluster.yml": { + "name": "example cluster", + "labels": {}, + "serverUrl": "https://example.com", + "$schema": "/openshift/cluster-1.yml", + "description": "example cluster" + } } } diff --git a/test/schemas/cluster.test.ts b/test/schemas/cluster.test.ts index 611a86b..84d54c1 100644 --- a/test/schemas/cluster.test.ts +++ b/test/schemas/cluster.test.ts @@ -18,7 +18,7 @@ describe('clusters', () => { .query({ query: '{ clusters { name } }' }) .end((err, res) => { res.should.have.status(200); - res.body.data.cluster[0].name.should.equal('example cluster'); + res.body.data.clusters[0].name.should.equal('example cluster'); done(); }); }); diff --git a/test/server.data.json b/test/server.data.json index 641e0e6..f192c64 100644 --- a/test/server.data.json +++ b/test/server.data.json @@ -1,51 +1,54 @@ { - "/role-A.yml": { - "$schema": "/access/role-1.yml", - "labels": {}, - "name": "role-A", - "permissions": [ - { - "$ref": "/permission-A.yml" - } - ] - }, - "/permission-A.yml": { - "$schema": "/access/permission-1.yml", - "name": "permission-A", - "service": "github-org-team", - "team": "team-A", - "org": "org-A", - "labels": {}, - "description": "description permission-A" - }, - "/app-A.yml": { - "$schema": "/app-sre/app-1.yml", - "labels": {}, - "title": "app-A", - "serviceOwner": { - "name": "serviceOwnerName", - "email": "test@example.com" + "resources": {}, + "data": { + "/role-A.yml": { + "$schema": "/access/role-1.yml", + "labels": {}, + "name": "role-A", + "permissions": [ + { + "$ref": "/permission-A.yml" + } + ] }, - "quayRepos": [ - { - "org": { - "$ref": "/quay-org-A.yml" - }, - "items": [ - { - "name": "repoA", - "description": "", - "public": true - } - ] - } - ] - }, - "/quay-org-A.yml": { - "$schema": "/dependencies/quay-org-1.yml", - "labels": {}, - "name": "quay-org-A", - "managedTeams": [ "teamA" ], - "description": "desc" + "/permission-A.yml": { + "$schema": "/access/permission-1.yml", + "name": "permission-A", + "service": "github-org-team", + "team": "team-A", + "org": "org-A", + "labels": {}, + "description": "description permission-A" + }, + "/app-A.yml": { + "$schema": "/app-sre/app-1.yml", + "labels": {}, + "title": "app-A", + "serviceOwner": { + "name": "serviceOwnerName", + "email": "test@example.com" + }, + "quayRepos": [ + { + "org": { + "$ref": "/quay-org-A.yml" + }, + "items": [ + { + "name": "repoA", + "description": "", + "public": true + } + ] + } + ] + }, + "/quay-org-A.yml": { + "$schema": "/dependencies/quay-org-1.yml", + "labels": {}, + "name": "quay-org-A", + "managedTeams": [ "teamA" ], + "description": "desc" + } } } diff --git a/test/server.test.ts b/test/server.test.ts index 8bb5a2d..0a32cf6 100644 --- a/test/server.test.ts +++ b/test/server.test.ts @@ -29,7 +29,7 @@ describe('server', () => { it('resolves item refs', (done) => { const query = `{ - role { + roles { name permissions { service @@ -42,7 +42,7 @@ describe('server', () => { .query({ query }) .end((err: any, res: any) => { validateGraphQLResponse(res); - const permissionsName: any = res.body.data.role[0].permissions[0].service; + const permissionsName: any = res.body.data.roles[0].permissions[0].service; permissionsName.should.equal('github-org-team'); done(); }); @@ -64,7 +64,7 @@ describe('server', () => { .query({ query }) .end((err: any, res: any) => { validateGraphQLResponse(res); - const orgResponse = res.body.data.app[0].quayRepos[0].org.name; + const orgResponse = res.body.data.apps[0].quayRepos[0].org.name; orgResponse.should.equal('quay-org-A'); done(); }); From 9dfc2848e1da1769a6f9e2cc50a2f7033d7990f9 Mon Sep 17 00:00:00 2001 From: Jaime Melis Date: Wed, 20 Feb 2019 13:30:06 +0100 Subject: [PATCH 8/8] add resource test --- test/server.data.json | 8 +++++++- test/server.test.ts | 20 ++++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/test/server.data.json b/test/server.data.json index f192c64..f338303 100644 --- a/test/server.data.json +++ b/test/server.data.json @@ -1,5 +1,11 @@ { - "resources": {}, + "resources": { + "/resource1.yml": { + "path": "/resource1.yml", + "content": "test resource", + "sha256sum": "ff" + } + }, "data": { "/role-A.yml": { "$schema": "/access/role-1.yml", diff --git a/test/server.test.ts b/test/server.test.ts index 0a32cf6..bb683d7 100644 --- a/test/server.test.ts +++ b/test/server.test.ts @@ -69,4 +69,24 @@ describe('server', () => { done(); }); }); + + it('can retrieve a resource', (done) => { + const query = `{ + resources(path: "/resource1.yml") { + content + sha256sum + path + } + }`; + + chai.request(server) + .get('/graphql') + .query({ query }) + .end((err: any, res: any) => { + validateGraphQLResponse(res); + const resource = res.body.data.resources[0]; + resource.content.should.equal('test resource'); + done(); + }); + }); });