def METHOD_NAME(
    cls, obj: KubernetesObject, rkey: Optional[str] = None
) -> NormalizedResource:
    if obj.namespace is None:
        raise ValueError(
            f"Cannot construct resource from Kubernetes object {obj.key} without namespace"
        )
    labels = dict(obj.labels)
    if not rkey:  # rkey is only set for annotations
        # Default rkey for native Kubernetes resources
        rkey = f"{obj.name}.{obj.namespace}"
        # Some other code uses the 'ambassador_crd' label to know which resource to update
        # .status for with the apiserver.  Which is (IMO) a horrible hack, but I'm not up for
        # changing it at the moment.
        labels["ambassador_crd"] = rkey
    else:
        # Don't let it think that an annotation can have its status updated.
        labels.pop("ambassador_crd", None)
    # When creating an Ambassador object from a Kubernetes object, we have to make
    # sure that we pay attention to 'errors', which will be set IFF watt's validation
    # finds errors.
    return cls.from_data(
        obj.kind,
        obj.name,
        errors=obj.get("errors"),
        namespace=obj.namespace,
        generation=obj.generation,
        version=obj.gvk.version,
        api_group=obj.gvk.api_group,
        labels=labels,
        spec=obj.spec,
        rkey=rkey,
    )