Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TIR - remove dynamic pod data and surface helm status #1135

Closed
wants to merge 5 commits into from

Conversation

henrjk
Copy link
Member

@henrjk henrjk commented Jul 1, 2024

This change is meant to be released with the change in opendevstack/ods-document-generation-templates#145 although there is no technical coupling at the moment.

If helm is used for deployment, the components deployed by helm are no longer listed as toplevel elements in the TIR. Instead the helm release is represented by its status so that users will see tables under:

Deployment Resource: -deploymentMean
Deployment Resource: -deploymentStatus

The DeploymentStatus has rows surfacing the releaseName, releaseRevision, namespace, deployStatus, deployDescription, lastDeployed and resources.

Here an example of the resources:
"Deployment: backend-helm-monorepo-chart-component-a, backend- helm-monorepo-chart-component-b, Service: backend-helm-monorepo-chart"

Non-Helm deployments are surfaced as before.

Further change notes:

  • To avoid CPS issues in Jenkins all types were using their own file and the Immutable annotation was avoided.
  • Type HelmStatusData captures helm status with high fidelity whereas HelmStatusSimpleData captures shallower information in particular omitting the details of resources except their names and kinds. This approach simplifies the json Helm status json parsing code while keeping the consuming code relatively lean.
    In the deployment artifact the simplified helmStatus is kept under key 'helmStatus' in the deploymentMean information. Which is also written to ods-deployments.json by DeploymentDescriptor.
  • PodData fields capturing dynamic data where removed, except for the podName which has a prefix useful for correlating dynamic data with pods. At the moment this is still needed for both tailor and helm deployments. The code which finds this named pods did require retry logic even for helm installs using --atomic.

If helm is used for deployment, the components deployed by helm are
no longer listed as toplevel elements in the TIR. Instead the
helm release is represented by its status so that users will see
tables under:

Deployment Resource: <helm-release-name>-deploymentMean
Deployment Resource: <helm-release-name>-deploymentStatus

The DeploymentStatus has rows surfacing the releaseName, releaseRevision, namespace, deployStatus, deployDescription, lastDeployed and resources.

Here an example from the resources:
"Deployment: backend-helm-monorepo-chart-component-a, backend- helm-monorepo-chart-component-b, Service: backend-helm-monorepo- chart"

Non-Helm deployments are surfaced as before.

Further change notes:
- To avoid CPS issues in Jenkins all types were using their own file
and the Immutable annotation was avoided.
- Type HelmStatusData captures helm status with high fidelity whereas
HelmStatusSimpleData captures shallower information in particular
omitting the details of resources except their names and kinds.
This approach simplifies the json Helm status json parsing code
while keeping the consuming code relatively lean.
In the deployment artifact the simplified helmStatus is kept under key
'helmStatus' in the deploymentMean information. Which is also written
to `ods-deployments.json` by DeploymentDescriptor.
- PodData fields capturing dynamic data where removed, except for the
podName which has a prefix useful for correlating dynamic data with
pods. At the moment this is still needed for both tailor and helm
deployments. The code which finds this named pods did require retry logic
even for helm installs using --atomic.
@henrjk henrjk self-assigned this Jul 1, 2024
@henrjk henrjk marked this pull request as ready for review July 1, 2024 13:43
@henrjk henrjk force-pushed the feature/tir-rm-dynamic-data-for-master branch from 750db34 to 449dd9e Compare July 2, 2024 11:43
@@ -94,10 +95,16 @@ class HelmDeploymentStrategy extends AbstractDeploymentStrategy {

logger.info "Rolling out ${context.componentId} with HELM, selector: ${options.selector}"
helmUpgrade(context.targetProject)
HelmStatusSimpleData helmStatus = openShift.helmStatus(context.targetProject, options.helmReleaseName)
def helmStatusMap = helmStatus.toMap()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This map seems to be used only for logging purposes. I would enclose the instruction that performs the log in a condition on logger.getDebugOn() and generate the map inside, so that it isn't generated unless necessary.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you - will adjust the code!

context.targetProject, DEPLOYMENT_KINDS, options.selector
)
logger.info("${this.class.name} -- HELM STATUS")
logger.info(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Logging the contents of the helm status map is detailed debug info. Please change this to logger.debug and enclose it in a condition on logger.getDebugOn() so that no processing is done, if debug mode is inactive.

JsonOutput.prettyPrint(
JsonOutput.toJson(helmStatusMap)))

// not sure if we need both HELM STATUS and DEPLOYMENT RESOURCES"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please, don't leave this kind of comments. Could you make a decision and remove it?

JsonOutput.prettyPrint(
JsonOutput.toJson(helmStatusMap)))

// not sure if we need both HELM STATUS and DEPLOYMENT RESOURCES"
logger.info("${this.class.name} -- DEPLOYMENT RESOURCES")
logger.info(
JsonOutput.prettyPrint(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This also feels like debug level. Let's discuss this.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The logging of DEPLOYMENT RESOURCES comes from master. Should it be changed?

@@ -124,7 +132,7 @@ class HelmDeploymentStrategy extends AbstractDeploymentStrategy {
options.helmValues['componentId'] = context.componentId

// we persist the original ones set from outside - here we just add ours
Map mergedHelmValues = [:]
Map mergedHelmValues = [:] as Map<String, String>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use def here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the suggestion - I will make that change and also look out for similar cases.

/**
* Helm releases become top level elements, tailor deployments are left alone.
*/
@SuppressWarnings('CyclomaticComplexity')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not a good practice to suppress quality warnings. Let's talk and see how we could simplify this code.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The codeNarc report says its cyclomatic complexity of 21 where the threshold is 20. Now in https://codenarc.org/codenarc-rules-size.html the rules are stated. Adding another statement if (logger.debugMode) to not do json encoding when not logging will raise complexity by one.
Let's discuss whether there are good ideas to make this more clear.

def object = new JsonSlurperClassic().parseText(helmStdout)
def helmStatusData = HelmStatusData.fromJsonObject(object)
helmStatusData
} catch (Exception e) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In groovy you can just catch(e), but it's better to catch concrete exceptions, if possible.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Surrounding code in OpenShiftService has simply catch (ex) {. Not sure this is better, but at least it would be one style.

@@ -429,7 +458,12 @@ class OpenShiftService {
)
}

// Returns data about the pods (replicas) of the deployment.
boolean isDeploymentKind(String kind) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels like a private method

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It used when generating the TIR data in assembleDeployments called by org.ods.orchestration.usecase.LeVADocumentUseCase#createTIR
My rationale was that the createTIR method should not need to know what deployment kinds we support. Let's discuss more.

// version is an integer but we map it to a string.
String version

@SuppressWarnings(['IfStatementBraces'])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better to comply with the rules instead of suppressing warnings

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To my eyes the code looks cleaner in this particular case.

info.resources = resourcesMap
status.info = new HelmStatusInfoData(info)
new HelmStatusData(status)
} catch (Exception e) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above

@henrjk
Copy link
Member Author

henrjk commented Jul 29, 2024

This PR has been replaced by PR #1143.

@henrjk henrjk closed this Jul 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants