### Description

Today, Amazon provider package supports SageMaker operators for a few operations, like training, tuning, pipelines, but it lacks the support for SageMaker Notebook instances. Boto3 provides necessary APIs to [create notebook instance](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sagemaker/client/create_notebook_instance.html), [start notebook instance](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sagemaker/client/start_notebook_instance.html), [stop network instance](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sagemaker/client/stop_notebook_instance.html) and [delete notebook instance](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sagemaker/client/delete_notebook_instance.html). Leveraging these APIs, we should add new operators to SageMaker set under Amazon provider. At the same time, having a sensor (synchronous as well as deferrable) for notebook instance execution that utilizes [describe notebook instance](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sagemaker/client/describe_notebook_instance.html) and waits for Stopped/Failed status would help with observability of the execution.

### Use case/motivation

Data Scientists are orchestrating ML use cases via Apache Airflow. A key component of ML use cases is running Jupyter Notebook on SageMaker. Having built-in operators and sensors would make it easy for Airflow users to run Notebook instances on SageMaker.

### Related issues

_No response_

### Are you willing to submit a PR?

- [ ] Yes I am willing to submit a PR!

### Code of Conduct

- [X] I agree to follow this project's [Code of Conduct](https://github.com/apache/airflow/blob/main/CODE_OF_CONDUCT.md)

"""Return OpenLineage data gathered from SageMaker's API response saved by transform job."""
        from airflow.providers.openlineage.extractors import OperatorLineage
        model_package_arn = None
        transform_input = None
        transform_output = None
        try:
            model_package_arn = self.serialized_model["PrimaryContainer"]["ModelPackageName"]
        except KeyError:
            self.log.error("Cannot find Model Package Name.", exc_info=True)
        try:
            transform_input = self.serialized_tranform["TransformInput"]["DataSource"]["S3DataSource"][
                "S3Uri"
            ]
            transform_output = self.serialized_tranform["TransformOutput"]["S3OutputPath"]
        except KeyError:
            self.log.error("Cannot find some required input/output details.", exc_info=True)
        inputs = []
        if transform_input is not None:
            inputs.append(self.path_to_s3_dataset(transform_input))
        if model_package_arn is not None:
            model_data_urls = self._get_model_data_urls(model_package_arn)
            for model_data_url in model_data_urls:
                inputs.append(self.path_to_s3_dataset(model_data_url))
        outputs = []
        if transform_output is not None:
            outputs.append(self.path_to_s3_dataset(transform_output))
        return OperatorLineage(inputs=inputs, outputs=outputs)
    def _get_model_data_urls(self, model_package_arn) -> list: