From 8c6c9d5a55d1041e57fea291c0f9412c3bfb4d13 Mon Sep 17 00:00:00 2001
From: tyler dunkel <tyler.dunkel@autocloud.dev>
Date: Mon, 10 Jan 2022 17:43:04 -0600
Subject: [PATCH 1/6] feat(services): add networkPolicy service

---
 src/enums/schemasMap.ts                   |  1 +
 src/enums/serviceMap.ts                   |  2 +
 src/enums/services.ts                     |  1 +
 src/services/namespace/schema.graphql     |  1 +
 src/services/networkPolicy/data.ts        | 22 ++++++
 src/services/networkPolicy/format.ts      | 85 +++++++++++++++++++++++
 src/services/networkPolicy/index.ts       | 12 ++++
 src/services/networkPolicy/mutation.ts    |  5 ++
 src/services/networkPolicy/schema.graphql | 52 ++++++++++++++
 src/types/generated.ts                    | 49 +++++++++++++
 10 files changed, 230 insertions(+)
 create mode 100644 src/services/networkPolicy/data.ts
 create mode 100644 src/services/networkPolicy/format.ts
 create mode 100644 src/services/networkPolicy/index.ts
 create mode 100644 src/services/networkPolicy/mutation.ts
 create mode 100644 src/services/networkPolicy/schema.graphql

