github.com/Racer159/jackal@v0.32.7-0.20240401174413-0bd2339e4f2e/src/types/k8s.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // SPDX-FileCopyrightText: 2021-Present The Jackal Authors 3 4 // Package types contains all the types used by Jackal. 5 package types 6 7 import ( 8 "fmt" 9 "time" 10 11 "github.com/Racer159/jackal/src/config/lang" 12 "github.com/Racer159/jackal/src/pkg/k8s" 13 "github.com/defenseunicorns/pkg/helpers" 14 ) 15 16 // WebhookStatus defines the status of a Component Webhook operating on a Jackal package secret. 17 type WebhookStatus string 18 19 // ComponentStatus defines the deployment status of a Jackal component within a package. 20 type ComponentStatus string 21 22 // DefaultWebhookWaitDuration is the default amount of time Jackal will wait for a webhook to complete. 23 const DefaultWebhookWaitDuration = time.Minute * 5 24 25 // All the different status options for a Jackal Component or a webhook that is running for a Jackal Component deployment. 26 const ( 27 WebhookStatusSucceeded WebhookStatus = "Succeeded" 28 WebhookStatusFailed WebhookStatus = "Failed" 29 WebhookStatusRunning WebhookStatus = "Running" 30 WebhookStatusRemoving WebhookStatus = "Removing" 31 32 ComponentStatusSucceeded ComponentStatus = "Succeeded" 33 ComponentStatusFailed ComponentStatus = "Failed" 34 ComponentStatusDeploying ComponentStatus = "Deploying" 35 ComponentStatusRemoving ComponentStatus = "Removing" 36 ) 37 38 // Values during setup of the initial jackal state 39 const ( 40 JackalGeneratedPasswordLen = 24 41 JackalGeneratedSecretLen = 48 42 JackalInClusterContainerRegistryNodePort = 31999 43 JackalRegistryPushUser = "jackal-push" 44 JackalRegistryPullUser = "jackal-pull" 45 46 JackalGitPushUser = "jackal-git-user" 47 JackalGitReadUser = "jackal-git-read-user" 48 49 JackalInClusterGitServiceURL = "http://jackal-gitea-http.jackal.svc.cluster.local:3000" 50 JackalInClusterArtifactServiceURL = JackalInClusterGitServiceURL + "/api/packages/" + JackalGitPushUser 51 ) 52 53 // JackalState is maintained as a secret in the Jackal namespace to track Jackal init data. 54 type JackalState struct { 55 JackalAppliance bool `json:"jackalAppliance" jsonschema:"description=Indicates if Jackal was initialized while deploying its own k8s cluster"` 56 Distro string `json:"distro" jsonschema:"description=K8s distribution of the cluster Jackal was deployed to"` 57 Architecture string `json:"architecture" jsonschema:"description=Machine architecture of the k8s node(s)"` 58 StorageClass string `json:"storageClass" jsonschema:"Default StorageClass value Jackal uses for variable templating"` 59 AgentTLS k8s.GeneratedPKI `json:"agentTLS" jsonschema:"PKI certificate information for the agent pods Jackal manages"` 60 61 GitServer GitServerInfo `json:"gitServer" jsonschema:"description=Information about the repository Jackal is configured to use"` 62 RegistryInfo RegistryInfo `json:"registryInfo" jsonschema:"description=Information about the container registry Jackal is configured to use"` 63 ArtifactServer ArtifactServerInfo `json:"artifactServer" jsonschema:"description=Information about the artifact registry Jackal is configured to use"` 64 LoggingSecret string `json:"loggingSecret" jsonschema:"description=Secret value that the internal Grafana server was seeded with"` 65 } 66 67 // DeployedPackage contains information about a Jackal Package that has been deployed to a cluster 68 // This object is saved as the data of a k8s secret within the 'Jackal' namespace (not as part of the JackalState secret). 69 type DeployedPackage struct { 70 Name string `json:"name"` 71 Data JackalPackage `json:"data"` 72 CLIVersion string `json:"cliVersion"` 73 Generation int `json:"generation"` 74 DeployedComponents []DeployedComponent `json:"deployedComponents"` 75 ComponentWebhooks map[string]map[string]Webhook `json:"componentWebhooks,omitempty"` 76 ConnectStrings ConnectStrings `json:"connectStrings,omitempty"` 77 } 78 79 // DeployedComponent contains information about a Jackal Package Component that has been deployed to a cluster. 80 type DeployedComponent struct { 81 Name string `json:"name"` 82 InstalledCharts []InstalledChart `json:"installedCharts"` 83 Status ComponentStatus `json:"status"` 84 ObservedGeneration int `json:"observedGeneration"` 85 } 86 87 // Webhook contains information about a Component Webhook operating on a Jackal package secret. 88 type Webhook struct { 89 Name string `json:"name"` 90 WaitDurationSeconds int `json:"waitDurationSeconds,omitempty"` 91 Status WebhookStatus `json:"status"` 92 ObservedGeneration int `json:"observedGeneration"` 93 } 94 95 // InstalledChart contains information about a Helm Chart that has been deployed to a cluster. 96 type InstalledChart struct { 97 Namespace string `json:"namespace"` 98 ChartName string `json:"chartName"` 99 } 100 101 // GitServerInfo contains information Jackal uses to communicate with a git repository to push/pull repositories to. 102 type GitServerInfo struct { 103 PushUsername string `json:"pushUsername" jsonschema:"description=Username of a user with push access to the git repository"` 104 PushPassword string `json:"pushPassword" jsonschema:"description=Password of a user with push access to the git repository"` 105 PullUsername string `json:"pullUsername" jsonschema:"description=Username of a user with pull-only access to the git repository. If not provided for an external repository then the push-user is used"` 106 PullPassword string `json:"pullPassword" jsonschema:"description=Password of a user with pull-only access to the git repository. If not provided for an external repository then the push-user is used"` 107 108 Address string `json:"address" jsonschema:"description=URL address of the git server"` 109 InternalServer bool `json:"internalServer" jsonschema:"description=Indicates if we are using a git server that Jackal is directly managing"` 110 } 111 112 // FillInEmptyValues sets every necessary value that's currently empty to a reasonable default 113 func (gs *GitServerInfo) FillInEmptyValues() error { 114 var err error 115 // Set default svc url if an external repository was not provided 116 if gs.Address == "" { 117 gs.Address = JackalInClusterGitServiceURL 118 gs.InternalServer = true 119 } 120 121 // Generate a push-user password if not provided by init flag 122 if gs.PushPassword == "" { 123 if gs.PushPassword, err = helpers.RandomString(JackalGeneratedPasswordLen); err != nil { 124 return fmt.Errorf("%s: %w", lang.ErrUnableToGenerateRandomSecret, err) 125 } 126 } 127 128 // Set read-user information if using an internal repository, otherwise copy from the push-user 129 if gs.PullUsername == "" { 130 if gs.InternalServer { 131 gs.PullUsername = JackalGitReadUser 132 } else { 133 gs.PullUsername = gs.PushUsername 134 } 135 } 136 if gs.PullPassword == "" { 137 if gs.InternalServer { 138 if gs.PullPassword, err = helpers.RandomString(JackalGeneratedPasswordLen); err != nil { 139 return fmt.Errorf("%s: %w", lang.ErrUnableToGenerateRandomSecret, err) 140 } 141 } else { 142 gs.PullPassword = gs.PushPassword 143 } 144 } 145 146 return nil 147 } 148 149 // ArtifactServerInfo contains information Jackal uses to communicate with a artifact registry to push/pull repositories to. 150 type ArtifactServerInfo struct { 151 PushUsername string `json:"pushUsername" jsonschema:"description=Username of a user with push access to the artifact registry"` 152 PushToken string `json:"pushPassword" jsonschema:"description=Password of a user with push access to the artifact registry"` 153 154 Address string `json:"address" jsonschema:"description=URL address of the artifact registry"` 155 InternalServer bool `json:"internalServer" jsonschema:"description=Indicates if we are using a artifact registry that Jackal is directly managing"` 156 } 157 158 // FillInEmptyValues sets every necessary value that's currently empty to a reasonable default 159 func (as *ArtifactServerInfo) FillInEmptyValues() { 160 // Set default svc url if an external registry was not provided 161 if as.Address == "" { 162 as.Address = JackalInClusterArtifactServiceURL 163 as.InternalServer = true 164 } 165 166 // Set the push username to the git push user if not specified 167 if as.PushUsername == "" { 168 as.PushUsername = JackalGitPushUser 169 } 170 } 171 172 // RegistryInfo contains information Jackal uses to communicate with a container registry to push/pull images. 173 type RegistryInfo struct { 174 PushUsername string `json:"pushUsername" jsonschema:"description=Username of a user with push access to the registry"` 175 PushPassword string `json:"pushPassword" jsonschema:"description=Password of a user with push access to the registry"` 176 PullUsername string `json:"pullUsername" jsonschema:"description=Username of a user with pull-only access to the registry. If not provided for an external registry than the push-user is used"` 177 PullPassword string `json:"pullPassword" jsonschema:"description=Password of a user with pull-only access to the registry. If not provided for an external registry than the push-user is used"` 178 179 Address string `json:"address" jsonschema:"description=URL address of the registry"` 180 NodePort int `json:"nodePort" jsonschema:"description=Nodeport of the registry. Only needed if the registry is running inside the kubernetes cluster"` 181 InternalRegistry bool `json:"internalRegistry" jsonschema:"description=Indicates if we are using a registry that Jackal is directly managing"` 182 183 Secret string `json:"secret" jsonschema:"description=Secret value that the registry was seeded with"` 184 } 185 186 // FillInEmptyValues sets every necessary value not already set to a reasonable default 187 func (ri *RegistryInfo) FillInEmptyValues() error { 188 var err error 189 // Set default NodePort if none was provided 190 if ri.NodePort == 0 { 191 ri.NodePort = JackalInClusterContainerRegistryNodePort 192 } 193 194 // Set default url if an external registry was not provided 195 if ri.Address == "" { 196 ri.InternalRegistry = true 197 ri.Address = fmt.Sprintf("%s:%d", helpers.IPV4Localhost, ri.NodePort) 198 } 199 200 // Generate a push-user password if not provided by init flag 201 if ri.PushPassword == "" { 202 if ri.PushPassword, err = helpers.RandomString(JackalGeneratedPasswordLen); err != nil { 203 return fmt.Errorf("%s: %w", lang.ErrUnableToGenerateRandomSecret, err) 204 } 205 } 206 207 // Set pull-username if not provided by init flag 208 if ri.PullUsername == "" { 209 if ri.InternalRegistry { 210 ri.PullUsername = JackalRegistryPullUser 211 } else { 212 // If this is an external registry and a pull-user wasn't provided, use the same credentials as the push user 213 ri.PullUsername = ri.PushUsername 214 } 215 } 216 if ri.PullPassword == "" { 217 if ri.InternalRegistry { 218 if ri.PullPassword, err = helpers.RandomString(JackalGeneratedPasswordLen); err != nil { 219 return fmt.Errorf("%s: %w", lang.ErrUnableToGenerateRandomSecret, err) 220 } 221 } else { 222 // If this is an external registry and a pull-user wasn't provided, use the same credentials as the push user 223 ri.PullPassword = ri.PushPassword 224 } 225 } 226 227 if ri.Secret == "" { 228 if ri.Secret, err = helpers.RandomString(JackalGeneratedSecretLen); err != nil { 229 return fmt.Errorf("%s: %w", lang.ErrUnableToGenerateRandomSecret, err) 230 } 231 } 232 233 return nil 234 }