func()

in pkg/service/gerrit/gerrit.go [110:295]


func (s ComponentService) Configure(instance *gerritApi.Gerrit) (*gerritApi.Gerrit, bool, error) {
	gerritUrl, err := s.GetGerritSSHUrl(instance)
	if err != nil {
		return instance, false, errors.Wrap(err, "unable to get Gerrit SSH URL")
	}

	executableFilePath, err := platformHelper.GetExecutableFilePath()
	if err != nil {
		return instance, false, errors.Wrap(err, "unable to get executable file path")
	}

	gerritScriptsPath := platformHelper.LocalScriptsRelativePath
	if !s.runningInCluster() {
		gerritScriptsPath = filepath.FromSlash(fmt.Sprintf("%v/../%v/%v", executableFilePath, platformHelper.LocalConfigsRelativePath, platformHelper.DefaultScriptsDirectory))
	}

	err = s.PlatformService.CreateSecret(
		instance,
		instance.Name+"-admin-password",
		map[string][]byte{
			user:     []byte(spec.GerritDefaultAdminUser),
			password: []byte(uniuri.New()),
		},
		map[string]string{},
	)
	if err != nil {
		return instance, false, errors.Wrapf(err, "failed to create admin Secret %s for Gerrit", instance.Name+"-admin-password")
	}

	sshPortService, err := s.GetServicePort(instance)
	if err != nil {
		return instance, false, err
	}

	sshPort, err := s.PlatformService.GetDeploymentSSHPort(instance)
	if err != nil {
		return instance, false, fmt.Errorf("failed to get SSH port for Gerrit instance %q: %w", instance.Name, err)
	}

	service, err := s.PlatformService.GetService(instance.Namespace, instance.Name)
	if err != nil {
		return instance, false, errors.Wrap(err, "unable to get Gerrit service")
	}

	err = s.PlatformService.UpdateService(service, sshPortService)
	if err != nil {
		return instance, false, errors.Wrapf(err, "unable to update Gerrit service")
	}

	dUpdated, err := s.updateDeploymentConfigPort(sshPort, sshPortService, instance)
	if err != nil {
		return instance, false, err
	}

	if dUpdated {
		return instance, true, nil
	}

	gerritApiUrl, err := s.getGerritRestApiUrl(instance)
	if err != nil {
		return instance, false, errors.Wrapf(err, "failed to get Gerrit REST API URL %v/%v", instance.Namespace, instance.Name)
	}

	gerritAdminPassword, err := s.getGerritAdminPassword(instance)
	if err != nil {
		return instance, false, errors.Wrapf(err, "failed to get Gerrit admin password from secret for %s/%s", instance.Namespace, instance.Name)
	}

	podList, err := s.PlatformService.GetPods(instance.Namespace, &metaV1.ListOptions{LabelSelector: "app=" + instance.Name})
	if err != nil || len(podList.Items) != 1 {
		return instance, false, errors.Wrapf(err, "unable to determine Gerrit pod name: %v", len(podList.Items))
	}

	_, gerritAdminPublicKey, err := s.createSSHKeyPairs(instance, instance.Name+admin)
	if err != nil {
		return instance, false, errors.Wrapf(err, "failed to create Gerrit admin SSH keypair %v/%v", instance.Namespace, instance.Name)
	}

	err = s.gerritClient.InitNewRestClient(instance, gerritApiUrl, spec.GerritDefaultAdminUser, gerritAdminPassword)
	if err != nil {
		return instance, false, errors.Wrapf(err, "failed to initialize Gerrit REST client for %v/%v", instance.Namespace, instance.Name)
	}

	status, err := s.gerritClient.CheckCredentials()
	if (status != http.StatusUnauthorized && status >= http.StatusBadRequest && status <= http.StatusHTTPVersionNotSupported) || err != nil {
		return instance, false, errors.Wrap(err, "failed to check credentials in Gerrit")
	}

	if status == http.StatusUnauthorized {
		// apparently we are trying to retry with default password
		err = s.gerritClient.InitNewRestClient(instance, gerritApiUrl, spec.GerritDefaultAdminUser, spec.GerritDefaultAdminPassword)
		if err != nil {
			return instance, false, errors.Wrapf(err, "Failed to initialize Gerrit REST client for %v/%v", instance.Namespace, instance.Name)
		}

		status, err = s.gerritClient.CheckCredentials()
		if (status != http.StatusUnauthorized && status >= http.StatusBadRequest && status <= http.StatusHTTPVersionNotSupported) || err != nil {
			return instance, false, errors.Wrap(err, "failed to check credentials in Gerrit")
		}

		if status == http.StatusUnauthorized {
			var adminInstance *gerritApi.Gerrit

			adminInstance, err = s.gerritClient.InitAdminUser(instance, s.PlatformService, gerritScriptsPath, podList.Items[0].Name,
				string(gerritAdminPublicKey))
			if err != nil {
				return adminInstance, false, errors.Wrap(err, "failed to initialize Gerrit Admin User")
			}
		}

		err = s.setGerritAdminUserPassword(instance, gerritUrl, gerritAdminPassword, gerritApiUrl, sshPortService)
		if err != nil {
			return instance, false, err
		}
	}

	gerritSecretName := instance.Name + admin

	gerritAdminSshKeys, err := s.PlatformService.GetSecret(instance.Namespace, instance.Name+admin)
	if err != nil {
		return instance, false, fmt.Errorf("failed to get secret %q for gerrit: %w", gerritSecretName, err)
	}

	podName := podList.Items[0].Name
	command := []string{"/bin/sh", "-c", "chown -R gerrit2:gerrit2 /var/gerrit/review_site"}

	_, _, err = s.PlatformService.ExecInPod(instance.Namespace, podName, command)
	if err != nil {
		return instance, false, fmt.Errorf("failed to exec command %q in a pod %q: %w", strings.Join(command, " "), podName, err)
	}

	err = s.gerritClient.InitNewSshClient(spec.GerritDefaultAdminUser, gerritAdminSshKeys[rsaID], gerritUrl, sshPortService)
	if err != nil {
		return instance, false, fmt.Errorf("failed to init ssh client for gerrit: %w", err)
	}

	ciToolsStatus, err := s.gerritClient.CheckGroup(spec.GerritCIToolsGroupName)
	if err != nil {
		return instance, false, fmt.Errorf("failed to check Gerrit group %q: %w", spec.GerritCIToolsGroupName, err)
	}

	projectBootstrappersStatus, err := s.gerritClient.CheckGroup(spec.GerritProjectBootstrappersGroupName)
	if err != nil {
		return instance, false, fmt.Errorf("failed to check Gerrit group %q: %w", spec.GerritProjectBootstrappersGroupName, err)
	}

	if *ciToolsStatus == http.StatusNotFound || *projectBootstrappersStatus == http.StatusNotFound {
		err = s.gerritClient.InitNewSshClient(spec.GerritDefaultAdminUser, gerritAdminSshKeys[rsaID], gerritUrl, sshPortService)
		if err != nil {
			return instance, false, fmt.Errorf("failed to init ssh client for gerrit: %w", err)
		}

		const errTemplate = "failed to create Gerrit group %q: %w"

		_, err = s.gerritClient.CreateGroup(spec.GerritCIToolsGroupName, spec.GerritCIToolsGroupDescription,
			true)
		if err != nil {
			return instance, false, fmt.Errorf(errTemplate, spec.GerritCIToolsGroupName, err)
		}

		_, err = s.gerritClient.CreateGroup(spec.GerritProjectBootstrappersGroupName,
			spec.GerritProjectBootstrappersGroupDescription, true)
		if err != nil {
			return instance, false, fmt.Errorf(errTemplate, spec.GerritProjectBootstrappersGroupName, err)
		}

		_, err = s.gerritClient.CreateGroup(spec.GerritProjectDevelopersGroupName,
			spec.GerritProjectDevelopersGroupNameDescription, true)
		if err != nil {
			return instance, false, fmt.Errorf(errTemplate, spec.GerritProjectDevelopersGroupName, err)
		}

		_, err = s.gerritClient.CreateGroup(spec.GerritReadOnlyGroupName, "", true)
		if err != nil {
			return instance, false, fmt.Errorf(errTemplate, spec.GerritReadOnlyGroupName, err)
		}

		err = s.gerritClient.InitAllProjects(instance, s.PlatformService, gerritScriptsPath, podList.Items[0].Name,
			string(gerritAdminPublicKey))
		if err != nil {
			return instance, false, errors.Wrapf(err, "failed to initialize Gerrit All-Projects project")
		}
	}

	return instance, false, nil
}