github.com/interconnectedcloud/qdr-operator@v0.0.0-20210826174505-576d2b33dac7/pkg/utils/configs/config.go (about)

     1  package configs
     2  
     3  import (
     4  	"bytes"
     5  	"strconv"
     6  	"text/template"
     7  
     8  	v1alpha1 "github.com/interconnectedcloud/qdr-operator/pkg/apis/interconnectedcloud/v1alpha1"
     9  	"github.com/interconnectedcloud/qdr-operator/pkg/constants"
    10  	"github.com/interconnectedcloud/qdr-operator/pkg/utils/openshift"
    11  )
    12  
    13  func isSslProfileDefined(m *v1alpha1.Interconnect, name string) bool {
    14  	for _, profile := range m.Spec.SslProfiles {
    15  		if profile.Name == name {
    16  			return true
    17  		}
    18  	}
    19  	return false
    20  }
    21  
    22  func isSslProfileUsed(m *v1alpha1.Interconnect, name string) bool {
    23  	for _, listener := range m.Spec.Listeners {
    24  		if listener.SslProfile == name {
    25  			return true
    26  		}
    27  	}
    28  	for _, listener := range m.Spec.InterRouterListeners {
    29  		if listener.SslProfile == name {
    30  			return true
    31  		}
    32  	}
    33  	return false
    34  }
    35  
    36  func isDefaultSslProfileDefined(m *v1alpha1.Interconnect) bool {
    37  	return isSslProfileDefined(m, "default")
    38  }
    39  
    40  func isDefaultSslProfileUsed(m *v1alpha1.Interconnect) bool {
    41  	return isSslProfileUsed(m, "default")
    42  }
    43  
    44  func isInterRouterSslProfileDefined(m *v1alpha1.Interconnect) bool {
    45  	return isSslProfileDefined(m, "inter-router")
    46  }
    47  
    48  func isInterRouterSslProfileUsed(m *v1alpha1.Interconnect) bool {
    49  	return isSslProfileUsed(m, "inter-router")
    50  }
    51  
    52  func getExposedListeners(listeners []v1alpha1.Listener) []v1alpha1.Listener {
    53  	exposedListeners := []v1alpha1.Listener{}
    54  	for _, listener := range listeners {
    55  		if listener.Expose {
    56  			exposedListeners = append(exposedListeners, listener)
    57  		}
    58  	}
    59  	return exposedListeners
    60  }
    61  
    62  func GetInterconnectExposedListeners(m *v1alpha1.Interconnect) []v1alpha1.Listener {
    63  	listeners := []v1alpha1.Listener{}
    64  	normal := getExposedListeners(m.Spec.Listeners)
    65  	internal := getExposedListeners(m.Spec.InterRouterListeners)
    66  	edge := getExposedListeners(m.Spec.EdgeListeners)
    67  	listeners = append(listeners, normal...)
    68  	listeners = append(listeners, internal...)
    69  	listeners = append(listeners, edge...)
    70  	return listeners
    71  }
    72  
    73  func GetInterconnectExposedHostnames(m *v1alpha1.Interconnect, profileName string) []string {
    74  	var hostNames []string
    75  	exposedListeners := GetInterconnectExposedListeners(m)
    76  	dns := openshift.GetDnsConfig()
    77  
    78  	for _, listener := range exposedListeners {
    79  		if listener.SslProfile == profileName {
    80  			target := listener.Name
    81  			if target == "" {
    82  				target = strconv.Itoa(int(listener.Port))
    83  			}
    84  			hostNames = append(hostNames, m.Name+"-"+target+"."+m.Namespace+"."+dns.Spec.BaseDomain)
    85  		}
    86  	}
    87  	hostNames = append(hostNames, m.Name+"."+m.Namespace+".svc.cluster.local")
    88  
    89  	return hostNames
    90  }
    91  
    92  func IsCaSecretNeeded(profile *v1alpha1.SslProfile) bool {
    93  	// If the ca and credentials are in the same secret, don't need to mount it twice
    94  	// If the credentials were generated and signed by the ca in the profile, then the credentials
    95  	// secret will contain the ca public key, so the ca secret doesn't need to be mounted
    96  	return profile.CaCert != profile.Credentials && !(profile.MutualAuth && profile.GenerateCredentials)
    97  }
    98  
    99  func SetInterconnectDefaults(m *v1alpha1.Interconnect, certMgrPresent bool) (bool, bool) {
   100  	requestCert := false
   101  	updateDefaults := false
   102  
   103  	if m.Spec.DeploymentPlan.Size == 0 {
   104  		m.Spec.DeploymentPlan.Size = 1
   105  		updateDefaults = true
   106  	}
   107  	if m.Spec.DeploymentPlan.Role == "" {
   108  		m.Spec.DeploymentPlan.Role = v1alpha1.RouterRoleInterior
   109  		updateDefaults = true
   110  	}
   111  	if m.Spec.DeploymentPlan.Placement == "" {
   112  		m.Spec.DeploymentPlan.Placement = v1alpha1.PlacementAny
   113  		updateDefaults = true
   114  	}
   115  	if m.Spec.DeploymentPlan.LivenessPort == 0 {
   116  		m.Spec.DeploymentPlan.LivenessPort = constants.HttpLivenessPort
   117  		updateDefaults = true
   118  	}
   119  
   120  	if m.Spec.Users == "" {
   121  		m.Spec.Users = m.Name + "-users"
   122  	}
   123  
   124  	if len(m.Spec.Addresses) == 0 {
   125  		m.Spec.Addresses = append(m.Spec.Addresses, v1alpha1.Address{
   126  			Prefix:       "closest",
   127  			Distribution: "closest",
   128  		})
   129  		m.Spec.Addresses = append(m.Spec.Addresses, v1alpha1.Address{
   130  			Prefix:       "multicast",
   131  			Distribution: "multicast",
   132  		})
   133  		m.Spec.Addresses = append(m.Spec.Addresses, v1alpha1.Address{
   134  			Prefix:       "unicast",
   135  			Distribution: "closest",
   136  		})
   137  		m.Spec.Addresses = append(m.Spec.Addresses, v1alpha1.Address{
   138  			Prefix:       "exclusive",
   139  			Distribution: "closest",
   140  		})
   141  		m.Spec.Addresses = append(m.Spec.Addresses, v1alpha1.Address{
   142  			Prefix:       "broadcast",
   143  			Distribution: "multicast",
   144  		})
   145  	}
   146  
   147  	if len(m.Spec.Listeners) == 0 {
   148  		m.Spec.Listeners = append(m.Spec.Listeners, v1alpha1.Listener{
   149  			Port: 5672,
   150  		}, v1alpha1.Listener{
   151  			Port:             8080,
   152  			Http:             true,
   153  			Expose:           true,
   154  			AuthenticatePeer: true,
   155  		})
   156  		if certMgrPresent {
   157  			m.Spec.Listeners = append(m.Spec.Listeners, v1alpha1.Listener{
   158  				Port:       5671,
   159  				SslProfile: "default",
   160  			})
   161  		}
   162  		updateDefaults = true
   163  	}
   164  	if m.Spec.DeploymentPlan.Role == v1alpha1.RouterRoleInterior {
   165  		if len(m.Spec.InterRouterListeners) == 0 {
   166  			if certMgrPresent {
   167  				m.Spec.InterRouterListeners = append(m.Spec.InterRouterListeners, v1alpha1.Listener{
   168  					Port:             55671,
   169  					SslProfile:       "inter-router",
   170  					Expose:           true,
   171  					AuthenticatePeer: true,
   172  					SaslMechanisms:   "EXTERNAL",
   173  				})
   174  			} else {
   175  				m.Spec.InterRouterListeners = append(m.Spec.InterRouterListeners, v1alpha1.Listener{
   176  					Port: 55672,
   177  				})
   178  			}
   179  			updateDefaults = true
   180  		}
   181  		if len(m.Spec.EdgeListeners) == 0 {
   182  			m.Spec.EdgeListeners = append(m.Spec.EdgeListeners, v1alpha1.Listener{
   183  				Port: 45672,
   184  			})
   185  			updateDefaults = true
   186  		}
   187  	}
   188  	if !isDefaultSslProfileDefined(m) && isDefaultSslProfileUsed(m) {
   189  		m.Spec.SslProfiles = append(m.Spec.SslProfiles, v1alpha1.SslProfile{
   190  			Name:                "default",
   191  			Credentials:         m.Name + "-default-credentials",
   192  			GenerateCredentials: true,
   193  		})
   194  		updateDefaults = true
   195  		requestCert = true
   196  	}
   197  	if !isInterRouterSslProfileDefined(m) && isInterRouterSslProfileUsed(m) {
   198  		m.Spec.SslProfiles = append(m.Spec.SslProfiles, v1alpha1.SslProfile{
   199  			Name:                "inter-router",
   200  			Credentials:         m.Name + "-inter-router-credentials",
   201  			CaCert:              m.Name + "-inter-router-ca",
   202  			GenerateCredentials: true,
   203  			GenerateCaCert:      true,
   204  			MutualAuth:          true,
   205  		})
   206  		updateDefaults = true
   207  		requestCert = true
   208  	}
   209  	if certMgrPresent {
   210  		for i := range m.Spec.SslProfiles {
   211  			if m.Spec.SslProfiles[i].Credentials == "" && m.Spec.SslProfiles[i].CaCert == "" {
   212  				m.Spec.SslProfiles[i].Credentials = m.Name + "-" + m.Spec.SslProfiles[i].Name + "-credentials"
   213  				m.Spec.SslProfiles[i].GenerateCredentials = true
   214  				if m.Spec.SslProfiles[i].MutualAuth {
   215  					m.Spec.SslProfiles[i].CaCert = m.Name + "-" + m.Spec.SslProfiles[i].Name + "-ca"
   216  					m.Spec.SslProfiles[i].GenerateCaCert = true
   217  				}
   218  				updateDefaults = true
   219  				requestCert = true
   220  			} else if m.Spec.SslProfiles[i].Credentials == "" && m.Spec.SslProfiles[i].MutualAuth {
   221  				m.Spec.SslProfiles[i].Credentials = m.Name + "-" + m.Spec.SslProfiles[i].Name + "-credentials"
   222  				m.Spec.SslProfiles[i].GenerateCredentials = true
   223  				updateDefaults = true
   224  				requestCert = true
   225  			} else if m.Spec.SslProfiles[i].CaCert == "" && m.Spec.SslProfiles[i].MutualAuth {
   226  				m.Spec.SslProfiles[i].CaCert = m.Name + "-" + m.Spec.SslProfiles[i].Name + "-ca"
   227  				m.Spec.SslProfiles[i].GenerateCaCert = true
   228  				updateDefaults = true
   229  				requestCert = true
   230  			} else if m.Spec.SslProfiles[i].GenerateCredentials || m.Spec.SslProfiles[i].GenerateCaCert {
   231  				requestCert = true
   232  			}
   233  		}
   234  	}
   235  	return requestCert && certMgrPresent, updateDefaults
   236  }
   237  
   238  func ConfigForInterconnect(m *v1alpha1.Interconnect) string {
   239  	config := `
   240  router {
   241      mode: {{.DeploymentPlan.Role}}
   242      id: ${HOSTNAME}
   243  }
   244  {{range .Listeners}}
   245  listener {
   246      {{- if .Name}}
   247      name: {{.Name}}
   248      {{- end}}
   249      {{- if .Host}}
   250      host: {{.Host}}
   251      {{- else}}
   252      host: 0.0.0.0
   253      {{- end}}
   254      {{- if .Port}}
   255      port: {{.Port}}
   256      {{- end}}
   257      {{- if .LinkCapacity}}
   258      linkCapacity: {{.LinkCapacity}}
   259      {{- end}}
   260      {{- if .RouteContainer}}
   261      role: route-container
   262      {{- else }}
   263      role: normal
   264      {{- end}}
   265      {{- if .Http}}
   266      http: true
   267      {{- end}}
   268      {{- if .AuthenticatePeer}}
   269      authenticatePeer: true
   270      {{- end}}
   271      {{- if .SaslMechanisms}}
   272      saslMechanisms: {{.SaslMechanisms}}
   273      {{- end}}
   274      {{- if .SslProfile}}
   275      sslProfile: {{.SslProfile}}
   276      {{- end}}
   277  }
   278  {{- end}}
   279  listener {
   280      name: health-and-stats
   281      port: {{.DeploymentPlan.LivenessPort}}
   282      http: true
   283      healthz: true
   284      metrics: true
   285      websockets: false
   286      httpRootDir: invalid
   287  }
   288  {{range .InterRouterListeners}}
   289  listener {
   290      {{- if .Name}}
   291      name: {{.Name}}
   292      {{- end}}
   293      role: inter-router
   294      {{- if .Host}}
   295      host: {{.Host}}
   296      {{- else}}
   297      host: 0.0.0.0
   298      {{- end}}
   299      {{- if .Port}}
   300      port: {{.Port}}
   301      {{- end}}
   302      {{- if .Cost}}
   303      cost: {{.Cost}}
   304      {{- end}}
   305      {{- if .LinkCapacity}}
   306      linkCapacity: {{.LinkCapacity}}
   307      {{- end}}
   308      {{- if .SaslMechanisms}}
   309      saslMechanisms: {{.SaslMechanisms}}
   310      {{- end}}
   311      {{- if .AuthenticatePeer}}
   312      authenticatePeer: true
   313      {{- end}}
   314      {{- if .SslProfile}}
   315      sslProfile: {{.SslProfile}}
   316      {{- end}}
   317  }
   318  {{- end}}
   319  {{range .EdgeListeners}}
   320  listener {
   321      {{- if .Name}}
   322      name: {{.Name}}
   323      {{- end}}
   324      role: edge
   325      {{- if .Host}}
   326      host: {{.Host}}
   327      {{- else}}
   328      host: 0.0.0.0
   329      {{- end}}
   330      {{- if .Port}}
   331      port: {{.Port}}
   332      {{- end}}
   333      {{- if .Cost}}
   334      cost: {{.Cost}}
   335      {{- end}}
   336      {{- if .LinkCapacity}}
   337      linkCapacity: {{.LinkCapacity}}
   338      {{- end}}
   339      {{- if .SaslMechanisms}}
   340      saslMechanisms: {{.SaslMechanisms}}
   341      {{- end}}
   342      {{- if .AuthenticatePeer}}
   343      authenticatePeer: true
   344      {{- end}}
   345      {{- if .SslProfile}}
   346      sslProfile: {{.SslProfile}}
   347      {{- end}}
   348  }
   349  {{- end}}
   350  {{range .SslProfiles}}
   351  sslProfile {
   352     name: {{.Name}}
   353     {{- if .Credentials}}
   354     certFile: /etc/qpid-dispatch-certs/{{.Name}}/{{.Credentials}}/tls.crt
   355     privateKeyFile: /etc/qpid-dispatch-certs/{{.Name}}/{{.Credentials}}/tls.key
   356     {{- end}}
   357     {{- if .CaCert}}
   358         {{- if eq .CaCert .Credentials}}
   359     caCertFile: /etc/qpid-dispatch-certs/{{.Name}}/{{.CaCert}}/ca.crt
   360         {{- else if and .GenerateCredentials .MutualAuth}}
   361     caCertFile: /etc/qpid-dispatch-certs/{{.Name}}/{{.Credentials}}/ca.crt
   362         {{- else}}
   363     caCertFile: /etc/qpid-dispatch-certs/{{.Name}}/{{.CaCert}}/tls.crt
   364         {{- end}}
   365     {{- end}}
   366  }
   367  {{- end}}
   368  {{range .Addresses}}
   369  address {
   370      {{- if .Prefix}}
   371      prefix: {{.Prefix}}
   372      {{- end}}
   373      {{- if .Pattern}}
   374      pattern: {{.Pattern}}
   375      {{- end}}
   376      {{- if .Distribution}}
   377      distribution: {{.Distribution}}
   378      {{- end}}
   379      {{- if .Waypoint}}
   380      waypoint: {{.Waypoint}}
   381      {{- end}}
   382      {{- if .IngressPhase}}
   383      ingressPhase: {{.IngressPhase}}
   384      {{- end}}
   385      {{- if .EgressPhase}}
   386      egressPhase: {{.EgressPhase}}
   387      {{- end}}
   388      {{- if .Priority}}
   389      priority: {{.Priority}}
   390      {{- end}}
   391      {{- if .EnableFallback}}
   392      enableFallback: {{.EnableFallback}}
   393      {{- end}}
   394  }
   395  {{- end}}
   396  {{range .AutoLinks}}
   397  autoLink {
   398      {{- if .Address}}
   399      addr: {{.Address}}
   400      {{- end}}
   401      {{- if .Direction}}
   402      direction: {{.Direction}}
   403      {{- end}}
   404      {{- if .ContainerId}}
   405      containerId: {{.ContainerId}}
   406      {{- end}}
   407      {{- if .Connection}}
   408      connection: {{.Connection}}
   409      {{- end}}
   410      {{- if .ExternalAddress}}
   411      externalAddress: {{.ExternalAddress}}
   412      {{- end}}
   413      {{- if .Phase}}
   414      phase: {{.Phase}}
   415      {{- end}}
   416      {{- if .Fallback}}
   417      fallback: {{.Fallback}}
   418      {{- end}}
   419  }
   420  {{- end}}
   421  {{range .LinkRoutes}}
   422  linkRoute {
   423      {{- if .Prefix}}
   424      prefix: {{.Prefix}}
   425      {{- end}}
   426      {{- if .Pattern}}
   427      pattern: {{.Pattern}}
   428      {{- end}}
   429      {{- if .Direction}}
   430      direction: {{.Direction}}
   431      {{- end}}
   432      {{- if .Connection}}
   433      connection: {{.Connection}}
   434      {{- end}}
   435      {{- if .ContainerId}}
   436      containerId: {{.ContainerId}}
   437      {{- end}}
   438      {{- if .AddExternalPrefix}}
   439      addExternalPrefix: {{.AddExternalPrefix}}
   440      {{- end}}
   441      {{- if .DelExternalPrefix}}
   442      delExternalPrefix: {{.DelExternalPrefix}}
   443      {{- end}}
   444  }
   445  {{- end}}
   446  {{range .Connectors}}
   447  connector {
   448      {{- if .Name}}
   449      name: {{.Name}}
   450      {{- end}}
   451      {{- if .Host}}
   452      host: {{.Host}}
   453      {{- end}}
   454      {{- if .Port}}
   455      port: {{.Port}}
   456      {{- end}}
   457      {{- if .RouteContainer}}
   458      role: route-container
   459      {{- else}}
   460      role: normal
   461      {{- end}}
   462      {{- if .Cost}}
   463      cost: {{.Cost}}
   464      {{- end}}
   465      {{- if .LinkCapacity}}
   466      linkCapacity: {{.LinkCapacity}}
   467      {{- end}}
   468      {{- if .SslProfile}}
   469      sslProfile: {{.SslProfile}}
   470      {{- end}}
   471      {{- if eq .VerifyHostname false}}
   472      verifyHostname: false
   473      {{- end}}
   474  }
   475  {{- end}}
   476  {{range .InterRouterConnectors}}
   477  connector {
   478      {{- if .Name}}
   479      name: {{.Name}}
   480      {{- end}}
   481      role: inter-router
   482      {{- if .Host}}
   483      host: {{.Host}}
   484      {{- end}}
   485      {{- if .Port}}
   486      port: {{.Port}}
   487      {{- end}}
   488      {{- if .Cost}}
   489      cost: {{.Cost}}
   490      {{- end}}
   491      {{- if .LinkCapacity}}
   492      linkCapacity: {{.LinkCapacity}}
   493      {{- end}}
   494      {{- if .SslProfile}}
   495      sslProfile: {{.SslProfile}}
   496      {{- end}}
   497      {{- if eq .VerifyHostname false}}
   498      verifyHostname: false
   499      {{- end}}
   500  }
   501  {{- end}}
   502  {{range .EdgeConnectors}}
   503  connector {
   504      {{- if .Name}}
   505      name: {{.Name}}
   506      {{- end}}
   507      role: edge
   508      {{- if .Host}}
   509      host: {{.Host}}
   510      {{- end}}
   511      {{- if .Port}}
   512      port: {{.Port}}
   513      {{- end}}
   514      {{- if .Cost}}
   515      cost: {{.Cost}}
   516      {{- end}}
   517      {{- if .LinkCapacity}}
   518      linkCapacity: {{.LinkCapacity}}
   519      {{- end}}
   520      {{- if .SslProfile}}
   521      sslProfile: {{.SslProfile}}
   522      {{- end}}
   523      {{- if eq .VerifyHostname false}}
   524      verifyHostname: false
   525      {{- end}}
   526  }
   527  {{- end}}`
   528  	var buff bytes.Buffer
   529  	qdrconfig := template.Must(template.New("qdrconfig").Parse(config))
   530  	qdrconfig.Execute(&buff, m.Spec)
   531  	return buff.String()
   532  }
   533  
   534  func ConfigForSasl(m *v1alpha1.Interconnect) string {
   535  	config := `
   536  pwcheck_method: auxprop
   537  auxprop_plugin: sasldb
   538  sasldb_path: /tmp/qdrouterd.sasldb
   539  `
   540  	return config
   541  }