diff --git a/src/enums/schemasMap.ts b/src/enums/schemasMap.ts
index c9bf2a9..e25b5e8 100644
--- a/src/enums/schemasMap.ts
+++ b/src/enums/schemasMap.ts
@@ -3,6 +3,7 @@ import services from './services'
 export default {
   [services.node]: 'k8sNode',
   [services.namespace]: 'k8sNamespace',
+  [services.networkPolicy]: 'k8sNetworkPolicy',
   [services.pod]: 'k8sPod',
   [services.deployment]: 'k8sDeployment',
   [services.secret]: 'k8sSecret',
diff --git a/src/enums/serviceMap.ts b/src/enums/serviceMap.ts
index bc140ba..0910cc6 100644
--- a/src/enums/serviceMap.ts
+++ b/src/enums/serviceMap.ts
@@ -13,10 +13,12 @@ import Secret from '../services/secret'
 import Role from '../services/role'
 import Job from '../services/job'
 import CronJob from '../services/cronJob'
+import NetworkPolicy from '../services/networkPolicy'
 
 export default {
   [services.node]: Node,
   [services.namespace]: Namespace,
+  [services.networkPolicy]: NetworkPolicy,
   [services.pod]: Pod,
   [services.deployment]: Deployment,
   [services.secret]: Secret,
diff --git a/src/enums/services.ts b/src/enums/services.ts
index 9ba5b41..8910d75 100644
--- a/src/enums/services.ts
+++ b/src/enums/services.ts
@@ -4,6 +4,7 @@ export default {
   ingress: 'ingress',
   job: 'job',
   namespace: 'namespace',
+  networkPolicy: 'networkPolicy',
   node: 'node',
   persistentVolume: 'persistentVolume',
   persistentVolumeClaim: 'persistentVolumeClaim',
diff --git a/src/services/namespace/schema.graphql b/src/services/namespace/schema.graphql
index b2c0aef..86b2fba 100644
--- a/src/services/namespace/schema.graphql
+++ b/src/services/namespace/schema.graphql
@@ -6,6 +6,7 @@ type k8sNamespace {
   metadata: k8sMetadata
   spec: k8sNamespaceSpec
   status: k8sNamespaceStatus
+  networkPolicy: [k8sNetworkPolicy] @hasInverse(field: namespace)
   node: [k8sNode] @hasInverse(field: namespace)
   pod: [k8sPod] @hasInverse(field: namespace)
   deployment: [k8sDeployment] @hasInverse(field: namespace)
diff --git a/src/services/networkPolicy/data.ts b/src/services/networkPolicy/data.ts
new file mode 100644
index 0000000..e4b841f
--- /dev/null
+++ b/src/services/networkPolicy/data.ts
@@ -0,0 +1,22 @@
+import CloudGraph from '@cloudgraph/sdk'
+import { V1NetworkPolicy } from '@kubernetes/client-node'
+import { k8sClient } from '../../types'
+
+const { logger } = CloudGraph
+
+export default async ({
+  config,
+}: { config: { client: k8sClient } }): Promise<V1NetworkPolicy[]> => {
+  const { client,  } = config
+
+  try {
+    const response = await client.networking.listNetworkPolicyForAllNamespaces()
+    const { body: { items = []} = {}} = response ?? {}
+    logger.debug(`Found ${items.length} k8s network policies`)
+
+    return items
+  } catch (e) {
+    logger.debug(e)
+    return []
+  }
+}
diff --git a/src/services/networkPolicy/format.ts b/src/services/networkPolicy/format.ts
new file mode 100644
index 0000000..68461bf
--- /dev/null
+++ b/src/services/networkPolicy/format.ts
@@ -0,0 +1,85 @@
+import cuid from 'cuid'
+import { V1NetworkPolicy, V1NetworkPolicyPeer, V1NetworkPolicyPort } from '@kubernetes/client-node'
+import { K8sNetworkPolicy } from '../../types/generated'
+import { convertObjToArrayWithId } from '../../util'
+import formatMetadata from '../../util/metadata'
+import { formatMatchedExpressionsAndFields } from '../pod/util'
+
+const formatPort = (port: V1NetworkPolicyPort) => {
+  return {
+    id: cuid(),
+    endPort: port?.endPort,
+    port: String(port?.port ?? ''),
+    protocol: port?.protocol
+  }
+}
+
+const formatPolicyPeer = (peer: V1NetworkPolicyPeer) => {
+  return {
+    id: cuid(),
+    ipBlock: {
+      cidr: peer?.ipBlock?.cidr,
+      except: peer?.ipBlock?.except
+    },
+    namespaceSelector: {
+      matchExpressions: formatMatchedExpressionsAndFields(peer?.namespaceSelector?.matchExpressions ?? []),
+      matchLabels: convertObjToArrayWithId(peer?.namespaceSelector?.matchLabels ?? {})
+    },
+    podSelector: {
+      matchExpressions: formatMatchedExpressionsAndFields(peer?.podSelector?.matchExpressions ?? []),
+      matchLabels: convertObjToArrayWithId(peer?.podSelector?.matchLabels ?? {})
+    }
+  }
+}
+export default ({
+  entity,
+  context,
+}: {
+  entity: V1NetworkPolicy
+  context: string
+}): K8sNetworkPolicy => {
+  const {
+    apiVersion,
+    kind,
+    metadata,
+    spec: {
+      egress,
+      ingress,
+      podSelector,
+      policyTypes
+    } = {}
+  } = entity
+
+
+  const formattedMetadata = formatMetadata(metadata)
+  const mappedEgress = egress?.map(({ ports, to })=> ({
+    id: cuid(),
+    ports: ports?.map(formatPort) ?? [],
+    to: to?.map(formatPolicyPeer) ?? []
+  })) ?? []
+
+  const mappedIngress = ingress?.map(({ ports, from })=> ({
+    id: cuid(),
+    ports: ports?.map(formatPort) ?? [],
+    from: from?.map(formatPolicyPeer) ?? []
+  })) ?? []
+
+  const formattedPodSelector = {
+    matchExpressions: formatMatchedExpressionsAndFields(podSelector?.matchExpressions ?? []),
+    matchLabels: convertObjToArrayWithId(podSelector?.matchLabels ?? {})
+  }
+
+  return {
+    id: formattedMetadata.id,
+    apiVersion,
+    kind,
+    context,
+    metadata: formattedMetadata.metadata,
+    spec: {
+      egress: mappedEgress,
+      ingress: mappedIngress,
+      podSelector: formattedPodSelector,
+      policyTypes
+    }
+  }
+}
diff --git a/src/services/networkPolicy/index.ts b/src/services/networkPolicy/index.ts
new file mode 100644
index 0000000..0df6c4f
--- /dev/null
+++ b/src/services/networkPolicy/index.ts
@@ -0,0 +1,12 @@
+import getData from './data'
+import format from './format'
+import mutation from './mutation'
+
+
+export default class NetworkPolicy {
+  format = format.bind(this)
+
+  getData = getData.bind(this)
+
+  mutation = mutation
+}
\ No newline at end of file
diff --git a/src/services/networkPolicy/mutation.ts b/src/services/networkPolicy/mutation.ts
new file mode 100644
index 0000000..760d0ca
--- /dev/null
+++ b/src/services/networkPolicy/mutation.ts
@@ -0,0 +1,5 @@
+export default `mutation($input: [Addk8sNetworkPolicyInput!]!) {
+  addk8sNetworkPolicy(input: $input, upsert: true) {
+    numUids
+  }
+}`;
diff --git a/src/services/networkPolicy/schema.graphql b/src/services/networkPolicy/schema.graphql
new file mode 100644
index 0000000..4914225
--- /dev/null
+++ b/src/services/networkPolicy/schema.graphql
@@ -0,0 +1,52 @@
+type k8sNetworkPolicy {
+  id: String! @id @search(by: [hash, regexp])
+  context: String! @search(by: [hash, regexp])
+  apiVersion: String @search(by: [hash, regexp])
+  kind: String @search(by: [hash, regexp])
+  metadata: k8sMetadata
+  spec: k8sNetworkPolicySpec
+  namespace: [k8sNamespace] @hasInverse(field: networkPolicy)
+}
+
+type k8sNetworkPolicySpec {
+  egress: [k8sNetworkPolicyEgress]
+  ingress: [k8sNetworkPolicyIngress]
+  podSelector: k8sDeploymentSelector
+  policyTypes: [String] @search(by: [hash, regexp])
+}
+
+type k8sDeploymentSelector {
+  matchExpressions: [k8sDeploymentExpressions]
+  matchLabels: [k8sKeyValueArray]
+}
+
+type k8sNetworkPolicyEgress {
+  id: String! @id @search(by: [hash, regexp])
+  ports: [k8sNetworkPolicyPort]
+  to: [k8sNetworkPolicyPeer]
+}
+
+type k8sNetworkPolicyIngress {
+  id: String! @id @search(by: [hash, regexp])
+  ports: [k8sNetworkPolicyPort]
+  from: [k8sNetworkPolicyPeer]
+}
+
+type k8sNetworkPolicyPort {
+  id: String! @id @search(by: [hash, regexp])
+  endPort: Int @search
+  port: String @search(by: [hash, regexp])
+  protocol: String @search(by: [hash, regexp])
+}
+
+type k8sNetworkPolicyPeer {
+  id: String! @id @search(by: [hash, regexp])
+  ipBlock: k8sNetworkPolicyPeerIpBlock
+  namespaceSelector: k8sDeploymentSelector
+  podSelector: k8sDeploymentSelector
+}
+
+type k8sNetworkPolicyPeerIpBlock {
+  cidr: String @search(by: [hash, regexp])
+  except: [String] @search(by: [hash, regexp])
+}
\ No newline at end of file
diff --git a/src/types/generated.ts b/src/types/generated.ts
index 869d28f..98df012 100644
--- a/src/types/generated.ts
+++ b/src/types/generated.ts
@@ -341,6 +341,7 @@ export type K8sNamespace = {
   metadata?: Maybe<K8sMetadata>;
   spec?: Maybe<K8sNamespaceSpec>;
   status?: Maybe<K8sNamespaceStatus>;
+  networkPolicy?: Maybe<Array<Maybe<K8sNetworkPolicy>>>;
   node?: Maybe<Array<Maybe<K8sNode>>>;
   pod?: Maybe<Array<Maybe<K8sPod>>>;
   deployment?: Maybe<Array<Maybe<K8sDeployment>>>;
@@ -365,6 +366,54 @@ export type K8sNamespaceStatus = {
   conditions?: Maybe<Array<Maybe<K8sConditions>>>;
 };
 
+export type K8sNetworkPolicy = {
+  id: Scalars['String'];
+  context: Scalars['String'];
+  apiVersion?: Maybe<Scalars['String']>;
+  kind?: Maybe<Scalars['String']>;
+  metadata?: Maybe<K8sMetadata>;
+  spec?: Maybe<K8sNetworkPolicySpec>;
+  namespace?: Maybe<Array<Maybe<K8sNamespace>>>;
+};
+
+export type K8sNetworkPolicyEgress = {
+  id: Scalars['String'];
+  ports?: Maybe<Array<Maybe<K8sNetworkPolicyPort>>>;
+  to?: Maybe<Array<Maybe<K8sNetworkPolicyPeer>>>;
+};
+
+export type K8sNetworkPolicyIngress = {
+  id: Scalars['String'];
+  ports?: Maybe<Array<Maybe<K8sNetworkPolicyPort>>>;
+  from?: Maybe<Array<Maybe<K8sNetworkPolicyPeer>>>;
+};
+
+export type K8sNetworkPolicyPeer = {
+  id: Scalars['String'];
+  ipBlock?: Maybe<K8sNetworkPolicyPeerIpBlock>;
+  namespaceSelector?: Maybe<K8sDeploymentSelector>;
+  podSelector?: Maybe<K8sDeploymentSelector>;
+};
+
+export type K8sNetworkPolicyPeerIpBlock = {
+  cidr?: Maybe<Scalars['String']>;
+  except?: Maybe<Array<Maybe<Scalars['String']>>>;
+};
+
+export type K8sNetworkPolicyPort = {
+  id: Scalars['String'];
+  endPort?: Maybe<Scalars['Int']>;
+  port?: Maybe<Scalars['String']>;
+  protocol?: Maybe<Scalars['String']>;
+};
+
+export type K8sNetworkPolicySpec = {
+  egress?: Maybe<Array<Maybe<K8sNetworkPolicyEgress>>>;
+  ingress?: Maybe<Array<Maybe<K8sNetworkPolicyIngress>>>;
+  podSelector?: Maybe<K8sDeploymentSelector>;
+  policyTypes?: Maybe<Array<Maybe<Scalars['String']>>>;
+};
+
 export type K8sNode = {
   id: Scalars['String'];
   context: Scalars['String'];

From eb8081df78ed6a9d4421f08e0fd01ffd426d50ed Mon Sep 17 00:00:00 2001
From: tyler dunkel <tyler.dunkel@autocloud.dev>
Date: Mon, 10 Jan 2022 17:45:57 -0600
Subject: [PATCH 2/6] chore(readme): update readme with networkPolicy service

---
 README.md | 1 +
 1 file changed, 1 insertion(+)

diff --git a/README.md b/README.md
index 881a81b..44e173e 100644
--- a/README.md
+++ b/README.md
@@ -41,6 +41,7 @@ Authenticate the CloudGraph k8s Provider any of the following ways:
 | ingress                      | namespace          |
 | job                          | namespace          |
 | namespace                    | ALL SERVICES       |
+| networkPolicy                | namespace          |
 | node                         | namespace          |
 | persistentVolume             | namespace          |
 | persistentVolumeClaim        | namespace          |

From d12bcd5be92a1c263421c4658cd95c4ecc6983fb Mon Sep 17 00:00:00 2001
From: tyler dunkel <tyler.dunkel@autocloud.dev>
Date: Tue, 11 Jan 2022 15:33:36 -0600
Subject: [PATCH 3/6] fix(config): update config log out to use context.name

---
 src/services/index.ts | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/src/services/index.ts b/src/services/index.ts
index b401693..9865ab1 100644
--- a/src/services/index.ts
+++ b/src/services/index.ts
@@ -99,7 +99,7 @@ export default class Provider extends CloudGraph.Client {
         'k8s'
       )} configuration successfully completed ${confettiBall}`
     )
-    this.logSelectedAccessRegionsAndResources(result.contexts, result.resources)
+    this.logSelectedAccessRegionsAndResources(result.contexts.map(({ name }) => name), result.resources)
     return result
   }
 
@@ -174,9 +174,7 @@ export default class Provider extends CloudGraph.Client {
       roles: rolesClient
     }
 
-    // rolesClient.listRoleForAllNamespaces
     // networkingClient.listNetworkPolicyForAllNamespaces
-    // batchClient.listCronJobForAllNamespaces
     // client.listConfigMapForAllNamespaces
     // client.listEndpointsForAllNamespaces
     // client.listEventForAllNamespaces

From 5a4030df7c31c910e56a54b8d6a336eba2ea2a67 Mon Sep 17 00:00:00 2001
From: tyler dunkel <tyler.dunkel@autocloud.dev>
Date: Wed, 12 Jan 2022 15:22:17 -0600
Subject: [PATCH 4/6] fix(services): update service connection names to plural

---
 src/enums/pluralization.ts                    | 17 +++++++++++
 src/services/cronJob/schema.graphql           |  2 +-
 src/services/deployment/schema.graphql        |  2 +-
 src/services/ingress/schema.graphql           |  2 +-
 src/services/job/schema.graphql               |  2 +-
 src/services/namespace/connections.ts         |  3 +-
 src/services/namespace/schema.graphql         | 28 +++++++++----------
 src/services/networkPolicy/schema.graphql     |  2 +-
 src/services/node/schema.graphql              |  2 +-
 src/services/persistentVolume/schema.graphql  |  2 +-
 .../persistentVolumeClaim/schema.graphql      |  2 +-
 src/services/pod/schema.graphql               |  2 +-
 src/services/role/schema.graphql              |  2 +-
 src/services/secret/schema.graphql            |  2 +-
 src/services/service/schema.graphql           |  2 +-
 src/services/serviceAccount/schema.graphql    |  2 +-
 src/services/storageClass/schema.graphql      |  2 +-
 src/types/generated.ts                        | 28 +++++++++----------
 18 files changed, 61 insertions(+), 43 deletions(-)
 create mode 100644 src/enums/pluralization.ts

diff --git a/src/enums/pluralization.ts b/src/enums/pluralization.ts
new file mode 100644
index 0000000..74d1db3
--- /dev/null
+++ b/src/enums/pluralization.ts
@@ -0,0 +1,17 @@
+export default {
+  cronJob: 'cronJobs',
+  deployment: 'deployments',
+  ingress: 'ingresses',
+  job: 'jobs',
+  namespace: 'namespaces',
+  networkPolicy: 'networkPolicies',
+  node: 'nodes',
+  persistentVolume: 'persistentVolumes',
+  persistentVolumeClaim: 'persistentVolumeClaims',
+  pod: 'pods',
+  role: 'roles',
+  secret: 'secrets',
+  service: 'services',
+  serviceAccount: 'serviceAccounts',
+  storageClass: 'storageClasses'
+}
\ No newline at end of file
diff --git a/src/services/cronJob/schema.graphql b/src/services/cronJob/schema.graphql
index 4e3ea2e..9333ae7 100644
--- a/src/services/cronJob/schema.graphql
+++ b/src/services/cronJob/schema.graphql
@@ -6,7 +6,7 @@ type k8sCronJob {
   metadata: k8sMetadata
   spec: k8sCronJobSpec
   status: k8sCronJobStatus
-  namespace: [k8sNamespace] @hasInverse(field: cronJob)
+  namespace: [k8sNamespace] @hasInverse(field: cronJobs)
 }
 
 type k8sCronJobSpec {
diff --git a/src/services/deployment/schema.graphql b/src/services/deployment/schema.graphql
index 64ee7ff..9f07a41 100644
--- a/src/services/deployment/schema.graphql
+++ b/src/services/deployment/schema.graphql
@@ -6,7 +6,7 @@ type k8sDeployment {
   metadata: k8sMetadata
   spec: k8sDeploymentSpec
   status: k8sDeploymentStatus
-  namespace: [k8sNamespace] @hasInverse(field: deployment)
+  namespace: [k8sNamespace] @hasInverse(field: deployments)
 }
 
 type k8sDeploymentSpec {
diff --git a/src/services/ingress/schema.graphql b/src/services/ingress/schema.graphql
index 96e2b99..6db25f9 100644
--- a/src/services/ingress/schema.graphql
+++ b/src/services/ingress/schema.graphql
@@ -6,7 +6,7 @@ type k8sIngress {
   metadata: k8sMetadata
   spec: k8sIngressSpec
   status: k8sIngressStatus
-  namespace: [k8sNamespace] @hasInverse(field: ingress)
+  namespace: [k8sNamespace] @hasInverse(field: ingresses)
 }
 
 type k8sIngressSpec {
diff --git a/src/services/job/schema.graphql b/src/services/job/schema.graphql
index 4e4b652..4ea226e 100644
--- a/src/services/job/schema.graphql
+++ b/src/services/job/schema.graphql
@@ -6,7 +6,7 @@ type k8sJob {
   metadata: k8sMetadata
   spec: k8sJobSpec
   status: k8sJobStatus
-  namespace: [k8sNamespace] @hasInverse(field: job)
+  namespace: [k8sNamespace] @hasInverse(field: jobs)
 }
 
 type k8sJobSpec {
diff --git a/src/services/namespace/connections.ts b/src/services/namespace/connections.ts
index b2e7e6f..8bc1682 100644
--- a/src/services/namespace/connections.ts
+++ b/src/services/namespace/connections.ts
@@ -3,6 +3,7 @@ import isEmpty from 'lodash/isEmpty'
 import { ServiceConnection } from '@cloudgraph/sdk'
 import { V1Namespace } from '@kubernetes/client-node'
 import services from '../../enums/services'
+import plurals from '../../enums/pluralization'
 
 /**
  * Service Account
@@ -36,7 +37,7 @@ export default ({
             id: service.metadata?.uid,
             resourceType: entity.name,
             relation: 'child',
-            field: entity.name
+            field: plurals[entity.name] ?? entity.name
           })
         }
       }
diff --git a/src/services/namespace/schema.graphql b/src/services/namespace/schema.graphql
index 86b2fba..9770450 100644
--- a/src/services/namespace/schema.graphql
+++ b/src/services/namespace/schema.graphql
@@ -6,20 +6,20 @@ type k8sNamespace {
   metadata: k8sMetadata
   spec: k8sNamespaceSpec
   status: k8sNamespaceStatus
-  networkPolicy: [k8sNetworkPolicy] @hasInverse(field: namespace)
-  node: [k8sNode] @hasInverse(field: namespace)
-  pod: [k8sPod] @hasInverse(field: namespace)
-  deployment: [k8sDeployment] @hasInverse(field: namespace)
-  ingress: [k8sIngress] @hasInverse(field: namespace)
-  secret: [k8sSecret] @hasInverse(field: namespace)
-  service: [k8sService] @hasInverse(field: namespace)
-  serviceAccount: [k8sServiceAccount] @hasInverse(field: namespace)
-  storageClass: [k8sStorageClass] @hasInverse(field: namespace)
-  persistentVolume: [k8sPersistentVolume] @hasInverse(field: namespace)
-  persistentVolumeClaim: [k8sPersistentVolumeClaim] @hasInverse(field: namespace)
-  role: [k8sRole] @hasInverse(field: namespace)
-  job: [k8sJob] @hasInverse(field: namespace)
-  cronJob: [k8sCronJob] @hasInverse(field: namespace)
+  networkPolicies: [k8sNetworkPolicy] @hasInverse(field: namespace)
+  nodes: [k8sNode] @hasInverse(field: namespace)
+  pods: [k8sPod] @hasInverse(field: namespace)
+  deployments: [k8sDeployment] @hasInverse(field: namespace)
+  ingresses: [k8sIngress] @hasInverse(field: namespace)
+  secrets: [k8sSecret] @hasInverse(field: namespace)
+  services: [k8sService] @hasInverse(field: namespace)
+  serviceAccounts: [k8sServiceAccount] @hasInverse(field: namespace)
+  storageClasses: [k8sStorageClass] @hasInverse(field: namespace)
+  persistentVolumes: [k8sPersistentVolume] @hasInverse(field: namespace)
+  persistentVolumeClaims: [k8sPersistentVolumeClaim] @hasInverse(field: namespace)
+  roles: [k8sRole] @hasInverse(field: namespace)
+  jobs: [k8sJob] @hasInverse(field: namespace)
+  cronJobs: [k8sCronJob] @hasInverse(field: namespace)
 }
 
 type k8sNamespaceSpec @generate(
diff --git a/src/services/networkPolicy/schema.graphql b/src/services/networkPolicy/schema.graphql
index 4914225..56a701b 100644
--- a/src/services/networkPolicy/schema.graphql
+++ b/src/services/networkPolicy/schema.graphql
@@ -5,7 +5,7 @@ type k8sNetworkPolicy {
   kind: String @search(by: [hash, regexp])
   metadata: k8sMetadata
   spec: k8sNetworkPolicySpec
-  namespace: [k8sNamespace] @hasInverse(field: networkPolicy)
+  namespace: [k8sNamespace] @hasInverse(field: networkPolicies)
 }
 
 type k8sNetworkPolicySpec {
diff --git a/src/services/node/schema.graphql b/src/services/node/schema.graphql
index c429e84..0c22805 100644
--- a/src/services/node/schema.graphql
+++ b/src/services/node/schema.graphql
@@ -9,7 +9,7 @@ type k8sNode {
   metadata: k8sMetadata
   spec: k8sNodeSpec
   status: k8sNodeStatus
-  namespace: [k8sNamespace] @hasInverse(field: node)
+  namespace: [k8sNamespace] @hasInverse(field: nodes)
 }
 
 type k8sMetadata @generate(
diff --git a/src/services/persistentVolume/schema.graphql b/src/services/persistentVolume/schema.graphql
index 6e32235..49b5e62 100644
--- a/src/services/persistentVolume/schema.graphql
+++ b/src/services/persistentVolume/schema.graphql
@@ -6,7 +6,7 @@ type k8sPersistentVolume {
   metadata: k8sMetadata
   spec: k8sPersistentVolumeSpec
   status: k8sPersistentVolumeStatus
-  namespace: [k8sNamespace] @hasInverse(field: persistentVolume)
+  namespace: [k8sNamespace] @hasInverse(field: persistentVolumes)
 }
 
 type k8sPersistentVolumeSpec @generate(
diff --git a/src/services/persistentVolumeClaim/schema.graphql b/src/services/persistentVolumeClaim/schema.graphql
index ffc4bbe..ff394fa 100644
--- a/src/services/persistentVolumeClaim/schema.graphql
+++ b/src/services/persistentVolumeClaim/schema.graphql
@@ -6,7 +6,7 @@ type k8sPersistentVolumeClaim {
   metadata: k8sMetadata
   spec: k8sPersistentVolumeClaimSpec
   status: k8sPersistentVolumeClaimStatus
-  namespace: [k8sNamespace] @hasInverse(field: persistentVolumeClaim)
+  namespace: [k8sNamespace] @hasInverse(field: persistentVolumeClaims)
 }
 
 type k8sPersistentVolumeClaimSpec @generate(
diff --git a/src/services/pod/schema.graphql b/src/services/pod/schema.graphql
index f9641c7..e7ad80b 100644
--- a/src/services/pod/schema.graphql
+++ b/src/services/pod/schema.graphql
@@ -6,7 +6,7 @@ type k8sPod {
   metadata: k8sMetadata
   spec: k8sPodSpec
   status: k8sPodStatus
-  namespace: [k8sNamespace] @hasInverse(field: pod)
+  namespace: [k8sNamespace] @hasInverse(field: pods)
 }
 
 type k8sPodSpec {
diff --git a/src/services/role/schema.graphql b/src/services/role/schema.graphql
index b95b4dd..6c9ce1f 100644
--- a/src/services/role/schema.graphql
+++ b/src/services/role/schema.graphql
@@ -5,7 +5,7 @@ type k8sRole {
   kind: String @search(by: [hash, regexp])
   metadata: k8sMetadata
   rules: [k8sRule]
-  namespace: [k8sNamespace] @hasInverse(field: role)
+  namespace: [k8sNamespace] @hasInverse(field: roles)
 }
 
 type k8sRule {
diff --git a/src/services/secret/schema.graphql b/src/services/secret/schema.graphql
index 76cd5c6..da548b7 100644
--- a/src/services/secret/schema.graphql
+++ b/src/services/secret/schema.graphql
@@ -8,5 +8,5 @@ type k8sSecret {
   immutable: Boolean @search
   stringData: [k8sKeyValueArray]
   type: String @search(by: [hash, regexp])
-  namespace: [k8sNamespace] @hasInverse(field: secret)
+  namespace: [k8sNamespace] @hasInverse(field: secrets)
 }
\ No newline at end of file
diff --git a/src/services/service/schema.graphql b/src/services/service/schema.graphql
index ed642bd..4759e46 100644
--- a/src/services/service/schema.graphql
+++ b/src/services/service/schema.graphql
@@ -6,7 +6,7 @@ type k8sService {
   metadata: k8sMetadata
   spec: k8sServiceSpec
   status: k8sServiceStatus
-  namespace: [k8sNamespace] @hasInverse(field: service)
+  namespace: [k8sNamespace] @hasInverse(field: services)
 }
 
 type k8sServiceSpec {
diff --git a/src/services/serviceAccount/schema.graphql b/src/services/serviceAccount/schema.graphql
index cc8a1da..3e82313 100644
--- a/src/services/serviceAccount/schema.graphql
+++ b/src/services/serviceAccount/schema.graphql
@@ -7,7 +7,7 @@ type k8sServiceAccount {
   automountServiceAccountToken: Boolean @search
   imagePullSecrets: [k8sImagePullSecret],
   secrets: [k8sServiceAccountSecret]
-  namespace: [k8sNamespace] @hasInverse(field: serviceAccount)
+  namespace: [k8sNamespace] @hasInverse(field: serviceAccounts)
 }
 
 type k8sImagePullSecret {
diff --git a/src/services/storageClass/schema.graphql b/src/services/storageClass/schema.graphql
index 6fe90c1..1ac0da0 100644
--- a/src/services/storageClass/schema.graphql
+++ b/src/services/storageClass/schema.graphql
@@ -11,7 +11,7 @@ type k8sStorageClass {
   parameters: [k8sKeyValueArray]
   reclaimPolicy: String @search(by: [hash, regexp])
   volumeBindingMode: String @search(by: [hash, regexp])
-  namespace: [k8sNamespace] @hasInverse(field: storageClass)
+  namespace: [k8sNamespace] @hasInverse(field: storageClasses)
 }
 
 type k8sStorageClassAllowedTopology {
diff --git a/src/types/generated.ts b/src/types/generated.ts
index 98df012..fd6ef75 100644
--- a/src/types/generated.ts
+++ b/src/types/generated.ts
@@ -341,20 +341,20 @@ export type K8sNamespace = {
   metadata?: Maybe<K8sMetadata>;
   spec?: Maybe<K8sNamespaceSpec>;
   status?: Maybe<K8sNamespaceStatus>;
-  networkPolicy?: Maybe<Array<Maybe<K8sNetworkPolicy>>>;
-  node?: Maybe<Array<Maybe<K8sNode>>>;
-  pod?: Maybe<Array<Maybe<K8sPod>>>;
-  deployment?: Maybe<Array<Maybe<K8sDeployment>>>;
-  ingress?: Maybe<Array<Maybe<K8sIngress>>>;
-  secret?: Maybe<Array<Maybe<K8sSecret>>>;
-  service?: Maybe<Array<Maybe<K8sService>>>;
-  serviceAccount?: Maybe<Array<Maybe<K8sServiceAccount>>>;
-  storageClass?: Maybe<Array<Maybe<K8sStorageClass>>>;
-  persistentVolume?: Maybe<Array<Maybe<K8sPersistentVolume>>>;
-  persistentVolumeClaim?: Maybe<Array<Maybe<K8sPersistentVolumeClaim>>>;
-  role?: Maybe<Array<Maybe<K8sRole>>>;
-  job?: Maybe<Array<Maybe<K8sJob>>>;
-  cronJob?: Maybe<Array<Maybe<K8sCronJob>>>;
+  networkPolicies?: Maybe<Array<Maybe<K8sNetworkPolicy>>>;
+  nodes?: Maybe<Array<Maybe<K8sNode>>>;
+  pods?: Maybe<Array<Maybe<K8sPod>>>;
+  deployments?: Maybe<Array<Maybe<K8sDeployment>>>;
+  ingresses?: Maybe<Array<Maybe<K8sIngress>>>;
+  secrets?: Maybe<Array<Maybe<K8sSecret>>>;
+  services?: Maybe<Array<Maybe<K8sService>>>;
+  serviceAccounts?: Maybe<Array<Maybe<K8sServiceAccount>>>;
+  storageClasses?: Maybe<Array<Maybe<K8sStorageClass>>>;
+  persistentVolumes?: Maybe<Array<Maybe<K8sPersistentVolume>>>;
+  persistentVolumeClaims?: Maybe<Array<Maybe<K8sPersistentVolumeClaim>>>;
+  roles?: Maybe<Array<Maybe<K8sRole>>>;
+  jobs?: Maybe<Array<Maybe<K8sJob>>>;
+  cronJobs?: Maybe<Array<Maybe<K8sCronJob>>>;
 };
 
 export type K8sNamespaceSpec = {

From 932fad23e4cc82561f2ed055ee7e5d21ed9f6fcf Mon Sep 17 00:00:00 2001
From: tyler dunkel <tyler.dunkel@autocloud.dev>
Date: Mon, 17 Jan 2022 14:53:49 -0600
Subject: [PATCH 5/6] fix(services): small fixes for cronJob and pod schemas

---
 src/services/cronJob/schema.graphql |  1 -
 src/services/pod/schema.graphql     | 20 +-------------------
 2 files changed, 1 insertion(+), 20 deletions(-)

diff --git a/src/services/cronJob/schema.graphql b/src/services/cronJob/schema.graphql
index 9333ae7..6abb32c 100644
--- a/src/services/cronJob/schema.graphql
+++ b/src/services/cronJob/schema.graphql
@@ -17,7 +17,6 @@ type k8sCronJobSpec {
   startingDeadlineSeconds: Int @search
   successfulJobsHistoryLimit: Int @search
   suspend: Boolean @search
-  template: k8sJobTemplate
 }
 
 type k8sCronJobStatus {
diff --git a/src/services/pod/schema.graphql b/src/services/pod/schema.graphql
index e7ad80b..a27e379 100644
--- a/src/services/pod/schema.graphql
+++ b/src/services/pod/schema.graphql
@@ -307,28 +307,10 @@ type k8sVolumePersistentVolumeClaim {
 }
 
 type k8sVolumeClaimTemplate {
-  metadata: k8sVolumeClaimTemplateMetadata
+  metadata: k8sMetadata
   spec: k8sVolumeClaimTemplateSpec
 }
 
-type k8sVolumeClaimTemplateMetadata {
-  annotations: [k8sKeyValueArray]
-  clusterName: String @search(by: [hash, regexp])
-  creationTimestamp: String @search(by: [hash, regexp])
-  deletionGracePeriodSeconds: Int @search
-  deletionTimestamp: String @search(by: [hash, regexp])
-  finalizers: [String] @search(by: [hash, regexp])
-  generateName: String @search(by: [hash, regexp])
-  generation: Int @search
-  labels: [k8sKeyValueArray]
-  name: String @search(by: [hash, regexp])
-  namespace: String @search(by: [hash, regexp])
-  ownerReferences: [k8sVolumeOwnerReference],
-  resourceVersion: String @search(by: [hash, regexp])
-  selfLink: String @search(by: [hash, regexp])
-  metadataUid: String @search(by: [hash, regexp])
-}
-
 type k8sVolumeClaimTemplateSpec {
   accessModes: [String] @search(by: [hash, regexp])
   dataSource: k8sVolumeclaimTemplateDataSource

From 0f0a66124870d5d895f01fff9c3336bfcfd270f5 Mon Sep 17 00:00:00 2001
From: tyler dunkel <tyler.dunkel@autocloud.dev>
Date: Mon, 17 Jan 2022 14:54:35 -0600
Subject: [PATCH 6/6] chore(version): bump version to 0.0.2

---
 package.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/package.json b/package.json
index dd64eae..c0e017e 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@cloudgraph/cg-provider-k8s",
-  "version": "0.0.1",
+  "version": "0.0.2",
   "description": "Kubernetes provider for the CloudGraph CLI",
   "publishConfig": {
     "access": "public"