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

Refactor the Operator's Golang package structure


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


      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.


      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
            0 Vote for this issue
            4 Start watching this issue