Uploaded image for project: 'OpenShift GitOps'
  1. OpenShift GitOps
  2. GITOPS-1912

Refactor the Operator's Golang package structure

XMLWordPrintable

    • Icon: Epic Epic
    • Resolution: Won't Do
    • Icon: Normal Normal
    • None
    • None
    • Operator
    • Refactor the Operator's Golang package structure
    • False
    • None
    • False
    • 0% To Do, 0% In Progress, 100% Done

      Description

      Currently, the Operator has four main packages defined

      • argocd
      • argocdexport
      • argoutil
      • openshift

      We need to break these down into smaller, logically well-defined packages.

      Why is this important?

      Especially the argocd package is huge and should be logically separated into smaller, better maintainable and testable packages.

      The argocd package defines so many symbols (functions, global variables, etc) that it becomes a major pain to maintain and understand from a contributor's perspective. 

      I tend to sarcastically refer to the Operator's code base as "a shell-script, just written in Go". 

      Acceptance criteria

      This task is for analyzing the existing code base's structure and coming up with a proposal for a new structure. The goals for the proposal are:

      • Packages are logically separated (e.g. for manipulating certain Kubernetes resources, such as Deployments, ConfigMaps, Secrets, etc)
      • Packages have well-defined public interfaces
      • Have some abstract data structures for the resources we manage with the Operator

      Care should be taken not to over-engineer the final solution, but also to have some robust, modern Golang architectural concepts in the code.

      Examples

      For example, a package permissions that would handle all RBAC relevant code and provides data types and functions such as:

      package permissions
      
      type Role struct {
      // some stuff
      }
      
      type ClusterRole struct {
      // some fields
      }}
      
      type RoleBinding struct {
      // some fields
      } 
      
      type ClusterRoleBinding struct {
      // some fields
      }
      
      type ServiceAccount struct {
      // some fields
      }
      
      func NewRole(name string) *Role {
      // some code
      }
      
      func NewServiceAccount(name string) *ServiceAccount {
      // some code
      }
      
      func (sa *ServiceAccount) GrantRole(r *Role, ns string) (*RoleBinding, error) {
      // some code that creates RoleBinding to bind r to sa
      }

      You get the idea.

      This will definitely help in avoiding repetition, helps maintenance by providing clean interfaces, helps unit testing and overall would improve the architectural design of the code base.

              jrao@redhat.com Jaideep Rao
              jfischer@redhat.com Jann Fischer
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

                Created:
                Updated:
                Resolved: