github.com/jenkins-x/jx/v2@v2.1.155/pkg/cmd/create/create_addon_pipeline_events.go (about) 1 package create 2 3 import ( 4 "strings" 5 "time" 6 7 "github.com/jenkins-x/jx/v2/pkg/cmd/create/options" 8 9 "github.com/jenkins-x/jx/v2/pkg/cmd/helper" 10 11 "github.com/jenkins-x/jx/v2/pkg/helm" 12 13 "github.com/jenkins-x/jx/v2/pkg/kube/services" 14 15 "github.com/pkg/errors" 16 "github.com/spf13/cobra" 17 meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 18 19 "fmt" 20 21 "github.com/jenkins-x/jx-logging/pkg/log" 22 "github.com/jenkins-x/jx/v2/pkg/cmd/opts" 23 "github.com/jenkins-x/jx/v2/pkg/cmd/templates" 24 "github.com/jenkins-x/jx/v2/pkg/kube" 25 "github.com/jenkins-x/jx/v2/pkg/util" 26 ) 27 28 const ( 29 defaultPEName = "pipeline-events" 30 defaultPENamespace = "pipeline-events" 31 defaultPEReleaseName = "jx-pipeline-events" 32 defaultPEVersion = "0.0.11" 33 kibanaServiceName = "jx-pipeline-events-kibana" 34 kibanaDeploymentName = "jx-pipeline-events-kibana" 35 esDeploymentName = "jx-pipeline-events-elasticsearch-client" 36 ) 37 38 var ( 39 createAddonPipelineEventsLong = templates.LongDesc(` 40 Creates the Jenkins X pipeline events addon 41 `) 42 43 createAddonPipelineEventsExample = templates.Examples(` 44 # Create the pipeline-events addon 45 jx create addon pipeline-events 46 47 # Create the pipeline-events addon in a custom namespace 48 jx create addon pipeline-events -n mynamespace 49 `) 50 ) 51 52 // CreateAddonPipelineEventsOptions the options for the create spring command 53 type CreateAddonPipelineEventsOptions struct { 54 CreateAddonOptions 55 Password string 56 } 57 58 // NewCmdCreateAddonPipelineEvents creates a command object for the "create" command 59 func NewCmdCreateAddonPipelineEvents(commonOpts *opts.CommonOptions) *cobra.Command { 60 options := &CreateAddonPipelineEventsOptions{ 61 CreateAddonOptions: CreateAddonOptions{ 62 CreateOptions: options.CreateOptions{ 63 CommonOptions: commonOpts, 64 }, 65 }, 66 } 67 68 cmd := &cobra.Command{ 69 Use: "pipeline-events", 70 Short: "Create the pipeline events addon", 71 Aliases: []string{"pe"}, 72 Long: createAddonPipelineEventsLong, 73 Example: createAddonPipelineEventsExample, 74 Run: func(cmd *cobra.Command, args []string) { 75 options.Cmd = cmd 76 options.Args = args 77 err := options.Run() 78 helper.CheckErr(err) 79 }, 80 } 81 82 options.addFlags(cmd, defaultPENamespace, defaultPEReleaseName, defaultPEVersion) 83 84 cmd.Flags().StringVarP(&options.Password, "password", "p", "", "Password to access pipeline-events services such as Kibana and Elasticsearch. Defaults to default Jenkins X admin password.") 85 return cmd 86 } 87 88 // Run implements the command 89 func (o *CreateAddonPipelineEventsOptions) Run() error { 90 91 if o.ReleaseName == "" { 92 return util.MissingOption(optionRelease) 93 } 94 95 err := o.EnsureHelm() 96 if err != nil { 97 return errors.Wrap(err, "failed to ensure that helm is present") 98 } 99 client, err := o.KubeClient() 100 if err != nil { 101 return err 102 } 103 104 _, devNamespace, err := o.KubeClientAndDevNamespace() 105 if err != nil { 106 return fmt.Errorf("cannot find a dev team namespace to get existing exposecontroller config from. %v", err) 107 } 108 109 log.Logger().Infof("found dev namespace %s", devNamespace) 110 111 setValues := strings.Split(o.SetValues, ",") 112 helmOptions := helm.InstallChartOptions{ 113 Chart: o.Chart, 114 ReleaseName: o.ReleaseName, 115 Version: o.Version, 116 Ns: o.Namespace, 117 SetValues: setValues, 118 } 119 err = o.InstallChartWithOptions(helmOptions) 120 if err != nil { 121 return fmt.Errorf("elasticsearch deployment failed: %v", err) 122 } 123 124 log.Logger().Info("waiting for elasticsearch deployment to be ready, this can take a few minutes") 125 126 err = kube.WaitForDeploymentToBeReady(client, esDeploymentName, o.Namespace, 10*time.Minute) 127 if err != nil { 128 return err 129 } 130 log.Logger().Info("waiting for kibana deployment to be ready, this can take a few minutes") 131 132 err = kube.WaitForDeploymentToBeReady(client, kibanaDeploymentName, o.Namespace, 10*time.Minute) 133 if err != nil { 134 return err 135 } 136 137 // annotate the kibana and elasticsearch services so exposecontroller can create an ingress rule 138 err = o.addExposecontrollerAnnotations(kibanaServiceName) 139 if err != nil { 140 return err 141 } 142 143 esServiceName := kube.AddonServices[defaultPEName] 144 err = o.addExposecontrollerAnnotations(esServiceName) 145 if err != nil { 146 return err 147 } 148 149 if o.Password == "" { 150 o.Password, err = o.GetDefaultAdminPassword(devNamespace) 151 if err != nil { 152 return err 153 } 154 } 155 // create the ingress rule 156 err = o.Expose(devNamespace, o.Namespace, o.Password) 157 if err != nil { 158 return err 159 } 160 161 // get the external services URL 162 kIng, err := services.GetServiceURLFromName(client, kibanaServiceName, o.Namespace) 163 if err != nil { 164 return fmt.Errorf("failed to get external URL for service %s: %v", kibanaServiceName, err) 165 } 166 167 // get the external services URL 168 esIng, err := services.GetServiceURLFromName(client, esServiceName, o.Namespace) 169 if err != nil { 170 return fmt.Errorf("failed to get external URL for service %s: %v", kibanaServiceName, err) 171 } 172 173 // create the local addonAuth.yaml file so `jx get cve` commands work 174 tokenOptions := CreateTokenAddonOptions{ 175 Password: o.Password, 176 Username: "admin", 177 ServerFlags: opts.ServerFlags{ 178 ServerURL: esIng, 179 ServerName: esDeploymentName, 180 }, 181 Kind: kube.ValueKindPipelineEvent, 182 CreateOptions: options.CreateOptions{ 183 CommonOptions: o.CommonOptions, 184 }, 185 } 186 err = tokenOptions.Run() 187 if err != nil { 188 return fmt.Errorf("failed to create addonAuth.yaml error: %v", err) 189 } 190 191 _, currentNamespace, err := o.KubeClientAndNamespace() 192 if err != nil { 193 return errors.Wrap(err, "getting current namespace") 194 } 195 _, err = client.CoreV1().Services(currentNamespace).Get(esServiceName, meta_v1.GetOptions{}) 196 if err != nil { 197 // create a services link 198 err = services.CreateServiceLink(client, currentNamespace, o.Namespace, esServiceName, esIng) 199 if err != nil { 200 return fmt.Errorf("failed creating a service link for %s in target namespace %s", esServiceName, o.Namespace) 201 } 202 } 203 204 log.Logger().Infof("kibana is available and running %s", kIng) 205 return nil 206 } 207 func (o *CreateAddonPipelineEventsOptions) addExposecontrollerAnnotations(serviceName string) error { 208 client, err := o.KubeClient() 209 if err != nil { 210 return err 211 } 212 213 svc, err := client.CoreV1().Services(o.Namespace).Get(serviceName, meta_v1.GetOptions{}) 214 if err != nil { 215 return fmt.Errorf("failed to get Service %s: %v", serviceName, err) 216 } 217 if svc.Annotations == nil { 218 svc.Annotations = map[string]string{} 219 } 220 221 annotationsUpdated := false 222 if svc.Annotations[kube.AnnotationExpose] == "" { 223 svc.Annotations[kube.AnnotationExpose] = "true" 224 annotationsUpdated = true 225 } 226 if svc.Annotations[kube.AnnotationIngress] == "" { 227 svc.Annotations[kube.AnnotationIngress] = "nginx.ingress.kubernetes.io/auth-type: basic\nnginx.ingress.kubernetes.io/auth-secret: jx-basic-auth" 228 annotationsUpdated = true 229 } 230 if annotationsUpdated { 231 svc, err = client.CoreV1().Services(o.Namespace).Update(svc) 232 if err != nil { 233 return fmt.Errorf("failed to update service %s/%s", o.Namespace, serviceName) 234 } 235 } 236 return nil 237 }