├── config ├── prometheus │ ├── kustomization.yaml │ └── monitor.yaml ├── certmanager │ ├── kustomization.yaml │ ├── kustomizeconfig.yaml │ └── certificate.yaml ├── webhook │ ├── kustomization.yaml │ ├── service.yaml │ └── kustomizeconfig.yaml ├── scorecard │ ├── bases │ │ └── config.yaml │ ├── patches │ │ ├── basic.config.yaml │ │ └── olm.config.yaml │ └── kustomization.yaml ├── rbac │ ├── auth_proxy_client_clusterrole.yaml │ ├── role_binding.yaml │ ├── auth_proxy_role_binding.yaml │ ├── leader_election_role_binding.yaml │ ├── auth_proxy_role.yaml │ ├── auth_proxy_service.yaml │ ├── bgp_viewer_role.yaml │ ├── nat_viewer_role.yaml │ ├── l4lb_viewer_role.yaml │ ├── link_viewer_role.yaml │ ├── vnet_viewer_role.yaml │ ├── bgpmeta_viewer_role.yaml │ ├── natmeta_viewer_role.yaml │ ├── subnet_viewer_role.yaml │ ├── l4lbmeta_viewer_role.yaml │ ├── linkmeta_viewer_role.yaml │ ├── switch_viewer_role.yaml │ ├── vnetmeta_viewer_role.yaml │ ├── softgate_viewer_role.yaml │ ├── kustomization.yaml │ ├── subnetmeta_viewer_role.yaml │ ├── switchmeta_viewer_role.yaml │ ├── allocation_viewer_role.yaml │ ├── controller_viewer_role.yaml │ ├── softgatemeta_viewer_role.yaml │ ├── allocationmeta_viewer_role.yaml │ ├── controllermeta_viewer_role.yaml │ ├── bgp_editor_role.yaml │ ├── inventoryprofile_viewer_role.yaml │ ├── nat_editor_role.yaml │ ├── l4lb_editor_role.yaml │ ├── link_editor_role.yaml │ ├── vnet_editor_role.yaml │ ├── bgpmeta_editor_role.yaml │ ├── inventoryprofilemeta_viewer_role.yaml │ ├── natmeta_editor_role.yaml │ ├── subnet_editor_role.yaml │ ├── switch_editor_role.yaml │ ├── l4lbmeta_editor_role.yaml │ ├── linkmeta_editor_role.yaml │ ├── vnetmeta_editor_role.yaml │ ├── softgate_editor_role.yaml │ ├── subnetmeta_editor_role.yaml │ ├── switchmeta_editor_role.yaml │ ├── allocation_editor_role.yaml │ ├── controller_editor_role.yaml │ ├── softgatemeta_editor_role.yaml │ ├── allocationmeta_editor_role.yaml │ ├── controllermeta_editor_role.yaml │ ├── inventoryprofile_editor_role.yaml │ ├── inventoryprofilemeta_editor_role.yaml │ └── leader_election_role.yaml ├── manager │ ├── kustomization.yaml │ ├── manager.yaml │ └── custom-env.yaml ├── crd │ ├── patches │ │ ├── cainjection_in_nats.yaml │ │ ├── cainjection_in_links.yaml │ │ ├── cainjection_in_natmeta.yaml │ │ ├── cainjection_in_sites.yaml │ │ ├── cainjection_in_subnets.yaml │ │ ├── cainjection_in_linkmeta.yaml │ │ ├── cainjection_in_sitemeta.yaml │ │ ├── cainjection_in_softgates.yaml │ │ ├── cainjection_in_switches.yaml │ │ ├── cainjection_in_allocations.yaml │ │ ├── cainjection_in_controllers.yaml │ │ ├── cainjection_in_softgatemeta.yaml │ │ ├── cainjection_in_subnetmeta.yaml │ │ ├── cainjection_in_switchmeta.yaml │ │ ├── cainjection_in_allocationmeta.yaml │ │ ├── cainjection_in_controllermeta.yaml │ │ ├── cainjection_in_inventoryprofiles.yaml │ │ ├── cainjection_in_inventoryprofilemeta.yaml │ │ ├── cainjection_in_ebgps.yaml │ │ ├── cainjection_in_l4lbs.yaml │ │ ├── cainjection_in_vnets.yaml │ │ ├── cainjection_in_ebgpmeta.yaml │ │ ├── cainjection_in_l4lbmeta.yaml │ │ ├── cainjection_in_vnetmeta.yaml │ │ ├── webhook_in_nats.yaml │ │ ├── webhook_in_links.yaml │ │ ├── webhook_in_natmeta.yaml │ │ ├── webhook_in_sites.yaml │ │ ├── webhook_in_subnets.yaml │ │ ├── webhook_in_linkmeta.yaml │ │ ├── webhook_in_sitemeta.yaml │ │ ├── webhook_in_softgates.yaml │ │ ├── webhook_in_switches.yaml │ │ ├── webhook_in_allocations.yaml │ │ ├── webhook_in_controllers.yaml │ │ ├── webhook_in_softgatemeta.yaml │ │ ├── webhook_in_subnetmeta.yaml │ │ ├── webhook_in_switchmeta.yaml │ │ ├── webhook_in_allocationmeta.yaml │ │ ├── webhook_in_controllermeta.yaml │ │ ├── webhook_in_inventoryprofiles.yaml │ │ ├── webhook_in_inventoryprofilemeta.yaml │ │ ├── webhook_in_ebgps.yaml │ │ ├── webhook_in_l4lbs.yaml │ │ ├── webhook_in_vnets.yaml │ │ ├── webhook_in_ebgpmeta.yaml │ │ ├── webhook_in_l4lbmeta.yaml │ │ └── webhook_in_vnetmeta.yaml │ ├── kustomizeconfig.yaml │ └── bases │ │ ├── k8s.netris.ai_controllermeta.yaml │ │ ├── k8s.netris.ai_linkmeta.yaml │ │ ├── k8s.netris.ai_subnetmeta.yaml │ │ ├── k8s.netris.ai_links.yaml │ │ ├── k8s.netris.ai_softgatemeta.yaml │ │ ├── k8s.netris.ai_allocationmeta.yaml │ │ └── k8s.netris.ai_controllers.yaml └── default │ ├── manager_webhook_patch.yaml │ ├── webhookcainjection_patch.yaml │ ├── manager_auth_proxy_patch.yaml │ └── kustomization.yaml ├── diagram.png ├── samples ├── controller.yaml ├── site.yaml ├── kustomization.yaml ├── l4lb.yaml ├── link.yaml ├── vnet.yaml ├── softgate.yaml ├── inventoryprofile.yaml ├── switch.yaml ├── allocation.yaml ├── nat.yaml ├── bgp.yaml └── subnet.yaml ├── deploy ├── charts │ └── netris-operator │ │ ├── templates │ │ ├── NOTES.txt │ │ ├── serviceaccount.yaml │ │ ├── service.yaml │ │ └── deployment.yaml │ │ ├── .helmignore │ │ ├── Chart.yaml │ │ ├── values.yaml │ │ └── crds │ │ ├── k8s.netris.ai_controllermeta.yaml │ │ ├── k8s.netris.ai_linkmeta.yaml │ │ ├── k8s.netris.ai_subnetmeta.yaml │ │ ├── k8s.netris.ai_links.yaml │ │ ├── k8s.netris.ai_softgatemeta.yaml │ │ ├── k8s.netris.ai_allocationmeta.yaml │ │ └── k8s.netris.ai_controllers.yaml └── README.md ├── .gitignore ├── hack └── boilerplate.go.txt ├── calicowatcher ├── calico.go ├── calico │ └── main.go └── utils.go ├── configloader ├── config.yml ├── configloader.go └── config.go ├── lbwatcher ├── types.go ├── pods.go └── utils.go ├── api └── v1alpha1 │ ├── groupversion_info.go │ ├── l4lb_functions.go │ ├── linkmeta_types.go │ ├── allocationmeta_types.go │ ├── sitemeta_types.go │ ├── subnetmeta_types.go │ ├── link_types.go │ ├── controllermeta_types.go │ ├── softgatemeta_types.go │ ├── natmeta_types.go │ ├── controller_types.go │ ├── inventoryprofilemeta_types.go │ └── switchmeta_types.go ├── Dockerfile ├── controllers ├── utils.go └── suite_test.go ├── netrisstorage ├── links.go ├── ports.go ├── nat.go ├── ebgps.go ├── sites.go ├── l4lbs.go ├── tenants.go ├── vpcs.go └── inventoryprofile.go ├── .github └── workflows │ ├── release.yml │ └── main.yml ├── README.md └── scripts └── rbac-helm-template.py /config/prometheus/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - monitor.yaml 3 | -------------------------------------------------------------------------------- /diagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/netrisai/netris-operator/HEAD/diagram.png -------------------------------------------------------------------------------- /config/certmanager/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - certificate.yaml 3 | 4 | configurations: 5 | - kustomizeconfig.yaml 6 | -------------------------------------------------------------------------------- /config/webhook/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - manifests.yaml 3 | - service.yaml 4 | 5 | configurations: 6 | - kustomizeconfig.yaml 7 | -------------------------------------------------------------------------------- /config/scorecard/bases/config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: scorecard.operatorframework.io/v1alpha3 2 | kind: Configuration 3 | metadata: 4 | name: config 5 | stages: 6 | - parallel: true 7 | tests: [] 8 | -------------------------------------------------------------------------------- /config/rbac/auth_proxy_client_clusterrole.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: metrics-reader 5 | rules: 6 | - nonResourceURLs: ["/metrics"] 7 | verbs: ["get"] 8 | -------------------------------------------------------------------------------- /samples/controller.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: k8s.netris.ai/v1alpha1 2 | kind: Controller 3 | metadata: 4 | name: my-controller 5 | spec: 6 | tenant: Admin 7 | description: My Controller 8 | site: santa-clara 9 | mainIp: 198.51.100.10 10 | -------------------------------------------------------------------------------- /config/manager/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - manager.yaml 3 | apiVersion: kustomize.config.k8s.io/v1beta1 4 | kind: Kustomization 5 | images: 6 | - name: controller 7 | newName: netrisai/netris-operator 8 | patchesStrategicMerge: 9 | - custom-env.yaml 10 | -------------------------------------------------------------------------------- /config/webhook/service.yaml: -------------------------------------------------------------------------------- 1 | 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | name: webhook-service 6 | namespace: system 7 | spec: 8 | ports: 9 | - port: 443 10 | targetPort: 9443 11 | selector: 12 | netris-operator: controller-manager 13 | -------------------------------------------------------------------------------- /samples/site.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: k8s.netris.ai/v1alpha1 2 | kind: Site 3 | metadata: 4 | name: santa-clara 5 | spec: 6 | publicAsn: 65001 7 | rohAsn: 65502 8 | vmAsn: 65503 9 | rohRoutingProfile: default 10 | siteMesh: hub 11 | aclDefaultPolicy: permit 12 | -------------------------------------------------------------------------------- /deploy/charts/netris-operator/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | Netris-Operator has been deployed successfully! 2 | 3 | More information on the netris resources and how to configure them 4 | can be found in our documentation: 5 | 6 | https://github.com/netrisai/netris-operator/tree/master/samples 7 | -------------------------------------------------------------------------------- /config/scorecard/patches/basic.config.yaml: -------------------------------------------------------------------------------- 1 | - op: add 2 | path: /stages/0/tests/- 3 | value: 4 | entrypoint: 5 | - scorecard-test 6 | - basic-check-spec 7 | image: quay.io/operator-framework/scorecard-test:v1.2.0 8 | labels: 9 | suite: basic 10 | test: basic-check-spec-test 11 | -------------------------------------------------------------------------------- /config/crd/patches/cainjection_in_nats.yaml: -------------------------------------------------------------------------------- 1 | # The following patch adds a directive for certmanager to inject CA into the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 7 | name: nats.k8s.netris.ai 8 | -------------------------------------------------------------------------------- /config/rbac/role_binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: manager-rolebinding 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: ClusterRole 8 | name: manager-role 9 | subjects: 10 | - kind: ServiceAccount 11 | name: default 12 | namespace: system 13 | -------------------------------------------------------------------------------- /config/crd/patches/cainjection_in_links.yaml: -------------------------------------------------------------------------------- 1 | # The following patch adds a directive for certmanager to inject CA into the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 7 | name: links.k8s.netris.ai 8 | -------------------------------------------------------------------------------- /config/crd/patches/cainjection_in_natmeta.yaml: -------------------------------------------------------------------------------- 1 | # The following patch adds a directive for certmanager to inject CA into the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 7 | name: natmeta.k8s.netris.ai 8 | -------------------------------------------------------------------------------- /config/crd/patches/cainjection_in_sites.yaml: -------------------------------------------------------------------------------- 1 | # The following patch adds a directive for certmanager to inject CA into the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 7 | name: sites.k8s.netris.ai 8 | -------------------------------------------------------------------------------- /config/crd/patches/cainjection_in_subnets.yaml: -------------------------------------------------------------------------------- 1 | # The following patch adds a directive for certmanager to inject CA into the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 7 | name: subnets.k8s.netris.ai 8 | -------------------------------------------------------------------------------- /config/rbac/auth_proxy_role_binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRoleBinding 3 | metadata: 4 | name: proxy-rolebinding 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: ClusterRole 8 | name: proxy-role 9 | subjects: 10 | - kind: ServiceAccount 11 | name: default 12 | namespace: system 13 | -------------------------------------------------------------------------------- /config/crd/patches/cainjection_in_linkmeta.yaml: -------------------------------------------------------------------------------- 1 | # The following patch adds a directive for certmanager to inject CA into the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 7 | name: linkmeta.k8s.netris.ai 8 | -------------------------------------------------------------------------------- /config/crd/patches/cainjection_in_sitemeta.yaml: -------------------------------------------------------------------------------- 1 | # The following patch adds a directive for certmanager to inject CA into the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 7 | name: sitemeta.k8s.netris.ai 8 | -------------------------------------------------------------------------------- /config/crd/patches/cainjection_in_softgates.yaml: -------------------------------------------------------------------------------- 1 | # The following patch adds a directive for certmanager to inject CA into the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 7 | name: softgates.k8s.netris.ai 8 | -------------------------------------------------------------------------------- /config/crd/patches/cainjection_in_switches.yaml: -------------------------------------------------------------------------------- 1 | # The following patch adds a directive for certmanager to inject CA into the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 7 | name: switches.k8s.netris.ai 8 | -------------------------------------------------------------------------------- /config/crd/patches/cainjection_in_allocations.yaml: -------------------------------------------------------------------------------- 1 | # The following patch adds a directive for certmanager to inject CA into the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 7 | name: allocations.k8s.netris.ai 8 | -------------------------------------------------------------------------------- /config/crd/patches/cainjection_in_controllers.yaml: -------------------------------------------------------------------------------- 1 | # The following patch adds a directive for certmanager to inject CA into the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 7 | name: controllers.k8s.netris.ai 8 | -------------------------------------------------------------------------------- /config/crd/patches/cainjection_in_softgatemeta.yaml: -------------------------------------------------------------------------------- 1 | # The following patch adds a directive for certmanager to inject CA into the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 7 | name: softgatemeta.k8s.netris.ai 8 | -------------------------------------------------------------------------------- /config/crd/patches/cainjection_in_subnetmeta.yaml: -------------------------------------------------------------------------------- 1 | # The following patch adds a directive for certmanager to inject CA into the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 7 | name: subnetmeta.k8s.netris.ai 8 | -------------------------------------------------------------------------------- /config/crd/patches/cainjection_in_switchmeta.yaml: -------------------------------------------------------------------------------- 1 | # The following patch adds a directive for certmanager to inject CA into the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 7 | name: switchmeta.k8s.netris.ai 8 | -------------------------------------------------------------------------------- /config/crd/patches/cainjection_in_allocationmeta.yaml: -------------------------------------------------------------------------------- 1 | # The following patch adds a directive for certmanager to inject CA into the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 7 | name: allocationmeta.k8s.netris.ai 8 | -------------------------------------------------------------------------------- /config/crd/patches/cainjection_in_controllermeta.yaml: -------------------------------------------------------------------------------- 1 | # The following patch adds a directive for certmanager to inject CA into the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 7 | name: controllermeta.k8s.netris.ai 8 | -------------------------------------------------------------------------------- /config/rbac/leader_election_role_binding.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: RoleBinding 3 | metadata: 4 | name: leader-election-rolebinding 5 | roleRef: 6 | apiGroup: rbac.authorization.k8s.io 7 | kind: Role 8 | name: leader-election-role 9 | subjects: 10 | - kind: ServiceAccount 11 | name: default 12 | namespace: system 13 | -------------------------------------------------------------------------------- /config/crd/patches/cainjection_in_inventoryprofiles.yaml: -------------------------------------------------------------------------------- 1 | # The following patch adds a directive for certmanager to inject CA into the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 7 | name: inventoryprofiles.k8s.netris.ai 8 | -------------------------------------------------------------------------------- /config/rbac/auth_proxy_role.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: proxy-role 5 | rules: 6 | - apiGroups: ["authentication.k8s.io"] 7 | resources: 8 | - tokenreviews 9 | verbs: ["create"] 10 | - apiGroups: ["authorization.k8s.io"] 11 | resources: 12 | - subjectaccessreviews 13 | verbs: ["create"] 14 | -------------------------------------------------------------------------------- /config/rbac/auth_proxy_service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | labels: 5 | netris-operator: controller-manager 6 | name: controller-manager-metrics-service 7 | namespace: system 8 | spec: 9 | ports: 10 | - name: https 11 | port: 8443 12 | targetPort: https 13 | selector: 14 | netris-operator: controller-manager 15 | -------------------------------------------------------------------------------- /samples/kustomization.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kustomize.config.k8s.io/v1beta1 2 | kind: Kustomization 3 | resources: 4 | - site.yaml 5 | - allocation.yaml 6 | - subnet.yaml 7 | - softgate.yaml 8 | - switch.yaml 9 | - controller.yaml 10 | - vnet.yaml 11 | - l4lb.yaml 12 | - bgp.yaml 13 | - link.yaml 14 | - nat.yaml 15 | - inventoryprofile.yaml 16 | -------------------------------------------------------------------------------- /config/crd/patches/cainjection_in_inventoryprofilemeta.yaml: -------------------------------------------------------------------------------- 1 | # The following patch adds a directive for certmanager to inject CA into the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | annotations: 6 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 7 | name: inventoryprofilemeta.k8s.netris.ai 8 | -------------------------------------------------------------------------------- /config/crd/patches/cainjection_in_ebgps.yaml: -------------------------------------------------------------------------------- 1 | # The following patch adds a directive for certmanager to inject CA into the CRD 2 | # CRD conversion requires k8s 1.13 or later. 3 | apiVersion: apiextensions.k8s.io/v1beta1 4 | kind: CustomResourceDefinition 5 | metadata: 6 | annotations: 7 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 8 | name: bgps.k8s.netris.ai 9 | -------------------------------------------------------------------------------- /config/crd/patches/cainjection_in_l4lbs.yaml: -------------------------------------------------------------------------------- 1 | # The following patch adds a directive for certmanager to inject CA into the CRD 2 | # CRD conversion requires k8s 1.13 or later. 3 | apiVersion: apiextensions.k8s.io/v1beta1 4 | kind: CustomResourceDefinition 5 | metadata: 6 | annotations: 7 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 8 | name: l4lbs.k8s.netris.ai 9 | -------------------------------------------------------------------------------- /config/crd/patches/cainjection_in_vnets.yaml: -------------------------------------------------------------------------------- 1 | # The following patch adds a directive for certmanager to inject CA into the CRD 2 | # CRD conversion requires k8s 1.13 or later. 3 | apiVersion: apiextensions.k8s.io/v1beta1 4 | kind: CustomResourceDefinition 5 | metadata: 6 | annotations: 7 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 8 | name: vnets.k8s.netris.ai 9 | -------------------------------------------------------------------------------- /config/crd/patches/cainjection_in_ebgpmeta.yaml: -------------------------------------------------------------------------------- 1 | # The following patch adds a directive for certmanager to inject CA into the CRD 2 | # CRD conversion requires k8s 1.13 or later. 3 | apiVersion: apiextensions.k8s.io/v1beta1 4 | kind: CustomResourceDefinition 5 | metadata: 6 | annotations: 7 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 8 | name: bgpmeta.k8s.netris.ai 9 | -------------------------------------------------------------------------------- /config/crd/patches/cainjection_in_l4lbmeta.yaml: -------------------------------------------------------------------------------- 1 | # The following patch adds a directive for certmanager to inject CA into the CRD 2 | # CRD conversion requires k8s 1.13 or later. 3 | apiVersion: apiextensions.k8s.io/v1beta1 4 | kind: CustomResourceDefinition 5 | metadata: 6 | annotations: 7 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 8 | name: l4lbmeta.k8s.netris.ai 9 | -------------------------------------------------------------------------------- /config/crd/patches/cainjection_in_vnetmeta.yaml: -------------------------------------------------------------------------------- 1 | # The following patch adds a directive for certmanager to inject CA into the CRD 2 | # CRD conversion requires k8s 1.13 or later. 3 | apiVersion: apiextensions.k8s.io/v1beta1 4 | kind: CustomResourceDefinition 5 | metadata: 6 | annotations: 7 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 8 | name: vnetmeta.k8s.netris.ai 9 | -------------------------------------------------------------------------------- /samples/l4lb.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: k8s.netris.ai/v1alpha1 2 | kind: L4LB 3 | metadata: 4 | name: my-l4lb 5 | spec: 6 | ownerTenant: Admin 7 | site: santa-clara 8 | state: active 9 | protocol: tcp 10 | frontend: 11 | port: 8443 12 | ip: 203.0.113.150 13 | backend: 14 | - 100.71.56.100:443 15 | - 100.71.56.101:443 16 | check: 17 | type: http 18 | timeout: 3000 19 | requestPath: / 20 | -------------------------------------------------------------------------------- /config/rbac/bgp_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to view bgps. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: bgp-viewer-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - bgps 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - apiGroups: 16 | - k8s.netris.ai 17 | resources: 18 | - bgps/status 19 | verbs: 20 | - get 21 | -------------------------------------------------------------------------------- /config/rbac/nat_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to view nats. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: nat-viewer-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - nats 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - apiGroups: 16 | - k8s.netris.ai 17 | resources: 18 | - nats/status 19 | verbs: 20 | - get 21 | -------------------------------------------------------------------------------- /config/rbac/l4lb_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to view l4lbs. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: l4lb-viewer-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - l4lbs 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - apiGroups: 16 | - k8s.netris.ai 17 | resources: 18 | - l4lbs/status 19 | verbs: 20 | - get 21 | -------------------------------------------------------------------------------- /config/rbac/link_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to view links. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: link-viewer-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - links 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - apiGroups: 16 | - k8s.netris.ai 17 | resources: 18 | - links/status 19 | verbs: 20 | - get 21 | -------------------------------------------------------------------------------- /config/rbac/vnet_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to view vnets. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: vnet-viewer-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - vnets 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - apiGroups: 16 | - k8s.netris.ai 17 | resources: 18 | - vnets/status 19 | verbs: 20 | - get 21 | -------------------------------------------------------------------------------- /config/rbac/bgpmeta_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to view bgpmeta. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: bgpmeta-viewer-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - bgpmeta 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - apiGroups: 16 | - k8s.netris.ai 17 | resources: 18 | - bgpmeta/status 19 | verbs: 20 | - get 21 | -------------------------------------------------------------------------------- /config/rbac/natmeta_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to view natmeta. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: natmeta-viewer-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - natmeta 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - apiGroups: 16 | - k8s.netris.ai 17 | resources: 18 | - natmeta/status 19 | verbs: 20 | - get 21 | -------------------------------------------------------------------------------- /config/rbac/subnet_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to view subnets. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: subnet-viewer-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - subnets 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - apiGroups: 16 | - k8s.netris.ai 17 | resources: 18 | - subnets/status 19 | verbs: 20 | - get 21 | -------------------------------------------------------------------------------- /deploy/charts/netris-operator/templates/serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.serviceAccount.create -}} 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: {{ include "netris-operator.serviceAccountName" . }} 6 | labels: 7 | {{- include "netris-operator.labels" . | nindent 4 }} 8 | {{- with .Values.serviceAccount.annotations }} 9 | annotations: 10 | {{- toYaml . | nindent 4 }} 11 | {{- end }} 12 | {{- end }} 13 | -------------------------------------------------------------------------------- /config/prometheus/monitor.yaml: -------------------------------------------------------------------------------- 1 | 2 | # Prometheus Monitor Service (Metrics) 3 | apiVersion: monitoring.coreos.com/v1 4 | kind: ServiceMonitor 5 | metadata: 6 | labels: 7 | netris-operator: controller-manager 8 | name: controller-manager-metrics-monitor 9 | namespace: system 10 | spec: 11 | endpoints: 12 | - path: /metrics 13 | port: https 14 | selector: 15 | matchLabels: 16 | netris-operator: controller-manager 17 | -------------------------------------------------------------------------------- /config/rbac/l4lbmeta_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to view l4lbmeta. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: l4lbmeta-viewer-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - l4lbmeta 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - apiGroups: 16 | - k8s.netris.ai 17 | resources: 18 | - l4lbmeta/status 19 | verbs: 20 | - get 21 | -------------------------------------------------------------------------------- /config/rbac/linkmeta_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to view linkmeta. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: linkmeta-viewer-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - linkmeta 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - apiGroups: 16 | - k8s.netris.ai 17 | resources: 18 | - linkmeta/status 19 | verbs: 20 | - get 21 | -------------------------------------------------------------------------------- /config/rbac/switch_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to view switches. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: switch-viewer-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - switches 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - apiGroups: 16 | - k8s.netris.ai 17 | resources: 18 | - switches/status 19 | verbs: 20 | - get 21 | -------------------------------------------------------------------------------- /config/rbac/vnetmeta_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to view vnetmeta. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: vnetmeta-viewer-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - vnetmeta 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - apiGroups: 16 | - k8s.netris.ai 17 | resources: 18 | - vnetmeta/status 19 | verbs: 20 | - get 21 | -------------------------------------------------------------------------------- /config/rbac/softgate_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to view softgates. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: softgate-viewer-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - softgates 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - apiGroups: 16 | - k8s.netris.ai 17 | resources: 18 | - softgates/status 19 | verbs: 20 | - get 21 | -------------------------------------------------------------------------------- /config/rbac/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - role.yaml 3 | - role_binding.yaml 4 | - leader_election_role.yaml 5 | - leader_election_role_binding.yaml 6 | # Comment the following 4 lines if you want to disable 7 | # the auth proxy (https://github.com/brancz/kube-rbac-proxy) 8 | # which protects your /metrics endpoint. 9 | - auth_proxy_service.yaml 10 | - auth_proxy_role.yaml 11 | - auth_proxy_role_binding.yaml 12 | - auth_proxy_client_clusterrole.yaml 13 | -------------------------------------------------------------------------------- /config/rbac/subnetmeta_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to view subnetmeta. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: subnetmeta-viewer-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - subnetmeta 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - apiGroups: 16 | - k8s.netris.ai 17 | resources: 18 | - subnetmeta/status 19 | verbs: 20 | - get 21 | -------------------------------------------------------------------------------- /config/rbac/switchmeta_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to view switchmeta. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: switchmeta-viewer-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - switchmeta 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - apiGroups: 16 | - k8s.netris.ai 17 | resources: 18 | - switchmeta/status 19 | verbs: 20 | - get 21 | -------------------------------------------------------------------------------- /config/rbac/allocation_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to view allocations. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: allocation-viewer-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - allocations 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - apiGroups: 16 | - k8s.netris.ai 17 | resources: 18 | - allocations/status 19 | verbs: 20 | - get 21 | -------------------------------------------------------------------------------- /config/rbac/controller_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to view controllers. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: controller-viewer-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - controllers 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - apiGroups: 16 | - k8s.netris.ai 17 | resources: 18 | - controllers/status 19 | verbs: 20 | - get 21 | -------------------------------------------------------------------------------- /config/rbac/softgatemeta_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to view softgatemeta. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: softgatemeta-viewer-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - softgatemeta 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - apiGroups: 16 | - k8s.netris.ai 17 | resources: 18 | - softgatemeta/status 19 | verbs: 20 | - get 21 | -------------------------------------------------------------------------------- /config/rbac/allocationmeta_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to view allocationmeta. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: allocationmeta-viewer-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - allocationmeta 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - apiGroups: 16 | - k8s.netris.ai 17 | resources: 18 | - allocationmeta/status 19 | verbs: 20 | - get 21 | -------------------------------------------------------------------------------- /config/rbac/controllermeta_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to view controllermeta. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: controllermeta-viewer-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - controllermeta 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - apiGroups: 16 | - k8s.netris.ai 17 | resources: 18 | - controllermeta/status 19 | verbs: 20 | - get 21 | -------------------------------------------------------------------------------- /config/scorecard/kustomization.yaml: -------------------------------------------------------------------------------- 1 | resources: 2 | - bases/config.yaml 3 | patchesJson6902: 4 | - path: patches/basic.config.yaml 5 | target: 6 | group: scorecard.operatorframework.io 7 | version: v1alpha3 8 | kind: Configuration 9 | name: config 10 | - path: patches/olm.config.yaml 11 | target: 12 | group: scorecard.operatorframework.io 13 | version: v1alpha3 14 | kind: Configuration 15 | name: config 16 | # +kubebuilder:scaffold:patchesJson6902 17 | -------------------------------------------------------------------------------- /config/crd/patches/webhook_in_nats.yaml: -------------------------------------------------------------------------------- 1 | # The following patch enables a conversion webhook for the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: nats.k8s.netris.ai 6 | spec: 7 | conversion: 8 | strategy: Webhook 9 | webhook: 10 | clientConfig: 11 | service: 12 | namespace: system 13 | name: webhook-service 14 | path: /convert 15 | conversionReviewVersions: 16 | - v1 17 | -------------------------------------------------------------------------------- /config/rbac/bgp_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to edit bgps. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: bgp-editor-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - bgps 11 | verbs: 12 | - create 13 | - delete 14 | - get 15 | - list 16 | - patch 17 | - update 18 | - watch 19 | - apiGroups: 20 | - k8s.netris.ai 21 | resources: 22 | - bgps/status 23 | verbs: 24 | - get 25 | -------------------------------------------------------------------------------- /config/rbac/inventoryprofile_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to view inventoryprofiles. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: inventoryprofile-viewer-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - inventoryprofiles 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - apiGroups: 16 | - k8s.netris.ai 17 | resources: 18 | - inventoryprofiles/status 19 | verbs: 20 | - get 21 | -------------------------------------------------------------------------------- /config/rbac/nat_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to edit nats. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: nat-editor-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - nats 11 | verbs: 12 | - create 13 | - delete 14 | - get 15 | - list 16 | - patch 17 | - update 18 | - watch 19 | - apiGroups: 20 | - k8s.netris.ai 21 | resources: 22 | - nats/status 23 | verbs: 24 | - get 25 | -------------------------------------------------------------------------------- /deploy/charts/netris-operator/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /config/certmanager/kustomizeconfig.yaml: -------------------------------------------------------------------------------- 1 | # This configuration is for teaching kustomize how to update name ref and var substitution 2 | nameReference: 3 | - kind: Issuer 4 | group: cert-manager.io 5 | fieldSpecs: 6 | - kind: Certificate 7 | group: cert-manager.io 8 | path: spec/issuerRef/name 9 | 10 | varReference: 11 | - kind: Certificate 12 | group: cert-manager.io 13 | path: spec/commonName 14 | - kind: Certificate 15 | group: cert-manager.io 16 | path: spec/dnsNames 17 | -------------------------------------------------------------------------------- /config/crd/patches/webhook_in_links.yaml: -------------------------------------------------------------------------------- 1 | # The following patch enables a conversion webhook for the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: links.k8s.netris.ai 6 | spec: 7 | conversion: 8 | strategy: Webhook 9 | webhook: 10 | clientConfig: 11 | service: 12 | namespace: system 13 | name: webhook-service 14 | path: /convert 15 | conversionReviewVersions: 16 | - v1 17 | -------------------------------------------------------------------------------- /config/crd/patches/webhook_in_natmeta.yaml: -------------------------------------------------------------------------------- 1 | # The following patch enables a conversion webhook for the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: natmeta.k8s.netris.ai 6 | spec: 7 | conversion: 8 | strategy: Webhook 9 | webhook: 10 | clientConfig: 11 | service: 12 | namespace: system 13 | name: webhook-service 14 | path: /convert 15 | conversionReviewVersions: 16 | - v1 17 | -------------------------------------------------------------------------------- /config/crd/patches/webhook_in_sites.yaml: -------------------------------------------------------------------------------- 1 | # The following patch enables a conversion webhook for the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: sites.k8s.netris.ai 6 | spec: 7 | conversion: 8 | strategy: Webhook 9 | webhook: 10 | clientConfig: 11 | service: 12 | namespace: system 13 | name: webhook-service 14 | path: /convert 15 | conversionReviewVersions: 16 | - v1 17 | -------------------------------------------------------------------------------- /config/crd/patches/webhook_in_subnets.yaml: -------------------------------------------------------------------------------- 1 | # The following patch enables a conversion webhook for the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: subnets.k8s.netris.ai 6 | spec: 7 | conversion: 8 | strategy: Webhook 9 | webhook: 10 | clientConfig: 11 | service: 12 | namespace: system 13 | name: webhook-service 14 | path: /convert 15 | conversionReviewVersions: 16 | - v1 17 | -------------------------------------------------------------------------------- /config/rbac/l4lb_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to edit l4lbs. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: l4lb-editor-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - l4lbs 11 | verbs: 12 | - create 13 | - delete 14 | - get 15 | - list 16 | - patch 17 | - update 18 | - watch 19 | - apiGroups: 20 | - k8s.netris.ai 21 | resources: 22 | - l4lbs/status 23 | verbs: 24 | - get 25 | -------------------------------------------------------------------------------- /config/rbac/link_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to edit links. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: link-editor-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - links 11 | verbs: 12 | - create 13 | - delete 14 | - get 15 | - list 16 | - patch 17 | - update 18 | - watch 19 | - apiGroups: 20 | - k8s.netris.ai 21 | resources: 22 | - links/status 23 | verbs: 24 | - get 25 | -------------------------------------------------------------------------------- /config/rbac/vnet_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to edit vnets. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: vnet-editor-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - vnets 11 | verbs: 12 | - create 13 | - delete 14 | - get 15 | - list 16 | - patch 17 | - update 18 | - watch 19 | - apiGroups: 20 | - k8s.netris.ai 21 | resources: 22 | - vnets/status 23 | verbs: 24 | - get 25 | -------------------------------------------------------------------------------- /config/crd/patches/webhook_in_linkmeta.yaml: -------------------------------------------------------------------------------- 1 | # The following patch enables a conversion webhook for the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: linkmeta.k8s.netris.ai 6 | spec: 7 | conversion: 8 | strategy: Webhook 9 | webhook: 10 | clientConfig: 11 | service: 12 | namespace: system 13 | name: webhook-service 14 | path: /convert 15 | conversionReviewVersions: 16 | - v1 17 | -------------------------------------------------------------------------------- /config/crd/patches/webhook_in_sitemeta.yaml: -------------------------------------------------------------------------------- 1 | # The following patch enables a conversion webhook for the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: sitemeta.k8s.netris.ai 6 | spec: 7 | conversion: 8 | strategy: Webhook 9 | webhook: 10 | clientConfig: 11 | service: 12 | namespace: system 13 | name: webhook-service 14 | path: /convert 15 | conversionReviewVersions: 16 | - v1 17 | -------------------------------------------------------------------------------- /config/crd/patches/webhook_in_softgates.yaml: -------------------------------------------------------------------------------- 1 | # The following patch enables a conversion webhook for the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: softgates.k8s.netris.ai 6 | spec: 7 | conversion: 8 | strategy: Webhook 9 | webhook: 10 | clientConfig: 11 | service: 12 | namespace: system 13 | name: webhook-service 14 | path: /convert 15 | conversionReviewVersions: 16 | - v1 17 | -------------------------------------------------------------------------------- /config/crd/patches/webhook_in_switches.yaml: -------------------------------------------------------------------------------- 1 | # The following patch enables a conversion webhook for the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: switches.k8s.netris.ai 6 | spec: 7 | conversion: 8 | strategy: Webhook 9 | webhook: 10 | clientConfig: 11 | service: 12 | namespace: system 13 | name: webhook-service 14 | path: /convert 15 | conversionReviewVersions: 16 | - v1 17 | -------------------------------------------------------------------------------- /deploy/charts/netris-operator/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ include "netris-operator.fullname" . }} 5 | labels: 6 | {{- include "netris-operator.labels" . | nindent 4 }} 7 | spec: 8 | type: {{ .Values.service.type }} 9 | ports: 10 | - port: {{ .Values.service.port }} 11 | targetPort: https 12 | protocol: TCP 13 | name: https 14 | selector: 15 | {{- include "netris-operator.selectorLabels" . | nindent 4 }} 16 | -------------------------------------------------------------------------------- /config/crd/patches/webhook_in_allocations.yaml: -------------------------------------------------------------------------------- 1 | # The following patch enables a conversion webhook for the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: allocations.k8s.netris.ai 6 | spec: 7 | conversion: 8 | strategy: Webhook 9 | webhook: 10 | clientConfig: 11 | service: 12 | namespace: system 13 | name: webhook-service 14 | path: /convert 15 | conversionReviewVersions: 16 | - v1 17 | -------------------------------------------------------------------------------- /config/crd/patches/webhook_in_controllers.yaml: -------------------------------------------------------------------------------- 1 | # The following patch enables a conversion webhook for the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: controllers.k8s.netris.ai 6 | spec: 7 | conversion: 8 | strategy: Webhook 9 | webhook: 10 | clientConfig: 11 | service: 12 | namespace: system 13 | name: webhook-service 14 | path: /convert 15 | conversionReviewVersions: 16 | - v1 17 | -------------------------------------------------------------------------------- /config/crd/patches/webhook_in_softgatemeta.yaml: -------------------------------------------------------------------------------- 1 | # The following patch enables a conversion webhook for the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: softgatemeta.k8s.netris.ai 6 | spec: 7 | conversion: 8 | strategy: Webhook 9 | webhook: 10 | clientConfig: 11 | service: 12 | namespace: system 13 | name: webhook-service 14 | path: /convert 15 | conversionReviewVersions: 16 | - v1 17 | -------------------------------------------------------------------------------- /config/crd/patches/webhook_in_subnetmeta.yaml: -------------------------------------------------------------------------------- 1 | # The following patch enables a conversion webhook for the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: subnetmeta.k8s.netris.ai 6 | spec: 7 | conversion: 8 | strategy: Webhook 9 | webhook: 10 | clientConfig: 11 | service: 12 | namespace: system 13 | name: webhook-service 14 | path: /convert 15 | conversionReviewVersions: 16 | - v1 17 | -------------------------------------------------------------------------------- /config/crd/patches/webhook_in_switchmeta.yaml: -------------------------------------------------------------------------------- 1 | # The following patch enables a conversion webhook for the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: switchmeta.k8s.netris.ai 6 | spec: 7 | conversion: 8 | strategy: Webhook 9 | webhook: 10 | clientConfig: 11 | service: 12 | namespace: system 13 | name: webhook-service 14 | path: /convert 15 | conversionReviewVersions: 16 | - v1 17 | -------------------------------------------------------------------------------- /config/rbac/bgpmeta_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to edit bgpmeta. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: bgpmeta-editor-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - bgpmeta 11 | verbs: 12 | - create 13 | - delete 14 | - get 15 | - list 16 | - patch 17 | - update 18 | - watch 19 | - apiGroups: 20 | - k8s.netris.ai 21 | resources: 22 | - bgpmeta/status 23 | verbs: 24 | - get 25 | -------------------------------------------------------------------------------- /config/rbac/inventoryprofilemeta_viewer_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to view inventoryprofilemeta. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: inventoryprofilemeta-viewer-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - inventoryprofilemeta 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - apiGroups: 16 | - k8s.netris.ai 17 | resources: 18 | - inventoryprofilemeta/status 19 | verbs: 20 | - get 21 | -------------------------------------------------------------------------------- /config/rbac/natmeta_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to edit natmeta. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: natmeta-editor-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - natmeta 11 | verbs: 12 | - create 13 | - delete 14 | - get 15 | - list 16 | - patch 17 | - update 18 | - watch 19 | - apiGroups: 20 | - k8s.netris.ai 21 | resources: 22 | - natmeta/status 23 | verbs: 24 | - get 25 | -------------------------------------------------------------------------------- /config/rbac/subnet_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to edit subnets. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: subnet-editor-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - subnets 11 | verbs: 12 | - create 13 | - delete 14 | - get 15 | - list 16 | - patch 17 | - update 18 | - watch 19 | - apiGroups: 20 | - k8s.netris.ai 21 | resources: 22 | - subnets/status 23 | verbs: 24 | - get 25 | -------------------------------------------------------------------------------- /config/rbac/switch_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to edit switches. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: switch-editor-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - switches 11 | verbs: 12 | - create 13 | - delete 14 | - get 15 | - list 16 | - patch 17 | - update 18 | - watch 19 | - apiGroups: 20 | - k8s.netris.ai 21 | resources: 22 | - switches/status 23 | verbs: 24 | - get 25 | -------------------------------------------------------------------------------- /config/crd/patches/webhook_in_allocationmeta.yaml: -------------------------------------------------------------------------------- 1 | # The following patch enables a conversion webhook for the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: allocationmeta.k8s.netris.ai 6 | spec: 7 | conversion: 8 | strategy: Webhook 9 | webhook: 10 | clientConfig: 11 | service: 12 | namespace: system 13 | name: webhook-service 14 | path: /convert 15 | conversionReviewVersions: 16 | - v1 17 | -------------------------------------------------------------------------------- /config/crd/patches/webhook_in_controllermeta.yaml: -------------------------------------------------------------------------------- 1 | # The following patch enables a conversion webhook for the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: controllermeta.k8s.netris.ai 6 | spec: 7 | conversion: 8 | strategy: Webhook 9 | webhook: 10 | clientConfig: 11 | service: 12 | namespace: system 13 | name: webhook-service 14 | path: /convert 15 | conversionReviewVersions: 16 | - v1 17 | -------------------------------------------------------------------------------- /config/rbac/l4lbmeta_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to edit l4lbmeta. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: l4lbmeta-editor-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - l4lbmeta 11 | verbs: 12 | - create 13 | - delete 14 | - get 15 | - list 16 | - patch 17 | - update 18 | - watch 19 | - apiGroups: 20 | - k8s.netris.ai 21 | resources: 22 | - l4lbmeta/status 23 | verbs: 24 | - get 25 | -------------------------------------------------------------------------------- /config/rbac/linkmeta_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to edit linkmeta. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: linkmeta-editor-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - linkmeta 11 | verbs: 12 | - create 13 | - delete 14 | - get 15 | - list 16 | - patch 17 | - update 18 | - watch 19 | - apiGroups: 20 | - k8s.netris.ai 21 | resources: 22 | - linkmeta/status 23 | verbs: 24 | - get 25 | -------------------------------------------------------------------------------- /config/rbac/vnetmeta_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to edit vnetmeta. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: vnetmeta-editor-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - vnetmeta 11 | verbs: 12 | - create 13 | - delete 14 | - get 15 | - list 16 | - patch 17 | - update 18 | - watch 19 | - apiGroups: 20 | - k8s.netris.ai 21 | resources: 22 | - vnetmeta/status 23 | verbs: 24 | - get 25 | -------------------------------------------------------------------------------- /config/crd/patches/webhook_in_inventoryprofiles.yaml: -------------------------------------------------------------------------------- 1 | # The following patch enables a conversion webhook for the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: inventoryprofiles.k8s.netris.ai 6 | spec: 7 | conversion: 8 | strategy: Webhook 9 | webhook: 10 | clientConfig: 11 | service: 12 | namespace: system 13 | name: webhook-service 14 | path: /convert 15 | conversionReviewVersions: 16 | - v1 17 | -------------------------------------------------------------------------------- /config/rbac/softgate_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to edit softgates. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: softgate-editor-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - softgates 11 | verbs: 12 | - create 13 | - delete 14 | - get 15 | - list 16 | - patch 17 | - update 18 | - watch 19 | - apiGroups: 20 | - k8s.netris.ai 21 | resources: 22 | - softgates/status 23 | verbs: 24 | - get 25 | -------------------------------------------------------------------------------- /config/rbac/subnetmeta_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to edit subnetmeta. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: subnetmeta-editor-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - subnetmeta 11 | verbs: 12 | - create 13 | - delete 14 | - get 15 | - list 16 | - patch 17 | - update 18 | - watch 19 | - apiGroups: 20 | - k8s.netris.ai 21 | resources: 22 | - subnetmeta/status 23 | verbs: 24 | - get 25 | -------------------------------------------------------------------------------- /config/rbac/switchmeta_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to edit switchmeta. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: switchmeta-editor-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - switchmeta 11 | verbs: 12 | - create 13 | - delete 14 | - get 15 | - list 16 | - patch 17 | - update 18 | - watch 19 | - apiGroups: 20 | - k8s.netris.ai 21 | resources: 22 | - switchmeta/status 23 | verbs: 24 | - get 25 | -------------------------------------------------------------------------------- /samples/link.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: k8s.netris.ai/v1alpha1 2 | kind: Link 3 | metadata: 4 | name: sw01-to-sw02 5 | spec: 6 | ports: 7 | - swp15@my-sw01 8 | - swp15@my-sw02 9 | --- 10 | apiVersion: k8s.netris.ai/v1alpha1 11 | kind: Link 12 | metadata: 13 | name: sg01-to-sw01 14 | spec: 15 | ports: 16 | - swp1@my-sg01 17 | - swp16@my-sw01 18 | --- 19 | apiVersion: k8s.netris.ai/v1alpha1 20 | kind: Link 21 | metadata: 22 | name: sg02-to-sw02 23 | spec: 24 | ports: 25 | - swp1@my-sg02 26 | - swp16@my-sw02 27 | -------------------------------------------------------------------------------- /config/crd/patches/webhook_in_inventoryprofilemeta.yaml: -------------------------------------------------------------------------------- 1 | # The following patch enables a conversion webhook for the CRD 2 | apiVersion: apiextensions.k8s.io/v1 3 | kind: CustomResourceDefinition 4 | metadata: 5 | name: inventoryprofilemeta.k8s.netris.ai 6 | spec: 7 | conversion: 8 | strategy: Webhook 9 | webhook: 10 | clientConfig: 11 | service: 12 | namespace: system 13 | name: webhook-service 14 | path: /convert 15 | conversionReviewVersions: 16 | - v1 17 | -------------------------------------------------------------------------------- /config/rbac/allocation_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to edit allocations. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: allocation-editor-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - allocations 11 | verbs: 12 | - create 13 | - delete 14 | - get 15 | - list 16 | - patch 17 | - update 18 | - watch 19 | - apiGroups: 20 | - k8s.netris.ai 21 | resources: 22 | - allocations/status 23 | verbs: 24 | - get 25 | -------------------------------------------------------------------------------- /config/rbac/controller_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to edit controllers. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: controller-editor-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - controllers 11 | verbs: 12 | - create 13 | - delete 14 | - get 15 | - list 16 | - patch 17 | - update 18 | - watch 19 | - apiGroups: 20 | - k8s.netris.ai 21 | resources: 22 | - controllers/status 23 | verbs: 24 | - get 25 | -------------------------------------------------------------------------------- /samples/vnet.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: k8s.netris.ai/v1alpha1 2 | kind: VNet 3 | metadata: 4 | name: my-vnet 5 | spec: 6 | ownerTenant: Admin 7 | guestTenants: [] 8 | sites: 9 | - name: santa-clara 10 | gateways: 11 | - prefix: 100.71.56.1/24 12 | dhcp: enabled 13 | dhcpOptionSet: Default 14 | dhcpStartIP: 100.71.56.10 15 | dhcpEndIP: 100.71.56.250 16 | switchPorts: 17 | - name: swp5@my-sw01 18 | vlanId: 1050 19 | - name: swp7@my-sw02 20 | -------------------------------------------------------------------------------- /config/rbac/softgatemeta_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to edit softgatemeta. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: softgatemeta-editor-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - softgatemeta 11 | verbs: 12 | - create 13 | - delete 14 | - get 15 | - list 16 | - patch 17 | - update 18 | - watch 19 | - apiGroups: 20 | - k8s.netris.ai 21 | resources: 22 | - softgatemeta/status 23 | verbs: 24 | - get 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Binaries for programs and plugins 3 | *.exe 4 | *.exe~ 5 | *.dll 6 | *.so 7 | *.dylib 8 | bin 9 | 10 | # Test binary, build with `go test -c` 11 | *.test 12 | 13 | # Output of the go coverage tool, specifically when used with LiteIDE 14 | *.out 15 | k8s 16 | 17 | # Kubernetes Generated files - skip generated files, except for vendored files 18 | 19 | !vendor/**/zz_generated.* 20 | 21 | # editor and IDE paraphernalia 22 | .idea 23 | *.swp 24 | *.swo 25 | *~ 26 | .netrc 27 | testbin 28 | config/samples 29 | .vscode 30 | -------------------------------------------------------------------------------- /config/rbac/allocationmeta_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to edit allocationmeta. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: allocationmeta-editor-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - allocationmeta 11 | verbs: 12 | - create 13 | - delete 14 | - get 15 | - list 16 | - patch 17 | - update 18 | - watch 19 | - apiGroups: 20 | - k8s.netris.ai 21 | resources: 22 | - allocationmeta/status 23 | verbs: 24 | - get 25 | -------------------------------------------------------------------------------- /config/rbac/controllermeta_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to edit controllermeta. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: controllermeta-editor-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - controllermeta 11 | verbs: 12 | - create 13 | - delete 14 | - get 15 | - list 16 | - patch 17 | - update 18 | - watch 19 | - apiGroups: 20 | - k8s.netris.ai 21 | resources: 22 | - controllermeta/status 23 | verbs: 24 | - get 25 | -------------------------------------------------------------------------------- /config/rbac/inventoryprofile_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to edit inventoryprofiles. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: inventoryprofile-editor-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - inventoryprofiles 11 | verbs: 12 | - create 13 | - delete 14 | - get 15 | - list 16 | - patch 17 | - update 18 | - watch 19 | - apiGroups: 20 | - k8s.netris.ai 21 | resources: 22 | - inventoryprofiles/status 23 | verbs: 24 | - get 25 | -------------------------------------------------------------------------------- /samples/softgate.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: k8s.netris.ai/v1alpha1 2 | kind: Softgate 3 | metadata: 4 | name: my-sg01 5 | spec: 6 | tenant: Admin 7 | description: My Softgate01 8 | site: santa-clara 9 | profile: my-profile 10 | # mainIp: 198.51.100.1 11 | # mgmtIp: 192.0.2.1 12 | --- 13 | apiVersion: k8s.netris.ai/v1alpha1 14 | kind: Softgate 15 | metadata: 16 | name: my-sg02 17 | spec: 18 | tenant: Admin 19 | description: My Softgate02 20 | site: santa-clara 21 | profile: my-profile 22 | # mainIp: 198.51.100.2 23 | # mgmtIp: 192.0.2.2 24 | -------------------------------------------------------------------------------- /config/rbac/inventoryprofilemeta_editor_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions for end users to edit inventoryprofilemeta. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: ClusterRole 4 | metadata: 5 | name: inventoryprofilemeta-editor-role 6 | rules: 7 | - apiGroups: 8 | - k8s.netris.ai 9 | resources: 10 | - inventoryprofilemeta 11 | verbs: 12 | - create 13 | - delete 14 | - get 15 | - list 16 | - patch 17 | - update 18 | - watch 19 | - apiGroups: 20 | - k8s.netris.ai 21 | resources: 22 | - inventoryprofilemeta/status 23 | verbs: 24 | - get 25 | -------------------------------------------------------------------------------- /config/crd/kustomizeconfig.yaml: -------------------------------------------------------------------------------- 1 | # This file is for teaching kustomize how to substitute name and namespace reference in CRD 2 | nameReference: 3 | - kind: Service 4 | version: v1 5 | fieldSpecs: 6 | - kind: CustomResourceDefinition 7 | group: apiextensions.k8s.io 8 | path: spec/conversion/webhookClientConfig/service/name 9 | 10 | namespace: 11 | - kind: CustomResourceDefinition 12 | group: apiextensions.k8s.io 13 | path: spec/conversion/webhookClientConfig/service/namespace 14 | create: false 15 | 16 | varReference: 17 | - path: metadata/annotations 18 | -------------------------------------------------------------------------------- /samples/inventoryprofile.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: k8s.netris.ai/v1alpha1 2 | kind: InventoryProfile 3 | metadata: 4 | name: my-profile 5 | spec: 6 | description: My First Inventory Profile 7 | timezone: America/Los_Angeles 8 | allowSshFromIpv4: 9 | - 100.71.56.0/24 10 | - 203.0.113.0/24 11 | allowSshFromIpv6: 12 | - 2001:db8:acad::/64 13 | ntpServers: 14 | - 0.pool.ntp.org 15 | - 132.163.96.5 16 | dnsServers: 17 | - 1.1.1.1 18 | - 8.8.8.8 19 | customRules: 20 | - srcSubnet: 10.0.0.0/8 21 | # srcPort: "" 22 | dstPort: "8443" 23 | protocol: tcp 24 | -------------------------------------------------------------------------------- /config/rbac/leader_election_role.yaml: -------------------------------------------------------------------------------- 1 | # permissions to do leader election. 2 | apiVersion: rbac.authorization.k8s.io/v1 3 | kind: Role 4 | metadata: 5 | name: leader-election-role 6 | rules: 7 | - apiGroups: 8 | - "" 9 | resources: 10 | - configmaps 11 | verbs: 12 | - get 13 | - list 14 | - watch 15 | - create 16 | - update 17 | - patch 18 | - delete 19 | - apiGroups: 20 | - "" 21 | resources: 22 | - configmaps/status 23 | verbs: 24 | - get 25 | - update 26 | - patch 27 | - apiGroups: 28 | - "" 29 | resources: 30 | - events 31 | verbs: 32 | - create 33 | - patch 34 | -------------------------------------------------------------------------------- /hack/boilerplate.go.txt: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021. Netris, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | -------------------------------------------------------------------------------- /config/default/manager_webhook_patch.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: controller-manager 5 | namespace: system 6 | spec: 7 | template: 8 | spec: 9 | containers: 10 | - name: manager 11 | ports: 12 | - containerPort: 9443 13 | name: webhook-server 14 | protocol: TCP 15 | volumeMounts: 16 | - mountPath: /tmp/k8s-webhook-server/serving-certs 17 | name: cert 18 | readOnly: true 19 | volumes: 20 | - name: cert 21 | secret: 22 | defaultMode: 420 23 | secretName: webhook-server-cert 24 | -------------------------------------------------------------------------------- /calicowatcher/calico.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021. Netris, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package calicowatcher 18 | -------------------------------------------------------------------------------- /samples/switch.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: k8s.netris.ai/v1alpha1 2 | kind: Switch 3 | metadata: 4 | name: my-sw01 5 | spec: 6 | tenant: Admin 7 | description: My Switch01 8 | nos: cumulus_linux 9 | site: santa-clara 10 | # asn: 4200000021 11 | profile: my-profile 12 | # mainIp: 198.51.100.3 13 | # mgmtIp: 192.0.2.3 14 | portsCount: 16 15 | --- 16 | apiVersion: k8s.netris.ai/v1alpha1 17 | kind: Switch 18 | metadata: 19 | name: my-sw02 20 | spec: 21 | tenant: Admin 22 | description: My Switch02 23 | nos: ubuntu_switch_dev 24 | site: santa-clara 25 | # asn: 4200000021 26 | profile: my-profile 27 | # mainIp: 198.51.100.4 28 | # mgmtIp: 192.0.2.4 29 | portsCount: 16 30 | -------------------------------------------------------------------------------- /config/crd/patches/webhook_in_ebgps.yaml: -------------------------------------------------------------------------------- 1 | # The following patch enables conversion webhook for CRD 2 | # CRD conversion requires k8s 1.13 or later. 3 | apiVersion: apiextensions.k8s.io/v1beta1 4 | kind: CustomResourceDefinition 5 | metadata: 6 | name: bgps.k8s.netris.ai 7 | spec: 8 | conversion: 9 | strategy: Webhook 10 | webhookClientConfig: 11 | # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank, 12 | # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager) 13 | caBundle: Cg== 14 | service: 15 | namespace: system 16 | name: webhook-service 17 | path: /convert 18 | -------------------------------------------------------------------------------- /config/crd/patches/webhook_in_l4lbs.yaml: -------------------------------------------------------------------------------- 1 | # The following patch enables conversion webhook for CRD 2 | # CRD conversion requires k8s 1.13 or later. 3 | apiVersion: apiextensions.k8s.io/v1beta1 4 | kind: CustomResourceDefinition 5 | metadata: 6 | name: l4lbs.k8s.netris.ai 7 | spec: 8 | conversion: 9 | strategy: Webhook 10 | webhookClientConfig: 11 | # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank, 12 | # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager) 13 | caBundle: Cg== 14 | service: 15 | namespace: system 16 | name: webhook-service 17 | path: /convert 18 | -------------------------------------------------------------------------------- /config/crd/patches/webhook_in_vnets.yaml: -------------------------------------------------------------------------------- 1 | # The following patch enables conversion webhook for CRD 2 | # CRD conversion requires k8s 1.13 or later. 3 | apiVersion: apiextensions.k8s.io/v1beta1 4 | kind: CustomResourceDefinition 5 | metadata: 6 | name: vnets.k8s.netris.ai 7 | spec: 8 | conversion: 9 | strategy: Webhook 10 | webhookClientConfig: 11 | # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank, 12 | # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager) 13 | caBundle: Cg== 14 | service: 15 | namespace: system 16 | name: webhook-service 17 | path: /convert 18 | -------------------------------------------------------------------------------- /config/crd/patches/webhook_in_ebgpmeta.yaml: -------------------------------------------------------------------------------- 1 | # The following patch enables conversion webhook for CRD 2 | # CRD conversion requires k8s 1.13 or later. 3 | apiVersion: apiextensions.k8s.io/v1beta1 4 | kind: CustomResourceDefinition 5 | metadata: 6 | name: bgpmeta.k8s.netris.ai 7 | spec: 8 | conversion: 9 | strategy: Webhook 10 | webhookClientConfig: 11 | # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank, 12 | # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager) 13 | caBundle: Cg== 14 | service: 15 | namespace: system 16 | name: webhook-service 17 | path: /convert 18 | -------------------------------------------------------------------------------- /config/crd/patches/webhook_in_l4lbmeta.yaml: -------------------------------------------------------------------------------- 1 | # The following patch enables conversion webhook for CRD 2 | # CRD conversion requires k8s 1.13 or later. 3 | apiVersion: apiextensions.k8s.io/v1beta1 4 | kind: CustomResourceDefinition 5 | metadata: 6 | name: l4lbmeta.k8s.netris.ai 7 | spec: 8 | conversion: 9 | strategy: Webhook 10 | webhookClientConfig: 11 | # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank, 12 | # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager) 13 | caBundle: Cg== 14 | service: 15 | namespace: system 16 | name: webhook-service 17 | path: /convert 18 | -------------------------------------------------------------------------------- /config/crd/patches/webhook_in_vnetmeta.yaml: -------------------------------------------------------------------------------- 1 | # The following patch enables conversion webhook for CRD 2 | # CRD conversion requires k8s 1.13 or later. 3 | apiVersion: apiextensions.k8s.io/v1beta1 4 | kind: CustomResourceDefinition 5 | metadata: 6 | name: vnetmeta.k8s.netris.ai 7 | spec: 8 | conversion: 9 | strategy: Webhook 10 | webhookClientConfig: 11 | # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank, 12 | # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager) 13 | caBundle: Cg== 14 | service: 15 | namespace: system 16 | name: webhook-service 17 | path: /convert 18 | -------------------------------------------------------------------------------- /config/default/webhookcainjection_patch.yaml: -------------------------------------------------------------------------------- 1 | # This patch add annotation to admission webhook config and 2 | # the variables $(CERTIFICATE_NAMESPACE) and $(CERTIFICATE_NAME) will be substituted by kustomize. 3 | apiVersion: admissionregistration.k8s.io/v1beta1 4 | kind: MutatingWebhookConfiguration 5 | metadata: 6 | name: mutating-webhook-configuration 7 | annotations: 8 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 9 | --- 10 | apiVersion: admissionregistration.k8s.io/v1beta1 11 | kind: ValidatingWebhookConfiguration 12 | metadata: 13 | name: validating-webhook-configuration 14 | annotations: 15 | cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) 16 | -------------------------------------------------------------------------------- /config/manager/manager.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | labels: 5 | netris-operator: controller-manager 6 | name: system 7 | --- 8 | apiVersion: apps/v1 9 | kind: Deployment 10 | metadata: 11 | name: controller-manager 12 | namespace: system 13 | labels: 14 | netris-operator: controller-manager 15 | spec: 16 | selector: 17 | matchLabels: 18 | netris-operator: controller-manager 19 | replicas: 1 20 | template: 21 | metadata: 22 | labels: 23 | netris-operator: controller-manager 24 | spec: 25 | containers: 26 | - command: 27 | - /manager 28 | args: 29 | - --enable-leader-election 30 | image: controller:latest 31 | imagePullPolicy: "Always" 32 | name: manager 33 | terminationGracePeriodSeconds: 10 34 | -------------------------------------------------------------------------------- /configloader/config.yml: -------------------------------------------------------------------------------- 1 | controller: 2 | # host: http://example.com # overwrite env: CONTROLLER_HOST 3 | # login: login # overwrite env: CONTROLLER_LOGIN 4 | # password: pass # overwrite env: CONTROLLER_PASSWORD 5 | # insecure: false # overwrite env: CONTROLLER_INSECURE 6 | 7 | # logdevmode: false # overwrite env: NOPERATOR_DEV_MODE 8 | # requeueinterval: 15 # overwrite env: NOPERATOR_REQUEUE_INTERVAL 9 | # calicoasnrange: 4230000000-4239999999 # overwrite env: NOPERATOR_CALICO_ASN_RANGE 10 | # l4lbtenant: # overwrite env: NOPERATOR_L4LB_TENANT 11 | # vpcid: 1 # overwrite env: NOPERATOR_VPC_ID (VPC ID, integer) 12 | -------------------------------------------------------------------------------- /config/default/manager_auth_proxy_patch.yaml: -------------------------------------------------------------------------------- 1 | # This patch inject a sidecar container which is a HTTP proxy for the 2 | # controller manager, it performs RBAC authorization against the Kubernetes API using SubjectAccessReviews. 3 | apiVersion: apps/v1 4 | kind: Deployment 5 | metadata: 6 | name: controller-manager 7 | namespace: system 8 | spec: 9 | template: 10 | spec: 11 | containers: 12 | - name: kube-rbac-proxy 13 | image: gcr.io/kubebuilder/kube-rbac-proxy:v0.8.0 14 | args: 15 | - "--secure-listen-address=0.0.0.0:8443" 16 | - "--upstream=http://127.0.0.1:8080/" 17 | - "--logtostderr=true" 18 | - "--v=0" 19 | ports: 20 | - containerPort: 8443 21 | name: https 22 | - name: manager 23 | args: 24 | - "--metrics-addr=127.0.0.1:8080" 25 | - "--enable-leader-election" 26 | -------------------------------------------------------------------------------- /samples/allocation.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: k8s.netris.ai/v1alpha1 2 | kind: Allocation 3 | metadata: 4 | name: my-allocation-mgmt 5 | spec: 6 | prefix: 192.0.2.0/24 7 | tenant: Admin 8 | --- 9 | apiVersion: k8s.netris.ai/v1alpha1 10 | kind: Allocation 11 | metadata: 12 | name: my-allocation-loopback 13 | spec: 14 | prefix: 198.51.100.0/24 15 | tenant: Admin 16 | --- 17 | apiVersion: k8s.netris.ai/v1alpha1 18 | kind: Allocation 19 | metadata: 20 | name: my-allocation-common 21 | spec: 22 | prefix: 203.0.113.0/24 23 | tenant: Admin 24 | --- 25 | apiVersion: k8s.netris.ai/v1alpha1 26 | kind: Allocation 27 | metadata: 28 | name: my-allocation-vnet 29 | spec: 30 | prefix: 100.71.56.0/24 31 | tenant: Admin 32 | --- 33 | apiVersion: k8s.netris.ai/v1alpha1 34 | kind: Allocation 35 | metadata: 36 | name: my-allocation-common-v6 37 | spec: 38 | prefix: 2001:db8:acad::/64 39 | tenant: Admin 40 | -------------------------------------------------------------------------------- /config/webhook/kustomizeconfig.yaml: -------------------------------------------------------------------------------- 1 | # the following config is for teaching kustomize where to look at when substituting vars. 2 | # It requires kustomize v2.1.0 or newer to work properly. 3 | nameReference: 4 | - kind: Service 5 | version: v1 6 | fieldSpecs: 7 | - kind: MutatingWebhookConfiguration 8 | group: admissionregistration.k8s.io 9 | path: webhooks/clientConfig/service/name 10 | - kind: ValidatingWebhookConfiguration 11 | group: admissionregistration.k8s.io 12 | path: webhooks/clientConfig/service/name 13 | 14 | namespace: 15 | - kind: MutatingWebhookConfiguration 16 | group: admissionregistration.k8s.io 17 | path: webhooks/clientConfig/service/namespace 18 | create: true 19 | - kind: ValidatingWebhookConfiguration 20 | group: admissionregistration.k8s.io 21 | path: webhooks/clientConfig/service/namespace 22 | create: true 23 | 24 | varReference: 25 | - path: metadata/annotations 26 | -------------------------------------------------------------------------------- /samples/nat.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: k8s.netris.ai/v1alpha1 2 | kind: Nat 3 | metadata: 4 | name: my-snat 5 | spec: 6 | comment: MY SNAT 7 | # state: enabled 8 | site: santa-clara 9 | action: snat 10 | protocol: all 11 | srcAddress: 100.71.56.0/24 12 | dstAddress: 0.0.0.0/0 13 | snatToIp: 203.0.113.192 14 | # snatToPool: 203.0.113.192/26 15 | --- 16 | apiVersion: k8s.netris.ai/v1alpha1 17 | kind: Nat 18 | metadata: 19 | name: my-dnat 20 | spec: 21 | comment: MY DNAT 22 | # state: enabled 23 | site: santa-clara 24 | action: dnat 25 | protocol: tcp 26 | srcAddress: 0.0.0.0/0 27 | srcPort: 1-65535 28 | dstAddress: 203.0.113.193/32 29 | dstPort: "8080" 30 | dnatToIp: 100.71.56.150/32 31 | dnatToPort: "80" 32 | --- 33 | apiVersion: k8s.netris.ai/v1alpha1 34 | kind: Nat 35 | metadata: 36 | name: my-snat-accept 37 | spec: 38 | comment: MY SNAT ACCEPT 39 | # state: enabled 40 | site: santa-clara 41 | action: accept_snat 42 | protocol: all 43 | srcAddress: 100.71.56.0/24 44 | dstAddress: 10.10.0.0/16 45 | -------------------------------------------------------------------------------- /samples/bgp.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: k8s.netris.ai/v1alpha1 2 | kind: BGP 3 | metadata: 4 | name: my-bgp 5 | spec: 6 | site: santa-clara 7 | hardware: my-sg01 8 | neighborAs: 23456 9 | transport: 10 | type: port 11 | name: swp14@my-sw01 12 | vlanId: 3000 13 | localIP: 172.16.0.1/30 14 | remoteIP: 172.16.0.2/30 15 | description: My BGP 16 | # state: enabled 17 | # multihop: 18 | # neighborAddress: 8.8.8.8 19 | # updateSource: 10.254.97.33 20 | # hops: 5 21 | # bgpPassword: somestrongpass 22 | # allowAsIn: 5 23 | # defaultOriginate: false 24 | # prefixInboundMax: 10000 25 | # inboundRouteMap: my-in-rm 26 | # outboundRouteMap: my-out-rm 27 | # localPreference: 100 28 | # weight: 0 29 | # prependInbound: 2 30 | # prependOutbound: 1 31 | prefixListInbound: 32 | - deny 127.0.0.0/8 le 32 33 | - permit 0.0.0.0/0 le 24 34 | prefixListOutbound: 35 | - permit 192.0.2.0/24 36 | - permit 198.51.100.0/24 37 | - permit 203.0.113.0/24 le 26 38 | sendBGPCommunity: 39 | - 65501:777 40 | -------------------------------------------------------------------------------- /config/certmanager/certificate.yaml: -------------------------------------------------------------------------------- 1 | # The following manifests contain a self-signed issuer CR and a certificate CR. 2 | # More document can be found at https://docs.cert-manager.io 3 | # WARNING: Targets CertManager 0.11 check https://docs.cert-manager.io/en/latest/tasks/upgrading/index.html for 4 | # breaking changes 5 | apiVersion: cert-manager.io/v1alpha2 6 | kind: Issuer 7 | metadata: 8 | name: selfsigned-issuer 9 | namespace: system 10 | spec: 11 | selfSigned: {} 12 | --- 13 | apiVersion: cert-manager.io/v1alpha2 14 | kind: Certificate 15 | metadata: 16 | name: serving-cert # this name should match the one appeared in kustomizeconfig.yaml 17 | namespace: system 18 | spec: 19 | # $(SERVICE_NAME) and $(SERVICE_NAMESPACE) will be substituted by kustomize 20 | dnsNames: 21 | - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc 22 | - $(SERVICE_NAME).$(SERVICE_NAMESPACE).svc.cluster.local 23 | issuerRef: 24 | kind: Issuer 25 | name: selfsigned-issuer 26 | secretName: webhook-server-cert # this secret will not be prefixed, since it's not managed by kustomize 27 | -------------------------------------------------------------------------------- /lbwatcher/types.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021. Netris, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package lbwatcher 18 | 19 | import ( 20 | "github.com/netrisai/netris-operator/netrisstorage" 21 | "sigs.k8s.io/controller-runtime/pkg/manager" 22 | ) 23 | 24 | // Watcher is the main structure in order to manage lb watcher 25 | type Watcher struct { 26 | Options Options 27 | NStorage *netrisstorage.Storage 28 | MGR manager.Manager 29 | } 30 | 31 | type lbIP struct { 32 | Name string 33 | IP string 34 | Port int 35 | NodePort int 36 | Protocol string 37 | Automatic bool 38 | } 39 | 40 | // Options . 41 | type Options struct { 42 | LogLevel string 43 | RequeueInterval int 44 | } 45 | -------------------------------------------------------------------------------- /config/manager/custom-env.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: controller-manager 5 | namespace: system 6 | spec: 7 | template: 8 | spec: 9 | containers: 10 | - name: manager 11 | env: 12 | - name: CONTROLLER_HOST 13 | valueFrom: 14 | secretKeyRef: 15 | name: netris-creds 16 | key: host 17 | - name: CONTROLLER_LOGIN 18 | valueFrom: 19 | secretKeyRef: 20 | name: netris-creds 21 | key: login 22 | - name: CONTROLLER_PASSWORD 23 | valueFrom: 24 | secretKeyRef: 25 | name: netris-creds 26 | key: password 27 | - name: CONTROLLER_INSECURE 28 | value: "false" 29 | - name: NOPERATOR_DEV_MODE 30 | value: "false" 31 | - name: NOPERATOR_REQUEUE_INTERVAL 32 | value: "15" 33 | - name: NOPERATOR_CALICO_ASN_RANGE 34 | value: "4230000000-4239999999" 35 | - name: NOPERATOR_L4LB_TENANT 36 | value: "" 37 | - name: NOPERATOR_VPC_ID 38 | value: "1" 39 | -------------------------------------------------------------------------------- /calicowatcher/calico/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021. Netris, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package calico 18 | 19 | import ( 20 | "context" 21 | "time" 22 | ) 23 | 24 | var ( 25 | cntxt = context.Background() 26 | contextTimeout = time.Duration(10 * time.Second) 27 | ) 28 | 29 | // Calico . 30 | type Calico struct { 31 | options Options 32 | } 33 | 34 | // Options . 35 | type Options struct { 36 | ContextTimeout int 37 | } 38 | 39 | // New creates the new calico client. 40 | func New(options Options) *Calico { 41 | if options.ContextTimeout > 0 { 42 | contextTimeout = time.Duration(time.Duration(options.ContextTimeout) * time.Second) 43 | } 44 | return &Calico{ 45 | options: options, 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /deploy/README.md: -------------------------------------------------------------------------------- 1 | # Netris-Operator Deployment 2 | 3 | Netris-operator runs within your Kubernetes cluster as a deployment resource. It utilizes CustomResourceDefinitions to configure netris cloud resources. 4 | 5 | It is deployed using regular YAML manifests, like any other application on Kubernetes. 6 | 7 | # Installing with regular manifests 8 | 9 | All resources are included in a single YAML manifest file: 10 | 11 | 1) Install the CustomResourceDefinitions and netris-operator itself: 12 | 13 | ``` 14 | kubectl apply -f https://github.com/netrisai/netris-operator/releases/latest/download/netris-operator.yaml 15 | ``` 16 | 17 | 18 | 2) Create credentials secret for netris-operator: 19 | 20 | ``` 21 | kubectl -n netris-operator create secret generic netris-creds \ 22 | --from-literal=host="http://example.com" \ 23 | --from-literal=login="login" --from-literal=password="pass" 24 | ``` 25 | 26 | # Installing with Helm 27 | 28 | As an alternative to the YAML manifests referenced above, we also provide an official Helm chart for installing netris-operator. 29 | ## Prerequisites 30 | 31 | - Kubernetes 1.16+ 32 | - Helm 3.1+ 33 | 34 | Documentation for netris-operator chart can be found 35 | [here](https://github.com/netrisai/netris-operator/tree/master/deploy/charts/netris-operator). 36 | -------------------------------------------------------------------------------- /lbwatcher/pods.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021. Netris, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package lbwatcher 18 | 19 | import ( 20 | "context" 21 | "fmt" 22 | 23 | v1 "k8s.io/api/core/v1" 24 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 25 | "k8s.io/client-go/kubernetes" 26 | ) 27 | 28 | func getPodsByLabelSeector(clientset *kubernetes.Clientset, namespace, selectors string) (*v1.PodList, error) { 29 | ctx, cancel := context.WithTimeout(cntxt, contextTimeout) 30 | defer cancel() 31 | listOptions := metav1.ListOptions{ 32 | LabelSelector: selectors, 33 | } 34 | pods, err := clientset.CoreV1().Pods(namespace).List(ctx, listOptions) 35 | if err != nil { 36 | return pods, fmt.Errorf("{getPods} %s", err) 37 | } 38 | return pods, nil 39 | } 40 | -------------------------------------------------------------------------------- /configloader/configloader.go: -------------------------------------------------------------------------------- 1 | package configloader 2 | 3 | import ( 4 | "errors" 5 | "log" 6 | "os" 7 | 8 | "github.com/kelseyhightower/envconfig" 9 | "gopkg.in/yaml.v2" 10 | ) 11 | 12 | const ymlExt = ".yml" 13 | 14 | func readFile(path string, configPtr interface{}) error { 15 | f, openErr := os.Open(path) 16 | if openErr != nil { 17 | return openErr 18 | } 19 | defer func() { 20 | err := f.Close() 21 | if err != nil { 22 | log.Printf("f.Close() error: %v", err) 23 | } 24 | }() 25 | 26 | decoder := yaml.NewDecoder(f) 27 | decErr := decoder.Decode(configPtr) 28 | if decErr != nil { 29 | return decErr 30 | } 31 | 32 | return nil 33 | } 34 | 35 | func readEnv(configPtr interface{}) error { 36 | err := envconfig.Process("", configPtr) 37 | if err != nil { 38 | return err 39 | } 40 | 41 | return nil 42 | } 43 | 44 | // Unmarshal "path" yml file path 45 | // "configPtr" pointer to result struct 46 | func Unmarshal(path string, configPtr interface{}) error { 47 | extension := path[len(path)-4:] 48 | if extension != ymlExt { 49 | return errors.New("only " + ymlExt + " file supported") 50 | } 51 | 52 | fileErr := readFile(path, configPtr) 53 | if fileErr != nil { 54 | log.Println("config.yml not loaded") 55 | } 56 | 57 | envErr := readEnv(configPtr) 58 | if envErr != nil { 59 | return envErr 60 | } 61 | 62 | return nil 63 | } 64 | -------------------------------------------------------------------------------- /api/v1alpha1/groupversion_info.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021. Netris, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Package v1alpha1 contains API Schema definitions for the k8s v1alpha1 API group 18 | // +kubebuilder:object:generate=true 19 | // +groupName=k8s.netris.ai 20 | package v1alpha1 21 | 22 | import ( 23 | "k8s.io/apimachinery/pkg/runtime/schema" 24 | "sigs.k8s.io/controller-runtime/pkg/scheme" 25 | ) 26 | 27 | var ( 28 | // GroupVersion is group version used to register these objects 29 | GroupVersion = schema.GroupVersion{Group: "k8s.netris.ai", Version: "v1alpha1"} 30 | 31 | // SchemeBuilder is used to add go types to the GroupVersionKind scheme 32 | SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} 33 | 34 | // AddToScheme adds the types in this group-version to the given scheme. 35 | AddToScheme = SchemeBuilder.AddToScheme 36 | ) 37 | -------------------------------------------------------------------------------- /config/scorecard/patches/olm.config.yaml: -------------------------------------------------------------------------------- 1 | - op: add 2 | path: /stages/0/tests/- 3 | value: 4 | entrypoint: 5 | - scorecard-test 6 | - olm-bundle-validation 7 | image: quay.io/operator-framework/scorecard-test:v1.2.0 8 | labels: 9 | suite: olm 10 | test: olm-bundle-validation-test 11 | - op: add 12 | path: /stages/0/tests/- 13 | value: 14 | entrypoint: 15 | - scorecard-test 16 | - olm-crds-have-validation 17 | image: quay.io/operator-framework/scorecard-test:v1.2.0 18 | labels: 19 | suite: olm 20 | test: olm-crds-have-validation-test 21 | - op: add 22 | path: /stages/0/tests/- 23 | value: 24 | entrypoint: 25 | - scorecard-test 26 | - olm-crds-have-resources 27 | image: quay.io/operator-framework/scorecard-test:v1.2.0 28 | labels: 29 | suite: olm 30 | test: olm-crds-have-resources-test 31 | - op: add 32 | path: /stages/0/tests/- 33 | value: 34 | entrypoint: 35 | - scorecard-test 36 | - olm-spec-descriptors 37 | image: quay.io/operator-framework/scorecard-test:v1.2.0 38 | labels: 39 | suite: olm 40 | test: olm-spec-descriptors-test 41 | - op: add 42 | path: /stages/0/tests/- 43 | value: 44 | entrypoint: 45 | - scorecard-test 46 | - olm-status-descriptors 47 | image: quay.io/operator-framework/scorecard-test:v1.2.0 48 | labels: 49 | suite: olm 50 | test: olm-status-descriptors-test 51 | -------------------------------------------------------------------------------- /configloader/config.go: -------------------------------------------------------------------------------- 1 | package configloader 2 | 3 | import ( 4 | "log" 5 | "os" 6 | "path" 7 | ) 8 | 9 | type config struct { 10 | Controller controller `yaml:"controller"` 11 | LogDevMode bool `yaml:"logdevmode" envconfig:"NOPERATOR_DEV_MODE"` 12 | RequeueInterval int `yaml:"requeueinterval" envconfig:"NOPERATOR_REQUEUE_INTERVAL"` 13 | CalicoASNRange string `yaml:"calicoasnrange" envconfig:"NOPERATOR_CALICO_ASN_RANGE"` 14 | L4lbTenant string `yaml:"l4lbtenant" envconfig:"NOPERATOR_L4LB_TENANT"` 15 | VPCID int `yaml:"vpcid" envconfig:"NOPERATOR_VPC_ID"` 16 | } 17 | 18 | type controller struct { 19 | Host string `yaml:"host" envconfig:"CONTROLLER_HOST"` 20 | Login string `yaml:"login" envconfig:"CONTROLLER_LOGIN"` 21 | Password string `yaml:"password" envconfig:"CONTROLLER_PASSWORD"` 22 | Insecure bool `yaml:"insecure" envconfig:"CONTROLLER_INSECURE"` 23 | } 24 | 25 | // Root . 26 | var Root *config 27 | 28 | func init() { 29 | wd, err := os.Getwd() 30 | if err != nil { 31 | panic(err) 32 | } 33 | 34 | ptr := &config{} 35 | err = Unmarshal(path.Join(wd, "configloader", "config.yml"), ptr) 36 | Root = ptr 37 | if err != nil { 38 | log.Fatalf("configloader error: %v", err) 39 | } else { 40 | if len(ptr.Controller.Host) == 0 { 41 | log.Fatalln("Please set netris controller credentials") 42 | } else { 43 | log.Printf("connecting to host - %v", ptr.Controller.Host) 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /calicowatcher/utils.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021. Netris, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package calicowatcher 18 | 19 | import ( 20 | "fmt" 21 | "net" 22 | 23 | "github.com/netrisai/netriswebapi/v2/types/ipam" 24 | ) 25 | 26 | func findIPAMByIP(ip string, subnets []*ipam.IPAM) (*ipam.IPAM, error) { 27 | for _, subnet := range subnets { 28 | ipAddr := net.ParseIP(ip) 29 | _, ipNet, err := net.ParseCIDR(subnet.Prefix) 30 | if err != nil { 31 | return nil, err 32 | } 33 | 34 | if ipNet.Contains(ipAddr) { 35 | if len(subnet.Children) > 0 { 36 | ip, err := findIPAMByIP(ip, subnet.Children) 37 | if ip != nil { 38 | return ip, err 39 | } 40 | } 41 | 42 | return subnet, nil 43 | 44 | } 45 | } 46 | 47 | return nil, fmt.Errorf("there are no subnet for specified IP address %s", ip) 48 | } 49 | 50 | func FindIPAMByIP(ip string, subnets []*ipam.IPAM) (*ipam.IPAM, error) { 51 | return findIPAMByIP(ip, subnets) 52 | } 53 | -------------------------------------------------------------------------------- /lbwatcher/utils.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021. Netris, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package lbwatcher 18 | 19 | import ( 20 | "fmt" 21 | "net" 22 | 23 | "github.com/netrisai/netriswebapi/v2/types/ipam" 24 | ) 25 | 26 | func (w *Watcher) findSiteByIP(ip string) (ipam.IDName, string, error) { 27 | var site ipam.IDName 28 | subnets := w.NStorage.SubnetsStorage.GetAll() 29 | 30 | subnetChilds := []*ipam.IPAM{} 31 | for _, subnet := range subnets { 32 | subnetChilds = append(subnetChilds, subnet.Children...) 33 | } 34 | 35 | for _, subnet := range subnetChilds { 36 | ipAddr := net.ParseIP(ip) 37 | _, ipNet, err := net.ParseCIDR(subnet.Prefix) 38 | if err != nil { 39 | return site, "", err 40 | } 41 | if ipNet.Contains(ipAddr) { 42 | if len(subnet.Sites) > 0 { 43 | return subnet.Sites[0], ipNet.String(), nil 44 | } 45 | } 46 | } 47 | 48 | return site, "", fmt.Errorf("There are no sites for specified IP address %s", ip) 49 | } 50 | -------------------------------------------------------------------------------- /deploy/charts/netris-operator/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: netris-operator 3 | description: A Helm chart for netris-operator 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 2.0.0 19 | 20 | # This is the version number of the application being deployed. This version number should be 21 | # incremented each time you make changes to the application. Versions are not expected to 22 | # follow Semantic Versioning. They should reflect the version the application is using. 23 | appVersion: v3.0.0 24 | home: https://github.com/netrisai/netris-operator 25 | icon: https://www.netris.ai/wp-content/uploads/2021/01/logo-300.png # [todo] Change url to permalink 26 | keywords: 27 | - netris-operator 28 | - netris 29 | - netops 30 | sources: 31 | - https://github.com/netrisai/netris-operator 32 | 33 | -------------------------------------------------------------------------------- /samples/subnet.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: k8s.netris.ai/v1alpha1 2 | kind: Subnet 3 | metadata: 4 | name: my-subnet-mgmt 5 | spec: 6 | prefix: 192.0.2.0/24 7 | tenant: Admin 8 | purpose: management 9 | defaultGateway: 192.0.2.254 10 | sites: 11 | - santa-clara 12 | --- 13 | apiVersion: k8s.netris.ai/v1alpha1 14 | kind: Subnet 15 | metadata: 16 | name: my-subnet-loopback 17 | spec: 18 | prefix: 198.51.100.0/24 19 | tenant: Admin 20 | purpose: loopback 21 | sites: 22 | - santa-clara 23 | --- 24 | apiVersion: k8s.netris.ai/v1alpha1 25 | kind: Subnet 26 | metadata: 27 | name: my-subnet-common 28 | spec: 29 | prefix: 203.0.113.0/25 30 | tenant: Admin 31 | purpose: common 32 | sites: 33 | - santa-clara 34 | --- 35 | apiVersion: k8s.netris.ai/v1alpha1 36 | kind: Subnet 37 | metadata: 38 | name: my-subnet-load-balancer 39 | spec: 40 | prefix: 203.0.113.128/26 41 | tenant: Admin 42 | purpose: load-balancer 43 | sites: 44 | - santa-clara 45 | --- 46 | apiVersion: k8s.netris.ai/v1alpha1 47 | kind: Subnet 48 | metadata: 49 | name: my-subnet-nat 50 | spec: 51 | prefix: 203.0.113.192/26 52 | tenant: Admin 53 | purpose: nat 54 | sites: 55 | - santa-clara 56 | --- 57 | apiVersion: k8s.netris.ai/v1alpha1 58 | kind: Subnet 59 | metadata: 60 | name: my-subnet-vnet 61 | spec: 62 | prefix: 100.71.56.0/24 63 | tenant: Admin 64 | purpose: common 65 | sites: 66 | - santa-clara 67 | --- 68 | apiVersion: k8s.netris.ai/v1alpha1 69 | kind: Subnet 70 | metadata: 71 | name: my-subnet-common-v6 72 | spec: 73 | prefix: 2001:db8:acad::/64 74 | tenant: Admin 75 | purpose: common 76 | sites: 77 | - santa-clara 78 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:experimental 2 | # Build arguments provided by buildx 3 | ARG TARGETOS=linux 4 | ARG TARGETARCH=amd64 5 | ARG TARGETPLATFORM=linux/amd64 6 | ARG BUILDPLATFORM=linux/amd64 7 | 8 | # Build the manager binary 9 | FROM --platform=$BUILDPLATFORM golang:1.18 as builder 10 | ARG TARGETOS 11 | ARG TARGETARCH 12 | ARG TARGETPLATFORM 13 | 14 | WORKDIR /workspace 15 | 16 | # Config ssh private key 17 | RUN mkdir -p -m 0600 ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts 18 | RUN git config --global --add url."git@github.com:".insteadOf "https://github.com/" 19 | 20 | # Copy the Go Modules manifests 21 | COPY go.mod go.mod 22 | COPY go.sum go.sum 23 | # cache deps before building and copying source so that we don't need to re-download as much 24 | # and so that source changes don't invalidate our downloaded layer 25 | RUN --mount=type=ssh,id=ssh_private_key_ci go mod download 26 | 27 | # Copy the go source 28 | COPY main.go main.go 29 | COPY api/ api/ 30 | COPY controllers/ controllers/ 31 | COPY configloader/ configloader/ 32 | COPY lbwatcher/ lbwatcher/ 33 | COPY calicowatcher/ calicowatcher/ 34 | COPY netrisstorage/ netrisstorage/ 35 | 36 | # Build 37 | RUN CGO_ENABLED=0 GOOS=${TARGETOS:-linux} GOARCH=${TARGETARCH:-amd64} GO111MODULE=on go build -a -o manager main.go 38 | 39 | # Use distroless as minimal base image to package the manager binary 40 | # Refer to https://github.com/GoogleContainerTools/distroless for more details 41 | FROM --platform=$TARGETPLATFORM gcr.io/distroless/static:nonroot 42 | ARG TARGETPLATFORM 43 | WORKDIR / 44 | COPY --from=builder /workspace/manager . 45 | USER nonroot:nonroot 46 | 47 | ENTRYPOINT ["/manager"] 48 | -------------------------------------------------------------------------------- /config/default/kustomization.yaml: -------------------------------------------------------------------------------- 1 | # Adds namespace to all resources. 2 | namespace: netris-operator 3 | 4 | # Value of this field is prepended to the 5 | # names of all resources, e.g. a deployment named 6 | # "wordpress" becomes "alices-wordpress". 7 | # Note that it should also match with the prefix (text before '-') of the namespace 8 | # field above. 9 | namePrefix: netris-operator- 10 | 11 | # Labels to add to all resources and selectors. 12 | #commonLabels: 13 | # someName: someValue 14 | 15 | # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in 16 | # crd/kustomization.yaml 17 | #- ../webhook 18 | # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 'WEBHOOK' components are required. 19 | #- ../certmanager 20 | # [PROMETHEUS] To enable prometheus monitor, uncomment all sections with 'PROMETHEUS'. 21 | #- ../prometheus 22 | 23 | # Protect the /metrics endpoint by putting it behind auth. 24 | # If you want your controller-manager to expose the /metrics 25 | # endpoint w/o any authn/z, please comment the following line. 26 | patchesStrategicMerge: 27 | - manager_auth_proxy_patch.yaml 28 | 29 | # [WEBHOOK] To enable webhook, uncomment all the sections with [WEBHOOK] prefix including the one in 30 | # crd/kustomization.yaml 31 | #- manager_webhook_patch.yaml 32 | 33 | # [CERTMANAGER] To enable cert-manager, uncomment all sections with 'CERTMANAGER'. 34 | # Uncomment 'CERTMANAGER' sections in crd/kustomization.yaml to enable the CA injection in the admission webhooks. 35 | # 'CERTMANAGER' needs to be enabled to use ca injection 36 | #- webhookcainjection_patch.yaml 37 | 38 | # the following config is for teaching kustomize how to do var substitution 39 | apiVersion: kustomize.config.k8s.io/v1beta1 40 | kind: Kustomization 41 | resources: 42 | - ../crd 43 | - ../rbac 44 | - ../manager 45 | -------------------------------------------------------------------------------- /controllers/utils.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021. Netris, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package controllers 18 | 19 | import ( 20 | "fmt" 21 | "net" 22 | 23 | k8sv1alpha1 "github.com/netrisai/netris-operator/api/v1alpha1" 24 | "github.com/netrisai/netriswebapi/v2/types/dhcp" 25 | ) 26 | 27 | func makeGateway(gateway k8sv1alpha1.VNetGateway, dhcpOptionSetsByNames map[string]*dhcp.DHCPOptionSet) k8sv1alpha1.VNetMetaGateway { 28 | version := "" 29 | ip, ipNet, err := net.ParseCIDR(gateway.Prefix) 30 | if err != nil { 31 | fmt.Println(err) 32 | return k8sv1alpha1.VNetMetaGateway{} 33 | } 34 | 35 | if len(ip.To4()) == net.IPv4len { 36 | version = "ipv4" 37 | } else { 38 | version = "ipv6" 39 | } 40 | 41 | gwLength, _ := ipNet.Mask.Size() 42 | apiGateway := k8sv1alpha1.VNetMetaGateway{ 43 | Gateway: ip.String(), 44 | GwLength: gwLength, 45 | Version: version, 46 | } 47 | 48 | if gateway.DHCP == "enabled" { 49 | apiGateway.DHCP = true 50 | apiGateway.DHCPStartIP = gateway.DHCPStartIP 51 | apiGateway.DHCPEndIP = gateway.DHCPEndIP 52 | 53 | if optionSet, ok := dhcpOptionSetsByNames[gateway.DHCPOptionSet]; ok && optionSet != nil { 54 | apiGateway.DHCPOptionSetID = optionSet.ID 55 | } 56 | } 57 | return apiGateway 58 | } 59 | 60 | func regParser(valueMatch []string, subexpNames []string) map[string]string { 61 | result := make(map[string]string) 62 | for i, name := range subexpNames { 63 | if i != 0 && name != "" { 64 | result[name] = valueMatch[i] 65 | } 66 | } 67 | return result 68 | } 69 | -------------------------------------------------------------------------------- /netrisstorage/links.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021. Netris, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package netrisstorage 18 | 19 | import ( 20 | "sync" 21 | 22 | "github.com/netrisai/netriswebapi/v2/types/link" 23 | ) 24 | 25 | // LinksStorage . 26 | type LinksStorage struct { 27 | sync.Mutex 28 | Links []*link.Link 29 | } 30 | 31 | // NewLinksStorage . 32 | func NewLinksStorage() *LinksStorage { 33 | return &LinksStorage{} 34 | } 35 | 36 | // GetAll . 37 | func (p *LinksStorage) GetAll() []*link.Link { 38 | p.Lock() 39 | defer p.Unlock() 40 | return p.getAll() 41 | } 42 | 43 | func (p *LinksStorage) getAll() []*link.Link { 44 | return p.Links 45 | } 46 | 47 | func (p *LinksStorage) storeAll(items []*link.Link) { 48 | p.Links = items 49 | } 50 | 51 | // Find . 52 | func (p *LinksStorage) Find(local, remote int) (*link.Link, bool) { 53 | p.Lock() 54 | defer p.Unlock() 55 | item, ok := p.find(local, remote) 56 | if !ok { 57 | _ = p.download() 58 | return p.find(local, remote) 59 | } 60 | return item, ok 61 | } 62 | 63 | func (p *LinksStorage) find(local, remote int) (*link.Link, bool) { 64 | for _, link := range p.Links { 65 | if (link.Local.ID == local && link.Remote.ID == remote) || (link.Local.ID == remote && link.Remote.ID == local) { 66 | return link, true 67 | } 68 | } 69 | return nil, false 70 | } 71 | 72 | // Download . 73 | func (p *LinksStorage) download() error { 74 | items, err := Cred.Link().Get() 75 | if err != nil { 76 | return err 77 | } 78 | p.storeAll(items) 79 | return nil 80 | } 81 | 82 | // Download . 83 | func (p *LinksStorage) Download() error { 84 | p.Lock() 85 | defer p.Unlock() 86 | return p.download() 87 | } 88 | -------------------------------------------------------------------------------- /netrisstorage/ports.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021. Netris, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package netrisstorage 18 | 19 | import ( 20 | "fmt" 21 | "sync" 22 | 23 | "github.com/netrisai/netriswebapi/v2/types/port" 24 | ) 25 | 26 | // PortsStorage . 27 | type PortsStorage struct { 28 | sync.Mutex 29 | Ports []*port.Port 30 | } 31 | 32 | // NewPortStorage . 33 | func NewPortStorage() *PortsStorage { 34 | return &PortsStorage{} 35 | } 36 | 37 | func (p *PortsStorage) storeAll(ports []*port.Port) { 38 | p.Ports = ports 39 | } 40 | 41 | // GetAll . 42 | func (p *PortsStorage) GetAll() []*port.Port { 43 | p.Lock() 44 | defer p.Unlock() 45 | return p.getAll() 46 | } 47 | 48 | func (p *PortsStorage) getAll() []*port.Port { 49 | return p.Ports 50 | } 51 | 52 | // FindByName . 53 | func (p *PortsStorage) FindByName(name string) (*port.Port, bool) { 54 | p.Lock() 55 | defer p.Unlock() 56 | return p.findByName(name) 57 | } 58 | 59 | func (p *PortsStorage) findByName(name string) (*port.Port, bool) { 60 | for _, port := range p.Ports { 61 | portName := fmt.Sprintf("%s@%s", port.Port_, port.SwitchName) 62 | if portName == name { 63 | return port, true 64 | } 65 | } 66 | return nil, false 67 | } 68 | 69 | // FindByID . 70 | func (p *PortsStorage) FindByID(id int) (*port.Port, bool) { 71 | p.Lock() 72 | defer p.Unlock() 73 | return p.findByID(id) 74 | } 75 | 76 | func (p *PortsStorage) findByID(id int) (*port.Port, bool) { 77 | for _, port := range p.Ports { 78 | if id == port.ID { 79 | return port, true 80 | } 81 | } 82 | return nil, false 83 | } 84 | 85 | // Download . 86 | func (p *PortsStorage) Download() error { 87 | p.Lock() 88 | defer p.Unlock() 89 | ports, err := Cred.Port().Get() 90 | if err != nil { 91 | return err 92 | } 93 | p.storeAll(ports) 94 | return nil 95 | } 96 | -------------------------------------------------------------------------------- /api/v1alpha1/l4lb_functions.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021. Netris, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package v1alpha1 18 | 19 | // GetServiceName gets the service name from annotations. 20 | func (l *L4LB) GetServiceName() string { 21 | return l.GetAnnotations()["servicename"] 22 | } 23 | 24 | // SetImportFlag set import flags into annotations. 25 | func (l *L4LB) SetImportFlag(s string) { 26 | anns := l.GetAnnotations() 27 | anns["resource.k8s.netris.ai/import"] = s 28 | l.SetAnnotations(anns) 29 | } 30 | 31 | // SetServiceName set service name into annotations. 32 | func (l *L4LB) SetServiceName(s string) { 33 | anns := l.GetAnnotations() 34 | anns["servicename"] = s 35 | l.SetAnnotations(anns) 36 | } 37 | 38 | // GetServiceNamespace gets the service namespace from annotations. 39 | func (l *L4LB) GetServiceNamespace() string { 40 | return l.GetAnnotations()["servicenamespace"] 41 | } 42 | 43 | // SetServiceNamespace set service namespace into annotations. 44 | func (l *L4LB) SetServiceNamespace(s string) { 45 | anns := l.GetAnnotations() 46 | anns["servicenamespace"] = s 47 | l.SetAnnotations(anns) 48 | } 49 | 50 | // GetServiceUID gets the service uuid from annotations. 51 | func (l *L4LB) GetServiceUID() string { 52 | return l.GetAnnotations()["serviceuid"] 53 | } 54 | 55 | // SetServiceUID set service uuid into annotations. 56 | func (l *L4LB) SetServiceUID(s string) { 57 | anns := l.GetAnnotations() 58 | anns["serviceuid"] = s 59 | l.SetAnnotations(anns) 60 | } 61 | 62 | // GetServiceIngressIPs gets the ingress ips from annotations. 63 | func (l *L4LB) GetServiceIngressIPs() string { 64 | return l.GetAnnotations()["serviceingressips"] 65 | } 66 | 67 | // SetServiceIngressIPs set ingress ips into annotations. 68 | func (l *L4LB) SetServiceIngressIPs(s string) { 69 | anns := l.GetAnnotations() 70 | anns["serviceingressips"] = s 71 | l.SetAnnotations(anns) 72 | } 73 | -------------------------------------------------------------------------------- /api/v1alpha1/linkmeta_types.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021. Netris, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package v1alpha1 18 | 19 | import ( 20 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 21 | ) 22 | 23 | // EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! 24 | // NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. 25 | 26 | // LinkMetaSpec defines the desired state of LinkMeta 27 | type LinkMetaSpec struct { 28 | // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster 29 | // Important: Run "make" to regenerate code after modifying this file 30 | Imported bool `json:"imported"` 31 | Reclaim bool `json:"reclaimPolicy"` 32 | LinkCRGeneration int64 `json:"linkGeneration"` 33 | ID string `json:"id"` 34 | LinkName string `json:"linkName"` 35 | 36 | Local int `json:"local"` 37 | Remote int `json:"remote"` 38 | } 39 | 40 | // LinkMetaStatus defines the observed state of LinkMeta 41 | type LinkMetaStatus struct { // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster 42 | // Important: Run "make" to regenerate code after modifying this file 43 | } 44 | 45 | //+kubebuilder:object:root=true 46 | //+kubebuilder:subresource:status 47 | 48 | // LinkMeta is the Schema for the linkmeta API 49 | type LinkMeta struct { 50 | metav1.TypeMeta `json:",inline"` 51 | metav1.ObjectMeta `json:"metadata,omitempty"` 52 | 53 | Spec LinkMetaSpec `json:"spec,omitempty"` 54 | Status LinkMetaStatus `json:"status,omitempty"` 55 | } 56 | 57 | //+kubebuilder:object:root=true 58 | 59 | // LinkMetaList contains a list of LinkMeta 60 | type LinkMetaList struct { 61 | metav1.TypeMeta `json:",inline"` 62 | metav1.ListMeta `json:"metadata,omitempty"` 63 | Items []LinkMeta `json:"items"` 64 | } 65 | 66 | func init() { 67 | SchemeBuilder.Register(&LinkMeta{}, &LinkMetaList{}) 68 | } 69 | -------------------------------------------------------------------------------- /deploy/charts/netris-operator/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ include "netris-operator.fullname" . }} 5 | labels: 6 | {{- include "netris-operator.labels" . | nindent 4 }} 7 | spec: 8 | replicas: {{ .Values.replicaCount }} 9 | selector: 10 | matchLabels: 11 | {{- include "netris-operator.selectorLabels" . | nindent 6 }} 12 | template: 13 | metadata: 14 | {{- with .Values.podAnnotations }} 15 | annotations: 16 | {{- toYaml . | nindent 8 }} 17 | {{- end }} 18 | labels: 19 | {{- include "netris-operator.selectorLabels" . | nindent 8 }} 20 | spec: 21 | {{- with .Values.imagePullSecrets }} 22 | imagePullSecrets: 23 | {{- toYaml . | nindent 8 }} 24 | {{- end }} 25 | serviceAccountName: {{ include "netris-operator.serviceAccountName" . }} 26 | securityContext: 27 | {{- toYaml .Values.podSecurityContext | nindent 8 }} 28 | terminationGracePeriodSeconds: 10 29 | containers: 30 | - name: {{ .Chart.Name }}-kube-rbac-proxy 31 | args: 32 | - --secure-listen-address=0.0.0.0:{{ .Values.service.port }} 33 | - --upstream=http://127.0.0.1:8080/ 34 | - --logtostderr=true 35 | - --v=0 36 | image: gcr.io/kubebuilder/kube-rbac-proxy:v0.8.0 37 | ports: 38 | - containerPort: {{ .Values.service.port }} 39 | name: https 40 | - name: {{ .Chart.Name }}-manager 41 | command: 42 | - /manager 43 | args: 44 | - --metrics-addr=127.0.0.1:8080 45 | - --enable-leader-election 46 | securityContext: 47 | {{- toYaml .Values.securityContext | nindent 12 }} 48 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" 49 | imagePullPolicy: {{ .Values.image.pullPolicy }} 50 | resources: 51 | {{- toYaml .Values.resources | nindent 12 }} 52 | env: 53 | {{- include "netris-operator.controller.envs" . | nindent 12 }} 54 | {{- with .Values.nodeSelector }} 55 | nodeSelector: 56 | {{- toYaml . | nindent 8 }} 57 | {{- end }} 58 | {{- with .Values.affinity }} 59 | affinity: 60 | {{- toYaml . | nindent 8 }} 61 | {{- end }} 62 | {{- with .Values.tolerations }} 63 | tolerations: 64 | {{- toYaml . | nindent 8 }} 65 | {{- end }} 66 | -------------------------------------------------------------------------------- /netrisstorage/nat.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021. Netris, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package netrisstorage 18 | 19 | import ( 20 | "sync" 21 | 22 | "github.com/netrisai/netriswebapi/v2/types/nat" 23 | ) 24 | 25 | // NATStorage . 26 | type NATStorage struct { 27 | sync.Mutex 28 | NAT []*nat.NAT 29 | } 30 | 31 | // NewNATStorage . 32 | func NewNATStorage() *NATStorage { 33 | return &NATStorage{} 34 | } 35 | 36 | // GetAll . 37 | func (p *NATStorage) GetAll() []*nat.NAT { 38 | p.Lock() 39 | defer p.Unlock() 40 | return p.getAll() 41 | } 42 | 43 | func (p *NATStorage) getAll() []*nat.NAT { 44 | return p.NAT 45 | } 46 | 47 | func (p *NATStorage) storeAll(items []*nat.NAT) { 48 | p.NAT = items 49 | } 50 | 51 | // FindByName . 52 | func (p *NATStorage) FindByName(name string) (*nat.NAT, bool) { 53 | p.Lock() 54 | defer p.Unlock() 55 | return p.findByName(name) 56 | } 57 | 58 | func (p *NATStorage) findByName(name string) (*nat.NAT, bool) { 59 | for _, nat := range p.NAT { 60 | if nat.Name == name { 61 | return nat, true 62 | } 63 | } 64 | return nil, false 65 | } 66 | 67 | // FindByID . 68 | func (p *NATStorage) FindByID(id int) (*nat.NAT, bool) { 69 | p.Lock() 70 | defer p.Unlock() 71 | item, ok := p.findByID(id) 72 | if !ok { 73 | _ = p.download() 74 | return p.findByID(id) 75 | } 76 | return item, ok 77 | } 78 | 79 | func (p *NATStorage) findByID(id int) (*nat.NAT, bool) { 80 | for _, nat := range p.NAT { 81 | if nat.ID == id { 82 | return nat, true 83 | } 84 | } 85 | return nil, false 86 | } 87 | 88 | // Download . 89 | func (p *NATStorage) download() error { 90 | items, err := Cred.NAT().Get() 91 | if err != nil { 92 | return err 93 | } 94 | p.storeAll(items) 95 | return nil 96 | } 97 | 98 | // Download . 99 | func (p *NATStorage) Download() error { 100 | p.Lock() 101 | defer p.Unlock() 102 | return p.download() 103 | } 104 | -------------------------------------------------------------------------------- /netrisstorage/ebgps.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021. Netris, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package netrisstorage 18 | 19 | import ( 20 | "sync" 21 | 22 | "github.com/netrisai/netriswebapi/v2/types/bgp" 23 | ) 24 | 25 | // BGPStorage . 26 | type BGPStorage struct { 27 | sync.Mutex 28 | BGPs []*bgp.EBGP 29 | } 30 | 31 | // NewBGPStorage . 32 | func NewBGPStorage() *BGPStorage { 33 | return &BGPStorage{ 34 | BGPs: []*bgp.EBGP{}, 35 | } 36 | } 37 | 38 | func (p *BGPStorage) storeAll(items []*bgp.EBGP) { 39 | p.BGPs = items 40 | } 41 | 42 | // GetAll . 43 | func (p *BGPStorage) GetAll() []*bgp.EBGP { 44 | p.Lock() 45 | defer p.Unlock() 46 | return p.getAll() 47 | } 48 | 49 | func (p *BGPStorage) getAll() []*bgp.EBGP { 50 | return p.BGPs 51 | } 52 | 53 | // FindByID . 54 | func (p *BGPStorage) FindByID(id int) (*bgp.EBGP, bool) { 55 | p.Lock() 56 | defer p.Unlock() 57 | item, ok := p.findByID(id) 58 | if !ok { 59 | _ = p.download() 60 | return p.findByID(id) 61 | } 62 | return item, ok 63 | } 64 | 65 | func (p *BGPStorage) findByID(id int) (*bgp.EBGP, bool) { 66 | for _, item := range p.BGPs { 67 | if item.ID == id { 68 | return item, true 69 | } 70 | } 71 | return nil, false 72 | } 73 | 74 | // FindByName . 75 | func (p *BGPStorage) FindByName(name string) (*bgp.EBGP, bool) { 76 | p.Lock() 77 | defer p.Unlock() 78 | return p.findByName(name) 79 | } 80 | 81 | func (p *BGPStorage) findByName(name string) (*bgp.EBGP, bool) { 82 | for _, item := range p.BGPs { 83 | if item.Name == name { 84 | return item, true 85 | } 86 | } 87 | return nil, false 88 | } 89 | 90 | // Download . 91 | func (p *BGPStorage) download() error { 92 | items, err := Cred.BGP().Get() 93 | if err != nil { 94 | return err 95 | } 96 | p.storeAll(items) 97 | return nil 98 | } 99 | 100 | // Download . 101 | func (p *BGPStorage) Download() error { 102 | p.Lock() 103 | defer p.Unlock() 104 | return p.download() 105 | } 106 | -------------------------------------------------------------------------------- /netrisstorage/sites.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021. Netris, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package netrisstorage 18 | 19 | import ( 20 | "sync" 21 | 22 | "github.com/netrisai/netriswebapi/v2/types/site" 23 | ) 24 | 25 | // SitesStorage . 26 | type SitesStorage struct { 27 | sync.Mutex 28 | Sites []*site.Site 29 | } 30 | 31 | // NewSitesStorage . 32 | func NewSitesStorage() *SitesStorage { 33 | return &SitesStorage{} 34 | } 35 | 36 | // GetAll . 37 | func (p *SitesStorage) GetAll() []*site.Site { 38 | p.Lock() 39 | defer p.Unlock() 40 | return p.getAll() 41 | } 42 | 43 | func (p *SitesStorage) getAll() []*site.Site { 44 | return p.Sites 45 | } 46 | 47 | func (p *SitesStorage) storeAll(items []*site.Site) { 48 | p.Sites = items 49 | } 50 | 51 | // FindByName . 52 | func (p *SitesStorage) FindByName(name string) (*site.Site, bool) { 53 | p.Lock() 54 | defer p.Unlock() 55 | return p.findByName(name) 56 | } 57 | 58 | func (p *SitesStorage) findByName(name string) (*site.Site, bool) { 59 | for _, site := range p.Sites { 60 | if site.Name == name { 61 | return site, true 62 | } 63 | } 64 | return nil, false 65 | } 66 | 67 | // FindByID . 68 | func (p *SitesStorage) FindByID(id int) (*site.Site, bool) { 69 | p.Lock() 70 | defer p.Unlock() 71 | item, ok := p.findByID(id) 72 | if !ok { 73 | _ = p.download() 74 | return p.findByID(id) 75 | } 76 | return item, ok 77 | } 78 | 79 | func (p *SitesStorage) findByID(id int) (*site.Site, bool) { 80 | for _, site := range p.Sites { 81 | if site.ID == id { 82 | return site, true 83 | } 84 | } 85 | return nil, false 86 | } 87 | 88 | // Download . 89 | func (p *SitesStorage) download() error { 90 | items, err := Cred.Site().Get() 91 | if err != nil { 92 | return err 93 | } 94 | p.storeAll(items) 95 | return nil 96 | } 97 | 98 | // Download . 99 | func (p *SitesStorage) Download() error { 100 | p.Lock() 101 | defer p.Unlock() 102 | return p.download() 103 | } 104 | -------------------------------------------------------------------------------- /api/v1alpha1/allocationmeta_types.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021. Netris, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package v1alpha1 18 | 19 | import ( 20 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 21 | ) 22 | 23 | // EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! 24 | // NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. 25 | 26 | // AllocationMetaSpec defines the desired state of AllocationMeta 27 | type AllocationMetaSpec struct { 28 | // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster 29 | // Important: Run "make" to regenerate code after modifying this file 30 | Imported bool `json:"imported"` 31 | Reclaim bool `json:"reclaimPolicy"` 32 | AllocationCRGeneration int64 `json:"allocationGeneration"` 33 | ID int `json:"id"` 34 | AllocationName string `json:"allocationName"` 35 | 36 | Prefix string `json:"prefix"` 37 | Tenant string `json:"tenant"` 38 | } 39 | 40 | // AllocationMetaStatus defines the observed state of AllocationMeta 41 | type AllocationMetaStatus struct { // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster 42 | // Important: Run "make" to regenerate code after modifying this file 43 | } 44 | 45 | //+kubebuilder:object:root=true 46 | //+kubebuilder:subresource:status 47 | 48 | // AllocationMeta is the Schema for the allocationmeta API 49 | type AllocationMeta struct { 50 | metav1.TypeMeta `json:",inline"` 51 | metav1.ObjectMeta `json:"metadata,omitempty"` 52 | 53 | Spec AllocationMetaSpec `json:"spec,omitempty"` 54 | Status AllocationMetaStatus `json:"status,omitempty"` 55 | } 56 | 57 | //+kubebuilder:object:root=true 58 | 59 | // AllocationMetaList contains a list of AllocationMeta 60 | type AllocationMetaList struct { 61 | metav1.TypeMeta `json:",inline"` 62 | metav1.ListMeta `json:"metadata,omitempty"` 63 | Items []AllocationMeta `json:"items"` 64 | } 65 | 66 | func init() { 67 | SchemeBuilder.Register(&AllocationMeta{}, &AllocationMetaList{}) 68 | } 69 | -------------------------------------------------------------------------------- /controllers/suite_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021. Netris, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package controllers 18 | 19 | import ( 20 | "path/filepath" 21 | "testing" 22 | 23 | . "github.com/onsi/ginkgo" 24 | . "github.com/onsi/gomega" 25 | "k8s.io/client-go/kubernetes/scheme" 26 | "k8s.io/client-go/rest" 27 | "sigs.k8s.io/controller-runtime/pkg/client" 28 | "sigs.k8s.io/controller-runtime/pkg/envtest" 29 | "sigs.k8s.io/controller-runtime/pkg/envtest/printer" 30 | logf "sigs.k8s.io/controller-runtime/pkg/log" 31 | "sigs.k8s.io/controller-runtime/pkg/log/zap" 32 | 33 | k8sv1alpha1 "github.com/netrisai/netris-operator/api/v1alpha1" 34 | // +kubebuilder:scaffold:imports 35 | ) 36 | 37 | // These tests use Ginkgo (BDD-style Go testing framework). Refer to 38 | // http://onsi.github.io/ginkgo/ to learn more about Ginkgo. 39 | 40 | var ( 41 | cfg *rest.Config 42 | k8sClient client.Client 43 | testEnv *envtest.Environment 44 | ) 45 | 46 | func TestAPIs(t *testing.T) { 47 | RegisterFailHandler(Fail) 48 | 49 | RunSpecsWithDefaultAndCustomReporters(t, 50 | "Controller Suite", 51 | []Reporter{printer.NewlineReporter{}}) 52 | } 53 | 54 | var _ = BeforeSuite(func(done Done) { 55 | logf.SetLogger(zap.New(zap.UseDevMode(true), zap.WriteTo(GinkgoWriter))) 56 | 57 | By("bootstrapping test environment") 58 | testEnv = &envtest.Environment{ 59 | CRDDirectoryPaths: []string{filepath.Join("..", "config", "crd", "bases")}, 60 | } 61 | 62 | var err error 63 | cfg, err = testEnv.Start() 64 | Expect(err).ToNot(HaveOccurred()) 65 | Expect(cfg).ToNot(BeNil()) 66 | 67 | err = k8sv1alpha1.AddToScheme(scheme.Scheme) 68 | Expect(err).NotTo(HaveOccurred()) 69 | 70 | // +kubebuilder:scaffold:scheme 71 | 72 | k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme}) 73 | Expect(err).ToNot(HaveOccurred()) 74 | Expect(k8sClient).ToNot(BeNil()) 75 | 76 | close(done) 77 | }, 60) 78 | 79 | var _ = AfterSuite(func() { 80 | By("tearing down the test environment") 81 | err := testEnv.Stop() 82 | Expect(err).ToNot(HaveOccurred()) 83 | }) 84 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: Create release 2 | on: 3 | push: 4 | # Sequence of patterns matched against refs/tags 5 | tags: 6 | - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10 7 | jobs: 8 | build: 9 | name: Upload Release Asset 10 | runs-on: ubuntu-22.04 11 | steps: 12 | - name: Checkout code 13 | uses: actions/checkout@v2 14 | - name: Git configs and known_hosts 15 | run: | 16 | export known_hosts=$(ssh-keyscan github.com) 17 | git config --global --add url."git@github.com:".insteadOf "https://github.com/" 18 | - name: Set up Go 19 | uses: actions/setup-go@v4 20 | with: 21 | go-version: "1.18" 22 | - name: Install SSH key 23 | uses: shimataro/ssh-key-action@v2 24 | with: 25 | key: ${{ secrets.SSH_PRIVATE_KEY_NETRISAPI }} 26 | known_hosts: ${known_hosts} 27 | - name: Generate Manifests 28 | run: make release 29 | - name: Create Release 30 | id: create_release 31 | uses: actions/create-release@v1 32 | env: 33 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 34 | with: 35 | tag_name: ${{ github.ref }} 36 | release_name: Release ${{ github.ref }} 37 | draft: false 38 | prerelease: false 39 | - name: Upload Release Asset 40 | uses: actions/upload-release-asset@v1 41 | env: 42 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 43 | with: 44 | upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps 45 | asset_path: ./deploy/netris-operator.yaml 46 | asset_name: netris-operator.yaml 47 | asset_content_type: text/yaml 48 | - name: Upload Release Asset - CRD 49 | uses: actions/upload-release-asset@v1 50 | env: 51 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 52 | with: 53 | upload_url: ${{ steps.create_release.outputs.upload_url }} # This pulls from the CREATE RELEASE step above, referencing it's ID to get its outputs object, which include a `upload_url`. See this blog post for more info: https://jasonet.co/posts/new-features-of-github-actions/#passing-data-to-future-steps 54 | asset_path: ./deploy/netris-operator.crds.yaml 55 | asset_name: netris-operator.crds.yaml 56 | asset_content_type: text/yaml 57 | -------------------------------------------------------------------------------- /netrisstorage/l4lbs.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021. Netris, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package netrisstorage 18 | 19 | import ( 20 | "sync" 21 | 22 | "github.com/netrisai/netriswebapi/v2/types/l4lb" 23 | ) 24 | 25 | // L4LBStorage . 26 | type L4LBStorage struct { 27 | sync.Mutex 28 | L4LBs []*l4lb.LoadBalancer 29 | } 30 | 31 | // NewL4LBStorage . 32 | func NewL4LBStorage() *L4LBStorage { 33 | return &L4LBStorage{} 34 | } 35 | 36 | // GetAll . 37 | func (p *L4LBStorage) GetAll() []*l4lb.LoadBalancer { 38 | p.Lock() 39 | defer p.Unlock() 40 | return p.getAll() 41 | } 42 | 43 | func (p *L4LBStorage) getAll() []*l4lb.LoadBalancer { 44 | return p.L4LBs 45 | } 46 | 47 | func (p *L4LBStorage) storeAll(items []*l4lb.LoadBalancer) { 48 | p.L4LBs = items 49 | } 50 | 51 | // FindByName . 52 | func (p *L4LBStorage) FindByName(name string) (*l4lb.LoadBalancer, bool) { 53 | p.Lock() 54 | defer p.Unlock() 55 | return p.findByName(name) 56 | } 57 | 58 | func (p *L4LBStorage) findByName(name string) (*l4lb.LoadBalancer, bool) { 59 | for _, item := range p.L4LBs { 60 | if item.Name == name { 61 | return item, true 62 | } 63 | } 64 | return nil, false 65 | } 66 | 67 | // FindByID . 68 | func (p *L4LBStorage) FindByID(id int) (*l4lb.LoadBalancer, bool) { 69 | p.Lock() 70 | defer p.Unlock() 71 | item, ok := p.findByID(id) 72 | if !ok { 73 | _ = p.download() 74 | return p.findByID(id) 75 | } 76 | return item, ok 77 | } 78 | 79 | func (p *L4LBStorage) findByID(id int) (*l4lb.LoadBalancer, bool) { 80 | for _, item := range p.L4LBs { 81 | if item.ID == id { 82 | return item, true 83 | } 84 | } 85 | return nil, false 86 | } 87 | 88 | // Download . 89 | func (p *L4LBStorage) download() error { 90 | items, err := Cred.L4LB().Get() 91 | if err != nil { 92 | return err 93 | } 94 | p.storeAll(items) 95 | return nil 96 | } 97 | 98 | // Download . 99 | func (p *L4LBStorage) Download() error { 100 | p.Lock() 101 | defer p.Unlock() 102 | return p.download() 103 | } 104 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Netris Operator 2 | 3 | [![Slack](https://img.shields.io/badge/slack-@netrisai-blue.svg?logo=slack)](https://www.netris.ai/slack/) 4 | [![GitHub release](https://img.shields.io/github/v/tag/netrisai/netris-operator.svg?label=release&sort=semver)](https://github.com/netrisai/netris-operator/releases) 5 | [![](https://github.com/netrisai/netris-operator/workflows/Create%20release/badge.svg)](https://github.com/netrisai/netris-operator/actions) 6 | [![Artifact HUB](https://img.shields.io/endpoint?url=https://artifacthub.io/badge/repository/netrisai)](https://artifacthub.io/packages/helm/netrisai/netris-operator) 7 | [![Go Report Card](https://goreportcard.com/badge/github.com/netrisai/netris-operator)](https://goreportcard.com/report/github.com/netrisai/netris-operator) 8 | [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) 9 | 10 | 11 | [Netris Operator](https://github.com/netrisai/netris-operator) is a Kubernetes Operator for managing and automating tasks related to managing Netris VPC. 12 | 13 | [Netris](https://netris.ai) automatically operates the physical switching network in your data center, bare metal cloud, or at the edge. Netris automatically enables routing, elastic load balancer, firewall, DHCP, NAT, and other essential network services utilizing ordinary servers and SmartNICs. Netris makes your network automatic, resilient, and uncomplicated - just like the cloud but very cost-efficient. 14 | 15 | 16 | ![](diagram.png) 17 | 18 | 19 | ## Deploying the Operator 20 | The current version of netris-operator requires Kubernetes >= 1.16. 21 | 22 | ### GitOps 23 | Kubernetes manifests are located in the `deploy/` folder. To deploy the operator manually using Kubernetes manifests or to integrate it into your GitOps flow please follow [these instructions](./deploy/). 24 | 25 | ### Helm Charts 26 | 27 | You can also use [Helm charts](./deploy/charts/netris-operator) to deploy Netris Operator. 28 | ## Documentation 29 | Netris Operator managing resources samples are available in the `samples/` [folder](./samples/). 30 | 31 | ## Compatibility with Netris-Controller 32 | | Operator version | Controller version | 33 | | -----------------| -------------------| 34 | | `v0.X` | `v2.9` | 35 | | `v1.X` | `v3.0` | 36 | | `v2.X` | `v3.1+` | 37 | | `v3.X` | `v4.1+` | 38 | | `v4.X` | `v4.3+` | 39 | 40 | 41 | ## Features 42 | * Managing Netris Controller via CRD 43 | * Automatically creating `L4LB` resource for `type: load-balancer` services 44 | * All CNIs are welcome 45 | -------------------------------------------------------------------------------- /deploy/charts/netris-operator/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for netris-operator. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | 5 | replicaCount: 1 6 | 7 | image: 8 | repository: netrisai/netris-operator 9 | pullPolicy: Always 10 | # Overrides the image tag whose default is the chart appVersion. 11 | tag: "" 12 | 13 | imagePullSecrets: [] 14 | nameOverride: "" 15 | fullnameOverride: "" 16 | 17 | controller: {} 18 | # host: http://example.com 19 | # login: login 20 | # password: pass 21 | # insecure: false 22 | 23 | controllerCreds: 24 | host: 25 | secretName: netris-creds 26 | key: host 27 | login: 28 | secretName: netris-creds 29 | key: login 30 | password: 31 | secretName: netris-creds 32 | key: password 33 | 34 | # Set the log level of netris-operator. Possible values 'info' or 'debug' 35 | logLevel: info 36 | 37 | # Set the requeue interval in seconds for the netris-operator. 38 | requeueInterval: 15 39 | 40 | # Set Nodes asn range. Used when Netris-Operator manages Calico CNI 41 | calicoASNRange: 4230000000-4239999999 42 | 43 | # Set the default Tenant for L4LB resources. If set, a tenant autodetection for L4LB resources will be disabled 44 | l4lbTenant: "" 45 | 46 | # Set VPC ID to handle (integer) 47 | vpcid: 1 48 | 49 | rbac: 50 | # Specifies whether RBAC resources should be created 51 | create: true 52 | 53 | serviceAccount: 54 | # Specifies whether a service account should be created 55 | create: true 56 | # Annotations to add to the service account 57 | annotations: {} 58 | # The name of the service account to use. 59 | # If not set and create is true, a name is generated using the fullname template 60 | name: "" 61 | 62 | podAnnotations: {} 63 | 64 | podSecurityContext: {} 65 | # fsGroup: 2000 66 | 67 | securityContext: {} 68 | # capabilities: 69 | # drop: 70 | # - ALL 71 | # readOnlyRootFilesystem: true 72 | # runAsNonRoot: true 73 | # runAsUser: 1000 74 | 75 | service: 76 | type: ClusterIP 77 | port: 8443 78 | 79 | resources: {} 80 | # We usually recommend not to specify default resources and to leave this as a conscious 81 | # choice for the user. This also increases chances charts run on environments with little 82 | # resources, such as Minikube. If you do want to specify resources, uncomment the following 83 | # lines, adjust them as necessary, and remove the curly braces after 'resources:'. 84 | # limits: 85 | # cpu: 100m 86 | # memory: 128Mi 87 | # requests: 88 | # cpu: 100m 89 | # memory: 128Mi 90 | 91 | nodeSelector: {} 92 | 93 | tolerations: [] 94 | 95 | affinity: {} 96 | -------------------------------------------------------------------------------- /netrisstorage/tenants.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021. Netris, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package netrisstorage 18 | 19 | import ( 20 | "sync" 21 | 22 | "github.com/netrisai/netriswebapi/v1/types/tenant" 23 | ) 24 | 25 | // TenantsStorage . 26 | type TenantsStorage struct { 27 | sync.Mutex 28 | Tenants []*tenant.Tenant 29 | } 30 | 31 | // NewTenantsStorage . 32 | func NewTenantsStorage() *TenantsStorage { 33 | return &TenantsStorage{} 34 | } 35 | 36 | // GetAll . 37 | func (p *TenantsStorage) GetAll() []*tenant.Tenant { 38 | p.Lock() 39 | defer p.Unlock() 40 | return p.getAll() 41 | } 42 | 43 | func (p *TenantsStorage) getAll() []*tenant.Tenant { 44 | return p.Tenants 45 | } 46 | 47 | func (p *TenantsStorage) storeAll(items []*tenant.Tenant) { 48 | p.Tenants = items 49 | } 50 | 51 | // FindByName . 52 | func (p *TenantsStorage) FindByName(name string) (*tenant.Tenant, bool) { 53 | p.Lock() 54 | defer p.Unlock() 55 | return p.findByName(name) 56 | } 57 | 58 | func (p *TenantsStorage) findByName(name string) (*tenant.Tenant, bool) { 59 | for _, item := range p.Tenants { 60 | if item.Name == name { 61 | return item, true 62 | } 63 | } 64 | return nil, false 65 | } 66 | 67 | // FindByID . 68 | func (p *TenantsStorage) FindByID(id int) (*tenant.Tenant, bool) { 69 | p.Lock() 70 | defer p.Unlock() 71 | item, ok := p.findByID(id) 72 | if !ok { 73 | _ = p.download() 74 | return p.findByID(id) 75 | } 76 | return item, ok 77 | } 78 | 79 | func (p *TenantsStorage) findByID(id int) (*tenant.Tenant, bool) { 80 | for _, item := range p.Tenants { 81 | if item.ID == id { 82 | return item, true 83 | } 84 | } 85 | return nil, false 86 | } 87 | 88 | // Download . 89 | func (p *TenantsStorage) download() error { 90 | items, err := Cred.Tenant().Get() 91 | if err != nil { 92 | return err 93 | } 94 | p.storeAll(items) 95 | return nil 96 | } 97 | 98 | // Download . 99 | func (p *TenantsStorage) Download() error { 100 | p.Lock() 101 | defer p.Unlock() 102 | return p.download() 103 | } 104 | -------------------------------------------------------------------------------- /api/v1alpha1/sitemeta_types.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021. Netris, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package v1alpha1 18 | 19 | import ( 20 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 21 | ) 22 | 23 | // EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! 24 | // NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. 25 | 26 | // SiteMetaStatus defines the observed state of SiteMeta 27 | type SiteMetaStatus struct { // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster 28 | // Important: Run "make" to regenerate code after modifying this file 29 | } 30 | 31 | // SiteMetaSpec defines the desired state of SiteMeta 32 | type SiteMetaSpec struct { 33 | // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster 34 | // Important: Run "make" to regenerate code after modifying this file 35 | Imported bool `json:"imported"` 36 | Reclaim bool `json:"reclaimPolicy"` 37 | SiteCRGeneration int64 `json:"siteGeneration"` 38 | ID int `json:"id"` 39 | SiteName string `json:"siteName"` 40 | 41 | PublicASN int `json:"publicAsn"` 42 | RohASN int `json:"rohAsn"` 43 | VMASN int `json:"vmAsn"` 44 | RohRoutingProfileID int `json:"rohRoutingProfile"` 45 | SiteMesh string `json:"siteMesh"` 46 | 47 | ACLDefaultPolicy string `json:"aclDefaultPolicy"` 48 | } 49 | 50 | // +kubebuilder:object:root=true 51 | // +kubebuilder:subresource:status 52 | 53 | // SiteMeta is the Schema for the sitemeta API 54 | type SiteMeta struct { 55 | metav1.TypeMeta `json:",inline"` 56 | metav1.ObjectMeta `json:"metadata,omitempty"` 57 | 58 | Spec SiteMetaSpec `json:"spec,omitempty"` 59 | Status SiteMetaStatus `json:"status,omitempty"` 60 | } 61 | 62 | // +kubebuilder:object:root=true 63 | 64 | // SiteMetaList contains a list of SiteMeta 65 | type SiteMetaList struct { 66 | metav1.TypeMeta `json:",inline"` 67 | metav1.ListMeta `json:"metadata,omitempty"` 68 | Items []SiteMeta `json:"items"` 69 | } 70 | 71 | func init() { 72 | SchemeBuilder.Register(&SiteMeta{}, &SiteMetaList{}) 73 | } 74 | -------------------------------------------------------------------------------- /api/v1alpha1/subnetmeta_types.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021. Netris, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package v1alpha1 18 | 19 | import ( 20 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 21 | ) 22 | 23 | // EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! 24 | // NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. 25 | 26 | // SubnetMetaSpec defines the desired state of SubnetMeta 27 | type SubnetMetaSpec struct { 28 | // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster 29 | // Important: Run "make" to regenerate code after modifying this file 30 | 31 | Imported bool `json:"imported"` 32 | Reclaim bool `json:"reclaimPolicy"` 33 | SubnetCRGeneration int64 `json:"subnetGeneration"` 34 | ID int `json:"id"` 35 | SubnetName string `json:"subnetName"` 36 | 37 | Prefix string `json:"prefix,omitempty"` 38 | TenantID int `json:"tenantid,omitempty"` 39 | Purpose string `json:"purpose,omitempty"` 40 | DefaultGateway string `json:"defaultGateway,omitempty"` 41 | Sites []int `json:"sites,omitempty"` 42 | } 43 | 44 | // SubnetMetaStatus defines the observed state of SubnetMeta 45 | type SubnetMetaStatus struct { // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster 46 | // Important: Run "make" to regenerate code after modifying this file 47 | } 48 | 49 | //+kubebuilder:object:root=true 50 | //+kubebuilder:subresource:status 51 | 52 | // SubnetMeta is the Schema for the subnetmeta API 53 | type SubnetMeta struct { 54 | metav1.TypeMeta `json:",inline"` 55 | metav1.ObjectMeta `json:"metadata,omitempty"` 56 | 57 | Spec SubnetMetaSpec `json:"spec,omitempty"` 58 | Status SubnetMetaStatus `json:"status,omitempty"` 59 | } 60 | 61 | //+kubebuilder:object:root=true 62 | 63 | // SubnetMetaList contains a list of SubnetMeta 64 | type SubnetMetaList struct { 65 | metav1.TypeMeta `json:",inline"` 66 | metav1.ListMeta `json:"metadata,omitempty"` 67 | Items []SubnetMeta `json:"items"` 68 | } 69 | 70 | func init() { 71 | SchemeBuilder.Register(&SubnetMeta{}, &SubnetMetaList{}) 72 | } 73 | -------------------------------------------------------------------------------- /api/v1alpha1/link_types.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021. Netris, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package v1alpha1 18 | 19 | import ( 20 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 21 | ) 22 | 23 | // EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! 24 | // NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. 25 | 26 | // LinkSpec defines the desired state of Link 27 | type LinkSpec struct { 28 | // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster 29 | // Important: Run "make" to regenerate code after modifying this file 30 | 31 | // +kubebuilder:validation:MinItems=2 32 | // +kubebuilder:validation:MaxItems=2 33 | Ports []LinkSpecPort `json:"ports"` 34 | } 35 | 36 | // LinkSpecPort . 37 | type LinkSpecPort string 38 | 39 | func (l LinkSpecPort) String() string { 40 | return string(l) 41 | } 42 | 43 | // LinkStatus defines the observed state of Link 44 | type LinkStatus struct { 45 | // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster 46 | // Important: Run "make" to regenerate code after modifying this file 47 | Status string `json:"status,omitempty"` 48 | Message string `json:"message,omitempty"` 49 | Ports string `json:"ports,omitempty"` 50 | } 51 | 52 | //+kubebuilder:object:root=true 53 | //+kubebuilder:subresource:status 54 | // +kubebuilder:printcolumn:name="Ports",type=string,JSONPath=`.status.ports` 55 | // +kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.status` 56 | // +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp` 57 | 58 | // Link is the Schema for the links API 59 | type Link struct { 60 | metav1.TypeMeta `json:",inline"` 61 | metav1.ObjectMeta `json:"metadata,omitempty"` 62 | 63 | Spec LinkSpec `json:"spec,omitempty"` 64 | Status LinkStatus `json:"status,omitempty"` 65 | } 66 | 67 | //+kubebuilder:object:root=true 68 | 69 | // LinkList contains a list of Link 70 | type LinkList struct { 71 | metav1.TypeMeta `json:",inline"` 72 | metav1.ListMeta `json:"metadata,omitempty"` 73 | Items []Link `json:"items"` 74 | } 75 | 76 | func init() { 77 | SchemeBuilder.Register(&Link{}, &LinkList{}) 78 | } 79 | -------------------------------------------------------------------------------- /api/v1alpha1/controllermeta_types.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021. Netris, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package v1alpha1 18 | 19 | import ( 20 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 21 | ) 22 | 23 | // EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! 24 | // NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. 25 | 26 | // ControllerMetaSpec defines the desired state of ControllerMeta 27 | type ControllerMetaSpec struct { 28 | // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster 29 | // Important: Run "make" to regenerate code after modifying this file 30 | 31 | Imported bool `json:"imported"` 32 | Reclaim bool `json:"reclaimPolicy"` 33 | ControllerCRGeneration int64 `json:"controllerGeneration"` 34 | ID int `json:"id"` 35 | ControllerName string `json:"controllerName"` 36 | 37 | TenantID int `json:"tenant,omitempty"` 38 | Description string `json:"description,omitempty"` 39 | SiteID int `json:"site,omitempty"` 40 | MainIP string `json:"mainIp,omitempty"` 41 | } 42 | 43 | // ControllerMetaStatus defines the observed state of ControllerMeta 44 | type ControllerMetaStatus struct { // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster 45 | // Important: Run "make" to regenerate code after modifying this file 46 | } 47 | 48 | //+kubebuilder:object:root=true 49 | //+kubebuilder:subresource:status 50 | 51 | // ControllerMeta is the Schema for the controllermeta API 52 | type ControllerMeta struct { 53 | metav1.TypeMeta `json:",inline"` 54 | metav1.ObjectMeta `json:"metadata,omitempty"` 55 | 56 | Spec ControllerMetaSpec `json:"spec,omitempty"` 57 | Status ControllerMetaStatus `json:"status,omitempty"` 58 | } 59 | 60 | //+kubebuilder:object:root=true 61 | 62 | // ControllerMetaList contains a list of ControllerMeta 63 | type ControllerMetaList struct { 64 | metav1.TypeMeta `json:",inline"` 65 | metav1.ListMeta `json:"metadata,omitempty"` 66 | Items []ControllerMeta `json:"items"` 67 | } 68 | 69 | func init() { 70 | SchemeBuilder.Register(&ControllerMeta{}, &ControllerMetaList{}) 71 | } 72 | -------------------------------------------------------------------------------- /api/v1alpha1/softgatemeta_types.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021. Netris, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package v1alpha1 18 | 19 | import ( 20 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 21 | ) 22 | 23 | // EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! 24 | // NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. 25 | 26 | // SoftgateMetaSpec defines the desired state of SoftgateMeta 27 | type SoftgateMetaSpec struct { 28 | // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster 29 | // Important: Run "make" to regenerate code after modifying this file 30 | 31 | Imported bool `json:"imported"` 32 | Reclaim bool `json:"reclaimPolicy"` 33 | SoftgateCRGeneration int64 `json:"softgateGeneration"` 34 | ID int `json:"id"` 35 | SoftgateName string `json:"softgateName"` 36 | 37 | TenantID int `json:"tenantid,omitempty"` 38 | Description string `json:"description,omitempty"` 39 | SiteID int `json:"siteid,omitempty"` 40 | ProfileID int `json:"profileid,omitempty"` 41 | MainIP string `json:"mainIp,omitempty"` 42 | MgmtIP string `json:"mgmtIp,omitempty"` 43 | } 44 | 45 | // SoftgateMetaStatus defines the observed state of SoftgateMeta 46 | type SoftgateMetaStatus struct { // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster 47 | // Important: Run "make" to regenerate code after modifying this file 48 | } 49 | 50 | //+kubebuilder:object:root=true 51 | //+kubebuilder:subresource:status 52 | 53 | // SoftgateMeta is the Schema for the softgatemeta API 54 | type SoftgateMeta struct { 55 | metav1.TypeMeta `json:",inline"` 56 | metav1.ObjectMeta `json:"metadata,omitempty"` 57 | 58 | Spec SoftgateMetaSpec `json:"spec,omitempty"` 59 | Status SoftgateMetaStatus `json:"status,omitempty"` 60 | } 61 | 62 | //+kubebuilder:object:root=true 63 | 64 | // SoftgateMetaList contains a list of SoftgateMeta 65 | type SoftgateMetaList struct { 66 | metav1.TypeMeta `json:",inline"` 67 | metav1.ListMeta `json:"metadata,omitempty"` 68 | Items []SoftgateMeta `json:"items"` 69 | } 70 | 71 | func init() { 72 | SchemeBuilder.Register(&SoftgateMeta{}, &SoftgateMetaList{}) 73 | } 74 | -------------------------------------------------------------------------------- /scripts/rbac-helm-template.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import argparse 4 | import yaml 5 | 6 | fullname = '{{ include "netris-operator.fullname" . }}' 7 | namespace = '{{ include "netris-operator.namespace" . }}' 8 | service_account_name = '{{ include "netris-operator.serviceAccountName" . }}' 9 | 10 | 11 | def main(): 12 | args = args_parser() 13 | with open(args.y, 'r') as f: 14 | yaml_items = yaml.safe_load(f) 15 | kind = '' 16 | try: 17 | kind = yaml_items['kind'] 18 | except KeyError: # not k8s resource 19 | exit(1) 20 | if 'creationTimestamp' in yaml_items['metadata']: 21 | del yaml_items['metadata']['creationTimestamp'] 22 | if kind == 'Role': 23 | role(yaml_items) 24 | elif kind == 'ClusterRole': 25 | cluster_role(yaml_items) 26 | elif kind == 'RoleBinding': 27 | role_binding(yaml_items) 28 | elif kind == 'ClusterRoleBinding': 29 | cluster_role_binding(yaml_items) 30 | else: # unexpected resource kind 31 | exit(1) 32 | 33 | 34 | def args_parser(): 35 | parser = argparse.ArgumentParser(description='rbac to helm template script') 36 | parser.add_argument('y', metavar='$1', type=str, help='yaml file path') 37 | args = parser.parse_args() 38 | return args 39 | 40 | 41 | def role(_yaml): 42 | name = _yaml['metadata']['name'] 43 | _yaml['metadata']['name'] = '{}-{}'.format(fullname, name) 44 | _yaml['metadata']['namespace'] = namespace 45 | print(_yaml) 46 | 47 | 48 | def role_binding(_yaml): 49 | name = _yaml['metadata']['name'] 50 | role_ref_name = _yaml['roleRef']['name'] 51 | _yaml['metadata']['name'] = '{}-{}'.format(fullname, name) 52 | _yaml['metadata']['namespace'] = namespace 53 | _yaml['roleRef']['name'] = '{}-{}'.format(fullname, role_ref_name) 54 | for key, value in enumerate(_yaml['subjects']): 55 | if value['kind'] == 'ServiceAccount': 56 | _yaml['subjects'][key]['name'] = service_account_name 57 | _yaml['subjects'][key]['namespace'] = namespace 58 | print(_yaml) 59 | 60 | 61 | def cluster_role(_yaml): 62 | name = _yaml['metadata']['name'] 63 | _yaml['metadata']['name'] = '{}-{}'.format(fullname, name) 64 | print(_yaml) 65 | 66 | 67 | def cluster_role_binding(_yaml): 68 | name = _yaml['metadata']['name'] 69 | role_ref_name = _yaml['roleRef']['name'] 70 | _yaml['metadata']['name'] = '{}-{}'.format(fullname, name) 71 | _yaml['roleRef']['name'] = '{}-{}'.format(fullname, role_ref_name) 72 | for key, value in enumerate(_yaml['subjects']): 73 | if value['kind'] == 'ServiceAccount': 74 | _yaml['subjects'][key]['name'] = service_account_name 75 | _yaml['subjects'][key]['namespace'] = namespace 76 | print(_yaml) 77 | 78 | 79 | if __name__ == '__main__': 80 | main() 81 | -------------------------------------------------------------------------------- /netrisstorage/vpcs.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2025. Netris, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package netrisstorage 18 | 19 | import ( 20 | "sync" 21 | 22 | "github.com/netrisai/netriswebapi/v2/types/vpc" 23 | ) 24 | 25 | // VPCStorage caches VPC objects retrieved from Netris API. 26 | type VPCStorage struct { 27 | sync.Mutex 28 | VPCs []*vpc.VPC 29 | } 30 | 31 | // NewVPCStorage creates new VPC storage. 32 | func NewVPCStorage() *VPCStorage { 33 | return &VPCStorage{} 34 | } 35 | 36 | // GetAll returns a copy of cached VPCs. 37 | func (p *VPCStorage) GetAll() []vpc.VPC { 38 | p.Lock() 39 | defer p.Unlock() 40 | vpcs := []vpc.VPC{} 41 | for _, item := range p.VPCs { 42 | vpcs = append(vpcs, *item) 43 | } 44 | return vpcs 45 | } 46 | 47 | // FindByName returns VPC by name if present in cache, triggering refresh on miss. 48 | func (p *VPCStorage) FindByName(name string) (*vpc.VPC, bool) { 49 | p.Lock() 50 | defer p.Unlock() 51 | item, ok := p.findByName(name) 52 | if !ok { 53 | _ = p.download() 54 | return p.findByName(name) 55 | } 56 | return item, ok 57 | } 58 | 59 | func (p *VPCStorage) findByName(name string) (*vpc.VPC, bool) { 60 | for _, item := range p.VPCs { 61 | if item.Name == name { 62 | return item, true 63 | } 64 | } 65 | return nil, false 66 | } 67 | 68 | // FindByID returns VPC by ID, refreshing cache on miss. 69 | func (p *VPCStorage) FindByID(id int) (*vpc.VPC, bool) { 70 | p.Lock() 71 | defer p.Unlock() 72 | item, ok := p.findByID(id) 73 | if !ok { 74 | _ = p.download() 75 | return p.findByID(id) 76 | } 77 | return item, ok 78 | } 79 | 80 | func (p *VPCStorage) findByID(id int) (*vpc.VPC, bool) { 81 | for _, item := range p.VPCs { 82 | if item.ID == id { 83 | return item, true 84 | } 85 | } 86 | return nil, false 87 | } 88 | 89 | func (p *VPCStorage) storeAll(items []*vpc.VPC) { 90 | p.VPCs = items 91 | } 92 | 93 | func (p *VPCStorage) download() error { 94 | items, err := Cred.VPC().Get() 95 | if err != nil { 96 | return err 97 | } 98 | p.storeAll(items) 99 | return nil 100 | } 101 | 102 | // Download refreshes cached VPCs. 103 | func (p *VPCStorage) Download() error { 104 | p.Lock() 105 | defer p.Unlock() 106 | return p.download() 107 | } 108 | -------------------------------------------------------------------------------- /config/crd/bases/k8s.netris.ai_controllermeta.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: apiextensions.k8s.io/v1 4 | kind: CustomResourceDefinition 5 | metadata: 6 | annotations: 7 | controller-gen.kubebuilder.io/version: v0.6.1 8 | creationTimestamp: null 9 | name: controllermeta.k8s.netris.ai 10 | spec: 11 | group: k8s.netris.ai 12 | names: 13 | kind: ControllerMeta 14 | listKind: ControllerMetaList 15 | plural: controllermeta 16 | singular: controllermeta 17 | scope: Namespaced 18 | versions: 19 | - name: v1alpha1 20 | schema: 21 | openAPIV3Schema: 22 | description: ControllerMeta is the Schema for the controllermeta API 23 | properties: 24 | apiVersion: 25 | description: 'APIVersion defines the versioned schema of this representation 26 | of an object. Servers should convert recognized schemas to the latest 27 | internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 28 | type: string 29 | kind: 30 | description: 'Kind is a string value representing the REST resource this 31 | object represents. Servers may infer this from the endpoint the client 32 | submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 33 | type: string 34 | metadata: 35 | type: object 36 | spec: 37 | description: ControllerMetaSpec defines the desired state of ControllerMeta 38 | properties: 39 | controllerGeneration: 40 | format: int64 41 | type: integer 42 | controllerName: 43 | type: string 44 | description: 45 | type: string 46 | id: 47 | type: integer 48 | imported: 49 | type: boolean 50 | mainIp: 51 | type: string 52 | reclaimPolicy: 53 | type: boolean 54 | site: 55 | type: integer 56 | tenant: 57 | type: integer 58 | required: 59 | - controllerGeneration 60 | - controllerName 61 | - id 62 | - imported 63 | - reclaimPolicy 64 | type: object 65 | status: 66 | description: ControllerMetaStatus defines the observed state of ControllerMeta 67 | type: object 68 | type: object 69 | served: true 70 | storage: true 71 | subresources: 72 | status: {} 73 | status: 74 | acceptedNames: 75 | kind: "" 76 | plural: "" 77 | conditions: [] 78 | storedVersions: [] 79 | -------------------------------------------------------------------------------- /config/crd/bases/k8s.netris.ai_linkmeta.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: apiextensions.k8s.io/v1 4 | kind: CustomResourceDefinition 5 | metadata: 6 | annotations: 7 | controller-gen.kubebuilder.io/version: v0.6.1 8 | creationTimestamp: null 9 | name: linkmeta.k8s.netris.ai 10 | spec: 11 | group: k8s.netris.ai 12 | names: 13 | kind: LinkMeta 14 | listKind: LinkMetaList 15 | plural: linkmeta 16 | singular: linkmeta 17 | scope: Namespaced 18 | versions: 19 | - name: v1alpha1 20 | schema: 21 | openAPIV3Schema: 22 | description: LinkMeta is the Schema for the linkmeta API 23 | properties: 24 | apiVersion: 25 | description: 'APIVersion defines the versioned schema of this representation 26 | of an object. Servers should convert recognized schemas to the latest 27 | internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 28 | type: string 29 | kind: 30 | description: 'Kind is a string value representing the REST resource this 31 | object represents. Servers may infer this from the endpoint the client 32 | submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 33 | type: string 34 | metadata: 35 | type: object 36 | spec: 37 | description: LinkMetaSpec defines the desired state of LinkMeta 38 | properties: 39 | id: 40 | type: string 41 | imported: 42 | description: 'INSERT ADDITIONAL SPEC FIELDS - desired state of cluster 43 | Important: Run "make" to regenerate code after modifying this file' 44 | type: boolean 45 | linkGeneration: 46 | format: int64 47 | type: integer 48 | linkName: 49 | type: string 50 | local: 51 | type: integer 52 | reclaimPolicy: 53 | type: boolean 54 | remote: 55 | type: integer 56 | required: 57 | - id 58 | - imported 59 | - linkGeneration 60 | - linkName 61 | - local 62 | - reclaimPolicy 63 | - remote 64 | type: object 65 | status: 66 | description: LinkMetaStatus defines the observed state of LinkMeta 67 | type: object 68 | type: object 69 | served: true 70 | storage: true 71 | subresources: 72 | status: {} 73 | status: 74 | acceptedNames: 75 | kind: "" 76 | plural: "" 77 | conditions: [] 78 | storedVersions: [] 79 | -------------------------------------------------------------------------------- /deploy/charts/netris-operator/crds/k8s.netris.ai_controllermeta.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: apiextensions.k8s.io/v1 4 | kind: CustomResourceDefinition 5 | metadata: 6 | annotations: 7 | controller-gen.kubebuilder.io/version: v0.6.1 8 | creationTimestamp: null 9 | name: controllermeta.k8s.netris.ai 10 | spec: 11 | group: k8s.netris.ai 12 | names: 13 | kind: ControllerMeta 14 | listKind: ControllerMetaList 15 | plural: controllermeta 16 | singular: controllermeta 17 | scope: Namespaced 18 | versions: 19 | - name: v1alpha1 20 | schema: 21 | openAPIV3Schema: 22 | description: ControllerMeta is the Schema for the controllermeta API 23 | properties: 24 | apiVersion: 25 | description: 'APIVersion defines the versioned schema of this representation 26 | of an object. Servers should convert recognized schemas to the latest 27 | internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 28 | type: string 29 | kind: 30 | description: 'Kind is a string value representing the REST resource this 31 | object represents. Servers may infer this from the endpoint the client 32 | submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 33 | type: string 34 | metadata: 35 | type: object 36 | spec: 37 | description: ControllerMetaSpec defines the desired state of ControllerMeta 38 | properties: 39 | controllerGeneration: 40 | format: int64 41 | type: integer 42 | controllerName: 43 | type: string 44 | description: 45 | type: string 46 | id: 47 | type: integer 48 | imported: 49 | type: boolean 50 | mainIp: 51 | type: string 52 | reclaimPolicy: 53 | type: boolean 54 | site: 55 | type: integer 56 | tenant: 57 | type: integer 58 | required: 59 | - controllerGeneration 60 | - controllerName 61 | - id 62 | - imported 63 | - reclaimPolicy 64 | type: object 65 | status: 66 | description: ControllerMetaStatus defines the observed state of ControllerMeta 67 | type: object 68 | type: object 69 | served: true 70 | storage: true 71 | subresources: 72 | status: {} 73 | status: 74 | acceptedNames: 75 | kind: "" 76 | plural: "" 77 | conditions: [] 78 | storedVersions: [] 79 | -------------------------------------------------------------------------------- /deploy/charts/netris-operator/crds/k8s.netris.ai_linkmeta.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: apiextensions.k8s.io/v1 4 | kind: CustomResourceDefinition 5 | metadata: 6 | annotations: 7 | controller-gen.kubebuilder.io/version: v0.6.1 8 | creationTimestamp: null 9 | name: linkmeta.k8s.netris.ai 10 | spec: 11 | group: k8s.netris.ai 12 | names: 13 | kind: LinkMeta 14 | listKind: LinkMetaList 15 | plural: linkmeta 16 | singular: linkmeta 17 | scope: Namespaced 18 | versions: 19 | - name: v1alpha1 20 | schema: 21 | openAPIV3Schema: 22 | description: LinkMeta is the Schema for the linkmeta API 23 | properties: 24 | apiVersion: 25 | description: 'APIVersion defines the versioned schema of this representation 26 | of an object. Servers should convert recognized schemas to the latest 27 | internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 28 | type: string 29 | kind: 30 | description: 'Kind is a string value representing the REST resource this 31 | object represents. Servers may infer this from the endpoint the client 32 | submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 33 | type: string 34 | metadata: 35 | type: object 36 | spec: 37 | description: LinkMetaSpec defines the desired state of LinkMeta 38 | properties: 39 | id: 40 | type: string 41 | imported: 42 | description: 'INSERT ADDITIONAL SPEC FIELDS - desired state of cluster 43 | Important: Run "make" to regenerate code after modifying this file' 44 | type: boolean 45 | linkGeneration: 46 | format: int64 47 | type: integer 48 | linkName: 49 | type: string 50 | local: 51 | type: integer 52 | reclaimPolicy: 53 | type: boolean 54 | remote: 55 | type: integer 56 | required: 57 | - id 58 | - imported 59 | - linkGeneration 60 | - linkName 61 | - local 62 | - reclaimPolicy 63 | - remote 64 | type: object 65 | status: 66 | description: LinkMetaStatus defines the observed state of LinkMeta 67 | type: object 68 | type: object 69 | served: true 70 | storage: true 71 | subresources: 72 | status: {} 73 | status: 74 | acceptedNames: 75 | kind: "" 76 | plural: "" 77 | conditions: [] 78 | storedVersions: [] 79 | -------------------------------------------------------------------------------- /config/crd/bases/k8s.netris.ai_subnetmeta.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: apiextensions.k8s.io/v1 4 | kind: CustomResourceDefinition 5 | metadata: 6 | annotations: 7 | controller-gen.kubebuilder.io/version: v0.6.1 8 | creationTimestamp: null 9 | name: subnetmeta.k8s.netris.ai 10 | spec: 11 | group: k8s.netris.ai 12 | names: 13 | kind: SubnetMeta 14 | listKind: SubnetMetaList 15 | plural: subnetmeta 16 | singular: subnetmeta 17 | scope: Namespaced 18 | versions: 19 | - name: v1alpha1 20 | schema: 21 | openAPIV3Schema: 22 | description: SubnetMeta is the Schema for the subnetmeta API 23 | properties: 24 | apiVersion: 25 | description: 'APIVersion defines the versioned schema of this representation 26 | of an object. Servers should convert recognized schemas to the latest 27 | internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 28 | type: string 29 | kind: 30 | description: 'Kind is a string value representing the REST resource this 31 | object represents. Servers may infer this from the endpoint the client 32 | submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 33 | type: string 34 | metadata: 35 | type: object 36 | spec: 37 | description: SubnetMetaSpec defines the desired state of SubnetMeta 38 | properties: 39 | defaultGateway: 40 | type: string 41 | id: 42 | type: integer 43 | imported: 44 | type: boolean 45 | prefix: 46 | type: string 47 | purpose: 48 | type: string 49 | reclaimPolicy: 50 | type: boolean 51 | sites: 52 | items: 53 | type: integer 54 | type: array 55 | subnetGeneration: 56 | format: int64 57 | type: integer 58 | subnetName: 59 | type: string 60 | tenantid: 61 | type: integer 62 | required: 63 | - id 64 | - imported 65 | - reclaimPolicy 66 | - subnetGeneration 67 | - subnetName 68 | type: object 69 | status: 70 | description: SubnetMetaStatus defines the observed state of SubnetMeta 71 | type: object 72 | type: object 73 | served: true 74 | storage: true 75 | subresources: 76 | status: {} 77 | status: 78 | acceptedNames: 79 | kind: "" 80 | plural: "" 81 | conditions: [] 82 | storedVersions: [] 83 | -------------------------------------------------------------------------------- /deploy/charts/netris-operator/crds/k8s.netris.ai_subnetmeta.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: apiextensions.k8s.io/v1 4 | kind: CustomResourceDefinition 5 | metadata: 6 | annotations: 7 | controller-gen.kubebuilder.io/version: v0.6.1 8 | creationTimestamp: null 9 | name: subnetmeta.k8s.netris.ai 10 | spec: 11 | group: k8s.netris.ai 12 | names: 13 | kind: SubnetMeta 14 | listKind: SubnetMetaList 15 | plural: subnetmeta 16 | singular: subnetmeta 17 | scope: Namespaced 18 | versions: 19 | - name: v1alpha1 20 | schema: 21 | openAPIV3Schema: 22 | description: SubnetMeta is the Schema for the subnetmeta API 23 | properties: 24 | apiVersion: 25 | description: 'APIVersion defines the versioned schema of this representation 26 | of an object. Servers should convert recognized schemas to the latest 27 | internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 28 | type: string 29 | kind: 30 | description: 'Kind is a string value representing the REST resource this 31 | object represents. Servers may infer this from the endpoint the client 32 | submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 33 | type: string 34 | metadata: 35 | type: object 36 | spec: 37 | description: SubnetMetaSpec defines the desired state of SubnetMeta 38 | properties: 39 | defaultGateway: 40 | type: string 41 | id: 42 | type: integer 43 | imported: 44 | type: boolean 45 | prefix: 46 | type: string 47 | purpose: 48 | type: string 49 | reclaimPolicy: 50 | type: boolean 51 | sites: 52 | items: 53 | type: integer 54 | type: array 55 | subnetGeneration: 56 | format: int64 57 | type: integer 58 | subnetName: 59 | type: string 60 | tenantid: 61 | type: integer 62 | required: 63 | - id 64 | - imported 65 | - reclaimPolicy 66 | - subnetGeneration 67 | - subnetName 68 | type: object 69 | status: 70 | description: SubnetMetaStatus defines the observed state of SubnetMeta 71 | type: object 72 | type: object 73 | served: true 74 | storage: true 75 | subresources: 76 | status: {} 77 | status: 78 | acceptedNames: 79 | kind: "" 80 | plural: "" 81 | conditions: [] 82 | storedVersions: [] 83 | -------------------------------------------------------------------------------- /config/crd/bases/k8s.netris.ai_links.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: apiextensions.k8s.io/v1 4 | kind: CustomResourceDefinition 5 | metadata: 6 | annotations: 7 | controller-gen.kubebuilder.io/version: v0.6.1 8 | creationTimestamp: null 9 | name: links.k8s.netris.ai 10 | spec: 11 | group: k8s.netris.ai 12 | names: 13 | kind: Link 14 | listKind: LinkList 15 | plural: links 16 | singular: link 17 | scope: Namespaced 18 | versions: 19 | - additionalPrinterColumns: 20 | - jsonPath: .status.ports 21 | name: Ports 22 | type: string 23 | - jsonPath: .status.status 24 | name: Status 25 | type: string 26 | - jsonPath: .metadata.creationTimestamp 27 | name: Age 28 | type: date 29 | name: v1alpha1 30 | schema: 31 | openAPIV3Schema: 32 | description: Link is the Schema for the links API 33 | properties: 34 | apiVersion: 35 | description: 'APIVersion defines the versioned schema of this representation 36 | of an object. Servers should convert recognized schemas to the latest 37 | internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 38 | type: string 39 | kind: 40 | description: 'Kind is a string value representing the REST resource this 41 | object represents. Servers may infer this from the endpoint the client 42 | submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 43 | type: string 44 | metadata: 45 | type: object 46 | spec: 47 | description: LinkSpec defines the desired state of Link 48 | properties: 49 | ports: 50 | items: 51 | description: LinkSpecPort . 52 | type: string 53 | maxItems: 2 54 | minItems: 2 55 | type: array 56 | required: 57 | - ports 58 | type: object 59 | status: 60 | description: LinkStatus defines the observed state of Link 61 | properties: 62 | message: 63 | type: string 64 | ports: 65 | type: string 66 | status: 67 | description: 'INSERT ADDITIONAL STATUS FIELD - define observed state 68 | of cluster Important: Run "make" to regenerate code after modifying 69 | this file' 70 | type: string 71 | type: object 72 | type: object 73 | served: true 74 | storage: true 75 | subresources: 76 | status: {} 77 | status: 78 | acceptedNames: 79 | kind: "" 80 | plural: "" 81 | conditions: [] 82 | storedVersions: [] 83 | -------------------------------------------------------------------------------- /api/v1alpha1/natmeta_types.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021. Netris, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package v1alpha1 18 | 19 | import ( 20 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 21 | ) 22 | 23 | // EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! 24 | // NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. 25 | 26 | // NatMetaSpec defines the desired state of NatMeta 27 | type NatMetaSpec struct { 28 | // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster 29 | // Important: Run "make" to regenerate code after modifying this file 30 | Imported bool `json:"imported"` 31 | Reclaim bool `json:"reclaimPolicy"` 32 | NatCRGeneration int64 `json:"natGeneration"` 33 | ID int `json:"id"` 34 | NatName string `json:"natName"` 35 | 36 | Comment string `json:"comment,omitempty"` 37 | State string `json:"state,omitempty"` 38 | SiteID int `json:"siteID"` 39 | Action string `json:"action"` 40 | Protocol string `json:"protocol"` 41 | SrcAddress string `json:"srcAddress"` 42 | SrcPort string `json:"srcPort,omitempty"` 43 | DstAddress string `json:"dstAddress"` 44 | DstPort string `json:"dstPort,omitempty"` 45 | SnatToIP string `json:"snatToIp,omitempty"` 46 | SnatToPool string `json:"snatToPool,omitempty"` 47 | DnatToIP string `json:"dnatToIp,omitempty"` 48 | DnatToPort string `json:"dnatToPort,omitempty"` 49 | } 50 | 51 | // NatMetaStatus defines the observed state of NatMeta 52 | type NatMetaStatus struct { 53 | // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster 54 | // Important: Run "make" to regenerate code after modifying this file 55 | } 56 | 57 | //+kubebuilder:object:root=true 58 | //+kubebuilder:subresource:status 59 | 60 | // NatMeta is the Schema for the natmeta API 61 | type NatMeta struct { 62 | metav1.TypeMeta `json:",inline"` 63 | metav1.ObjectMeta `json:"metadata,omitempty"` 64 | 65 | Spec NatMetaSpec `json:"spec,omitempty"` 66 | Status NatMetaStatus `json:"status,omitempty"` 67 | } 68 | 69 | //+kubebuilder:object:root=true 70 | 71 | // NatMetaList contains a list of NatMeta 72 | type NatMetaList struct { 73 | metav1.TypeMeta `json:",inline"` 74 | metav1.ListMeta `json:"metadata,omitempty"` 75 | Items []NatMeta `json:"items"` 76 | } 77 | 78 | func init() { 79 | SchemeBuilder.Register(&NatMeta{}, &NatMetaList{}) 80 | } 81 | -------------------------------------------------------------------------------- /config/crd/bases/k8s.netris.ai_softgatemeta.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: apiextensions.k8s.io/v1 4 | kind: CustomResourceDefinition 5 | metadata: 6 | annotations: 7 | controller-gen.kubebuilder.io/version: v0.6.1 8 | creationTimestamp: null 9 | name: softgatemeta.k8s.netris.ai 10 | spec: 11 | group: k8s.netris.ai 12 | names: 13 | kind: SoftgateMeta 14 | listKind: SoftgateMetaList 15 | plural: softgatemeta 16 | singular: softgatemeta 17 | scope: Namespaced 18 | versions: 19 | - name: v1alpha1 20 | schema: 21 | openAPIV3Schema: 22 | description: SoftgateMeta is the Schema for the softgatemeta API 23 | properties: 24 | apiVersion: 25 | description: 'APIVersion defines the versioned schema of this representation 26 | of an object. Servers should convert recognized schemas to the latest 27 | internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 28 | type: string 29 | kind: 30 | description: 'Kind is a string value representing the REST resource this 31 | object represents. Servers may infer this from the endpoint the client 32 | submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 33 | type: string 34 | metadata: 35 | type: object 36 | spec: 37 | description: SoftgateMetaSpec defines the desired state of SoftgateMeta 38 | properties: 39 | description: 40 | type: string 41 | id: 42 | type: integer 43 | imported: 44 | type: boolean 45 | mainIp: 46 | type: string 47 | mgmtIp: 48 | type: string 49 | profileid: 50 | type: integer 51 | reclaimPolicy: 52 | type: boolean 53 | siteid: 54 | type: integer 55 | softgateGeneration: 56 | format: int64 57 | type: integer 58 | softgateName: 59 | type: string 60 | tenantid: 61 | type: integer 62 | required: 63 | - id 64 | - imported 65 | - reclaimPolicy 66 | - softgateGeneration 67 | - softgateName 68 | type: object 69 | status: 70 | description: SoftgateMetaStatus defines the observed state of SoftgateMeta 71 | type: object 72 | type: object 73 | served: true 74 | storage: true 75 | subresources: 76 | status: {} 77 | status: 78 | acceptedNames: 79 | kind: "" 80 | plural: "" 81 | conditions: [] 82 | storedVersions: [] 83 | -------------------------------------------------------------------------------- /config/crd/bases/k8s.netris.ai_allocationmeta.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: apiextensions.k8s.io/v1 4 | kind: CustomResourceDefinition 5 | metadata: 6 | annotations: 7 | controller-gen.kubebuilder.io/version: v0.6.1 8 | creationTimestamp: null 9 | name: allocationmeta.k8s.netris.ai 10 | spec: 11 | group: k8s.netris.ai 12 | names: 13 | kind: AllocationMeta 14 | listKind: AllocationMetaList 15 | plural: allocationmeta 16 | singular: allocationmeta 17 | scope: Namespaced 18 | versions: 19 | - name: v1alpha1 20 | schema: 21 | openAPIV3Schema: 22 | description: AllocationMeta is the Schema for the allocationmeta API 23 | properties: 24 | apiVersion: 25 | description: 'APIVersion defines the versioned schema of this representation 26 | of an object. Servers should convert recognized schemas to the latest 27 | internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 28 | type: string 29 | kind: 30 | description: 'Kind is a string value representing the REST resource this 31 | object represents. Servers may infer this from the endpoint the client 32 | submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 33 | type: string 34 | metadata: 35 | type: object 36 | spec: 37 | description: AllocationMetaSpec defines the desired state of AllocationMeta 38 | properties: 39 | allocationGeneration: 40 | format: int64 41 | type: integer 42 | allocationName: 43 | type: string 44 | id: 45 | type: integer 46 | imported: 47 | description: 'INSERT ADDITIONAL SPEC FIELDS - desired state of cluster 48 | Important: Run "make" to regenerate code after modifying this file' 49 | type: boolean 50 | prefix: 51 | type: string 52 | reclaimPolicy: 53 | type: boolean 54 | tenant: 55 | type: string 56 | required: 57 | - allocationGeneration 58 | - allocationName 59 | - id 60 | - imported 61 | - prefix 62 | - reclaimPolicy 63 | - tenant 64 | type: object 65 | status: 66 | description: AllocationMetaStatus defines the observed state of AllocationMeta 67 | type: object 68 | type: object 69 | served: true 70 | storage: true 71 | subresources: 72 | status: {} 73 | status: 74 | acceptedNames: 75 | kind: "" 76 | plural: "" 77 | conditions: [] 78 | storedVersions: [] 79 | -------------------------------------------------------------------------------- /deploy/charts/netris-operator/crds/k8s.netris.ai_links.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: apiextensions.k8s.io/v1 4 | kind: CustomResourceDefinition 5 | metadata: 6 | annotations: 7 | controller-gen.kubebuilder.io/version: v0.6.1 8 | creationTimestamp: null 9 | name: links.k8s.netris.ai 10 | spec: 11 | group: k8s.netris.ai 12 | names: 13 | kind: Link 14 | listKind: LinkList 15 | plural: links 16 | singular: link 17 | scope: Namespaced 18 | versions: 19 | - additionalPrinterColumns: 20 | - jsonPath: .status.ports 21 | name: Ports 22 | type: string 23 | - jsonPath: .status.status 24 | name: Status 25 | type: string 26 | - jsonPath: .metadata.creationTimestamp 27 | name: Age 28 | type: date 29 | name: v1alpha1 30 | schema: 31 | openAPIV3Schema: 32 | description: Link is the Schema for the links API 33 | properties: 34 | apiVersion: 35 | description: 'APIVersion defines the versioned schema of this representation 36 | of an object. Servers should convert recognized schemas to the latest 37 | internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 38 | type: string 39 | kind: 40 | description: 'Kind is a string value representing the REST resource this 41 | object represents. Servers may infer this from the endpoint the client 42 | submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 43 | type: string 44 | metadata: 45 | type: object 46 | spec: 47 | description: LinkSpec defines the desired state of Link 48 | properties: 49 | ports: 50 | items: 51 | description: LinkSpecPort . 52 | type: string 53 | maxItems: 2 54 | minItems: 2 55 | type: array 56 | required: 57 | - ports 58 | type: object 59 | status: 60 | description: LinkStatus defines the observed state of Link 61 | properties: 62 | message: 63 | type: string 64 | ports: 65 | type: string 66 | status: 67 | description: 'INSERT ADDITIONAL STATUS FIELD - define observed state 68 | of cluster Important: Run "make" to regenerate code after modifying 69 | this file' 70 | type: string 71 | type: object 72 | type: object 73 | served: true 74 | storage: true 75 | subresources: 76 | status: {} 77 | status: 78 | acceptedNames: 79 | kind: "" 80 | plural: "" 81 | conditions: [] 82 | storedVersions: [] 83 | -------------------------------------------------------------------------------- /deploy/charts/netris-operator/crds/k8s.netris.ai_softgatemeta.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: apiextensions.k8s.io/v1 4 | kind: CustomResourceDefinition 5 | metadata: 6 | annotations: 7 | controller-gen.kubebuilder.io/version: v0.6.1 8 | creationTimestamp: null 9 | name: softgatemeta.k8s.netris.ai 10 | spec: 11 | group: k8s.netris.ai 12 | names: 13 | kind: SoftgateMeta 14 | listKind: SoftgateMetaList 15 | plural: softgatemeta 16 | singular: softgatemeta 17 | scope: Namespaced 18 | versions: 19 | - name: v1alpha1 20 | schema: 21 | openAPIV3Schema: 22 | description: SoftgateMeta is the Schema for the softgatemeta API 23 | properties: 24 | apiVersion: 25 | description: 'APIVersion defines the versioned schema of this representation 26 | of an object. Servers should convert recognized schemas to the latest 27 | internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 28 | type: string 29 | kind: 30 | description: 'Kind is a string value representing the REST resource this 31 | object represents. Servers may infer this from the endpoint the client 32 | submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 33 | type: string 34 | metadata: 35 | type: object 36 | spec: 37 | description: SoftgateMetaSpec defines the desired state of SoftgateMeta 38 | properties: 39 | description: 40 | type: string 41 | id: 42 | type: integer 43 | imported: 44 | type: boolean 45 | mainIp: 46 | type: string 47 | mgmtIp: 48 | type: string 49 | profileid: 50 | type: integer 51 | reclaimPolicy: 52 | type: boolean 53 | siteid: 54 | type: integer 55 | softgateGeneration: 56 | format: int64 57 | type: integer 58 | softgateName: 59 | type: string 60 | tenantid: 61 | type: integer 62 | required: 63 | - id 64 | - imported 65 | - reclaimPolicy 66 | - softgateGeneration 67 | - softgateName 68 | type: object 69 | status: 70 | description: SoftgateMetaStatus defines the observed state of SoftgateMeta 71 | type: object 72 | type: object 73 | served: true 74 | storage: true 75 | subresources: 76 | status: {} 77 | status: 78 | acceptedNames: 79 | kind: "" 80 | plural: "" 81 | conditions: [] 82 | storedVersions: [] 83 | -------------------------------------------------------------------------------- /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Test, Build and Push 2 | on: 3 | push: 4 | # Sequence of patterns matched against refs/tags 5 | tags: 6 | - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10 7 | jobs: 8 | main: 9 | runs-on: ubuntu-22.04 10 | timeout-minutes: 20 11 | steps: 12 | - name: Checkout 13 | uses: actions/checkout@v2 14 | - name: Set up Go 15 | uses: actions/setup-go@v4 16 | with: 17 | go-version: "1.18" 18 | 19 | - name: Git configs and known_hosts 20 | run: | 21 | export known_hosts=$(ssh-keyscan github.com) 22 | git config --global --add url."git@github.com:".insteadOf "https://github.com/" 23 | 24 | - name: Install SSH key 25 | uses: shimataro/ssh-key-action@v2 26 | with: 27 | key: ${{ secrets.SSH_PRIVATE_KEY_NETRISAPI }} 28 | known_hosts: ${known_hosts} 29 | 30 | - name: Switch the default system shell 31 | run: sudo rm /bin/sh; sudo ln -s bash /bin/sh 32 | 33 | - name: Make test 34 | run: CONTROLLER_HOST="example.com" make test 35 | 36 | - name: Prepare 37 | id: prep 38 | run: | 39 | DOCKER_IMAGE=${GITHUB_REPOSITORY} 40 | VERSION=edge 41 | if [[ $GITHUB_REF == refs/tags/* ]]; then 42 | VERSION=${GITHUB_REF#refs/tags/} 43 | elif [[ $GITHUB_REF == refs/heads/* ]]; then 44 | VERSION=$(echo ${GITHUB_REF#refs/heads/} | sed -r 's#/+#-#g') 45 | elif [[ $GITHUB_REF == refs/pull/* ]]; then 46 | VERSION=pr-${{ github.event.number }} 47 | fi 48 | TAGS="${DOCKER_IMAGE}:${VERSION}" 49 | if [ "${{ github.event_name }}" = "push" ]; then 50 | TAGS="$TAGS,${DOCKER_IMAGE}:sha-${GITHUB_SHA::8}" 51 | fi 52 | echo ::set-output name=version::${VERSION} 53 | echo ::set-output name=tags::${TAGS} 54 | echo ::set-output name=created::$(date -u +'%Y-%m-%dT%H:%M:%SZ') 55 | 56 | - name: Set up QEMU 57 | uses: docker/setup-qemu-action@v1 58 | 59 | - name: Set up Docker Buildx 60 | uses: docker/setup-buildx-action@v1 61 | 62 | - name: Login to DockerHub 63 | if: github.event_name != 'pull_request' 64 | uses: docker/login-action@v1 65 | with: 66 | username: ${{ secrets.DOCKER_USERNAME }} 67 | password: ${{ secrets.DOCKER_PASSWORD }} 68 | 69 | - name: Build and push 70 | uses: docker/build-push-action@v2 71 | with: 72 | context: . 73 | file: ./Dockerfile 74 | platforms: linux/amd64,linux/arm64 75 | push: ${{ github.event_name != 'pull_request' }} 76 | tags: ${{ steps.prep.outputs.tags }} 77 | ssh: | 78 | ssh_private_key_ci=/home/runner/.ssh/id_rsa 79 | labels: | 80 | org.opencontainers.image.source=${{ github.event.repository.html_url }} 81 | org.opencontainers.image.created=${{ steps.prep.outputs.created }} 82 | org.opencontainers.image.revision=${{ github.sha }} 83 | -------------------------------------------------------------------------------- /deploy/charts/netris-operator/crds/k8s.netris.ai_allocationmeta.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: apiextensions.k8s.io/v1 4 | kind: CustomResourceDefinition 5 | metadata: 6 | annotations: 7 | controller-gen.kubebuilder.io/version: v0.6.1 8 | creationTimestamp: null 9 | name: allocationmeta.k8s.netris.ai 10 | spec: 11 | group: k8s.netris.ai 12 | names: 13 | kind: AllocationMeta 14 | listKind: AllocationMetaList 15 | plural: allocationmeta 16 | singular: allocationmeta 17 | scope: Namespaced 18 | versions: 19 | - name: v1alpha1 20 | schema: 21 | openAPIV3Schema: 22 | description: AllocationMeta is the Schema for the allocationmeta API 23 | properties: 24 | apiVersion: 25 | description: 'APIVersion defines the versioned schema of this representation 26 | of an object. Servers should convert recognized schemas to the latest 27 | internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 28 | type: string 29 | kind: 30 | description: 'Kind is a string value representing the REST resource this 31 | object represents. Servers may infer this from the endpoint the client 32 | submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 33 | type: string 34 | metadata: 35 | type: object 36 | spec: 37 | description: AllocationMetaSpec defines the desired state of AllocationMeta 38 | properties: 39 | allocationGeneration: 40 | format: int64 41 | type: integer 42 | allocationName: 43 | type: string 44 | id: 45 | type: integer 46 | imported: 47 | description: 'INSERT ADDITIONAL SPEC FIELDS - desired state of cluster 48 | Important: Run "make" to regenerate code after modifying this file' 49 | type: boolean 50 | prefix: 51 | type: string 52 | reclaimPolicy: 53 | type: boolean 54 | tenant: 55 | type: string 56 | required: 57 | - allocationGeneration 58 | - allocationName 59 | - id 60 | - imported 61 | - prefix 62 | - reclaimPolicy 63 | - tenant 64 | type: object 65 | status: 66 | description: AllocationMetaStatus defines the observed state of AllocationMeta 67 | type: object 68 | type: object 69 | served: true 70 | storage: true 71 | subresources: 72 | status: {} 73 | status: 74 | acceptedNames: 75 | kind: "" 76 | plural: "" 77 | conditions: [] 78 | storedVersions: [] 79 | -------------------------------------------------------------------------------- /config/crd/bases/k8s.netris.ai_controllers.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: apiextensions.k8s.io/v1 4 | kind: CustomResourceDefinition 5 | metadata: 6 | annotations: 7 | controller-gen.kubebuilder.io/version: v0.6.1 8 | creationTimestamp: null 9 | name: controllers.k8s.netris.ai 10 | spec: 11 | group: k8s.netris.ai 12 | names: 13 | kind: Controller 14 | listKind: ControllerList 15 | plural: controllers 16 | singular: controller 17 | scope: Namespaced 18 | versions: 19 | - additionalPrinterColumns: 20 | - jsonPath: .spec.tenant 21 | name: Tenant 22 | type: string 23 | - jsonPath: .spec.site 24 | name: Site 25 | type: string 26 | - jsonPath: .spec.mainIp 27 | name: Main IP 28 | type: string 29 | - jsonPath: .status.status 30 | name: Status 31 | type: string 32 | - jsonPath: .metadata.creationTimestamp 33 | name: Age 34 | type: date 35 | name: v1alpha1 36 | schema: 37 | openAPIV3Schema: 38 | description: Controller is the Schema for the controllers API 39 | properties: 40 | apiVersion: 41 | description: 'APIVersion defines the versioned schema of this representation 42 | of an object. Servers should convert recognized schemas to the latest 43 | internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 44 | type: string 45 | kind: 46 | description: 'Kind is a string value representing the REST resource this 47 | object represents. Servers may infer this from the endpoint the client 48 | submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 49 | type: string 50 | metadata: 51 | type: object 52 | spec: 53 | description: ControllerSpec defines the desired state of Controller 54 | properties: 55 | description: 56 | type: string 57 | mainIp: 58 | pattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$ 59 | type: string 60 | site: 61 | type: string 62 | tenant: 63 | type: string 64 | type: object 65 | status: 66 | description: ControllerStatus defines the observed state of Controller 67 | properties: 68 | message: 69 | type: string 70 | status: 71 | type: string 72 | type: object 73 | type: object 74 | served: true 75 | storage: true 76 | subresources: 77 | status: {} 78 | status: 79 | acceptedNames: 80 | kind: "" 81 | plural: "" 82 | conditions: [] 83 | storedVersions: [] 84 | -------------------------------------------------------------------------------- /netrisstorage/inventoryprofile.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021. Netris, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package netrisstorage 18 | 19 | import ( 20 | "sync" 21 | 22 | "github.com/netrisai/netriswebapi/v1/types/inventoryprofile" 23 | ) 24 | 25 | // InventoryProfileStorage . 26 | type InventoryProfileStorage struct { 27 | sync.Mutex 28 | InventoryProfile []*inventoryprofile.Profile 29 | } 30 | 31 | // NewInventoryProfileStorage . 32 | func NewInventoryProfileStorage() *InventoryProfileStorage { 33 | return &InventoryProfileStorage{} 34 | } 35 | 36 | // GetAll . 37 | func (p *InventoryProfileStorage) GetAll() []*inventoryprofile.Profile { 38 | p.Lock() 39 | defer p.Unlock() 40 | return p.getAll() 41 | } 42 | 43 | func (p *InventoryProfileStorage) getAll() []*inventoryprofile.Profile { 44 | return p.InventoryProfile 45 | } 46 | 47 | func (p *InventoryProfileStorage) storeAll(items []*inventoryprofile.Profile) { 48 | p.InventoryProfile = items 49 | } 50 | 51 | // FindByName . 52 | func (p *InventoryProfileStorage) FindByName(name string) (*inventoryprofile.Profile, bool) { 53 | p.Lock() 54 | defer p.Unlock() 55 | return p.findByName(name) 56 | } 57 | 58 | func (p *InventoryProfileStorage) findByName(name string) (*inventoryprofile.Profile, bool) { 59 | for _, inventoryProfile := range p.InventoryProfile { 60 | if inventoryProfile.Name == name { 61 | return inventoryProfile, true 62 | } 63 | } 64 | return nil, false 65 | } 66 | 67 | // FindByID . 68 | func (p *InventoryProfileStorage) FindByID(id int) (*inventoryprofile.Profile, bool) { 69 | p.Lock() 70 | defer p.Unlock() 71 | item, ok := p.findByID(id) 72 | if !ok { 73 | _ = p.download() 74 | return p.findByID(id) 75 | } 76 | return item, ok 77 | } 78 | 79 | func (p *InventoryProfileStorage) findByID(id int) (*inventoryprofile.Profile, bool) { 80 | for _, inventoryProfile := range p.InventoryProfile { 81 | if inventoryProfile.ID == id { 82 | return inventoryProfile, true 83 | } 84 | } 85 | return nil, false 86 | } 87 | 88 | // Download . 89 | func (p *InventoryProfileStorage) download() error { 90 | items, err := Cred.InventoryProfile().Get() 91 | if err != nil { 92 | return err 93 | } 94 | p.storeAll(items) 95 | return nil 96 | } 97 | 98 | // Download . 99 | func (p *InventoryProfileStorage) Download() error { 100 | p.Lock() 101 | defer p.Unlock() 102 | return p.download() 103 | } 104 | -------------------------------------------------------------------------------- /deploy/charts/netris-operator/crds/k8s.netris.ai_controllers.yaml: -------------------------------------------------------------------------------- 1 | 2 | --- 3 | apiVersion: apiextensions.k8s.io/v1 4 | kind: CustomResourceDefinition 5 | metadata: 6 | annotations: 7 | controller-gen.kubebuilder.io/version: v0.6.1 8 | creationTimestamp: null 9 | name: controllers.k8s.netris.ai 10 | spec: 11 | group: k8s.netris.ai 12 | names: 13 | kind: Controller 14 | listKind: ControllerList 15 | plural: controllers 16 | singular: controller 17 | scope: Namespaced 18 | versions: 19 | - additionalPrinterColumns: 20 | - jsonPath: .spec.tenant 21 | name: Tenant 22 | type: string 23 | - jsonPath: .spec.site 24 | name: Site 25 | type: string 26 | - jsonPath: .spec.mainIp 27 | name: Main IP 28 | type: string 29 | - jsonPath: .status.status 30 | name: Status 31 | type: string 32 | - jsonPath: .metadata.creationTimestamp 33 | name: Age 34 | type: date 35 | name: v1alpha1 36 | schema: 37 | openAPIV3Schema: 38 | description: Controller is the Schema for the controllers API 39 | properties: 40 | apiVersion: 41 | description: 'APIVersion defines the versioned schema of this representation 42 | of an object. Servers should convert recognized schemas to the latest 43 | internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 44 | type: string 45 | kind: 46 | description: 'Kind is a string value representing the REST resource this 47 | object represents. Servers may infer this from the endpoint the client 48 | submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 49 | type: string 50 | metadata: 51 | type: object 52 | spec: 53 | description: ControllerSpec defines the desired state of Controller 54 | properties: 55 | description: 56 | type: string 57 | mainIp: 58 | pattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$ 59 | type: string 60 | site: 61 | type: string 62 | tenant: 63 | type: string 64 | type: object 65 | status: 66 | description: ControllerStatus defines the observed state of Controller 67 | properties: 68 | message: 69 | type: string 70 | status: 71 | type: string 72 | type: object 73 | type: object 74 | served: true 75 | storage: true 76 | subresources: 77 | status: {} 78 | status: 79 | acceptedNames: 80 | kind: "" 81 | plural: "" 82 | conditions: [] 83 | storedVersions: [] 84 | -------------------------------------------------------------------------------- /api/v1alpha1/controller_types.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021. Netris, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package v1alpha1 18 | 19 | import ( 20 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 21 | ) 22 | 23 | // EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! 24 | // NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. 25 | 26 | // ControllerSpec defines the desired state of Controller 27 | type ControllerSpec struct { 28 | // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster 29 | // Important: Run "make" to regenerate code after modifying this file 30 | 31 | Tenant string `json:"tenant,omitempty"` 32 | Description string `json:"description,omitempty"` 33 | Site string `json:"site,omitempty"` 34 | 35 | // +kubebuilder:validation:Pattern=`^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$` 36 | MainIP string `json:"mainIp,omitempty"` 37 | } 38 | 39 | // ControllerStatus defines the observed state of Controller 40 | type ControllerStatus struct { 41 | // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster 42 | // Important: Run "make" to regenerate code after modifying this file 43 | 44 | Status string `json:"status,omitempty"` 45 | Message string `json:"message,omitempty"` 46 | } 47 | 48 | // +kubebuilder:object:root=true 49 | // +kubebuilder:subresource:status 50 | // +kubebuilder:printcolumn:name="Tenant",type=string,JSONPath=`.spec.tenant` 51 | // +kubebuilder:printcolumn:name="Site",type=string,JSONPath=`.spec.site` 52 | // +kubebuilder:printcolumn:name="Main IP",type=string,JSONPath=`.spec.mainIp` 53 | // +kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.status` 54 | // +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp` 55 | 56 | // Controller is the Schema for the controllers API 57 | type Controller struct { 58 | metav1.TypeMeta `json:",inline"` 59 | metav1.ObjectMeta `json:"metadata,omitempty"` 60 | 61 | Spec ControllerSpec `json:"spec,omitempty"` 62 | Status ControllerStatus `json:"status,omitempty"` 63 | } 64 | 65 | //+kubebuilder:object:root=true 66 | 67 | // ControllerList contains a list of Controller 68 | type ControllerList struct { 69 | metav1.TypeMeta `json:",inline"` 70 | metav1.ListMeta `json:"metadata,omitempty"` 71 | Items []Controller `json:"items"` 72 | } 73 | 74 | func init() { 75 | SchemeBuilder.Register(&Controller{}, &ControllerList{}) 76 | } 77 | -------------------------------------------------------------------------------- /api/v1alpha1/inventoryprofilemeta_types.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021. Netris, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package v1alpha1 18 | 19 | import ( 20 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 21 | ) 22 | 23 | // EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! 24 | // NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. 25 | 26 | // InventoryProfileMetaSpec defines the desired state of InventoryProfileMeta 27 | type InventoryProfileMetaSpec struct { 28 | Imported bool `json:"imported"` 29 | Reclaim bool `json:"reclaimPolicy"` 30 | InventoryProfileCRGeneration int64 `json:"inventoryProfileGeneration"` 31 | ID int `json:"id"` 32 | InventoryProfileName string `json:"inventoryProfileName"` 33 | 34 | Description string `json:"description,omitempty"` 35 | 36 | Timezone string `json:"timezone"` 37 | 38 | AllowSSHFromIPv4 []string `json:"allowSshFromIpv4,omitempty"` 39 | AllowSSHFromIPv6 []string `json:"allowSshFromIpv6,omitempty"` 40 | NTPServers []string `json:"ntpServers,omitempty"` 41 | DNSServers []string `json:"dnsServers,omitempty"` 42 | CustomRules []InventoryProfileCustomRule `json:"customRules,omitempty"` 43 | } 44 | 45 | // InventoryProfileMetaStatus defines the observed state of InventoryProfileMeta 46 | type InventoryProfileMetaStatus struct { 47 | // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster 48 | // Important: Run "make" to regenerate code after modifying this file 49 | } 50 | 51 | //+kubebuilder:object:root=true 52 | //+kubebuilder:subresource:status 53 | 54 | // InventoryProfileMeta is the Schema for the inventoryprofilemeta API 55 | type InventoryProfileMeta struct { 56 | metav1.TypeMeta `json:",inline"` 57 | metav1.ObjectMeta `json:"metadata,omitempty"` 58 | 59 | Spec InventoryProfileMetaSpec `json:"spec,omitempty"` 60 | Status InventoryProfileMetaStatus `json:"status,omitempty"` 61 | } 62 | 63 | //+kubebuilder:object:root=true 64 | 65 | // InventoryProfileMetaList contains a list of InventoryProfileMeta 66 | type InventoryProfileMetaList struct { 67 | metav1.TypeMeta `json:",inline"` 68 | metav1.ListMeta `json:"metadata,omitempty"` 69 | Items []InventoryProfileMeta `json:"items"` 70 | } 71 | 72 | func init() { 73 | SchemeBuilder.Register(&InventoryProfileMeta{}, &InventoryProfileMetaList{}) 74 | } 75 | -------------------------------------------------------------------------------- /api/v1alpha1/switchmeta_types.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021. Netris, Inc. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package v1alpha1 18 | 19 | import ( 20 | "github.com/netrisai/netriswebapi/v2/types/inventory" 21 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 22 | ) 23 | 24 | // EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! 25 | // NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. 26 | 27 | // SwitchMetaSpec defines the desired state of SwitchMeta 28 | type SwitchMetaSpec struct { 29 | // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster 30 | // Important: Run "make" to regenerate code after modifying this file 31 | Imported bool `json:"imported"` 32 | Reclaim bool `json:"reclaimPolicy"` 33 | SwitchCRGeneration int64 `json:"switchGeneration"` 34 | ID int `json:"id"` 35 | SwitchName string `json:"switchName"` 36 | 37 | TenantID int `json:"tenant,omitempty"` 38 | Description string `json:"description,omitempty"` 39 | NOS inventory.NOS `json:"nos,omitempty"` 40 | SiteID int `json:"site,omitempty"` 41 | ASN int `json:"asn,omitempty"` 42 | ProfileID int `json:"profile,omitempty"` 43 | MainIP string `json:"mainIp,omitempty"` 44 | MgmtIP string `json:"mgmtIp,omitempty"` 45 | PortsCount int `json:"portsCount,omitempty"` 46 | MacAddress string `json:"macAddress,omitempty"` 47 | } 48 | 49 | // SwitchMetaStatus defines the observed state of SwitchMeta 50 | type SwitchMetaStatus struct { // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster 51 | // Important: Run "make" to regenerate code after modifying this file 52 | } 53 | 54 | //+kubebuilder:object:root=true 55 | //+kubebuilder:subresource:status 56 | 57 | // SwitchMeta is the Schema for the switchmeta API 58 | type SwitchMeta struct { 59 | metav1.TypeMeta `json:",inline"` 60 | metav1.ObjectMeta `json:"metadata,omitempty"` 61 | 62 | Spec SwitchMetaSpec `json:"spec,omitempty"` 63 | Status SwitchMetaStatus `json:"status,omitempty"` 64 | } 65 | 66 | //+kubebuilder:object:root=true 67 | 68 | // SwitchMetaList contains a list of SwitchMeta 69 | type SwitchMetaList struct { 70 | metav1.TypeMeta `json:",inline"` 71 | metav1.ListMeta `json:"metadata,omitempty"` 72 | Items []SwitchMeta `json:"items"` 73 | } 74 | 75 | func init() { 76 | SchemeBuilder.Register(&SwitchMeta{}, &SwitchMetaList{}) 77 | } 78 | --------------------------------------------------------------------------------