Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 97 additions & 7 deletions tools/ack-discover/controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@
import project_stages
import service

# A cache of Github Issues for new service controllers
_sc_issues = None
# The Github Project for tracking service controllers
_sc_proj = None
# The project cards associated with the Planned column in the service
# controller Github Project
_sc_proj_planned_cards = None


@dataclasses.dataclass
class Release:
Expand All @@ -39,36 +47,50 @@ class Controller:
source_repo_url: str = None
image_repo: str = None
chart_repo: str = None
gh_issue_url: str = None


def collect_all(writer, gh, ep_client, services):
"""Returns a map, keyed by service package name, of ControllerInfo objects
describing the ACK controllers.
"""
writer.debug("[collect_controllers] collecting ACK controller information ... ")
writer.debug("[controller.collect_all] collecting ACK controller information ... ")
ack_org = gh.get_organization("aws-controllers-k8s")
result= {}

for service_package_name, service in services.items():
writer.debug(f"[collect_controllers] finding controller info for {service_package_name} ...")
writer.debug(f"[controller.collect_all] finding controller info for {service_package_name} ...")

project_stage = project_stages.NONE
maintenance_phase = maintenance_phases.NONE
# We check if there has been a GH issue created for the AWS service and
# if that GH issue has been placed in the Service Controller Github
# Project's "Planned" ProjectColumn.
gh_issue = get_controller_request_issue(writer, gh, service)
gh_issue_url = None
if gh_issue is not None:
gh_issue_url = gh_issue.html_url
project_stage = project_stages.PROPOSED
if is_planned(writer, gh, gh_issue):
project_stage = project_stages.PLANNED

try:
repo = ack_org.get_repo(service_package_name+"-controller")
except github.UnknownObjectException:
controller = Controller(
service=service,
latest_release=None,
project_stage=project_stages.NONE,
maintenance_phase=maintenance_phases.NONE,
project_stage=project_stage,
maintenance_phase=maintenance_phase,
source_repo_url=None,
image_repo=None,
chart_repo=None,
gh_issue_url=gh_issue_url,
)
result[service_package_name] = controller
Copy link
Contributor

Choose a reason for hiding this comment

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

For the case of EC2, would the current logic skip creating a controller for EC2 VPC issue? Or does services.items() contain an entry for both EC2 and EC2 VPC ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

good question... in the case of EC2, we already have a controller so the service record's project phase is set to RELEASED. But for other services where we have multiple GH issues we will need to manually handle those I think.

Copy link
Contributor

Choose a reason for hiding this comment

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

But for other services where we have multiple GH issues we will need to manually handle those I think.

I don't quite understand why services have multiple GH issues labeled Service Controller if the intent is each of these map to a single repo (or a single service API in aws-sdk). Ex EC2:

[Brainstorm] This code could be a good opportunity to "enforce" GH issue structure in that it expects 1 repo per Service Controller GH issue. We can consolidate existing issues today and since "services" is a known list with infrequent updates we can create all GH issues ahead of time for each service aligning with the expected format.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@brycahta agreed, we could definitely take the opportunity to clean up our GH issues and standardize the service controller release roadmap project. For this particular PR, though, it's solving the initial problem at hand, which is to properly list PROPOSED and PLANNED project stages for specific services. This is important because I'm trying to replace the hand-edited services matrix with a table that is generated from the data produced by the ack-discover tool...

continue

latest_release = Release()
project_stage = project_stages.NONE
maintenance_phase = maintenance_phases.NONE

image_repo_url = f"{ecrpublic.BASE_ECR_URL}/{service_package_name}-controller"
image_repo_latest_version = None
Expand Down Expand Up @@ -105,6 +127,7 @@ def collect_all(writer, gh, ep_client, services):
source_repo_url=repo.url,
image_repo=image_repo,
chart_repo=chart_repo,
gh_issue_url=gh_issue_url,
)
result[service_package_name] = controller
return result
Expand All @@ -115,7 +138,7 @@ def get_runtime_and_aws_sdk_version(writer, repo, image_version):
controller's go.mod file at the specified image version (which is a Git tag
on the repo...).
"""
writer.debug("[get_runtime_and_aws_sdk_version] fetching go.mod for", repo.name, "at Git tag", image_version)
writer.debug("[controller.get_runtime_and_aws_sdk_version] fetching go.mod for", repo.name, "at Git tag", image_version)
runtime_version = None
aws_sdk_version = None
try:
Expand All @@ -133,3 +156,70 @@ def get_runtime_and_aws_sdk_version(writer, repo, image_version):
# proper Git tags for releases...
pass
return runtime_version, aws_sdk_version


def get_controller_request_issue(writer, gh, service):
"""Returns the Github Issue for the service, or None if no such issue
exists.
"""
global _sc_issues
ack_org = gh.get_organization("aws-controllers-k8s")
community_repo = ack_org.get_repo("community")
writer.debug(f"[controller.get_github_issue] finding Github Issue for {service.package_name} ...")
if _sc_issues is None:
sc_label = community_repo.get_label(name="Service Controller")
_sc_issues = community_repo.get_issues(labels=[sc_label])

for issue in _sc_issues:
# The GH issues with label "Service Controller" all have the same title
# pattern: "<Service Name> service controller"
Comment on lines +174 to +175
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 big assumption. Will someone be going through and updating each of the service controller requests to match this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Not sure what else we can do, unfortunately... we can't really lock down the Issue title template :)

issue_title = issue.title.lower().replace("service controller", "")
issue_title = issue_title.strip()
if issue_title == service.package_name.lower():
return issue
if service.full_name is not None:
full_name = service.full_name.lower()
if issue_title == full_name:
return issue
if service.abbrev_name is not None:
abbrev_name = service.abbrev_name.lower()
if issue_title == abbrev_name:
return issue
return None


def get_service_controller_project(writer, gh):
"""Returns the GH project for tracking service controllers.
"""
global _sc_proj
ack_org = gh.get_organization("aws-controllers-k8s")
community_repo = ack_org.get_repo("community")
writer.debug(f"[controller.get_service_controller_project] finding service controller Github Project ...")
if _sc_proj is None:
projs = community_repo.get_projects()
for p in projs:
if p.name == "Service Controller Release Roadmap":
_sc_proj = p
break
return _sc_proj


def is_planned(writer, gh, gh_issue):
"""Returns whether the supplied GH issue for a service controller appears
in the Planned board on our Service Controller Github Project.
"""
global _sc_proj_planned_cards
ack_org = gh.get_organization("aws-controllers-k8s")
community_repo = ack_org.get_repo("community")
writer.debug(f"[controller.is_planned] looking up project card matching Github Issue {gh_issue.id} ...")
if _sc_proj_planned_cards is None:
sc_proj = get_service_controller_project(writer, gh)
for pc in sc_proj.get_columns():
if pc.name == "Planned":
_sc_proj_planned_cards = pc.get_cards()
break
for pc in _sc_proj_planned_cards:
if pc.content_url == gh_issue.url:
return True

return False