Full Code of cortexlabs/cortex for AI

master dc48c02ed50a cached
702 files
5.2 MB
1.4M tokens
3806 symbols
1 requests
Download .txt
Showing preview only (5,594K chars total). Download the full file or copy to clipboard to get everything.
Repository: cortexlabs/cortex
Branch: master
Commit: dc48c02ed50a
Files: 702
Total size: 5.2 MB

Directory structure:
gitextract_xza_bns1/

├── .circleci/
│   └── config.yml
├── .dockerignore
├── .gitbook.yaml
├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug-report.md
│   │   ├── feature-request.md
│   │   └── question.md
│   └── pull_request_template.md
├── .gitignore
├── CONTRIBUTING.md
├── LICENSE
├── Makefile
├── README.md
├── build/
│   ├── amend-image.sh
│   ├── amend-images.sh
│   ├── build-image.sh
│   ├── build-images.sh
│   ├── cli.sh
│   ├── generate_ami_mapping.go
│   ├── images.sh
│   ├── lint-docs.sh
│   ├── lint.sh
│   ├── push-image.sh
│   ├── push-images.sh
│   └── test.sh
├── cli/
│   ├── cluster/
│   │   ├── delete.go
│   │   ├── deploy.go
│   │   ├── errors.go
│   │   ├── get.go
│   │   ├── info.go
│   │   ├── lib_http_client.go
│   │   ├── logs.go
│   │   └── refresh.go
│   ├── cmd/
│   │   ├── cluster.go
│   │   ├── completion.go
│   │   ├── const.go
│   │   ├── delete.go
│   │   ├── deploy.go
│   │   ├── describe.go
│   │   ├── env.go
│   │   ├── errors.go
│   │   ├── get.go
│   │   ├── lib_apis.go
│   │   ├── lib_async_apis.go
│   │   ├── lib_aws_creds.go
│   │   ├── lib_batch_apis.go
│   │   ├── lib_cli_config.go
│   │   ├── lib_client_id.go
│   │   ├── lib_cluster_config.go
│   │   ├── lib_manager.go
│   │   ├── lib_realtime_apis.go
│   │   ├── lib_task_apis.go
│   │   ├── lib_traffic_splitters.go
│   │   ├── lib_watch.go
│   │   ├── logs.go
│   │   ├── refresh.go
│   │   ├── root.go
│   │   └── version.go
│   ├── lib/
│   │   └── routines/
│   │       └── routines.go
│   ├── main.go
│   └── types/
│       ├── cliconfig/
│       │   ├── cli_config.go
│       │   ├── config_key.go
│       │   ├── environment.go
│       │   └── errors.go
│       └── flags/
│           ├── errors.go
│           └── output_type.go
├── cmd/
│   ├── activator/
│   │   └── main.go
│   ├── async-gateway/
│   │   └── main.go
│   ├── autoscaler/
│   │   └── main.go
│   ├── dequeuer/
│   │   └── main.go
│   ├── enqueuer/
│   │   └── main.go
│   ├── operator/
│   │   └── main.go
│   └── proxy/
│       └── main.go
├── dev/
│   ├── build_cli.sh
│   ├── create_user.py
│   ├── delete_ecr_repos.py
│   ├── export_images.sh
│   ├── find_missing_docs_links.py
│   ├── format.sh
│   ├── generate_cli_md.sh
│   ├── generate_python_client_md.sh
│   ├── get_operator_url.py
│   ├── load.go
│   ├── minimum_aws_policy.json
│   ├── operator_local.sh
│   ├── prometheus.md
│   ├── registry.sh
│   ├── update_cli_config.py
│   ├── util.sh
│   └── versions.md
├── docs/
│   ├── README.md
│   ├── clients/
│   │   ├── cli.md
│   │   ├── install.md
│   │   ├── python.md
│   │   └── uninstall.md
│   ├── clusters/
│   │   ├── advanced/
│   │   │   ├── kubectl.md
│   │   │   ├── registry.md
│   │   │   └── self-hosted-images.md
│   │   ├── instances/
│   │   │   ├── multi.md
│   │   │   └── spot.md
│   │   ├── management/
│   │   │   ├── auth.md
│   │   │   ├── create.md
│   │   │   ├── delete.md
│   │   │   ├── environments.md
│   │   │   ├── production.md
│   │   │   └── update.md
│   │   ├── networking/
│   │   │   ├── api-gateway.md
│   │   │   ├── custom-domain.md
│   │   │   ├── https.md
│   │   │   ├── load-balancers.md
│   │   │   └── vpc-peering.md
│   │   └── observability/
│   │       ├── alerting.md
│   │       ├── logging.md
│   │       └── metrics.md
│   ├── overview.md
│   ├── start.md
│   ├── summary.md
│   └── workloads/
│       ├── async/
│       │   ├── async.md
│       │   ├── autoscaling.md
│       │   ├── configuration.md
│       │   ├── containers.md
│       │   ├── example.md
│       │   └── statuses.md
│       ├── batch/
│       │   ├── batch.md
│       │   ├── configuration.md
│       │   ├── containers.md
│       │   ├── example.md
│       │   ├── jobs.md
│       │   └── statuses.md
│       ├── realtime/
│       │   ├── autoscaling.md
│       │   ├── configuration.md
│       │   ├── containers.md
│       │   ├── example.md
│       │   ├── metrics.md
│       │   ├── realtime.md
│       │   ├── statuses.md
│       │   ├── traffic-splitter.md
│       │   └── troubleshooting.md
│       └── task/
│           ├── configuration.md
│           ├── containers.md
│           ├── example.md
│           ├── jobs.md
│           ├── statuses.md
│           └── task.md
├── get-cli.sh
├── go.mod
├── go.sum
├── images/
│   ├── activator/
│   │   └── Dockerfile
│   ├── async-gateway/
│   │   └── Dockerfile
│   ├── autoscaler/
│   │   └── Dockerfile
│   ├── cluster-autoscaler/
│   │   └── Dockerfile
│   ├── controller-manager/
│   │   └── Dockerfile
│   ├── dequeuer/
│   │   └── Dockerfile
│   ├── enqueuer/
│   │   └── Dockerfile
│   ├── event-exporter/
│   │   └── Dockerfile
│   ├── fluent-bit/
│   │   └── Dockerfile
│   ├── grafana/
│   │   └── Dockerfile
│   ├── istio-pilot/
│   │   └── Dockerfile
│   ├── istio-proxy/
│   │   └── Dockerfile
│   ├── kube-rbac-proxy/
│   │   └── Dockerfile
│   ├── kubexit/
│   │   └── Dockerfile
│   ├── manager/
│   │   └── Dockerfile
│   ├── metrics-server/
│   │   └── Dockerfile
│   ├── neuron-device-plugin/
│   │   └── Dockerfile
│   ├── neuron-scheduler/
│   │   └── Dockerfile
│   ├── nvidia-device-plugin/
│   │   └── Dockerfile
│   ├── operator/
│   │   └── Dockerfile
│   ├── prometheus/
│   │   └── Dockerfile
│   ├── prometheus-config-reloader/
│   │   └── Dockerfile
│   ├── prometheus-dcgm-exporter/
│   │   └── Dockerfile
│   ├── prometheus-kube-state-metrics/
│   │   └── Dockerfile
│   ├── prometheus-node-exporter/
│   │   └── Dockerfile
│   ├── prometheus-operator/
│   │   └── Dockerfile
│   ├── prometheus-statsd-exporter/
│   │   └── Dockerfile
│   └── proxy/
│       └── Dockerfile
├── manager/
│   ├── check_cortex_version.sh
│   ├── cluster_config_env.py
│   ├── debug.sh
│   ├── generate_eks.py
│   ├── get_api_load_balancer_state.py
│   ├── get_operator_load_balancer_state.py
│   ├── get_operator_target_group_status.py
│   ├── helpers.py
│   ├── install.sh
│   ├── manifests/
│   │   ├── activator.yaml.j2
│   │   ├── ami.json
│   │   ├── apis.yaml.j2
│   │   ├── async-gateway.yaml.j2
│   │   ├── autoscaler.yaml.j2
│   │   ├── cluster-autoscaler.yaml.j2
│   │   ├── default_cortex_cli_config.yaml
│   │   ├── event-exporter.yaml
│   │   ├── fluent-bit.yaml.j2
│   │   ├── grafana/
│   │   │   ├── grafana-dashboard-async.yaml
│   │   │   ├── grafana-dashboard-batch.yaml
│   │   │   ├── grafana-dashboard-cluster.yaml
│   │   │   ├── grafana-dashboard-control-plane.yaml
│   │   │   ├── grafana-dashboard-nodes.yaml
│   │   │   ├── grafana-dashboard-realtime.yaml
│   │   │   ├── grafana-dashboard-task.yaml
│   │   │   └── grafana.yaml.j2
│   │   ├── inferentia.yaml
│   │   ├── istio.yaml.j2
│   │   ├── kube-proxy.patch.yaml
│   │   ├── metrics-server.yaml
│   │   ├── namespaces.yaml
│   │   ├── nvidia.yaml
│   │   ├── operator.yaml.j2
│   │   ├── prometheus-additional-scrape-configs.yaml.j2
│   │   ├── prometheus-dcgm-exporter.yaml
│   │   ├── prometheus-kube-state-metrics.yaml
│   │   ├── prometheus-kubelet-exporter.yaml
│   │   ├── prometheus-monitoring.yaml
│   │   ├── prometheus-node-exporter.yaml
│   │   ├── prometheus-operator.yaml
│   │   └── prometheus-statsd-exporter.yaml
│   ├── refresh.sh
│   ├── render_template.py
│   ├── requirements.txt
│   ├── uninstall.sh
│   └── upgrade_kube_proxy_mode.py
├── pkg/
│   ├── activator/
│   │   ├── activator.go
│   │   ├── activator_test.go
│   │   ├── api_activator.go
│   │   ├── api_activator_test.go
│   │   ├── handler.go
│   │   ├── handler_test.go
│   │   ├── helpers.go
│   │   └── request_stats.go
│   ├── async-gateway/
│   │   ├── endpoint.go
│   │   ├── queue.go
│   │   ├── service.go
│   │   ├── storage.go
│   │   └── types.go
│   ├── autoscaler/
│   │   ├── async_scaler.go
│   │   ├── autoscaler.go
│   │   ├── autoscaler_test.go
│   │   ├── client.go
│   │   ├── handler.go
│   │   ├── realtime_scaler.go
│   │   ├── recommendations.go
│   │   └── scaler_func.go
│   ├── config/
│   │   └── config.go
│   ├── consts/
│   │   └── consts.go
│   ├── crds/
│   │   ├── Makefile
│   │   ├── PROJECT
│   │   ├── apis/
│   │   │   └── batch/
│   │   │       └── v1alpha1/
│   │   │           ├── batchjob_metrics.go
│   │   │           ├── batchjob_types.go
│   │   │           ├── groupversion_info.go
│   │   │           └── zz_generated.deepcopy.go
│   │   ├── config/
│   │   │   ├── crd/
│   │   │   │   ├── bases/
│   │   │   │   │   └── batch.cortex.dev_batchjobs.yaml
│   │   │   │   ├── kustomization.yaml
│   │   │   │   ├── kustomizeconfig.yaml
│   │   │   │   └── patches/
│   │   │   │       ├── cainjection_in_batchjobs.yaml
│   │   │   │       └── webhook_in_batchjobs.yaml
│   │   │   ├── default/
│   │   │   │   ├── kustomization.yaml
│   │   │   │   ├── manager_auth_proxy_patch.yaml
│   │   │   │   └── manager_config_patch.yaml
│   │   │   ├── manager/
│   │   │   │   ├── controller_manager_config.yaml
│   │   │   │   ├── kustomization.yaml
│   │   │   │   └── manager.yaml
│   │   │   ├── prometheus/
│   │   │   │   ├── kustomization.yaml
│   │   │   │   └── monitor.yaml
│   │   │   ├── rbac/
│   │   │   │   ├── auth_proxy_client_clusterrole.yaml
│   │   │   │   ├── auth_proxy_role.yaml
│   │   │   │   ├── auth_proxy_role_binding.yaml
│   │   │   │   ├── auth_proxy_service.yaml
│   │   │   │   ├── batchjob_editor_role.yaml
│   │   │   │   ├── batchjob_viewer_role.yaml
│   │   │   │   ├── kustomization.yaml
│   │   │   │   ├── leader_election_role.yaml
│   │   │   │   ├── leader_election_role_binding.yaml
│   │   │   │   ├── role.yaml
│   │   │   │   ├── role_binding.yaml
│   │   │   │   └── service_account.yaml
│   │   │   └── samples/
│   │   │       └── batch_v1alpha1_batchjob.yaml
│   │   ├── controllers/
│   │   │   ├── batch/
│   │   │   │   ├── batchjob_controller.go
│   │   │   │   ├── batchjob_controller_config.go
│   │   │   │   ├── batchjob_controller_helpers.go
│   │   │   │   ├── batchjob_controller_test.go
│   │   │   │   └── suite_test.go
│   │   │   └── errors.go
│   │   ├── hack/
│   │   │   ├── boilerplate.go.txt
│   │   │   └── run_manager.sh
│   │   └── main.go
│   ├── dequeuer/
│   │   ├── async_handler.go
│   │   ├── async_handler_test.go
│   │   ├── async_stats.go
│   │   ├── async_stats_test.go
│   │   ├── batch_handler.go
│   │   ├── batch_handler_test.go
│   │   ├── dequeuer.go
│   │   ├── dequeuer_test.go
│   │   ├── errors.go
│   │   ├── http_handler.go
│   │   ├── message_handler.go
│   │   ├── probes.go
│   │   ├── probes_test.go
│   │   ├── queue_attributes.go
│   │   └── request_stats.go
│   ├── enqueuer/
│   │   ├── enqueuer.go
│   │   ├── errors.go
│   │   ├── helpers.go
│   │   └── uploader.go
│   ├── health/
│   │   └── health.go
│   ├── lib/
│   │   ├── archive/
│   │   │   ├── archive_test.go
│   │   │   ├── archiver.go
│   │   │   ├── errors.go
│   │   │   ├── input.go
│   │   │   ├── tar.go
│   │   │   ├── tgz.go
│   │   │   └── zip.go
│   │   ├── aws/
│   │   │   ├── acm.go
│   │   │   ├── apigateway.go
│   │   │   ├── autoscaling.go
│   │   │   ├── aws.go
│   │   │   ├── clients.go
│   │   │   ├── cloudformation.go
│   │   │   ├── cloudwatch.go
│   │   │   ├── credentials.go
│   │   │   ├── ec2.go
│   │   │   ├── ec2_test.go
│   │   │   ├── ecr.go
│   │   │   ├── eks.go
│   │   │   ├── elb.go
│   │   │   ├── elbv2.go
│   │   │   ├── errors.go
│   │   │   ├── gen_resource_metadata.py
│   │   │   ├── iam.go
│   │   │   ├── resource_metadata.go
│   │   │   ├── s3.go
│   │   │   ├── servicequotas.go
│   │   │   ├── sqs.go
│   │   │   └── sts.go
│   │   ├── cast/
│   │   │   ├── interface.go
│   │   │   └── interface_test.go
│   │   ├── configreader/
│   │   │   ├── bool.go
│   │   │   ├── bool_list.go
│   │   │   ├── bool_ptr.go
│   │   │   ├── errors.go
│   │   │   ├── float32.go
│   │   │   ├── float32_list.go
│   │   │   ├── float32_ptr.go
│   │   │   ├── float64.go
│   │   │   ├── float64_list.go
│   │   │   ├── float64_ptr.go
│   │   │   ├── int.go
│   │   │   ├── int32.go
│   │   │   ├── int32_list.go
│   │   │   ├── int32_ptr.go
│   │   │   ├── int64.go
│   │   │   ├── int64_list.go
│   │   │   ├── int64_ptr.go
│   │   │   ├── int_list.go
│   │   │   ├── int_ptr.go
│   │   │   ├── interface.go
│   │   │   ├── interface_map.go
│   │   │   ├── interface_map_list.go
│   │   │   ├── interface_test.go
│   │   │   ├── reader.go
│   │   │   ├── reader_test.go
│   │   │   ├── string.go
│   │   │   ├── string_list.go
│   │   │   ├── string_map.go
│   │   │   ├── string_ptr.go
│   │   │   ├── types.go
│   │   │   └── validators.go
│   │   ├── console/
│   │   │   └── format.go
│   │   ├── cron/
│   │   │   └── cron.go
│   │   ├── debug/
│   │   │   └── debug.go
│   │   ├── docker/
│   │   │   ├── docker.go
│   │   │   └── errors.go
│   │   ├── errors/
│   │   │   ├── error.go
│   │   │   ├── errors.go
│   │   │   ├── message.go
│   │   │   ├── multi.go
│   │   │   └── stack.go
│   │   ├── exit/
│   │   │   └── exit.go
│   │   ├── files/
│   │   │   ├── errors.go
│   │   │   ├── files.go
│   │   │   └── files_test.go
│   │   ├── hash/
│   │   │   └── hash.go
│   │   ├── json/
│   │   │   ├── errors.go
│   │   │   └── json.go
│   │   ├── k8s/
│   │   │   ├── configmap.go
│   │   │   ├── deployment.go
│   │   │   ├── errors.go
│   │   │   ├── hpa.go
│   │   │   ├── ingress.go
│   │   │   ├── job.go
│   │   │   ├── k8s.go
│   │   │   ├── node.go
│   │   │   ├── parsers.go
│   │   │   ├── pod.go
│   │   │   ├── quantity.go
│   │   │   ├── secret.go
│   │   │   ├── service.go
│   │   │   ├── virtual_service.go
│   │   │   └── volume.go
│   │   ├── logging/
│   │   │   ├── errors.go
│   │   │   └── logging.go
│   │   ├── maps/
│   │   │   ├── interface.go
│   │   │   └── string.go
│   │   ├── math/
│   │   │   ├── float32.go
│   │   │   ├── float64.go
│   │   │   ├── int.go
│   │   │   ├── int32.go
│   │   │   └── int64.go
│   │   ├── msgpack/
│   │   │   ├── errors.go
│   │   │   └── msgpack.go
│   │   ├── parallel/
│   │   │   ├── parallel.go
│   │   │   └── parallel_test.go
│   │   ├── pointer/
│   │   │   ├── equal.go
│   │   │   ├── pointer.go
│   │   │   └── pointer_test.go
│   │   ├── print/
│   │   │   └── print.go
│   │   ├── prompt/
│   │   │   ├── errors.go
│   │   │   └── prompt.go
│   │   ├── random/
│   │   │   └── random.go
│   │   ├── regex/
│   │   │   ├── regex.go
│   │   │   └── regex_test.go
│   │   ├── requests/
│   │   │   ├── errors.go
│   │   │   └── requests.go
│   │   ├── sets/
│   │   │   └── strset/
│   │   │       ├── strset.go
│   │   │       ├── strset_test.go
│   │   │       └── threadsafe/
│   │   │           ├── strset.go
│   │   │           └── strset_test.go
│   │   ├── slices/
│   │   │   ├── bool.go
│   │   │   ├── errors.go
│   │   │   ├── float32.go
│   │   │   ├── float64.go
│   │   │   ├── float64_ptr.go
│   │   │   ├── float64_ptr_test.go
│   │   │   ├── int.go
│   │   │   ├── int32.go
│   │   │   ├── int64.go
│   │   │   ├── sort.go
│   │   │   ├── string.go
│   │   │   └── string_test.go
│   │   ├── strings/
│   │   │   ├── operations.go
│   │   │   ├── operations_test.go
│   │   │   ├── parse.go
│   │   │   ├── stringify.go
│   │   │   └── stringify_test.go
│   │   ├── structs/
│   │   │   ├── deepcopy.go
│   │   │   └── deepcopy_test.go
│   │   ├── table/
│   │   │   ├── errors.go
│   │   │   ├── key_value.go
│   │   │   └── table.go
│   │   ├── telemetry/
│   │   │   ├── error_cache.go
│   │   │   ├── errors.go
│   │   │   └── telemetry.go
│   │   ├── time/
│   │   │   └── time.go
│   │   └── urls/
│   │       ├── errors.go
│   │       └── urls.go
│   ├── operator/
│   │   ├── endpoints/
│   │   │   ├── delete.go
│   │   │   ├── deploy.go
│   │   │   ├── describe.go
│   │   │   ├── errors.go
│   │   │   ├── get.go
│   │   │   ├── get_batch_job.go
│   │   │   ├── get_task_job.go
│   │   │   ├── info.go
│   │   │   ├── logs.go
│   │   │   ├── logs_job.go
│   │   │   ├── middleware.go
│   │   │   ├── params.go
│   │   │   ├── refresh.go
│   │   │   ├── respond.go
│   │   │   ├── stop_batch_job.go
│   │   │   ├── stop_task_job.go
│   │   │   ├── submit_batch.go
│   │   │   ├── submit_task.go
│   │   │   └── verify_cortex.go
│   │   ├── lib/
│   │   │   ├── exit/
│   │   │   │   └── exit.go
│   │   │   └── routines/
│   │   │       └── routines.go
│   │   ├── operator/
│   │   │   ├── cron.go
│   │   │   ├── deployed_resource.go
│   │   │   ├── errors.go
│   │   │   ├── k8s.go
│   │   │   ├── logging.go
│   │   │   ├── memory_capacity.go
│   │   │   ├── storage.go
│   │   │   └── workload_logging.go
│   │   ├── resources/
│   │   │   ├── asyncapi/
│   │   │   │   ├── api.go
│   │   │   │   ├── errors.go
│   │   │   │   ├── k8s_specs.go
│   │   │   │   ├── queue.go
│   │   │   │   ├── queue_metrics.go
│   │   │   │   └── status.go
│   │   │   ├── errors.go
│   │   │   ├── job/
│   │   │   │   ├── batchapi/
│   │   │   │   │   ├── api.go
│   │   │   │   │   ├── errors.go
│   │   │   │   │   ├── job.go
│   │   │   │   │   ├── job_status.go
│   │   │   │   │   ├── k8s_specs.go
│   │   │   │   │   ├── queue.go
│   │   │   │   │   ├── s3_iterator.go
│   │   │   │   │   └── validations.go
│   │   │   │   ├── cache.go
│   │   │   │   ├── consts.go
│   │   │   │   ├── errors.go
│   │   │   │   ├── state.go
│   │   │   │   ├── taskapi/
│   │   │   │   │   ├── api.go
│   │   │   │   │   ├── cron.go
│   │   │   │   │   ├── job.go
│   │   │   │   │   ├── job_status.go
│   │   │   │   │   ├── k8s_specs.go
│   │   │   │   │   ├── metrics.go
│   │   │   │   │   └── validations.go
│   │   │   │   └── worker_stats.go
│   │   │   ├── realtimeapi/
│   │   │   │   ├── api.go
│   │   │   │   ├── errors.go
│   │   │   │   ├── k8s_specs.go
│   │   │   │   └── status.go
│   │   │   ├── resources.go
│   │   │   ├── trafficsplitter/
│   │   │   │   ├── api.go
│   │   │   │   └── k8s_specs.go
│   │   │   └── validations.go
│   │   └── schema/
│   │       ├── config_key.go
│   │       ├── job_submission.go
│   │       └── schema.go
│   ├── probe/
│   │   ├── handler.go
│   │   ├── handler_test.go
│   │   ├── probe.go
│   │   └── probe_test.go
│   ├── proxy/
│   │   ├── breaker.go
│   │   ├── breaker_test.go
│   │   ├── handler.go
│   │   ├── handler_test.go
│   │   ├── proxy.go
│   │   ├── proxy_test.go
│   │   └── request_stats.go
│   ├── types/
│   │   ├── async/
│   │   │   ├── s3_paths.go
│   │   │   └── status.go
│   │   ├── clusterconfig/
│   │   │   ├── availability_zones.go
│   │   │   ├── aws_policy.go
│   │   │   ├── cluster_config.go
│   │   │   ├── config_key.go
│   │   │   ├── errors.go
│   │   │   ├── load_balancer_scheme.go
│   │   │   ├── load_balancer_type.go
│   │   │   ├── nat_gateway_type.go
│   │   │   ├── network_validations.go
│   │   │   ├── subnet_visibility.go
│   │   │   └── volume_types.go
│   │   ├── clusterstate/
│   │   │   ├── clusterstate.go
│   │   │   ├── errors.go
│   │   │   └── state.go
│   │   ├── metrics/
│   │   │   ├── batch_metrics.go
│   │   │   ├── metrics_test.go
│   │   │   └── queue_metrics.go
│   │   ├── spec/
│   │   │   ├── api.go
│   │   │   ├── errors.go
│   │   │   ├── id_gen.go
│   │   │   ├── job.go
│   │   │   ├── utils.go
│   │   │   └── validations.go
│   │   ├── status/
│   │   │   ├── job_code.go
│   │   │   ├── job_status.go
│   │   │   └── status.go
│   │   └── userconfig/
│   │       ├── api.go
│   │       ├── config_key.go
│   │       ├── kind.go
│   │       ├── log_level.go
│   │       └── resource.go
│   └── workloads/
│       ├── configmap.go
│       ├── helpers.go
│       ├── init.go
│       └── k8s.go
├── python/
│   └── client/
│       ├── README.md
│       ├── cortex/
│       │   ├── __init__.py
│       │   ├── binary/
│       │   │   └── __init__.py
│       │   ├── client.py
│       │   ├── consts.py
│       │   ├── exceptions.py
│       │   ├── telemetry.py
│       │   └── util.py
│       └── setup.py
└── test/
    ├── README.md
    ├── apis/
    │   ├── async/
    │   │   ├── hello-world/
    │   │   │   ├── app/
    │   │   │   │   ├── main.py
    │   │   │   │   └── requirements.txt
    │   │   │   ├── build-cpu.sh
    │   │   │   ├── cortex_cpu.yaml
    │   │   │   └── cpu.Dockerfile
    │   │   └── text-generator/
    │   │       ├── app/
    │   │       │   ├── main.py
    │   │       │   ├── requirements-cpu.txt
    │   │       │   └── requirements-gpu.txt
    │   │       ├── build-cpu.sh
    │   │       ├── build-gpu.sh
    │   │       ├── cortex_cpu.yaml
    │   │       ├── cortex_gpu.yaml
    │   │       ├── cpu.Dockerfile
    │   │       ├── expectations.yaml
    │   │       ├── gpu.Dockerfile
    │   │       └── sample.json
    │   ├── batch/
    │   │   ├── image-classifier-alexnet/
    │   │   │   ├── app/
    │   │   │   │   ├── main.py
    │   │   │   │   ├── requirements-cpu.txt
    │   │   │   │   └── requirements-gpu.txt
    │   │   │   ├── build-cpu.sh
    │   │   │   ├── build-gpu.sh
    │   │   │   ├── cortex_cpu.yaml
    │   │   │   ├── cortex_gpu.yaml
    │   │   │   ├── cpu.Dockerfile
    │   │   │   ├── gpu.Dockerfile
    │   │   │   ├── sample.json
    │   │   │   └── submit.py
    │   │   └── sum/
    │   │       ├── app/
    │   │       │   ├── main.py
    │   │       │   └── requirements.txt
    │   │       ├── build-cpu.sh
    │   │       ├── cortex_cpu.yaml
    │   │       ├── cpu.Dockerfile
    │   │       ├── sample.json
    │   │       ├── sample_generator.py
    │   │       └── submit.py
    │   ├── realtime/
    │   │   ├── hello-world/
    │   │   │   ├── app/
    │   │   │   │   ├── main.py
    │   │   │   │   └── requirements.txt
    │   │   │   ├── build-cpu.sh
    │   │   │   ├── cortex_cpu.yaml
    │   │   │   ├── cortex_cpu_arm64.yaml
    │   │   │   ├── cortex_scale_to_zero.yaml
    │   │   │   ├── cpu.Dockerfile
    │   │   │   └── sample.json
    │   │   ├── image-classifier-resnet50/
    │   │   │   ├── README.md
    │   │   │   ├── build-cpu.sh
    │   │   │   ├── build-gpu.sh
    │   │   │   ├── build-neuron-rtd.sh
    │   │   │   ├── build-neuron-tf-serving.sh
    │   │   │   ├── client.py
    │   │   │   ├── client_inf.py
    │   │   │   ├── cortex_cpu.yaml
    │   │   │   ├── cortex_gpu.yaml
    │   │   │   ├── cortex_inf.yaml
    │   │   │   ├── cortex_inf_rtd.yaml
    │   │   │   ├── cpu.Dockerfile
    │   │   │   ├── gpu.Dockerfile
    │   │   │   ├── neuron-rtd.Dockerfile
    │   │   │   ├── neuron-tf-serving.Dockerfile
    │   │   │   └── sample.json
    │   │   ├── multi-container/
    │   │   │   ├── app/
    │   │   │   │   ├── main.py
    │   │   │   │   └── requirements.txt
    │   │   │   ├── build-tfs-cpu.sh
    │   │   │   ├── build-web-cpu.sh
    │   │   │   ├── cortex_cpu.yaml
    │   │   │   ├── sample.json
    │   │   │   ├── tfs-cpu.Dockerfile
    │   │   │   └── web-cpu.Dockerfile
    │   │   ├── prime-generator/
    │   │   │   ├── app/
    │   │   │   │   ├── main.py
    │   │   │   │   └── requirements.txt
    │   │   │   ├── build-cpu.sh
    │   │   │   ├── cortex_cpu.yaml
    │   │   │   ├── cpu.Dockerfile
    │   │   │   └── sample.json
    │   │   ├── sleep/
    │   │   │   ├── app/
    │   │   │   │   ├── main.py
    │   │   │   │   └── requirements.txt
    │   │   │   ├── build-cpu.sh
    │   │   │   ├── cortex_cpu.yaml
    │   │   │   └── cpu.Dockerfile
    │   │   └── text-generator/
    │   │       ├── app/
    │   │       │   ├── main.py
    │   │       │   ├── requirements-cpu.txt
    │   │       │   └── requirements-gpu.txt
    │   │       ├── build-cpu.sh
    │   │       ├── build-gpu.sh
    │   │       ├── cortex_cpu.yaml
    │   │       ├── cortex_gpu.yaml
    │   │       ├── cpu.Dockerfile
    │   │       ├── gpu.Dockerfile
    │   │       └── sample.json
    │   ├── task/
    │   │   └── iris-classifier-trainer/
    │   │       ├── app/
    │   │       │   ├── main.py
    │   │       │   └── requirements.txt
    │   │       ├── build-cpu.sh
    │   │       ├── cortex_cpu.yaml
    │   │       ├── cpu.Dockerfile
    │   │       └── submit.py
    │   └── trafficsplitter/
    │       └── hello-world/
    │           ├── .dockerignore
    │           ├── cortex_cpu.yaml
    │           └── sample.json
    ├── e2e/
    │   ├── README.md
    │   ├── e2e/
    │   │   ├── __init__.py
    │   │   ├── cluster.py
    │   │   ├── exceptions.py
    │   │   ├── expectations.py
    │   │   ├── generator.py
    │   │   ├── tests.py
    │   │   └── utils.py
    │   ├── pytest.ini
    │   ├── setup.py
    │   └── tests/
    │       ├── __init__.py
    │       ├── aws/
    │       │   ├── __init__.py
    │       │   ├── conftest.py
    │       │   ├── test_async.py
    │       │   ├── test_autoscaling.py
    │       │   ├── test_batch.py
    │       │   ├── test_load.py
    │       │   ├── test_long_running.py
    │       │   ├── test_realtime.py
    │       │   ├── test_scale_to_zero.py
    │       │   └── test_task.py
    │       └── conftest.py
    └── utils/
        ├── README.md
        ├── build-all.sh
        ├── build.sh
        └── throughput_test.py

================================================
FILE CONTENTS
================================================

================================================
FILE: .circleci/config.yml
================================================
version: 2.1

orbs:
  slack: circleci/slack@4.2.0

commands:
  install-go:
    steps:
      - run:
          name: Install Go
          command: |
            sudo rm -rf /usr/local/go
            wget https://dl.google.com/go/go1.17.3.linux-amd64.tar.gz
            sudo tar -C /usr/local -xzf go1.17.3.linux-amd64.tar.gz
            rm -rf go*.tar.gz
            echo 'export PATH=$PATH:/usr/local/go/bin' >> $BASH_ENV
            echo 'export PATH=$PATH:~/go/bin' >> $BASH_ENV
            mkdir ~/go
            echo 'export GOPATH=~/go' >> $BASH_ENV

  quay-login:
    description: Log Docker agent into Quay.io
    steps:
      - run:
          name: Login to Quay
          command: docker login -u=$QUAY_USERNAME -p=$QUAY_PASSWORD quay.io

jobs:
  lint:
    docker:
      - image: cimg/python:3.7
    resource_class: medium
    steps:
      - checkout
      - install-go
      - restore_cache:
          keys:
            - go-mod-v1-{{ checksum "go.sum" }}
            - go-mod-v1-
      - run:
          name: Install Linting Tools
          command: |
            go get -u -v golang.org/x/lint/golint
            go get -u -v github.com/kyoh86/looppointer/cmd/looppointer
            pip3 install aiohttp black==20.8b1 click==8.0.4
      - run:
          name: Lint
          command: make lint
          no_output_timeout: 20m
      - save_cache:
          key: go-mod-v1-{{ checksum "go.sum" }}
          paths:
            - "~/go/pkg/mod"

  test:
    machine:
      image: ubuntu-2004:202201-02 # machine executor necessary to run go integration tests
    resource_class: medium
    steps:
      - checkout
      - install-go
      - restore_cache:
          keys:
            - go-mod-v1-{{ checksum "go.sum" }}
            - go-mod-v1-
      - run:
          name: Initialize Credentials
          command: |
            echo 'export AWS_ACCESS_KEY_ID=${TEST_AWS_ACCESS_KEY_ID}' >> $BASH_ENV
            echo 'export AWS_SECRET_ACCESS_KEY=${TEST_AWS_SECRET_ACCESS_KEY}' >> $BASH_ENV
      - run:
          name: Generate Cluster Config
          command: |
            mkdir -p dev/config
            cat \<< EOF > ./dev/config/cluster.yaml
            cluster_name: cortex-nightly
            region: us-east-1
            node_groups:
              - name: cpu
                instance_type: m5.large
                min_instances: 1
                max_instances: 1
            EOF
      - run:
          name: Go Tests
          command: make test
      - save_cache:
          key: go-mod-v1-{{ checksum "go.sum" }}
          paths:
            - "~/go/pkg/mod"

  build-and-upload-cli:
    docker:
      - image: cimg/python:3.7
    resource_class: medium
    steps:
      - checkout
      - install-go
      - run: pip install awscli
      - run: make ci-build-cli
      - run: make ci-build-and-upload-cli

  build-and-push-images-amd64:
    machine:
      image: ubuntu-2004:202101-01
    resource_class: medium
    steps:
      - checkout
      - run:
          name: Build CI Images (amd64)
          command: make ci-build-images-amd64
          no_output_timeout: 20m
      - quay-login
      - run:
          name: Push CI Images (amd64)
          command: make ci-push-images-amd64
          no_output_timeout: 20m

  build-and-push-images-arm64:
    machine:
      image: ubuntu-2004:202201-02
    resource_class: arm.medium
    steps:
      - checkout
      - run:
          name: Build CI Images (arm64)
          command: make ci-build-images-arm64
          no_output_timeout: 20m
      - quay-login
      - run:
          name: Push CI Images (arm64)
          command: make ci-push-images-arm64
          no_output_timeout: 20m

  amend-images:
    docker:
      - image: cimg/python:3.7
    environment:
      DOCKER_CLI_EXPERIMENTAL: enabled
    resource_class: medium
    steps:
      - setup_remote_docker
      - checkout
      - quay-login
      - run:
          name: Amend CI Images
          command: make ci-amend-images
          no_output_timeout: 20m

  cluster-up:
    docker:
      - image: cimg/python:3.7
    steps:
      - setup_remote_docker
      - checkout
      - run:
          name: Install Dependencies
          command: |
            pip install boto3 pyyaml awscli
            pip install https://s3-us-west-2.amazonaws.com/get-cortex/master/python/cortex-master.tar.gz
      - run:
          name: Initialize Credentials
          command: |
            echo 'export AWS_ACCESS_KEY_ID=${NIGHTLY_AWS_ACCESS_KEY_ID}' >> $BASH_ENV
            echo 'export AWS_SECRET_ACCESS_KEY=${NIGHTLY_AWS_SECRET_ACCESS_KEY}' >> $BASH_ENV
      - run:
          name: Generate Cluster Config
          # using a variety of node groups to test the multi-instance-type cluster functionality
          command: |
            cat \<< EOF > ./cluster.yaml
            cluster_name: cortex-nightly
            region: us-east-1
            node_groups:
              - name: spot
                instance_type: t3.medium
                min_instances: 16
                max_instances: 16
                spot: true
              - name: cpu
                instance_type: c5.xlarge
                min_instances: 1
                max_instances: 2
              - name: gpu
                instance_type: g4dn.xlarge
                min_instances: 1
                max_instances: 2
              - name: inferentia
                instance_type: inf1.xlarge
                min_instances: 1
                max_instances: 2
              - name: arm
                instance_type: a1.large
                min_instances: 1
                max_instances: 2
            EOF
      - run:
          name: Create/Update AWS User policy
          command: python ./dev/create_user.py cortex-nightly $NIGHTLY_AWS_ACCOUNT_ID us-east-1 > $BASH_ENV
      - run:
          name: Wait for new keys to propagate in AWS
          command: sleep 10
      - run:
          name: Verify configuration of credentials
          command: aws sts get-caller-identity | jq ".Arn" | grep "dev-cortex-nightly-us-east-1"
      - run:
          name: Create Cluster
          command: cortex cluster up cluster.yaml --configure-env cortex -y
      - slack/notify:
          event: fail
          channel: "#builds"
          template: basic_fail_1

  e2e-tests:
    docker:
      - image: cimg/python:3.7
    steps:
      - checkout
      - run:
          name: Install Dependencies
          command: |
            pip install boto3 pyyaml awscli
            pip install -e ./test/e2e
            pip install https://s3-us-west-2.amazonaws.com/get-cortex/master/python/cortex-master.tar.gz
      - run:
          name: Initialize Credentials
          command: |
            echo 'export AWS_ACCESS_KEY_ID=${NIGHTLY_AWS_ACCESS_KEY_ID}' >> $BASH_ENV
            echo 'export AWS_SECRET_ACCESS_KEY=${NIGHTLY_AWS_SECRET_ACCESS_KEY}' >> $BASH_ENV
      - run:
          name: Configure Cortex CLI
          command: cortex env configure cortex --operator-endpoint $(python dev/get_operator_url.py cortex-nightly us-east-1)
      - run:
          name: Run E2E Tests
          no_output_timeout: 30m
          command: |
            pytest -v test/e2e/tests --env cortex --x86-nodegroups spot,cpu,gpu,inferentia --arm-nodegroups arm --skip-autoscaling --skip-load --skip-long-running
            pytest -v test/e2e/tests --env cortex --x86-nodegroups spot,cpu,gpu,inferentia -k test_autoscaling
            pytest -v test/e2e/tests --env cortex --x86-nodegroups spot,cpu,gpu,inferentia -k test_load
      - slack/notify:
          event: fail
          channel: "#builds"
          template: basic_fail_1

  cluster-down:
    docker:
      - image: cimg/python:3.7
    steps:
      - setup_remote_docker
      - checkout
      - run:
          name: Install Dependencies
          command: |
            pip install boto3 pyyaml awscli
            pip install https://s3-us-west-2.amazonaws.com/get-cortex/master/python/cortex-master.tar.gz
      - run:
          name: Initialize Credentials
          command: |
            echo 'export AWS_ACCESS_KEY_ID=${NIGHTLY_AWS_ACCESS_KEY_ID}' >> $BASH_ENV
            echo 'export AWS_SECRET_ACCESS_KEY=${NIGHTLY_AWS_SECRET_ACCESS_KEY}' >> $BASH_ENV
      - run:
          name: Create/Update AWS User policy
          command: python ./dev/create_user.py cortex-nightly $NIGHTLY_AWS_ACCOUNT_ID us-east-1 > $BASH_ENV
      - run:
          name: Wait for new keys to propagate in AWS
          command: sleep 10
      - run:
          name: Verify configuration of credentials
          command: aws sts get-caller-identity | jq ".Arn" | grep "dev-cortex-nightly-us-east-1"
      - run:
          name: Delete Cluster
          command: cortex cluster down --name cortex-nightly --region us-east-1 -y
          when: always
      - slack/notify:
          event: fail
          channel: "#builds"
          template: basic_fail_1

workflows:
  build:
    jobs:
      - lint
      - test
      - build-and-deploy-approval:
          type: approval
          filters:
            branches:
              only:
                - /^[0-9]+\.[0-9]+$/
      - build-and-upload-cli:
          requires:
            - lint
            - test
            - build-and-deploy-approval
          filters:
            branches:
              only:
                - master
                - /^[0-9]+\.[0-9]+$/
      - build-and-push-images-amd64:
          requires:
            - lint
            - test
            - build-and-deploy-approval
          filters:
            branches:
              only:
                - master
                - /^[0-9]+\.[0-9]+$/
      - build-and-push-images-arm64:
          requires:
            - lint
            - test
            - build-and-deploy-approval
          filters:
            branches:
              only:
                - master
                - /^[0-9]+\.[0-9]+$/
      - amend-images:
          requires:
            - build-and-push-images-amd64
            - build-and-push-images-arm64
          filters:
            branches:
              only:
                - master
                - /^[0-9]+\.[0-9]+$/

  # nightly-cluster-up:
  #   triggers:
  #     - schedule:
  #         cron: "0 0 * * *"
  #         filters:
  #           branches:
  #             only:
  #               - master
  #   jobs:
  #     - cluster-up

  # nightly-e2e-tests:
  #   triggers:
  #     - schedule:
  #         cron: "0 1 * * *"
  #         filters:
  #           branches:
  #             only:
  #               - master
  #   jobs:
  #     - e2e-tests

  # nightly-cluster-down:
  #   triggers:
  #     - schedule:
  #         cron: "0 2 * * *"
  #         filters:
  #           branches:
  #             only:
  #               - master
  #   jobs:
  #     - cluster-down


================================================
FILE: .dockerignore
================================================
/vendor/
/bin/
/testbin/
/dev/
/docs/
/test/

**/.*
**/*.md
**/*.zip

**/*.pyc
**/*.pyo
**/*.pyd
**/__pycache__/

**/hack/
**/PROJECT
**/Makefile


================================================
FILE: .gitbook.yaml
================================================
root: ./docs/

structure:
  readme: ./start.md
  summary: summary.md


================================================
FILE: .github/ISSUE_TEMPLATE/bug-report.md
================================================
---
name: Bug report
about: Report a bug
title: ''
labels: bug
assignees: ''

---

### Version

(use `cortex version` to determine your version)

### Description

(describe the bug)

### Configuration

(paste relevant `cortex.yaml` or `cluster.yaml` configuration)

### Steps to reproduce

1. ...
2. ...
3. ...

### Expected behavior

(describe the behavior you expected)

### Actual behavior

(describe the behavior you experienced)

### Screenshots

(optional)

### Stack traces

(error output from CloudWatch Insights or from a random pod `cortex logs <api name>`)

```text
<paste stack traces here>
```

### Additional context

(optional)

### Suggested solution

(optional)


================================================
FILE: .github/ISSUE_TEMPLATE/feature-request.md
================================================
---
name: Feature request
about: Request a feature
title: ''
labels: enhancement
assignees: ''

---

### Description

(describe the feature)

### Motivation

(how this will improve the product / what problem will this solve / what is the use case)

### Additional context

(optional)


================================================
FILE: .github/ISSUE_TEMPLATE/question.md
================================================
---
name: Question
about: Ask a question
title: ''
labels: question
assignees: ''

---


================================================
FILE: .github/pull_request_template.md
================================================
closes #<issue ID>

---

checklist:

- [ ] run `make test` and `make lint`
- [ ] test manually (i.e. build/push all images, restart operator, and re-deploy APIs)
- [ ] update examples
- [ ] update docs and add any new files to `summary.md` (view in [gitbook](https://cortex-labs.gitbook.io/staging/-MOmCGMADSRNQahK3Kox/) after merging)
- [ ] cherry-pick into release branches if applicable
- [ ] alert the dev team if the dev environment changed


================================================
FILE: .gitignore
================================================
/vendor/
/bin/
/testbin/
/dev/config/

# PYTHON
__pycache__/
*.py[cod]
*$py.class
.python-version
.env
.venv
*.egg-info
*.pytest_cache

# OSX
.DS_Store
._*

# MISC
*.zip
.unison*
.vscode/

# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, build with `go test -c`
*.test

# Kubernetes Generated files - skip generated files, except for vendored files

!vendor/**/zz_generated.*

# editor and IDE paraphernalia
.idea
*.swp
*.swo
*~


================================================
FILE: CONTRIBUTING.md
================================================
# Contributing

## Remote development

We recommend that you run your development environment on an EC2 instance due to frequent docker registry pushing. We've had a good experience using [Mutagen](https://mutagen.io/documentation/introduction) to synchronize local / remote filesystems.

## Prerequisites

### System packages

To install the necessary system packages on Ubuntu, you can run these commands:

```bash
sudo apt-get update
sudo apt install -y apt-transport-https ca-certificates software-properties-common gnupg-agent curl zip python3 python3-pip python3-dev build-essential jq tree
sudo python3 -m pip install --upgrade pip setuptools boto3
```

### Go

To install Go on linux, run:

```bash
mkdir -p ~/bin && \
wget https://dl.google.com/go/go1.17.3.linux-amd64.tar.gz && \
sudo tar -xvf go1.17.3.linux-amd64.tar.gz && \
sudo mv go /usr/local && \
rm go1.17.3.linux-amd64.tar.gz && \
echo 'export PATH="/usr/local/go/bin:$HOME/go/bin:$PATH"' >> $HOME/.bashrc
```

And then log out and back in.

### Docker

To install Docker on Ubuntu, run:

```bash
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - && \
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" && \
sudo apt update && \
sudo apt install -y docker-ce docker-ce-cli containerd.io && \
sudo usermod -aG docker $USER
```

And then log out and back in. Then, bootstrap a buildx builder:

```bash
docker buildx create --driver-opt image=moby/buildkit:master --name builder --platform linux/amd64,linux/arm64 --use
docker buildx inspect --bootstrap builder
```

### kubectl

To install kubectl on linux, run:

```bash
curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl && \
chmod +x ./kubectl && \
sudo mv ./kubectl /usr/local/bin/kubectl
```

### eksctl

To install eksctl run:

```bash
curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp && \
sudo mv /tmp/eksctl /usr/local/bin
```

### aws-cli (v1)

Follow [these instructions](https://github.com/aws/aws-cli#installation) to install aws-cli (v1).

E.g. to install it globally, run:

```bash
sudo python3 -m pip install awscli

aws configure
```

## Cortex dev environment

### Clone the repo

Clone the project:

```bash
git clone https://github.com/cortexlabs/cortex.git
cd cortex
```

Run the tests:

```bash
make test
```

### Dev tools

Install development tools by running:

```bash
make tools
```

After the dependencies are installed, there may be a diff in `go.mod` and `go.sum`, which you can revert.

Run the linter:

```bash
make lint
```

We use `gofmt` for formatting Go files, `black` for Python files (line length = 100), and the VS Code [yaml extension](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml) for YAML files. It is recommended to enable these in your code editor, but you can also run the Go and Python formatters from the terminal:

```bash
make format

git diff  # there should be no diff
```

### Cluster configuration

Create a config directory in the repo's root directory:

```bash
mkdir dev/config
```

Create `dev/config/env.sh` with the following information:

```bash
# dev/config/env.sh

export AWS_ACCOUNT_ID="***"  # you can find your account ID in the AWS web console; here is an example: 764403040417
export AWS_REGION="***"  # you can use any AWS region you'd like, e.g. "us-west-2"
export AWS_ACCESS_KEY_ID="***"  # alternatively, you can remove this to use the default credentials chain on your machine
export AWS_SECRET_ACCESS_KEY="***"  # alternatively, you can remove this to use the default credentials chain on your machine
export DEFAULT_USER_ARN="arn:aws:iam::<ACCOUNT_ID>:<AWS IAM ENTITY>" # (e.g. arn:aws-us-gov:iam::123456789:user/foo)
```

Create the ECR registries:

```bash
make registry-create
```

Create `dev/config/cluster.yaml`. Paste the following config, and update `region` and all registry URLs (replace `<account_id>` with your AWS account ID, and replace `<region>` with your region):

```yaml
# dev/config/cluster.yaml

cluster_name: cortex
region: <region>  # e.g. us-west-2

node_groups:
  - name: worker-ng
    instance_type: m5.large
    min_instances: 1
    max_instances: 5
```

### Building

Add this to your bash profile (e.g. `~/.bash_profile`, `~/.profile` or `~/.bashrc`), replacing the placeholders accordingly:

```bash
# set the default image registry
export CORTEX_DEV_DEFAULT_IMAGE_REGISTRY="<account_id>.dkr.ecr.<region>.amazonaws.com/cortexlabs"

# enable api server monitoring in grafana
export CORTEX_DEV_ADD_CONTROL_PLANE_DASHBOARD="true"

# redirect analytics and error reporting to our dev environment
export CORTEX_TELEMETRY_SENTRY_DSN="https://c334df915c014ffa93f2076769e5b334@sentry.io/1848098"
export CORTEX_TELEMETRY_SEGMENT_WRITE_KEY="0WvoJyCey9z1W2EW7rYTPJUMRYat46dl"

# instruct the Python client to use your development CLI binary (update the path to point to your cortex repo)
export CORTEX_CLI_PATH="<cortex_repo_path>/bin/cortex"

# create a cortex alias which runs your development CLI
alias cortex="$CORTEX_CLI_PATH"
```

Refresh your bash profile:

```bash
. ~/.bash_profile  # or: `. ~/.bashrc`
```

Build the Cortex CLI:

```bash
make cli  # the binary will be placed in <path/to/cortex>/bin/cortex
cortex version  # should show "master"
```

Build and push all Cortex images:

```bash
make images-all
```

## Dev workflow

Here is the typical full dev workflow which covers most cases:

1. `make cluster-up` (creates a cluster using `dev/config/cluster.yaml`)
2. `make devstart` (deletes the in-cluster operator, builds the CLI, and starts the operator locally; file changes will trigger the CLI and operator to re-build)
3. Make your changes
4. `make images-dev` (only necessary if changes were made outside of the operator and CLI)
5. Test your changes e.g. via `cortex deploy` (and repeat steps 3 and 4 as necessary)
6. `make cluster-down` (deletes your cluster)

If you want to switch back to the in-cluster operator:

1. `<ctrl+c>` to stop your local operator
2. `make operator-start` to restart the operator in your cluster

### Dev workflow optimizations

If you are only modifying the CLI, `make cli-watch` will build the CLI and re-build it when files are changed. When doing this, you can leave the operator running in the cluster instead of running it locally.

If you are only modifying the operator, `make operator-local` will build and start the operator locally, and build/restart it when files are changed.

See `Makefile` for additional dev commands.


================================================
FILE: LICENSE
================================================
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [yyyy] [name of copyright owner]

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.


================================================
FILE: Makefile
================================================
#!make

# Copyright 2022 Cortex Labs, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

SHELL := /bin/bash
export BASH_ENV=./dev/config/env.sh

# declare all targets as phony to avoid collisions with local files or folders
.PHONY: $(MAKECMDGOALS)

#######
# Dev #
#######

# Cortex

# build cli, start local operator, and watch for changes
devstart:
	@$(MAKE) operator-stop || true
	@./dev/operator_local.sh || true

cli:
	@mkdir -p ./bin
	@go build -o ./bin/cortex ./cli

# build cli and watch for changes
cli-watch:
	@rerun -watch ./pkg ./cli -run sh -c "clear && echo 'building cli...' && go build -o ./bin/cortex ./cli && clear && echo '\033[1;32mCLI built\033[0m'" || true

# start local operator and watch for changes
operator-local:
	@$(MAKE) operator-stop || true
	@./dev/operator_local.sh --operator-only || true

# start local operator and attach the delve debugger to it (in server mode)
operator-local-dbg:
	@$(MAKE) operator-stop || true
	@./dev/operator_local.sh --debug || true

# configure kubectl to point to the cluster specified in dev/config/cluster.yaml
kubectl:
	@eval $$(python3 ./manager/cluster_config_env.py ./dev/config/cluster.yaml) && eval $$(python3 ./dev/create_user.py $$CORTEX_CLUSTER_NAME $$AWS_ACCOUNT_ID $$CORTEX_REGION) && eksctl utils write-kubeconfig --cluster="$$CORTEX_CLUSTER_NAME" --region="$$CORTEX_REGION" --verbose=0 | (grep -v "saved kubeconfig as" || true); eksctl create iamidentitymapping --region $$CORTEX_REGION --cluster $$CORTEX_CLUSTER_NAME --arn $$DEFAULT_USER_ARN --group system:masters --username $$DEFAULT_USER_ARN

cluster-up:
	@$(MAKE) images-all
	@$(MAKE) cli
	@kill $(shell pgrep -f rerun) >/dev/null 2>&1 || true
	@eval $$(python3 ./manager/cluster_config_env.py ./dev/config/cluster.yaml) && eval $$(python3 ./dev/create_user.py $$CORTEX_CLUSTER_NAME $$AWS_ACCOUNT_ID $$CORTEX_REGION) && sleep 10 && ./bin/cortex cluster up ./dev/config/cluster.yaml --configure-env="$$CORTEX_CLUSTER_NAME"; eksctl create iamidentitymapping --region $$CORTEX_REGION --cluster $$CORTEX_CLUSTER_NAME --arn $$DEFAULT_USER_ARN --group system:masters --username $$DEFAULT_USER_ARN
	@$(MAKE) kubectl

cluster-up-y:
	@$(MAKE) images-all
	@$(MAKE) cli
	@kill $(shell pgrep -f rerun) >/dev/null 2>&1 || true
	@eval $$(python3 ./manager/cluster_config_env.py ./dev/config/cluster.yaml) && eval $$(python3 ./dev/create_user.py $$CORTEX_CLUSTER_NAME $$AWS_ACCOUNT_ID $$CORTEX_REGION) && sleep 10 && ./bin/cortex cluster up ./dev/config/cluster.yaml --configure-env="$$CORTEX_CLUSTER_NAME" --yes; eksctl create iamidentitymapping --region $$CORTEX_REGION --cluster $$CORTEX_CLUSTER_NAME --arn $$DEFAULT_USER_ARN --group system:masters --username $$DEFAULT_USER_ARN
	@$(MAKE) kubectl

cluster-configure:
	@$(MAKE) images-manager-skip-push
	@$(MAKE) cli
	@kill $(shell pgrep -f rerun) >/dev/null 2>&1 || true
	@eval $$(python3 ./manager/cluster_config_env.py ./dev/config/cluster.yaml) && eval $$(python3 ./dev/create_user.py $$CORTEX_CLUSTER_NAME $$AWS_ACCOUNT_ID $$CORTEX_REGION) && sleep 10 && ./bin/cortex cluster configure ./dev/config/cluster.yaml; eksctl create iamidentitymapping --region $$CORTEX_REGION --cluster $$CORTEX_CLUSTER_NAME --arn $$DEFAULT_USER_ARN --group system:masters --username $$DEFAULT_USER_ARN
	@$(MAKE) kubectl

cluster-configure-y:
	@$(MAKE) images-manager-skip-push
	@$(MAKE) cli
	@kill $(shell pgrep -f rerun) >/dev/null 2>&1 || true
	@eval $$(python3 ./manager/cluster_config_env.py ./dev/config/cluster.yaml) && eval $$(python3 ./dev/create_user.py $$CORTEX_CLUSTER_NAME $$AWS_ACCOUNT_ID $$CORTEX_REGION) && sleep 10 && ./bin/cortex cluster configure ./dev/config/cluster.yaml --yes; eksctl create iamidentitymapping --region $$CORTEX_REGION --cluster $$CORTEX_CLUSTER_NAME --arn $$DEFAULT_USER_ARN --group system:masters --username $$DEFAULT_USER_ARN
	@$(MAKE) kubectl

cluster-down:
	@$(MAKE) images-manager-skip-push
	@$(MAKE) cli
	@kill $(shell pgrep -f rerun) >/dev/null 2>&1 || true
	@eval $$(python3 ./manager/cluster_config_env.py ./dev/config/cluster.yaml) && eval $$(python3 ./dev/create_user.py $$CORTEX_CLUSTER_NAME $$AWS_ACCOUNT_ID $$CORTEX_REGION) && sleep 10 && ./bin/cortex cluster down --config=./dev/config/cluster.yaml

cluster-down-y:
	@$(MAKE) images-manager-skip-push
	@$(MAKE) cli
	@kill $(shell pgrep -f rerun) >/dev/null 2>&1 || true
	@eval $$(python3 ./manager/cluster_config_env.py ./dev/config/cluster.yaml) && eval $$(python3 ./dev/create_user.py $$CORTEX_CLUSTER_NAME $$AWS_ACCOUNT_ID $$CORTEX_REGION) && sleep 10 && ./bin/cortex cluster down --config=./dev/config/cluster.yaml --yes

cluster-info:
	@$(MAKE) images-manager-skip-push
	@$(MAKE) cli
	@eval $$(python3 ./manager/cluster_config_env.py ./dev/config/cluster.yaml) && eval $$(python3 ./dev/create_user.py $$CORTEX_CLUSTER_NAME $$AWS_ACCOUNT_ID $$CORTEX_REGION) && sleep 10 && ./bin/cortex cluster info --config=./dev/config/cluster.yaml --configure-env="$$CORTEX_CLUSTER_NAME" --yes

update-credentials:
	@eval $$(python3 ./manager/cluster_config_env.py ./dev/config/cluster.yaml) && python3 ./dev/create_user.py $$CORTEX_CLUSTER_NAME $$AWS_ACCOUNT_ID $$CORTEX_REGION

# stop the in-cluster operator
operator-stop:
	@$(MAKE) kubectl
	@kubectl scale --namespace=default deployments/operator --replicas=0

# start the in-cluster operator
operator-start:
	@$(MAKE) kubectl
	@kubectl scale --namespace=default deployments/operator --replicas=1
	@operator_pod=$$(kubectl get pods -l workloadID=operator --namespace=default -o jsonpath='{.items[0].metadata.name}') && kubectl wait --for=condition=ready pod $$operator_pod --namespace=default

# restart the in-cluster operator
operator-restart:
	@$(MAKE) kubectl
	@kubectl delete pods -l workloadID=operator --namespace=default
	@operator_pod=$$(kubectl get pods -l workloadID=operator --namespace=default -o jsonpath='{.items[0].metadata.name}') && kubectl wait --for=condition=ready pod $$operator_pod --namespace=default

# build and update the in-cluster operator
operator-update:
	@$(MAKE) kubectl
	@kubectl scale --namespace=default deployments/operator --replicas=0
	@./dev/registry.sh update-single operator
	@kubectl scale --namespace=default deployments/operator --replicas=1
	@operator_pod=$$(kubectl get pods -l workloadID=operator --namespace=default -o jsonpath='{.items[0].metadata.name}') && kubectl wait --for=condition=ready pod $$operator_pod --namespace=default

# restart all in-cluster async-gateways
async-gateway-restart:
	@$(MAKE) kubectl
	@kubectl delete pods -l cortex.dev/async=gateway --namespace=default

# build and update all in-cluster async-gateways
async-gateway-update:
	@$(MAKE) kubectl
	@./dev/registry.sh update-single async-gateway
	@kubectl delete pods -l cortex.dev/async=gateway --namespace=default

# docker images
images-all:
	@./dev/registry.sh update all
images-all-multi-arch:
	@./dev/registry.sh update all --include-arm64-arch
images-all-skip-push:
	@./dev/registry.sh update all --skip-push

images-dev:
	@./dev/registry.sh update dev
images-dev-multi-arch:
	@./dev/registry.sh update dev --include-arm64-arch
images-dev-skip-push:
	@./dev/registry.sh update dev --skip-push

images-manager-skip-push:
	@./dev/registry.sh update-single manager --skip-push

images-clean-cache:
	@./dev/registry.sh clean-cache

registry-create:
	@./dev/registry.sh create

registry-clean:
	@./dev/registry.sh clean

# Misc

tools:
	@go get -u -v golang.org/x/lint/golint
	@go get -u -v github.com/kyoh86/looppointer/cmd/looppointer
	@go get -u -v github.com/VojtechVitek/rerun/cmd/rerun
	@go get -u -v github.com/go-delve/delve/cmd/dlv
	@python3 -m pip install aiohttp boto3 pyyaml pydoc-markdown==3.* black==20.8b1 -U
	@python3 -m pip install -e test/e2e

format:
	@./dev/format.sh

#########
# Tests #
#########

# build test api images
# make sure you login with your quay credentials
build-test-api-images:
	@./test/utils/build-all.sh quay.io/cortexlabs-test

test:
	@./build/test.sh go

# run e2e tests on an existing cluster
# read test/e2e/README.md for instructions first
test-e2e:
	@$(MAKE) images-all
	@$(MAKE) operator-restart
	@eval $$(python3 ./manager/cluster_config_env.py ./dev/config/cluster.yaml) && CORTEX_CLI_PATH="$$(pwd)/bin/cortex" ./build/test.sh e2e -e "$$CORTEX_CLUSTER_NAME"

# run e2e tests with a new cluster
# read test/e2e/README.md for instructions first
test-e2e-new:
	@$(MAKE) images-all
	@eval $$(python3 ./manager/cluster_config_env.py ./dev/config/cluster.yaml) && CORTEX_CLI_PATH="$$(pwd)/bin/cortex" ./build/test.sh e2e "$$(pwd)/dev/config/cluster.yaml" --create-cluster

lint:
	@./build/lint.sh

# this is a subset of lint.sh, and is only meant to be run on master
lint-docs:
	@./build/lint-docs.sh

###############
# CI Commands #
###############

ci-build-images-amd64:
	@./build/build-images.sh amd64 quay.io docker.io

ci-build-images-arm64:
	@./build/build-images.sh arm64 quay.io docker.io

ci-push-images-amd64:
	@./build/push-images.sh amd64 quay.io docker.io

ci-push-images-arm64:
	@./build/push-images.sh arm64 quay.io docker.io

ci-amend-images:
	@./build/amend-images.sh quay.io docker.io

ci-build-cli:
	@./build/cli.sh

ci-build-and-upload-cli:
	@./build/cli.sh upload


================================================
FILE: README.md
================================================
**[Docs](https://docs.cortexlabs.com)** • **[Slack](https://community.cortexlabs.com)**

<br>

<img src='https://cortex-public.s3.us-west-2.amazonaws.com/logo.png' height='32'>

<br>

Note: This project is no longer actively maintained by its original authors.

# Production infrastructure for machine learning at scale

Deploy, manage, and scale machine learning models in production.

<br>

## Serverless workloads

**Realtime** - respond to requests in real-time and autoscale based on in-flight request volumes.

**Async** - process requests asynchronously and autoscale based on request queue length.

**Batch** - run distributed and fault-tolerant batch processing jobs on-demand.

<br>

## Automated cluster management

**Autoscaling** - elastically scale clusters with CPU and GPU instances.

**Spot instances** - run workloads on spot instances with automated on-demand backups.

**Environments** - create multiple clusters with different configurations.

<br>

## CI/CD and observability integrations

**Provisioning** - provision clusters with declarative configuration or a Terraform provider.

**Metrics** - send metrics to any monitoring tool or use pre-built Grafana dashboards.

**Logs** - stream logs to any log management tool or use the pre-built CloudWatch integration.

<br>

## Built for AWS

**EKS** - Cortex runs on top of EKS to scale workloads reliably and cost-effectively.

**VPC** - deploy clusters into a VPC on your AWS account to keep your data private.

**IAM** - integrate with IAM for authentication and authorization workflows.


================================================
FILE: build/amend-image.sh
================================================
#!/bin/bash

# Copyright 2022 Cortex Labs, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


set -euo pipefail

CORTEX_VERSION=master

host_primary=$1
host_backup=$2
image=$3

hosts=(
    "$host_primary"
    "$host_backup"
)
echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin

for host in "${hosts[@]}"; do
    docker manifest create $host/cortexlabs/${image}:${CORTEX_VERSION} \
        -a $host/cortexlabs/${image}:manifest-${CORTEX_VERSION}-amd64 \
        -a $host/cortexlabs/${image}:manifest-${CORTEX_VERSION}-arm64
    docker manifest push $host/cortexlabs/${image}:${CORTEX_VERSION}
done


================================================
FILE: build/amend-images.sh
================================================
#!/bin/bash

# Copyright 2022 Cortex Labs, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


set -euo pipefail

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")"/.. >/dev/null && pwd)"

source $ROOT/build/images.sh
source $ROOT/dev/util.sh

host_primary=$1
host_backup=$2

for image in "${multi_arch_images[@]}"; do
    $ROOT/build/amend-image.sh $host_primary $host_backup $image
done


================================================
FILE: build/build-image.sh
================================================
#!/bin/bash

# Copyright 2022 Cortex Labs, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


set -euo pipefail

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")"/.. >/dev/null && pwd)"

CORTEX_VERSION=master

host_primary=$1
host_backup=$2
image=$3
is_multi_arch=$4
arch=$5

if [ "$is_multi_arch" = "true" ]; then
  tag="manifest-${CORTEX_VERSION}-$arch"
else
  tag="${CORTEX_VERSION}"
fi

docker build $ROOT \
  --build-arg TARGETOS=linux \
  --build-arg TARGETARCH=$arch \
  -f $ROOT/images/$image/Dockerfile \
  -t $host_primary/cortexlabs/${image}:${tag} \
  -t $host_backup/cortexlabs/${image}:${tag}


================================================
FILE: build/build-images.sh
================================================
#!/bin/bash

# Copyright 2022 Cortex Labs, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


set -euo pipefail

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")"/.. >/dev/null && pwd)"

source $ROOT/build/images.sh
source $ROOT/dev/util.sh

arch=$1
host_primary=$2
host_backup=$3

for image in "${all_images[@]}"; do
  is_multi_arch="false"
  if [[ " ${multi_arch_images[*]} " =~ " $image " ]]; then
    is_multi_arch="true"
    $ROOT/build/build-image.sh $host_primary $host_backup $image $is_multi_arch $arch
  elif [ "$arch" = "amd64" ]; then
    $ROOT/build/build-image.sh $host_primary $host_backup $image $is_multi_arch $arch
  fi
done


================================================
FILE: build/cli.sh
================================================
#!/bin/bash

# Copyright 2022 Cortex Labs, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


set -euo pipefail

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")"/.. >/dev/null && pwd)"

CORTEX_VERSION=master

arg1=${1:-""}
upload="false"
if [ "$arg1" == "upload" ]; then
  upload="true"
fi

function build_and_upload() {
  set -euo pipefail

  os=$1
  echo -e "\nBuilding Cortex CLI for $os"
  GOOS=$os GOARCH=amd64 CGO_ENABLED=0 go build -o cortex "$ROOT/cli"
  if [ "$upload" == "true" ]; then
    echo "Uploading Cortex CLI to s3://$CLI_BUCKET_NAME/$CORTEX_VERSION/cli/$os/cortex"
    aws s3 cp cortex s3://$CLI_BUCKET_NAME/$CORTEX_VERSION/cli/$os/cortex --only-show-errors

    zip cortex.zip cortex
    echo "Uploading zipped Cortex CLI to s3://$CLI_BUCKET_NAME/$CORTEX_VERSION/cli/$os/cortex.zip"
    aws s3 cp cortex.zip s3://$CLI_BUCKET_NAME/$CORTEX_VERSION/cli/$os/cortex.zip --only-show-errors
    rm cortex.zip
  fi
  echo "Done ✓"
  rm cortex
}

function build_python {
  pushd $ROOT/python/client
  python setup.py sdist

  if [ "$upload" == "true" ]; then
    echo "Uploading Cortex CLI to s3://$CLI_BUCKET_NAME/$CORTEX_VERSION/python/cortex-$CORTEX_VERSION.tar.gz"
    aws s3 cp dist/cortex-$CORTEX_VERSION.tar.gz s3://$CLI_BUCKET_NAME/$CORTEX_VERSION/python/cortex-$CORTEX_VERSION.tar.gz
  fi

  rm -rf dist/
  rm -rf cortex.egg-info/

  popd
}

build_and_upload darwin

build_and_upload linux

build_python


================================================
FILE: build/generate_ami_mapping.go
================================================
/*
Copyright 2022 Cortex Labs, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package main

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"sort"
	"time"

	"github.com/pkg/errors"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/ec2"
	"github.com/aws/aws-sdk-go/service/ec2/ec2iface"
)

// run with `go run build/generate_ami_mapping.go manager/manifests/ami.json`
// copied from https://github.com/weaveworks/eksctl/blob/c211e68d3c8cf3c7f800768bfa0251dda17e011c/pkg/apis/eksctl.io/v1alpha5/types.go
// most of this code can be removed once eksctl can be imported: https://github.com/weaveworks/eksctl/issues/813
const (
	eksResourceAccountStandard = "602401143452"

	// eksResourceAccountAPEast1 defines the AWS EKS account ID that provides node resources in ap-east-1 region
	eksResourceAccountAPEast1 = "800184023465"

	// eksResourceAccountMESouth1 defines the AWS EKS account ID that provides node resources in me-south-1 region
	eksResourceAccountMESouth1 = "558608220178"

	// eksResourceAccountCNNorthWest1 defines the AWS EKS account ID that provides node resources in cn-northwest-1 region
	eksResourceAccountCNNorthWest1 = "961992271922"

	// eksResourceAccountCNNorth1 defines the AWS EKS account ID that provides node resources in cn-north-1
	eksResourceAccountCNNorth1 = "918309763551"

	// eksResourceAccountAFSouth1 defines the AWS EKS account ID that provides node resources in af-south-1
	eksResourceAccountAFSouth1 = "877085696533"

	// eksResourceAccountEUSouth1 defines the AWS EKS account ID that provides node resources in eu-south-1
	eksResourceAccountEUSouth1 = "590381155156"

	// eksResourceAccountUSGovWest1 defines the AWS EKS account ID that provides node resources in us-gov-west-1
	eksResourceAccountUSGovWest1 = "013241004608"

	// eksResourceAccountUSGovEast1 defines the AWS EKS account ID that provides node resources in us-gov-east-1
	eksResourceAccountUSGovEast1 = "151742754352"
)

// Regions
const (
	// RegionUSWest1 represents the US West Region North California
	RegionUSWest1 = "us-west-1"

	// RegionUSWest2 represents the US West Region Oregon
	RegionUSWest2 = "us-west-2"

	// RegionUSEast1 represents the US East Region North Virginia
	RegionUSEast1 = "us-east-1"

	// RegionUSEast2 represents the US East Region Ohio
	RegionUSEast2 = "us-east-2"

	// RegionCACentral1 represents the Canada Central Region
	RegionCACentral1 = "ca-central-1"

	// RegionEUWest1 represents the EU West Region Ireland
	RegionEUWest1 = "eu-west-1"

	// RegionEUWest2 represents the EU West Region London
	RegionEUWest2 = "eu-west-2"

	// RegionEUWest3 represents the EU West Region Paris
	RegionEUWest3 = "eu-west-3"

	// RegionEUNorth1 represents the EU North Region Stockholm
	RegionEUNorth1 = "eu-north-1"

	// RegionEUCentral1 represents the EU Central Region Frankfurt
	RegionEUCentral1 = "eu-central-1"

	// RegionEUSouth1 represents te Eu South Region Milan
	RegionEUSouth1 = "eu-south-1"

	// RegionAPNorthEast1 represents the Asia-Pacific North East Region Tokyo
	RegionAPNorthEast1 = "ap-northeast-1"

	// RegionAPNorthEast2 represents the Asia-Pacific North East Region Seoul
	RegionAPNorthEast2 = "ap-northeast-2"

	// RegionAPNorthEast3 represents the Asia-Pacific North East region Osaka
	RegionAPNorthEast3 = "ap-northeast-3"

	// RegionAPSouthEast1 represents the Asia-Pacific South East Region Singapore
	RegionAPSouthEast1 = "ap-southeast-1"

	// RegionAPSouthEast2 represents the Asia-Pacific South East Region Sydney
	RegionAPSouthEast2 = "ap-southeast-2"

	// RegionAPSouth1 represents the Asia-Pacific South Region Mumbai
	RegionAPSouth1 = "ap-south-1"

	// RegionAPEast1 represents the Asia Pacific Region Hong Kong
	RegionAPEast1 = "ap-east-1"

	// RegionMESouth1 represents the Middle East Region Bahrain
	RegionMESouth1 = "me-south-1"

	// RegionSAEast1 represents the South America Region Sao Paulo
	RegionSAEast1 = "sa-east-1"

	// RegionAFSouth1 represents the Africa Region Cape Town
	RegionAFSouth1 = "af-south-1"

	// RegionCNNorthwest1 represents the China region Ningxia
	RegionCNNorthwest1 = "cn-northwest-1"

	// RegionCNNorth1 represents the China region Beijing
	RegionCNNorth1 = "cn-north-1"

	// RegionUSGovWest1 represents the region GovCloud (US-West)
	RegionUSGovWest1 = "us-gov-west-1"

	// RegionUSGovEast1 represents the region GovCloud (US-East)
	RegionUSGovEast1 = "us-gov-east-1"

	// DefaultRegion defines the default region, where to deploy the EKS cluster
	DefaultRegion = RegionUSWest2
)

// SupportedRegions are the regions where EKS is available
func SupportedRegions() []string {
	return []string{
		RegionUSWest1,
		RegionUSWest2,
		RegionUSEast1,
		RegionUSEast2,
		RegionCACentral1,
		RegionEUWest1,
		RegionEUWest2,
		RegionEUWest3,
		RegionEUNorth1,
		RegionEUCentral1,
		RegionEUSouth1,
		RegionAPNorthEast1,
		RegionAPNorthEast2,
		RegionAPNorthEast3,
		RegionAPSouthEast1,
		RegionAPSouthEast2,
		RegionAPSouth1,
		RegionAPEast1,
		RegionMESouth1,
		RegionSAEast1,
		RegionAFSouth1,
		RegionUSGovWest1,
		RegionUSGovEast1,
		// RegionCNNorthwest1,
		// RegionCNNorth1,
	}
}

func EKSResourceAccountID(region string) string {
	switch region {
	case RegionAPEast1:
		return eksResourceAccountAPEast1
	case RegionMESouth1:
		return eksResourceAccountMESouth1
	case RegionCNNorthwest1:
		return eksResourceAccountCNNorthWest1
	case RegionCNNorth1:
		return eksResourceAccountCNNorth1
	case RegionUSGovWest1:
		return eksResourceAccountUSGovWest1
	case RegionUSGovEast1:
		return eksResourceAccountUSGovEast1
	case RegionAFSouth1:
		return eksResourceAccountAFSouth1
	case RegionEUSouth1:
		return eksResourceAccountEUSouth1
	default:
		return eksResourceAccountStandard
	}
}

func main() {
	if len(os.Args) > 3 {
		fmt.Println("usage: go run generate_ami_mapping.go <abs_dest_path> public|govcloud")
		os.Exit(1)
	}

	destFile := os.Args[1]
	cloudType := os.Args[2]

	if cloudType != "public" && cloudType != "govcloud" {
		log.Fatalf("%s is not a valid value; specify public or govcloud", cloudType)
	}

	k8sVersionMap := map[string]map[string]map[string]string{}

	if _, err := os.Stat(destFile); !os.IsNotExist(err) {
		jsonBytes, err := ioutil.ReadFile(destFile)
		if err != nil {
			log.Fatal(err.Error())
		}
		json.Unmarshal(jsonBytes, &k8sVersionMap)
	}

	k8sVersion := "1.22"

	if k8sVersionMap[k8sVersion] == nil {
		k8sVersionMap[k8sVersion] = map[string]map[string]string{}
	}
	for _, region := range SupportedRegions() {
		if (cloudType == "govcloud") != (region == RegionUSGovEast1 || region == RegionUSGovWest1) {
			// cloudType == "govcloud" xor (region is us govclouds)
			continue
		}
		fmt.Print(region)
		sess := session.New(&aws.Config{Region: aws.String(region)})
		svc := ec2.New(sess)
		cpuAmd64AMI, err := FindImage(svc, EKSResourceAccountID(region), fmt.Sprintf("amazon-eks-node-%s-v*", k8sVersion))
		if err != nil {
			log.Fatal(err.Error())
		}
		cpuArm64AMI, err := FindImage(svc, EKSResourceAccountID(region), fmt.Sprintf("amazon-eks-arm64-node-%s-v*", k8sVersion))
		if err != nil {
			log.Fatal(err.Error())
		}
		acceleratedAmd64AMI, err := FindImage(svc, EKSResourceAccountID(region), fmt.Sprintf("amazon-eks-gpu-node-%s-v*", k8sVersion))
		if err != nil {
			log.Fatal(err.Error())
		}

		if k8sVersionMap[k8sVersion][region] == nil {
			k8sVersionMap[k8sVersion][region] = map[string]string{}
		}
		k8sVersionMap[k8sVersion][region] = map[string]string{
			"cpu_amd64":         cpuAmd64AMI,
			"cpu_arm64":         cpuArm64AMI,
			"accelerated_amd64": acceleratedAmd64AMI,
		}
		fmt.Println(" ✓")
	}

	marshalledBytes, err := json.MarshalIndent(k8sVersionMap, "", "\t")
	if err != nil {
		log.Fatal(err.Error())
	}

	marshalledBytes = append(marshalledBytes, []byte("\n")...)

	err = ioutil.WriteFile(destFile, marshalledBytes, 0664)
	if err != nil {
		log.Fatal(err.Error())
	}
}

func FindImage(ec2api ec2iface.EC2API, ownerAccount, namePattern string) (string, error) {
	input := &ec2.DescribeImagesInput{
		Owners: []*string{&ownerAccount},
		Filters: []*ec2.Filter{
			{
				Name:   aws.String("name"),
				Values: []*string{&namePattern},
			},
			{
				Name:   aws.String("virtualization-type"),
				Values: []*string{aws.String("hvm")},
			},
			{
				Name:   aws.String("root-device-type"),
				Values: []*string{aws.String("ebs")},
			},
			{
				Name:   aws.String("is-public"),
				Values: []*string{aws.String("true")},
			},
			{
				Name:   aws.String("state"),
				Values: []*string{aws.String("available")},
			},
		},
	}

	output, err := ec2api.DescribeImages(input)
	if err != nil {
		return "", errors.Wrapf(err, "error querying AWS for images")
	}

	if len(output.Images) < 1 {
		return "", nil
	}

	if len(output.Images) == 1 {
		return *output.Images[0].ImageId, nil
	}

	// Sort images so newest is first
	sort.Slice(output.Images, func(i, j int) bool {
		//nolint:gosec
		creationLeft, _ := time.Parse(time.RFC3339, *output.Images[i].CreationDate)
		//nolint:gosec
		creationRight, _ := time.Parse(time.RFC3339, *output.Images[j].CreationDate)
		return creationLeft.After(creationRight)
	})

	return *output.Images[0].ImageId, nil
}


================================================
FILE: build/images.sh
================================================
#!/bin/bash

# Copyright 2022 Cortex Labs, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# images to build/push for development and CI commands
# each image should appear exactly once on this page

set -euo pipefail

dev_images=(
  "manager"
  "proxy"
  "async-gateway"
  "enqueuer"
  "dequeuer"
  "autoscaler"
  "activator"
)

non_dev_images=(
  "cluster-autoscaler"
  "operator"
  "controller-manager"
  "istio-proxy"
  "istio-pilot"
  "fluent-bit"
  "prometheus"
  "prometheus-config-reloader"
  "prometheus-operator"
  "prometheus-statsd-exporter"
  "prometheus-dcgm-exporter"
  "prometheus-kube-state-metrics"
  "prometheus-node-exporter"
  "kube-rbac-proxy"
  "grafana"
  "event-exporter"
  "metrics-server"
  "nvidia-device-plugin"
  "neuron-device-plugin"
  "neuron-scheduler"
  "kubexit"
)

# for linux/amd64 and linux/arm64
multi_arch_images=(
  "proxy"
  "async-gateway"
  "enqueuer"
  "dequeuer"
  "fluent-bit"
  "prometheus-node-exporter"
  "kube-rbac-proxy"
  "kubexit"
)

all_images=(
  "${dev_images[@]}"
  "${non_dev_images[@]}"
)


================================================
FILE: build/lint-docs.sh
================================================
#!/bin/bash

# Copyright 2022 Cortex Labs, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# This is a subset of lint.sh, and is only meant to be run on master

set -euo pipefail

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")"/.. >/dev/null && pwd)"

# Check docs links
output=$(python3 $ROOT/dev/find_missing_docs_links.py)
if [[ $output ]]; then
  echo "docs file(s) have broken links:"
  echo "$output"
  exit 1
fi

# Check for trailing whitespace
output=$(cd "$ROOT/docs" && find . -type f \
-exec egrep -l " +$" {} \;)
if [[ $output ]]; then
  echo "File(s) have lines with trailing whitespace:"
  echo "$output"
  exit 1
fi

# Check for missing new line at end of file
output=$(cd "$ROOT/docs" && find . -type f \
-print0 | \
xargs -0 -L1 bash -c 'test "$(tail -c 1 "$0")" && echo "No new line at end of $0"' || true)
if [[ $output ]]; then
  echo "$output"
  exit 1
fi

# Check for multiple new lines at end of file
output=$(cd "$ROOT/docs" && find . -type f \
-print0 | \
xargs -0 -L1 bash -c 'test "$(tail -c 2 "$0")" || echo "Multiple new lines at end of $0"' || true)
if [[ $output ]]; then
  echo "$output"
  exit 1
fi

# Check for new line(s) at beginning of file
output=$(cd "$ROOT/docs" && find . -type f \
-print0 | \
xargs -0 -L1 bash -c 'test "$(head -c 1 "$0")" || echo "New line at beginning of $0"' || true)
if [[ $output ]]; then
  echo "$output"
  exit 1
fi


================================================
FILE: build/lint.sh
================================================
#!/bin/bash

# Copyright 2022 Cortex Labs, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


set -euo pipefail

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")"/.. >/dev/null && pwd)"

git_branch="${CIRCLE_BRANCH:-""}"
if [ "$git_branch" = "" ]; then
  git_branch=$(cd "$ROOT" && git rev-parse --abbrev-ref HEAD)
fi

is_release_branch="false"
if echo "$git_branch" | grep -Eq ^[0-9]+.[0-9]+$; then
  is_release_branch="true"
fi

if ! command -v golint >/dev/null 2>&1; then
  echo "golint must be installed"
  exit 1
fi

if ! command -v looppointer >/dev/null 2>&1; then
  echo "looppointer must be installed"
  exit 1
fi

if ! command -v gofmt >/dev/null 2>&1; then
  echo "gofmt must be installed"
  exit 1
fi

if ! command -v black >/dev/null 2>&1; then
  echo "black must be installed"
  exit 1
fi

go mod tidy
go vet "$ROOT/..."

output=$(golint "$ROOT/..." | grep -v "comment" || true)
if [[ $output ]]; then
  echo "$output"
  exit 1
fi

output=$(looppointer "$ROOT/...")
if [[ $output ]]; then
  echo "$output"
  exit 1
fi

output=$(gofmt -s -l "$ROOT")
if [[ $output ]]; then
  echo "go files not properly formatted:"
  echo "$output"
  exit 1
fi

output=$(black --quiet --diff --line-length=100 "$ROOT")
if [[ $output ]]; then
  echo "python files not properly formatted:"
  echo "$output"
  black --version
  exit 1
fi

# Check for missing license
output=$(cd "$ROOT" && find . -type f \
! -path "./vendor/*" \
! -path "**/.vscode/*" \
! -path "**/.idea/*" \
! -path "**/.history/*" \
! -path "**/testbin/*" \
! -path "**/__pycache__/*" \
! -path "**/.pytest_cache/*" \
! -path "**/*.egg-info/*" \
! -path "./test/*" \
! -path "./dev/config/*" \
! -path "**/bin/*" \
! -path "./.circleci/*" \
! -path "./.git/*" \
! -path "./pkg/crds/config/*" \
! -path "**/tmp/*" \
! -name LICENSE \
! -name "*requirements.txt" \
! -name "go.*" \
! -name "*.md" \
! -name "*.json" \
! -name ".*" \
! -name "*.bin" \
! -name "Dockerfile" \
! -name "PROJECT" \
-exec grep -L "Copyright 2022 Cortex Labs, Inc" {} \;)
if [[ $output ]]; then
  echo "File(s) are missing Cortex license:"
  echo "$output"
  exit 1
fi

if [ "$is_release_branch" = "true" ]; then
  # Check for occurrences of "master" which should be changed to the version number
  output=$(cd "$ROOT" && find . -type f \
  ! -path "./build/lint.sh" \
  ! -path "./vendor/*" \
  ! -path "**/.vscode/*" \
  ! -path "**/.idea/*" \
  ! -path "**/.history/*" \
  ! -path "**/testbin/*" \
  ! -path "**/__pycache__/*" \
  ! -path "**/.pytest_cache/*" \
  ! -path "**/*.egg-info/*" \
  ! -path "./dev/config/*" \
  ! -path "**/bin/*" \
  ! -path "./.git/*" \
  ! -name ".*" \
  ! -name "*.bin" \
  -exec grep -R -A 5 -e "CORTEX_VERSION" {} \;)
  output=$(echo "$output" | grep -e "master" || true)
  if [[ $output ]]; then
    echo 'occurrences of "master" which should be changed to the version number:'
    echo "$output"
    exit 1
  fi
fi

# Check for trailing whitespace
output=$(cd "$ROOT" && find . -type f \
! -path "./vendor/*" \
! -path "**/.idea/*" \
! -path "**/.history/*" \
! -path "**/.vscode/*" \
! -path "**/testbin/*" \
! -path "**/__pycache__/*" \
! -path "**/.pytest_cache/*" \
! -path "**/*.egg-info/*" \
! -path "./dev/config/*" \
! -path "**/bin/*" \
! -path "./.git/*" \
! -path "./pkg/crds/config/*" \
! -name ".*" \
! -name "*.bin" \
! -name "*.wav" \
-exec egrep -l " +$" {} \;)
if [[ $output ]]; then
  echo "File(s) have lines with trailing whitespace:"
  echo "$output"
  exit 1
fi

# Check for missing new line at end of file
output=$(cd "$ROOT" && find . -type f \
! -path "./vendor/*" \
! -path "**/.idea/*" \
! -path "**/.history/*" \
! -path "**/.vscode/*" \
! -path "**/testbin/*" \
! -path "**/__pycache__/*" \
! -path "**/.pytest_cache/*" \
! -path "**/*.egg-info/*" \
! -path "./dev/config/*" \
! -path "./pkg/crds/config/*" \
! -path "**/bin/*" \
! -path "./.git/*" \
! -name ".*" \
! -name "*.bin" \
! -name "*.wav" \
! -name "*.json" \
-print0 | \
xargs -0 -L1 bash -c 'test "$(tail -c 1 "$0")" && echo "No new line at end of $0"' || true)
if [[ $output ]]; then
  echo "$output"
  exit 1
fi

# Check for multiple new lines at end of file
output=$(cd "$ROOT" && find . -type f \
! -path "./vendor/*" \
! -path "**/.vscode/*" \
! -path "**/.idea/*" \
! -path "**/.history/*" \
! -path "**/testbin/*" \
! -path "**/__pycache__/*" \
! -path "**/.pytest_cache/*" \
! -path "**/*.egg-info/*" \
! -path "./dev/config/*" \
! -path "**/bin/*" \
! -path "./.git/*" \
! -name ".*" \
! -name "*.bin" \
! -name "*.wav" \
-print0 | \
xargs -0 -L1 bash -c 'test "$(tail -c 2 "$0")" || [ ! -s "$0" ] || echo "Multiple new lines at end of $0"' || true)
if [[ $output ]]; then
  echo "$output"
  exit 1
fi

# Check for new line(s) at beginning of file
output=$(cd "$ROOT" && find . -type f \
! -path "./vendor/*" \
! -path "**/.idea/*" \
! -path "**/.history/*" \
! -path "**/.vscode/*" \
! -path "**/testbin/*" \
! -path "**/__pycache__/*" \
! -path "**/.pytest_cache/*" \
! -path "**/*.egg-info/*" \
! -path "./dev/config/*" \
! -path "./pkg/crds/config/*" \
! -path "./bin/*" \
! -path "./.git/*" \
! -name ".*" \
! -name "*.bin" \
! -name "*.wav" \
! -name "boilerplate.go.txt" \
-print0 | \
xargs -0 -L1 bash -c 'test "$(head -c 1 "$0")" || [ ! -s "$0" ] || echo "New line at beginning of $0"' || true)
if [[ $output ]]; then
  echo "$output"
  exit 1
fi

# Check that minimum_aws_policy.json is in-sync with docs
output=$(python3 -c "
import sys
policy=open('./dev/minimum_aws_policy.json').read()
doc=open('./docs/clusters/management/auth.md').read()
print(policy in doc)")
if [[ "$output" != "True" ]]; then
  echo "./dev/minimum_aws_policy.json and the policy in ./docs/clusters/management/auth.md are out of sync"
  exit 1
fi

# Check docs links
output=$(python3 $ROOT/dev/find_missing_docs_links.py)
if [[ $output ]]; then
  echo "docs file(s) have broken links:"
  echo "$output"
  exit 1
fi


================================================
FILE: build/push-image.sh
================================================
#!/bin/bash

# Copyright 2022 Cortex Labs, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


set -euo pipefail

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")"/.. >/dev/null && pwd)"

CORTEX_VERSION=master

host_primary=$1
host_backup=$2
image=$3
is_multi_arch=$4
arch=$5

echo "$DOCKER_PASSWORD" | docker login -u "$DOCKER_USERNAME" --password-stdin
if [ "$is_multi_arch" = "true" ]; then
  tag="manifest-${CORTEX_VERSION}-$arch"
else
  tag="${CORTEX_VERSION}"
fi

docker push $host_primary/cortexlabs/${image}:${tag}
docker push $host_backup/cortexlabs/${image}:${tag}


================================================
FILE: build/push-images.sh
================================================
#!/bin/bash

# Copyright 2022 Cortex Labs, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


set -euo pipefail

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")"/.. >/dev/null && pwd)"

source $ROOT/build/images.sh
source $ROOT/dev/util.sh

arch=$1
host_primary=$2
host_backup=$3

for image in "${all_images[@]}"; do
  is_multi_arch="false"
  if [[ " ${multi_arch_images[*]} " =~ " $image " ]]; then
    is_multi_arch="true"
    $ROOT/build/push-image.sh $host_primary $host_backup $image $is_multi_arch $arch
  elif [ "$arch" = "amd64" ]; then
    $ROOT/build/push-image.sh $host_primary $host_backup $image $is_multi_arch $arch
  fi
done


================================================
FILE: build/test.sh
================================================
#!/bin/bash

# Copyright 2022 Cortex Labs, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.


set -euo pipefail

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")"/.. >/dev/null && pwd)"
ENVTEST_ASSETS_DIR=${ROOT}/testbin

cluster_env="undefined"
create_cluster="no"
positional_args=()
while [[ $# -gt 0 ]]; do
  key="$1"
  case $key in
    -e|--cluster-env)
    cluster_env="$2"
    shift
    ;;
    -c|--create-cluster)
    create_cluster="yes"
    shift
    ;;
    *)
    positional_args+=("$1")
    shift
    ;;
  esac
done
set -- "${positional_args[@]}"
positional_args=()
for i in "$@"; do
  case $i in
    -e=*|--cluster-env=*)
    cluster_env="${i#*=}"
    shift
    ;;
    -c|--create-cluster)
    create_cluster="yes"
    shift
    ;;
    *)
    positional_args+=("$1")
    shift
    ;;
  esac
done
set -- "${positional_args[@]}"
for arg in "$@"; do
  if [[ "$arg" == -* ]]; then
    echo "unknown flag: $arg"
    exit 1
  fi
done

cmd=${1:-""}
sub_cmd=${2:-""}

function run_go_tests() {
  (
    cd $ROOT
    mkdir -p ${ENVTEST_ASSETS_DIR}
	  test -f ${ENVTEST_ASSETS_DIR}/setup-envtest.sh || curl -sSLo ${ENVTEST_ASSETS_DIR}/setup-envtest.sh https://raw.githubusercontent.com/kubernetes-sigs/controller-runtime/v0.7.2/hack/setup-envtest.sh
	  source ${ENVTEST_ASSETS_DIR}/setup-envtest.sh; fetch_envtest_tools ${ENVTEST_ASSETS_DIR}; setup_envtest_env ${ENVTEST_ASSETS_DIR}
    go test -race ./... && echo "go tests passed"
  )
}

function run_e2e_tests() {
  if [ "$create_cluster" = "yes" ]; then
    pytest $ROOT/test/e2e/tests --config "$sub_cmd"
  else
    pytest $ROOT/test/e2e/tests --env "$cluster_env"
  fi
}

if [ "$cmd" = "go" ]; then
  run_go_tests
elif [ "$cmd" = "e2e" ]; then
  run_e2e_tests
fi


================================================
FILE: cli/cluster/delete.go
================================================
/*
Copyright 2022 Cortex Labs, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package cluster

import (
	"fmt"
	"path"

	"github.com/cortexlabs/cortex/pkg/lib/errors"
	"github.com/cortexlabs/cortex/pkg/lib/json"
	"github.com/cortexlabs/cortex/pkg/lib/pointer"
	"github.com/cortexlabs/cortex/pkg/lib/prompt"
	s "github.com/cortexlabs/cortex/pkg/lib/strings"
	"github.com/cortexlabs/cortex/pkg/operator/schema"
	"github.com/cortexlabs/cortex/pkg/types/userconfig"
)

func Delete(operatorConfig OperatorConfig, apiName string, keepCache bool, force bool) (schema.DeleteResponse, error) {
	if !force {
		readyReplicas := getReadyRealtimeAPIReplicasOrNil(operatorConfig, apiName)
		if readyReplicas != nil && *readyReplicas > 2 {
			prompt.YesOrExit(fmt.Sprintf("are you sure you want to delete %s (which has %d live replicas)?", apiName, *readyReplicas), "", "")
		}
	}

	params := map[string]string{
		"apiName":   apiName,
		"keepCache": s.Bool(keepCache),
	}

	httpRes, err := HTTPDelete(operatorConfig, "/delete/"+apiName, params)
	if err != nil {
		return schema.DeleteResponse{}, err
	}

	var deleteRes schema.DeleteResponse
	err = json.Unmarshal(httpRes, &deleteRes)
	if err != nil {
		return schema.DeleteResponse{}, errors.Wrap(err, "/delete", string(httpRes))
	}

	return deleteRes, nil
}

func getReadyRealtimeAPIReplicasOrNil(operatorConfig OperatorConfig, apiName string) *int32 {
	httpRes, err := HTTPGet(operatorConfig, "/get/"+apiName)
	if err != nil {
		return nil
	}

	var apiRes schema.APIResponse
	if err = json.Unmarshal(httpRes, &apiRes); err != nil {
		return nil
	}

	if apiRes.Status == nil {
		return nil
	}

	return pointer.Int32(apiRes.Status.Ready)
}

func StopJob(operatorConfig OperatorConfig, kind userconfig.Kind, apiName string, jobID string) (schema.DeleteResponse, error) {
	params := map[string]string{
		"apiName": apiName,
		"jobID":   jobID,
	}

	var endpointComponent string
	if kind == userconfig.BatchAPIKind {
		endpointComponent = "batch"
	} else {
		endpointComponent = "tasks"
	}

	httpRes, err := HTTPDelete(operatorConfig, path.Join("/"+endpointComponent, apiName), params)
	if err != nil {
		return schema.DeleteResponse{}, err
	}

	var deleteRes schema.DeleteResponse
	err = json.Unmarshal(httpRes, &deleteRes)
	if err != nil {
		return schema.DeleteResponse{}, errors.Wrap(err, string(httpRes))
	}

	return deleteRes, nil
}


================================================
FILE: cli/cluster/deploy.go
================================================
/*
Copyright 2022 Cortex Labs, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package cluster

import (
	"path/filepath"

	"github.com/cortexlabs/cortex/pkg/lib/errors"
	"github.com/cortexlabs/cortex/pkg/lib/json"
	s "github.com/cortexlabs/cortex/pkg/lib/strings"
	"github.com/cortexlabs/cortex/pkg/operator/schema"
)

func Deploy(operatorConfig OperatorConfig, configPath string, deploymentBytesMap map[string][]byte, force bool) ([]schema.DeployResult, error) {
	params := map[string]string{
		"force":          s.Bool(force),
		"configFileName": filepath.Base(configPath),
	}
	uploadInput := &HTTPUploadInput{
		Bytes: deploymentBytesMap,
	}

	response, err := HTTPUpload(operatorConfig, "/deploy", uploadInput, params)
	if err != nil {
		return nil, err
	}

	var deployResults []schema.DeployResult
	if err := json.Unmarshal(response, &deployResults); err != nil {
		return nil, errors.Wrap(err, "/deploy", string(response))
	}

	return deployResults, nil
}


================================================
FILE: cli/cluster/errors.go
================================================
/*
Copyright 2022 Cortex Labs, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package cluster

import (
	"fmt"
	"net/url"
	"strings"

	"github.com/cortexlabs/cortex/pkg/consts"
	"github.com/cortexlabs/cortex/pkg/lib/errors"
	"github.com/cortexlabs/cortex/pkg/lib/urls"
)

const (
	_errStrCantMakeRequest = "unable to make request"
	_errStrRead            = "unable to read"
)

func errStrFailedToConnect(u url.URL) string {
	return "failed to connect to " + urls.TrimQueryParamsURL(u)
}

const (
	ErrFailedToConnectOperator       = "cli.failed_to_connect_operator"
	ErrOperatorSocketRead            = "cli.operator_socket_read"
	ErrResponseUnknown               = "cli.response_unknown"
	ErrOperatorResponseUnknown       = "cli.operator_response_unknown"
	ErrOperatorStreamResponseUnknown = "cli.operator_stream_response_unknown"
)

func ErrorFailedToConnectOperator(originalError error, envName string, operatorURL string) error {
	msg := ""
	if originalError != nil {
		msg += urls.TrimQueryParamsStr(errors.Message(originalError)) + "\n\n"
	}

	if envName == "" {
		msg += fmt.Sprintf("unable to connect to your cluster (operator endpoint: %s)\n\n", operatorURL)
		msg += "if you don't have a cluster running:\n"
		msg += "    → to create a cluster, run `cortex cluster up`\n"
		msg += "\nif you have a cluster running:\n"
		msg += "    → run `cortex cluster info --configure-env ENV_NAME` to update your environment (replace ENV_NAME with your desired environment name, and include `--config <cluster.yaml>` if you have a cluster configuration file)\n"
	} else {
		msg += fmt.Sprintf("unable to connect to your cluster in the %s environment (operator endpoint: %s)\n\n", envName, operatorURL)
		msg += "if you don't have a cluster running:\n"
		msg += fmt.Sprintf("    → if you'd like to create a cluster, run `cortex cluster up --configure-env %s`\n", envName)
		msg += fmt.Sprintf("    → otherwise you can ignore this message, and prevent it in the future with `cortex env delete %s`\n", envName)
		msg += "\nif you have a cluster running:\n"
		msg += fmt.Sprintf("    → run `cortex cluster info --configure-env %s` to update your environment (include `--config <cluster.yaml>` if you have a cluster configuration file)\n", envName)
		msg += fmt.Sprintf("    → if you set `operator_load_balancer_scheme: internal` in your cluster configuration file, your CLI must run from within a VPC that has access to your cluster's VPC (see https://docs.cortexlabs.com/v/%s/)\n", consts.CortexVersionMinor)
		msg += fmt.Sprintf("    → confirm that the ip address of this machine falls within the CIDR ranges specified in `operator_load_balancer_cidr_whitelist`")
	}

	return errors.WithStack(&errors.Error{
		Kind:    ErrFailedToConnectOperator,
		Message: msg,
	})
}

func ErrorOperatorSocketRead(err error) error {
	return errors.WithStack(&errors.Error{
		Kind:    ErrOperatorSocketRead,
		Message: err.Error(),
		NoPrint: true,
	})
}

func ErrorResponseUnknown(body string, statusCode int) error {
	msg := body
	if strings.TrimSpace(body) == "" {
		msg = fmt.Sprintf("empty response (status code %d)", statusCode)
	}

	return errors.WithStack(&errors.Error{
		Kind:    ErrResponseUnknown,
		Message: msg,
	})
}

func ErrorOperatorResponseUnknown(body string, statusCode int) error {
	return errors.WithStack(&errors.Error{
		Kind:    ErrOperatorResponseUnknown,
		Message: fmt.Sprintf("unexpected response from operator (status code %d): %s", statusCode, body),
	})
}

func ErrorOperatorStreamResponseUnknown(body string, statusCode int) error {
	return errors.WithStack(&errors.Error{
		Kind:    ErrOperatorStreamResponseUnknown,
		Message: fmt.Sprintf("unexpected response from operator (status code %d): %s", statusCode, body),
	})
}


================================================
FILE: cli/cluster/get.go
================================================
/*
Copyright 2022 Cortex Labs, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package cluster

import (
	"path"

	"github.com/cortexlabs/cortex/pkg/lib/errors"
	"github.com/cortexlabs/cortex/pkg/lib/json"
	"github.com/cortexlabs/cortex/pkg/operator/schema"
)

func GetAPIs(operatorConfig OperatorConfig) ([]schema.APIResponse, error) {
	httpRes, err := HTTPGet(operatorConfig, "/get")
	if err != nil {
		return nil, err
	}

	var apisRes []schema.APIResponse
	if err = json.Unmarshal(httpRes, &apisRes); err != nil {
		return nil, errors.Wrap(err, "/get", string(httpRes))
	}
	return apisRes, nil
}

func GetAPI(operatorConfig OperatorConfig, apiName string) ([]schema.APIResponse, error) {
	httpRes, err := HTTPGet(operatorConfig, "/get/"+apiName)
	if err != nil {
		return nil, err
	}

	var apiRes []schema.APIResponse
	if err = json.Unmarshal(httpRes, &apiRes); err != nil {
		return nil, errors.Wrap(err, "/get/"+apiName, string(httpRes))
	}

	return apiRes, nil
}

func DescribeAPI(operatorConfig OperatorConfig, apiName string) ([]schema.APIResponse, error) {
	httpRes, err := HTTPGet(operatorConfig, "/describe/"+apiName)
	if err != nil {
		return nil, err
	}

	var apiRes []schema.APIResponse
	if err = json.Unmarshal(httpRes, &apiRes); err != nil {
		return nil, errors.Wrap(err, "/describe/"+apiName, string(httpRes))
	}

	return apiRes, nil
}

func GetAPIByID(operatorConfig OperatorConfig, apiName string, apiID string) ([]schema.APIResponse, error) {
	httpRes, err := HTTPGet(operatorConfig, "/get/"+apiName+"/"+apiID)
	if err != nil {
		return nil, err
	}

	var apiRes []schema.APIResponse
	if err = json.Unmarshal(httpRes, &apiRes); err != nil {
		return nil, errors.Wrap(err, "/get/"+apiName+"/"+apiID, string(httpRes))
	}

	return apiRes, nil
}

func GetBatchJob(operatorConfig OperatorConfig, apiName string, jobID string) (schema.BatchJobResponse, error) {
	endpoint := path.Join("/batch", apiName)
	httpRes, err := HTTPGet(operatorConfig, endpoint, map[string]string{"jobID": jobID})
	if err != nil {
		return schema.BatchJobResponse{}, err
	}

	var jobRes schema.BatchJobResponse
	if err = json.Unmarshal(httpRes, &jobRes); err != nil {
		return schema.BatchJobResponse{}, errors.Wrap(err, endpoint, string(httpRes))
	}

	return jobRes, nil
}

func GetTaskJob(operatorConfig OperatorConfig, apiName string, jobID string) (schema.TaskJobResponse, error) {
	endpoint := path.Join("/tasks", apiName)
	httpRes, err := HTTPGet(operatorConfig, endpoint, map[string]string{"jobID": jobID})
	if err != nil {
		return schema.TaskJobResponse{}, err
	}

	var jobRes schema.TaskJobResponse
	if err = json.Unmarshal(httpRes, &jobRes); err != nil {
		return schema.TaskJobResponse{}, errors.Wrap(err, endpoint, string(httpRes))
	}

	return jobRes, nil
}


================================================
FILE: cli/cluster/info.go
================================================
/*
Copyright 2022 Cortex Labs, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package cluster

import (
	"github.com/cortexlabs/cortex/pkg/lib/errors"
	"github.com/cortexlabs/cortex/pkg/lib/json"
	"github.com/cortexlabs/cortex/pkg/operator/schema"
)

func Info(operatorConfig OperatorConfig) (*schema.InfoResponse, error) {
	httpResponse, err := HTTPGet(operatorConfig, "/info")
	if err != nil {
		return nil, errors.Wrap(err, "unable to connect to operator", "/info")
	}

	var infoResponse schema.InfoResponse
	err = json.Unmarshal(httpResponse, &infoResponse)
	if err != nil {
		return nil, errors.Wrap(err, "/info", string(httpResponse))
	}

	return &infoResponse, nil
}


================================================
FILE: cli/cluster/lib_http_client.go
================================================
/*
Copyright 2022 Cortex Labs, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package cluster

import (
	"bytes"
	"crypto/tls"
	"io"
	"io/ioutil"
	"mime/multipart"
	"net/http"
	"time"

	"github.com/cortexlabs/cortex/pkg/consts"
	"github.com/cortexlabs/cortex/pkg/lib/archive"
	"github.com/cortexlabs/cortex/pkg/lib/aws"
	"github.com/cortexlabs/cortex/pkg/lib/errors"
	"github.com/cortexlabs/cortex/pkg/lib/files"
	"github.com/cortexlabs/cortex/pkg/lib/json"
	"github.com/cortexlabs/cortex/pkg/operator/schema"
)

type OperatorClient struct {
	*http.Client
}

type OperatorConfig struct {
	Telemetry        bool
	ClientID         string
	EnvName          string
	OperatorEndpoint string
}

func HTTPGet(operatorConfig OperatorConfig, endpoint string, qParams ...map[string]string) ([]byte, error) {
	req, err := operatorRequest(operatorConfig, "GET", endpoint, nil, qParams...)
	if err != nil {
		return nil, err
	}
	return makeOperatorRequest(operatorConfig, req)
}

func HTTPPostObjAsJSON(operatorConfig OperatorConfig, endpoint string, requestData interface{}, qParams ...map[string]string) ([]byte, error) {
	jsonRequestData, err := json.Marshal(requestData)
	if err != nil {
		return nil, err
	}
	return HTTPPostJSON(operatorConfig, endpoint, jsonRequestData, qParams...)
}

func HTTPPostJSON(operatorConfig OperatorConfig, endpoint string, jsonRequestData []byte, qParams ...map[string]string) ([]byte, error) {
	payload := bytes.NewBuffer(jsonRequestData)
	req, err := operatorRequest(operatorConfig, http.MethodPost, endpoint, payload, qParams...)
	if err != nil {
		return nil, err
	}
	req.Header.Set("Content-Type", "application/json")
	return makeOperatorRequest(operatorConfig, req)
}

func HTTPPostNoBody(operatorConfig OperatorConfig, endpoint string, qParams ...map[string]string) ([]byte, error) {
	req, err := operatorRequest(operatorConfig, http.MethodPost, endpoint, nil, qParams...)
	if err != nil {
		return nil, err
	}
	return makeOperatorRequest(operatorConfig, req)
}

func HTTPDelete(operatorConfig OperatorConfig, endpoint string, qParams ...map[string]string) ([]byte, error) {
	req, err := operatorRequest(operatorConfig, http.MethodDelete, endpoint, nil, qParams...)
	if err != nil {
		return nil, err
	}
	return makeOperatorRequest(operatorConfig, req)
}

type HTTPUploadInput struct {
	FilePaths map[string]string
	Bytes     map[string][]byte
}

func HTTPUpload(operatorConfig OperatorConfig, endpoint string, input *HTTPUploadInput, qParams ...map[string]string) ([]byte, error) {
	body := new(bytes.Buffer)
	writer := multipart.NewWriter(body)

	for fileName, filePath := range input.FilePaths {
		file, err := files.Open(filePath)
		if err != nil {
			return nil, err
		}

		defer file.Close()
		if err := addFileToMultipart(fileName, writer, file); err != nil {
			return nil, err
		}
	}

	for fileName, fileBytes := range input.Bytes {
		if err := addFileToMultipart(fileName, writer, bytes.NewReader(fileBytes)); err != nil {
			return nil, err
		}
	}

	if err := writer.Close(); err != nil {
		return nil, errors.Wrap(err, _errStrCantMakeRequest)
	}

	req, err := operatorRequest(operatorConfig, http.MethodPost, endpoint, body, qParams...)
	if err != nil {
		return nil, err
	}

	req.Header.Set("Content-Type", writer.FormDataContentType())
	return makeOperatorRequest(operatorConfig, req)
}

func addFileToMultipart(fileName string, writer *multipart.Writer, reader io.Reader) error {
	part, err := writer.CreateFormFile(fileName, fileName)
	if err != nil {
		return errors.Wrap(err, _errStrCantMakeRequest)
	}

	if _, err = io.Copy(part, reader); err != nil {
		return errors.Wrap(err, _errStrCantMakeRequest)
	}
	return nil
}

func HTTPUploadZip(operatorConfig OperatorConfig, endpoint string, zipInput *archive.Input, fileName string, qParams ...map[string]string) ([]byte, error) {
	zipBytes, _, err := archive.ZipToMem(zipInput)
	if err != nil {
		return nil, errors.Wrap(err, "failed to zip configuration file")
	}

	uploadInput := &HTTPUploadInput{
		Bytes: map[string][]byte{
			fileName: zipBytes,
		},
	}
	return HTTPUpload(operatorConfig, endpoint, uploadInput, qParams...)
}

func operatorRequest(operatorConfig OperatorConfig, method string, endpoint string, body io.Reader, qParams ...map[string]string) (*http.Request, error) {
	req, err := http.NewRequest(method, operatorConfig.OperatorEndpoint+endpoint, body)
	if err != nil {
		return nil, errors.Wrap(err, _errStrCantMakeRequest)
	}

	values := req.URL.Query()
	for _, paramMap := range qParams {
		for key, value := range paramMap {
			values.Set(key, value)
		}
	}
	req.URL.RawQuery = values.Encode()

	return req, nil
}

func makeOperatorRequest(operatorConfig OperatorConfig, request *http.Request) ([]byte, error) {
	if operatorConfig.Telemetry {
		values := request.URL.Query()
		values.Set("clientID", operatorConfig.ClientID)
		request.URL.RawQuery = values.Encode()
	}

	request.Header.Set("CortexAPIVersion", consts.CortexVersion)
	awsClient, err := aws.New()
	if err != nil {
		return nil, err
	}

	authHeader, err := awsClient.IdentityRequestAsHeader()
	if err != nil {
		return nil, err
	}
	request.Header.Set(consts.AuthHeader, authHeader)

	timeout := 600 * time.Second
	if request.URL.Path == "/info" {
		timeout = 10 * time.Second
	}

	client := &http.Client{
		Timeout: timeout,
		Transport: &http.Transport{
			TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
		},
	}

	response, err := client.Do(request)
	if err != nil {
		return nil, ErrorFailedToConnectOperator(err, operatorConfig.EnvName, operatorConfig.OperatorEndpoint)
	}
	defer response.Body.Close()

	if response.StatusCode != 200 {
		bodyBytes, err := ioutil.ReadAll(response.Body)
		if err != nil {
			return nil, errors.Wrap(err, _errStrRead)
		}

		var output schema.ErrorResponse
		err = json.Unmarshal(bodyBytes, &output)
		if err != nil || output.Message == "" {
			return nil, ErrorOperatorResponseUnknown(string(bodyBytes), response.StatusCode)
		}

		return nil, errors.WithStack(&errors.Error{
			Kind:        output.Kind,
			Message:     output.Message,
			NoTelemetry: true,
		})
	}

	bodyBytes, err := ioutil.ReadAll(response.Body)
	if err != nil {
		return nil, errors.Wrap(err, _errStrRead)
	}
	return bodyBytes, nil
}


================================================
FILE: cli/cluster/logs.go
================================================
/*
Copyright 2022 Cortex Labs, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package cluster

import (
	"crypto/tls"
	"fmt"
	"io/ioutil"
	"net/http"
	"os"
	"os/signal"
	"strings"

	"github.com/cortexlabs/cortex/cli/lib/routines"
	"github.com/cortexlabs/cortex/pkg/consts"
	"github.com/cortexlabs/cortex/pkg/lib/aws"
	"github.com/cortexlabs/cortex/pkg/lib/errors"
	"github.com/cortexlabs/cortex/pkg/lib/exit"
	"github.com/cortexlabs/cortex/pkg/lib/json"
	"github.com/cortexlabs/cortex/pkg/operator/schema"
	"github.com/gorilla/websocket"
)

func GetLogs(operatorConfig OperatorConfig, apiName string) (schema.LogResponse, error) {
	httpRes, err := HTTPGet(operatorConfig, "/logs/"+apiName)
	if err != nil {
		return schema.LogResponse{}, err
	}

	var logResponse schema.LogResponse
	if err = json.Unmarshal(httpRes, &logResponse); err != nil {
		return schema.LogResponse{}, errors.Wrap(err, "/logs/"+apiName, string(httpRes))
	}

	return logResponse, nil
}

func GetJobLogs(operatorConfig OperatorConfig, apiName string, jobID string) (schema.LogResponse, error) {
	httpRes, err := HTTPGet(operatorConfig, "/logs/"+apiName, map[string]string{"jobID": jobID})
	if err != nil {
		return schema.LogResponse{}, err
	}

	var logResponse schema.LogResponse
	if err = json.Unmarshal(httpRes, &logResponse); err != nil {
		return schema.LogResponse{}, errors.Wrap(err, "/logs/"+apiName, string(httpRes))
	}

	return logResponse, nil
}

func StreamLogs(operatorConfig OperatorConfig, apiName string) error {
	return streamLogs(operatorConfig, "/streamlogs/"+apiName)
}

func StreamJobLogs(operatorConfig OperatorConfig, apiName string, jobID string) error {
	return streamLogs(operatorConfig, "/streamlogs/"+apiName, map[string]string{"jobID": jobID})
}

func streamLogs(operatorConfig OperatorConfig, path string, qParams ...map[string]string) error {
	interrupt := make(chan os.Signal, 1)
	signal.Notify(interrupt, os.Interrupt)

	req, err := operatorRequest(operatorConfig, "GET", path, nil, qParams...)
	if err != nil {
		return err
	}

	values := req.URL.Query()
	if operatorConfig.Telemetry {
		values.Set("clientID", operatorConfig.ClientID)
	}

	req.URL.RawQuery = values.Encode()
	wsURL := req.URL.String()
	wsURL = strings.Replace(wsURL, "http", "ws", 1)

	header := http.Header{}
	header.Set("CortexAPIVersion", consts.CortexVersion)
	awsClient, err := aws.New()
	if err != nil {
		return err
	}

	authHeader, err := awsClient.IdentityRequestAsHeader()
	if err != nil {
		return err
	}
	header.Set(consts.AuthHeader, authHeader)

	var dialer = websocket.Dialer{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}

	connection, response, err := dialer.Dial(wsURL, header)
	if err != nil && response == nil {
		return ErrorFailedToConnectOperator(err, operatorConfig.EnvName, strings.Replace(operatorConfig.OperatorEndpoint, "http", "ws", 1))
	}
	defer response.Body.Close()

	if err != nil {
		bodyBytes, err := ioutil.ReadAll(response.Body)
		if err != nil || bodyBytes == nil || string(bodyBytes) == "" {
			return ErrorFailedToConnectOperator(err, operatorConfig.EnvName, strings.Replace(operatorConfig.OperatorEndpoint, "http", "ws", 1))
		}
		var output schema.ErrorResponse
		err = json.Unmarshal(bodyBytes, &output)
		if err != nil || output.Message == "" {
			return ErrorOperatorStreamResponseUnknown(string(bodyBytes), response.StatusCode)
		}
		return errors.WithStack(&errors.Error{
			Kind:        output.Kind,
			Message:     output.Message,
			NoTelemetry: true,
		})
	}
	defer connection.Close()

	done := make(chan struct{})
	handleConnection(connection, done)
	closeConnection(connection, done, interrupt)
	return nil
}

func handleConnection(connection *websocket.Conn, done chan struct{}) {
	routines.RunWithPanicHandler(func() {
		defer close(done)
		for {
			_, message, err := connection.ReadMessage()
			if err != nil {
				exit.Error(ErrorOperatorSocketRead(err))
			}
			fmt.Print(string(message))
		}
	}, false)
}

func closeConnection(connection *websocket.Conn, done chan struct{}, interrupt chan os.Signal) {
	for {
		select {
		case <-done:
			return
		case <-interrupt:
			connection.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
			return
		}
	}
}


================================================
FILE: cli/cluster/refresh.go
================================================
/*
Copyright 2022 Cortex Labs, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package cluster

import (
	"github.com/cortexlabs/cortex/pkg/lib/errors"
	"github.com/cortexlabs/cortex/pkg/lib/json"
	s "github.com/cortexlabs/cortex/pkg/lib/strings"
	"github.com/cortexlabs/cortex/pkg/operator/schema"
)

func Refresh(operatorConfig OperatorConfig, apiName string, force bool) (schema.RefreshResponse, error) {
	params := map[string]string{
		"force": s.Bool(force),
	}

	httpRes, err := HTTPPostNoBody(operatorConfig, "/refresh/"+apiName, params)
	if err != nil {
		return schema.RefreshResponse{}, err
	}

	var refreshRes schema.RefreshResponse
	err = json.Unmarshal(httpRes, &refreshRes)
	if err != nil {
		return schema.RefreshResponse{}, errors.Wrap(err, "/refresh", string(httpRes))
	}

	return refreshRes, nil
}


================================================
FILE: cli/cmd/cluster.go
================================================
/*
Copyright 2022 Cortex Labs, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package cmd

import (
	"encoding/base64"
	"fmt"
	"os"
	"path/filepath"
	"regexp"
	"strings"
	"time"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/service/autoscaling"
	"github.com/aws/aws-sdk-go/service/ec2"
	"github.com/aws/aws-sdk-go/service/eks"
	"github.com/aws/aws-sdk-go/service/elb"
	"github.com/aws/aws-sdk-go/service/elbv2"
	"github.com/aws/aws-sdk-go/service/s3"
	"github.com/cortexlabs/cortex/cli/cluster"
	"github.com/cortexlabs/cortex/cli/types/cliconfig"
	"github.com/cortexlabs/cortex/cli/types/flags"
	"github.com/cortexlabs/cortex/pkg/consts"
	"github.com/cortexlabs/cortex/pkg/health"
	awslib "github.com/cortexlabs/cortex/pkg/lib/aws"
	"github.com/cortexlabs/cortex/pkg/lib/console"
	"github.com/cortexlabs/cortex/pkg/lib/docker"
	"github.com/cortexlabs/cortex/pkg/lib/errors"
	"github.com/cortexlabs/cortex/pkg/lib/exit"
	"github.com/cortexlabs/cortex/pkg/lib/files"
	libjson "github.com/cortexlabs/cortex/pkg/lib/json"
	"github.com/cortexlabs/cortex/pkg/lib/k8s"
	libmath "github.com/cortexlabs/cortex/pkg/lib/math"
	"github.com/cortexlabs/cortex/pkg/lib/pointer"
	"github.com/cortexlabs/cortex/pkg/lib/prompt"
	s "github.com/cortexlabs/cortex/pkg/lib/strings"
	"github.com/cortexlabs/cortex/pkg/lib/table"
	"github.com/cortexlabs/cortex/pkg/lib/telemetry"
	libtime "github.com/cortexlabs/cortex/pkg/lib/time"
	"github.com/cortexlabs/cortex/pkg/operator/schema"
	"github.com/cortexlabs/cortex/pkg/types/clusterconfig"
	"github.com/cortexlabs/cortex/pkg/types/clusterstate"
	"github.com/cortexlabs/yaml"
	"github.com/spf13/cobra"
	"k8s.io/apimachinery/pkg/runtime"
	clientgoscheme "k8s.io/client-go/kubernetes/scheme"
	"k8s.io/client-go/rest"
	"sigs.k8s.io/aws-iam-authenticator/pkg/token"
)

var (
	_flagClusterUpEnv                string
	_flagClusterInfoEnv              string
	_flagClusterConfig               string
	_flagClusterName                 string
	_flagClusterRegion               string
	_flagClusterInfoDebug            bool
	_flagClusterInfoPrintConfig      bool
	_flagClusterDisallowPrompt       bool
	_flagClusterDownKeepAWSResources bool
)

var _eksctlPrefixRegex = regexp.MustCompile(`^.*[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2} \[.+] {2}`)

func clusterInit() {
	_clusterUpCmd.Flags().SortFlags = false
	_clusterUpCmd.Flags().StringVarP(&_flagClusterUpEnv, "configure-env", "e", "", "name of environment to configure (default: the name of your cluster)")
	_clusterUpCmd.Flags().BoolVarP(&_flagClusterDisallowPrompt, "yes", "y", false, "skip prompts")
	_clusterCmd.AddCommand(_clusterUpCmd)

	_clusterInfoCmd.Flags().SortFlags = false
	addClusterConfigFlag(_clusterInfoCmd)
	addClusterNameFlag(_clusterInfoCmd)
	addClusterRegionFlag(_clusterInfoCmd)
	_clusterInfoCmd.Flags().VarP(&_flagOutput, "output", "o", fmt.Sprintf("output format: one of %s", strings.Join(flags.OutputTypeStrings(), "|")))
	_clusterInfoCmd.Flags().StringVarP(&_flagClusterInfoEnv, "configure-env", "e", "", "name of environment to configure")
	_clusterInfoCmd.Flags().BoolVarP(&_flagClusterInfoDebug, "debug", "d", false, "save the current cluster state to a file")
	_clusterInfoCmd.Flags().BoolVarP(&_flagClusterInfoPrintConfig, "print-config", "", false, "print the cluster config")
	_clusterInfoCmd.Flags().BoolVarP(&_flagClusterDisallowPrompt, "yes", "y", false, "skip prompts")
	_clusterCmd.AddCommand(_clusterInfoCmd)

	_clusterConfigureCmd.Flags().SortFlags = false
	_clusterConfigureCmd.Flags().BoolVarP(&_flagClusterDisallowPrompt, "yes", "y", false, "skip prompts")
	_clusterCmd.AddCommand(_clusterConfigureCmd)

	_clusterDownCmd.Flags().SortFlags = false
	addClusterConfigFlag(_clusterDownCmd)
	addClusterNameFlag(_clusterDownCmd)
	addClusterRegionFlag(_clusterDownCmd)
	_clusterDownCmd.Flags().BoolVarP(&_flagClusterDisallowPrompt, "yes", "y", false, "skip prompts")
	_clusterDownCmd.Flags().BoolVar(&_flagClusterDownKeepAWSResources, "keep-aws-resources", false, "skip deletion of resources that cortex provisioned on aws (bucket contents, ebs volumes, log group)")
	_clusterCmd.AddCommand(_clusterDownCmd)

	_clusterExportCmd.Flags().SortFlags = false
	addClusterConfigFlag(_clusterExportCmd)
	addClusterNameFlag(_clusterExportCmd)
	addClusterRegionFlag(_clusterExportCmd)
	_clusterCmd.AddCommand(_clusterExportCmd)

	_clusterHealthCmd.Flags().SortFlags = false
	addClusterConfigFlag(_clusterHealthCmd)
	addClusterNameFlag(_clusterHealthCmd)
	addClusterRegionFlag(_clusterHealthCmd)
	_clusterHealthCmd.Flags().VarP(&_flagOutput, "output", "o", fmt.Sprintf("output format: one of %s", strings.Join(flags.OutputTypeStringsExcluding(flags.YAMLOutputType), "|")))
	_clusterCmd.AddCommand(_clusterHealthCmd)
}

func addClusterConfigFlag(cmd *cobra.Command) {
	cmd.Flags().StringVarP(&_flagClusterConfig, "config", "c", "", "path to a cluster configuration file")
	err := cmd.Flags().SetAnnotation("config", cobra.BashCompFilenameExt, _configFileExts)
	if err != nil {
		exit.Error(err) // should never happen
	}
}

func addClusterNameFlag(cmd *cobra.Command) {
	cmd.Flags().StringVarP(&_flagClusterName, "name", "n", "", "name of the cluster")
}

func addClusterRegionFlag(cmd *cobra.Command) {
	cmd.Flags().StringVarP(&_flagClusterRegion, "region", "r", "", "aws region of the cluster")
}

var _clusterCmd = &cobra.Command{
	Use:   "cluster",
	Short: "manage cortex clusters (contains subcommands)",
}

var _clusterUpCmd = &cobra.Command{
	Use:   "up CLUSTER_CONFIG_FILE",
	Short: "spin up a cluster on aws",
	Args:  cobra.ExactArgs(1),
	Run: func(cmd *cobra.Command, args []string) {
		telemetry.EventNotify("cli.cluster.up")

		clusterConfigFile := args[0]

		if _, err := docker.GetDockerClient(); err != nil {
			exit.Error(err)
		}

		accessConfig, err := getNewClusterAccessConfig(clusterConfigFile)
		if err != nil {
			exit.Error(err)
		}

		envName := _flagClusterUpEnv
		if envName == "" {
			envName = accessConfig.ClusterName
		}

		envExists, err := isEnvConfigured(envName)
		if err != nil {
			exit.Error(err)
		}
		if envExists {
			if _flagClusterDisallowPrompt {
				fmt.Printf("found an existing environment named \"%s\", which will be overwritten to connect to this cluster once it's created\n\n", envName)
			} else {
				prompt.YesOrExit(fmt.Sprintf("found an existing environment named \"%s\"; would you like to overwrite it to connect to this cluster once it's created?", envName), "", "you can specify a different environment name to be configured to connect to this cluster by specifying the --configure-env flag (e.g. `cortex cluster up --configure-env prod`); or you can list your environments with `cortex env list` and delete an environment with `cortex env delete ENV_NAME`")
			}
		}

		awsClient, err := newAWSClient(accessConfig.Region, true)
		if err != nil {
			exit.Error(err)
		}

		stacks, err := clusterstate.GetClusterStacks(awsClient, accessConfig)
		if err != nil {
			exit.Error(err)
		}

		state := clusterstate.GetClusterState(stacks)
		if err := clusterstate.AssertClusterState(stacks, state, clusterstate.StateClusterDoesntExist); err != nil {
			exit.Error(err)
		}

		promptIfNotAdmin(awsClient, _flagClusterDisallowPrompt)

		clusterConfig, err := getInstallClusterConfig(awsClient, clusterConfigFile)
		if err != nil {
			exit.Error(err)
		}

		confirmInstallClusterConfig(clusterConfig, awsClient, _flagClusterDisallowPrompt)

		err = createS3BucketIfNotFound(awsClient, clusterConfig.Bucket, clusterConfig.Tags)
		if err != nil {
			exit.Error(err)
		}

		err = setLifecycleRulesOnClusterUp(awsClient, clusterConfig.Bucket, clusterConfig.ClusterUID)
		if err != nil {
			exit.Error(err)
		}

		err = createLogGroupIfNotFound(awsClient, clusterConfig.ClusterName, clusterConfig.Tags)
		if err != nil {
			exit.Error(err)
		}

		accountID, _, err := awsClient.GetCachedAccountID()
		if err != nil {
			exit.Error(err)
		}

		err = clusterconfig.CreateDefaultPolicy(awsClient, clusterconfig.CortexPolicyTemplateArgs{
			ClusterName: clusterConfig.ClusterName,
			LogGroup:    clusterConfig.ClusterName,
			Bucket:      clusterConfig.Bucket,
			Region:      clusterConfig.Region,
			AccountID:   accountID,
		})
		if err != nil {
			exit.Error(err)
		}

		out, exitCode, err := runManagerWithClusterConfig("/root/install.sh", clusterConfig, awsClient, nil, nil, nil)
		if err != nil {
			exit.Error(err)
		}
		if exitCode == nil || *exitCode != 0 {
			out = s.LastNChars(filterEKSCTLOutput(out), 8192) // get the last 8192 characters because that is the sentry message limit
			eksCluster, err := awsClient.EKSClusterOrNil(clusterConfig.ClusterName)
			if err != nil {
				helpStr := "\ndebugging tips (may or may not apply to this error):"
				helpStr += fmt.Sprintf("\n* if your cluster started spinning up but was unable to provision instances, additional error information may be found in the activity history of your cluster's autoscaling groups (select each autoscaling group and click the \"Activity\" or \"Activity History\" tab): https://console.aws.amazon.com/ec2/autoscaling/home?region=%s#AutoScalingGroups:", clusterConfig.Region)
				helpStr += "\n* if your cluster started spinning up, please run `cortex cluster down` to delete the cluster before trying to create this cluster again"
				fmt.Println(helpStr)
				exit.Error(ErrorClusterUp(out))
			}

			// the cluster never started spinning up
			if eksCluster == nil {
				exit.Error(ErrorClusterUp(out))
			}

			clusterTags := map[string]string{clusterconfig.ClusterNameTag: clusterConfig.ClusterName}
			asgs, err := awsClient.AutoscalingGroups(clusterTags)
			if err != nil {
				helpStr := "\ndebugging tips (may or may not apply to this error):"
				helpStr += fmt.Sprintf("\n* if your cluster was unable to provision instances, additional error information may be found in the activity history of your cluster's autoscaling groups (select each autoscaling group and click the \"Activity\" or \"Activity History\" tab): https://console.aws.amazon.com/ec2/autoscaling/home?region=%s#AutoScalingGroups:", clusterConfig.Region)
				helpStr += "\n* please run `cortex cluster down` to delete the cluster before trying to create this cluster again"
				fmt.Println(helpStr)
				exit.Error(ErrorClusterUp(out + helpStr))
			}

			// no autoscaling groups were created
			if len(asgs) == 0 {
				helpStr := "\nplease run `cortex cluster down` to delete the cluster before trying to create this cluster again"
				fmt.Println(helpStr)
				exit.Error(ErrorClusterUp(out + helpStr))
			}

			for _, asg := range asgs {
				activity, err := awsClient.MostRecentASGActivity(*asg.AutoScalingGroupName)
				if err != nil {
					helpStr := "\ndebugging tips (may or may not apply to this error):"
					helpStr += fmt.Sprintf("\n* if your cluster was unable to provision instances, additional error information may be found in the activity history of your cluster's autoscaling groups (select each autoscaling group and click the \"Activity\" or \"Activity History\" tab): https://console.aws.amazon.com/ec2/autoscaling/home?region=%s#AutoScalingGroups:", clusterConfig.Region)
					helpStr += "\n* please run `cortex cluster down` to delete the cluster before trying to create this cluster again"
					fmt.Println(helpStr)
					exit.Error(ErrorClusterUp(out + helpStr))
				}

				if activity != nil && (activity.StatusCode == nil || *activity.StatusCode != autoscaling.ScalingActivityStatusCodeSuccessful) {
					status := "(none)"
					if activity.StatusCode != nil {
						status = *activity.StatusCode
					}
					description := "(none)"
					if activity.Description != nil {
						description = *activity.Description
					}

					helpStr := "\nyour cluster was unable to provision EC2 instances; here is one of the encountered errors:"
					helpStr += fmt.Sprintf("\n\n> status: %s\n> description: %s", status, description)
					helpStr += fmt.Sprintf("\n\nadditional error information might be found in the activity history of your cluster's autoscaling groups (select each autoscaling group and click the \"Activity\" or \"Activity History\" tab): https://console.aws.amazon.com/ec2/autoscaling/home?region=%s#AutoScalingGroups:", clusterConfig.Region)
					helpStr += "\n\nplease run `cortex cluster down` to delete the cluster before trying to create this cluster again"
					fmt.Println(helpStr)
					exit.Error(ErrorClusterUp(out + helpStr))
				}
			}

			// No failed asg activities
			helpStr := "\nplease run `cortex cluster down` to delete the cluster before trying to create this cluster again"
			fmt.Println(helpStr)
			exit.Error(ErrorClusterUp(out + helpStr))
		}

		loadBalancer, err := getNLBLoadBalancer(clusterConfig.ClusterName, OperatorLoadBalancer, awsClient)
		if err != nil {
			exit.Error(errors.Append(err, fmt.Sprintf("\n\nyou can attempt to resolve this issue and configure your cli environment by running `cortex cluster info --configure-env %s`", envName)))
		}

		newEnvironment := cliconfig.Environment{
			Name:             envName,
			OperatorEndpoint: "https://" + *loadBalancer.DNSName,
		}

		err = addEnvToCLIConfig(newEnvironment, true)
		if err != nil {
			exit.Error(errors.Append(err, fmt.Sprintf("\n\nyou can attempt to resolve this issue and configure your cli environment by running `cortex cluster info --configure-env %s`", envName)))
		}

		if envExists {
			fmt.Printf(console.Bold("\nthe environment named \"%s\" has been updated to point to this cluster (and was set as the default environment)\n"), envName)
		} else {
			fmt.Printf(console.Bold("\nan environment named \"%s\" has been configured to point to this cluster (and was set as the default environment)\n"), envName)
		}
	},
}

var _clusterConfigureCmd = &cobra.Command{
	Use:   "configure CLUSTER_CONFIG_FILE",
	Short: "update the cluster's configuration",
	Args:  cobra.ExactArgs(1),
	Run: func(cmd *cobra.Command, args []string) {
		telemetry.Event("cli.cluster.configure")

		clusterConfigFile := args[0]

		if _, err := docker.GetDockerClient(); err != nil {
			exit.Error(err)
		}

		accessConfig, err := getNewClusterAccessConfig(clusterConfigFile)
		if err != nil {
			exit.Error(err)
		}

		awsClient, err := newAWSClient(accessConfig.Region, true)
		if err != nil {
			exit.Error(err)
		}

		restConfig, err := getClusterRESTConfig(awsClient, accessConfig.ClusterName)
		if err != nil {
			exit.Error(err)
		}

		scheme := runtime.NewScheme()
		if err := clientgoscheme.AddToScheme(scheme); err != nil {
			exit.Error(err)
		}

		k8sClient, err := k8s.New(consts.DefaultNamespace, false, restConfig, scheme)
		if err != nil {
			exit.Error(err)
		}

		stacks, err := clusterstate.GetClusterStacks(awsClient, accessConfig)
		if err != nil {
			exit.Error(err)
		}

		state := clusterstate.GetClusterState(stacks)
		if err := clusterstate.AssertClusterState(stacks, state, clusterstate.StateClusterExists); err != nil {
			exit.Error(err)
		}

		oldClusterConfig := refreshCachedClusterConfig(awsClient, accessConfig, true)

		promptIfNotAdmin(awsClient, _flagClusterDisallowPrompt)

		newClusterConfig, configureChanges, err := getConfigureClusterConfig(awsClient, k8sClient, stacks, oldClusterConfig, clusterConfigFile)
		if err != nil {
			exit.Error(err)
		}

		if !configureChanges.HasChanges() {
			fmt.Println("your cluster is already up to date")
			exit.Ok()
		}

		confirmConfigureClusterConfig(configureChanges, oldClusterConfig, *newClusterConfig, _flagClusterDisallowPrompt)

		out, exitCode, err := runManagerWithClusterConfig("/root/install.sh --configure", newClusterConfig, awsClient, nil, nil, []string{
			"CORTEX_NODEGROUP_NAMES_TO_UPDATE=" + strings.Join(configureChanges.NodeGroupsToUpdate, " "),        // NodeGroupsToUpdate contain the cluster config node-group names
			"CORTEX_NODEGROUP_NAMES_TO_ADD=" + strings.Join(configureChanges.NodeGroupsToAdd, " "),              // NodeGroupsToAdd contain the cluster config node-group names
			"CORTEX_EKS_NODEGROUP_NAMES_TO_REMOVE=" + strings.Join(configureChanges.EKSNodeGroupsToRemove, " "), // EKSNodeGroupsToRemove contain the EKS node-group names
		})
		if err != nil {
			exit.Error(err)
		}
		if exitCode == nil || *exitCode != 0 {
			out = s.LastNChars(out, 8192) // get the last 8192 characters because that is the sentry message limit

			helpStr := "\ndebugging tips (may or may not apply to this error):"
			helpStr += fmt.Sprintf(
				"\n* if your cluster was unable to provision/remove/scale some nodegroups, additional error information may be found in the description of your cloudformation stack (https://console.aws.amazon.com/cloudformation/home?region=%s#/stacks)"+
					" or in the activity history of your cluster's autoscaling groups (select each autoscaling group and click the  \"Activity\" or \"Activity History\" tab) (https://console.aws.amazon.com/ec2/autoscaling/home?region=%s#AutoScalingGroups)",
				oldClusterConfig.Region,
				oldClusterConfig.Region,
			)
			fmt.Println(helpStr)
			exit.Error(ErrorClusterConfigure(out + helpStr))
		}
	},
}

var _clusterInfoCmd = &cobra.Command{
	Use:   "info",
	Short: "get information about a cluster",
	Args:  cobra.NoArgs,
	Run: func(cmd *cobra.Command, args []string) {
		telemetry.Event("cli.cluster.info")

		if _, err := docker.GetDockerClient(); err != nil {
			exit.Error(err)
		}

		accessConfig, err := getClusterAccessConfigWithCache(true)
		if err != nil {
			exit.Error(err)
		}

		if _flagClusterInfoPrintConfig && _flagOutput == flags.PrettyOutputType {
			_flagOutput = flags.YAMLOutputType
		}

		awsClient, err := newAWSClient(accessConfig.Region, _flagOutput == flags.PrettyOutputType)
		if err != nil {
			exit.Error(err)
		}

		if _flagClusterInfoPrintConfig && _flagClusterInfoDebug {
			exit.Error(ErrorMutuallyExclusiveFlags("--print-config", "--debug"))
		}
		if _flagClusterInfoDebug && _flagOutput != flags.PrettyOutputType {
			exit.Error(ErrorMutuallyExclusiveFlags("--debug", "--output"))
		}

		stacks, err := clusterstate.GetClusterStacks(awsClient, accessConfig)
		if err != nil {
			exit.Error(err)
		}

		state := clusterstate.GetClusterState(stacks)
		if err := clusterstate.AssertClusterState(stacks, state, clusterstate.StateClusterExists); err != nil {
			exit.Error(err)
		}

		if _flagClusterInfoDebug {
			cmdDebug(awsClient, accessConfig)
		} else if _flagClusterInfoPrintConfig {
			cmdPrintConfig(awsClient, accessConfig, _flagOutput)
		} else {
			cmdInfo(awsClient, accessConfig, stacks, _flagOutput, _flagClusterDisallowPrompt)
		}
	},
}

var _clusterDownCmd = &cobra.Command{
	Use:   "down",
	Short: "spin down a cluster",
	Args:  cobra.NoArgs,
	Run: func(cmd *cobra.Command, args []string) {
		telemetry.Event("cli.cluster.down")

		if _, err := docker.GetDockerClient(); err != nil {
			exit.Error(err)
		}

		accessConfig, err := getClusterAccessConfigWithCache(true)
		if err != nil {
			exit.Error(err)
		}

		// Check AWS access
		awsClient, err := newAWSClient(accessConfig.Region, true)
		if err != nil {
			exit.Error(err)
		}

		accountID, _, err := awsClient.GetCachedAccountID()
		if err != nil {
			exit.Error(err)
		}
		bucketName := clusterconfig.BucketName(accountID, accessConfig.ClusterName, accessConfig.Region)

		warnIfNotAdmin(awsClient)

		if _flagClusterDisallowPrompt {
			fmt.Printf("your cluster named \"%s\" in %s will be spun down and all apis will be deleted\n\n", accessConfig.ClusterName, accessConfig.Region)
		} else {
			prompt.YesOrExit(fmt.Sprintf("your cluster named \"%s\" in %s will be spun down and all apis will be deleted, are you sure you want to continue?", accessConfig.ClusterName, accessConfig.Region), "", "")
		}

		var clusterExists bool
		errorsList := []error{}

		fmt.Print("○ retrieving cluster ... ")
		stacks, err := clusterstate.GetClusterStacks(awsClient, accessConfig)
		if err != nil {
			errorsList = append(errorsList, err)
			fmt.Print("failed ✗")
			fmt.Printf("\n\ncouldn't retrieve cluster state; check the cluster stacks in the cloudformation console: https://%s.console.aws.amazon.com/cloudformation\n", accessConfig.Region)
			errors.PrintError(err)
			fmt.Println()
		} else {
			if clusterstate.GetClusterState(stacks) == clusterstate.StateClusterDoesntExist {
				fmt.Println("cluster doesn't exist ✓")
			} else {
				fmt.Println("✓")
				clusterExists = true
			}
		}

		// updating CLI env is best-effort, so ignore errors
		loadBalancer, _ := getNLBLoadBalancer(accessConfig.ClusterName, OperatorLoadBalancer, awsClient)

		fmt.Print("○ deleting sqs queues ... ")
		numDeleted, err := awsClient.DeleteQueuesWithPrefix(clusterconfig.SQSNamePrefix(accessConfig.ClusterName))
		if err != nil {
			errorsList = append(errorsList, err)
			fmt.Print("failed ✗")
			fmt.Printf("\n\nfailed to delete all sqs queues; please delete queues starting with the name %s via the cloudwatch console: https://%s.console.aws.amazon.com/sqs/v2/home\n", clusterconfig.SQSNamePrefix(accessConfig.ClusterName), accessConfig.Region)
			errors.PrintError(err)
			fmt.Println()
		} else if numDeleted == 0 {
			fmt.Println("no sqs queues exist ✓")
		} else {
			fmt.Println("✓")
		}

		clusterDoesntExist := !clusterExists
		if clusterExists {
			fmt.Print("○ spinning down the cluster ...")
			out, exitCode, err := runManagerAccessCommand("/root/uninstall.sh", *accessConfig, awsClient, nil, nil)
			if err != nil {
				errorsList = append(errorsList, err)
				fmt.Println()
				errors.PrintError(err)
			} else if exitCode == nil || *exitCode != 0 {
				template := "\nNote: if this error cannot be resolved, please ensure that all CloudFormation stacks for this cluster eventually become fully deleted (%s)."
				template += " If the stack deletion process has failed, please delete the stacks directly from the AWS console (this may require manually deleting particular AWS resources that are blocking the stack deletion)."
				template += " In addition to deleting the stacks manually from the AWS console, also make sure to empty and remove the %s bucket"
				helpStr := fmt.Sprintf(template, clusterstate.CloudFormationURL(accessConfig.ClusterName, accessConfig.Region), bucketName)
				fmt.Println(helpStr)
				errorsList = append(errorsList, ErrorClusterDown(filterEKSCTLOutput(out)+helpStr))
			} else {
				clusterDoesntExist = true
			}
			fmt.Println()
		}

		// set lifecycle policy to clean the bucket
		var bucketExists bool
		if !_flagClusterDownKeepAWSResources {
			fmt.Printf("○ setting lifecycle policy to empty the %s bucket ... ", bucketName)
			bucketExists, err := awsClient.DoesBucketExist(bucketName)
			if err != nil {
				errorsList = append(errorsList, err)
				fmt.Print("failed ✗")
				fmt.Printf("\n\nfailed to set lifecycle policy to empty the %s bucket; you can remove the bucket manually via the s3 console: https://s3.console.aws.amazon.com/s3/management/%s\n", bucketName, bucketName)
				errors.PrintError(err)
				fmt.Println()
			} else if !bucketExists {
				fmt.Println("bucket doesn't exist ✗")
			} else {
				err = setLifecycleRulesOnClusterDown(awsClient, bucketName)
				if err != nil {
					errorsList = append(errorsList, err)
					fmt.Print("failed ✗")
					fmt.Printf("\n\nfailed to set lifecycle policy to empty the %s bucket; you can remove the bucket manually via the s3 console: https://s3.console.aws.amazon.com/s3/management/%s\n", bucketName, bucketName)
					errors.PrintError(err)
					fmt.Println()
				} else {
					fmt.Println("✓")
				}
			}
		}

		// delete policy after spinning down the cluster (which deletes the roles) because policies can't be deleted if they are attached to roles
		if clusterDoesntExist {
			policyARN := clusterconfig.DefaultPolicyARN(accountID, accessConfig.ClusterName, accessConfig.Region)
			fmt.Printf("○ deleting auto-generated iam policy %s ... ", policyARN)
			if policy, err := awsClient.GetPolicyOrNil(policyARN); err != nil {
				errorsList = append(errorsList, err)
				fmt.Print("failed ✗")
				fmt.Printf("\n\nfailed to delete auto-generated cortex policy %s; please delete the policy via the iam console: https://console.aws.amazon.com/iam/home#/policies\n", policyARN)
				errors.PrintError(err)
				fmt.Println()
			} else if policy == nil {
				fmt.Println("policy doesn't exist ✓")
			} else {
				err = awsClient.DeletePolicy(policyARN)
				if err != nil {
					errorsList = append(errorsList, err)
					fmt.Print("failed ✗")
					fmt.Printf("\n\nfailed to delete auto-generated cortex policy %s; please delete the policy via the iam console: https://console.aws.amazon.com/iam/home#/policies\n", policyARN)
					errors.PrintError(err)
					fmt.Println()
				} else {
					fmt.Println("✓")
				}
			}
		}

		if !_flagClusterDownKeepAWSResources {
			fmt.Print("○ deleting ebs volumes ... ")
			volumes, err := listPVCVolumesForCluster(awsClient, accessConfig.ClusterName)
			if err != nil {
				errorsList = append(errorsList, err)
				fmt.Println("\n\nfailed to list volumes for deletion; please delete any volumes associated with your cluster via the ec2 console: https://console.aws.amazon.com/ec2/v2/home?#Volumes")
				errors.PrintError(err)
				fmt.Println()
			} else {
				var failedToDeleteVolumes []string
				var lastErr error
				for _, volume := range volumes {
					err := awsClient.DeleteVolume(*volume.VolumeId)
					if err != nil {
						failedToDeleteVolumes = append(failedToDeleteVolumes, *volume.VolumeId)
						lastErr = err
					}
				}
				if len(volumes) == 0 {
					fmt.Println("no ebs volumes exist ✓")
				} else if lastErr != nil {
					errorsList = append(errorsList, lastErr)
					fmt.Printf("\n\nfailed to delete %s %s; please delete %s via the ec2 console: https://console.aws.amazon.com/ec2/v2/home?#Volumes\n", s.PluralS("volume", len(failedToDeleteVolumes)), s.UserStrsAnd(failedToDeleteVolumes), s.PluralCustom("it", "them", len(failedToDeleteVolumes)))
					errors.PrintError(lastErr)
					fmt.Println()
				} else {
					fmt.Println("✓")
				}
			}

			fmt.Printf("○ deleting log group %s ... ", accessConfig.ClusterName)
			logGroupExists, err := awsClient.DoesLogGroupExist(accessConfig.ClusterName)
			if err != nil {
				errorsList = append(errorsList, err)
				fmt.Print("failed ✗")
				fmt.Printf("\n\nfailed to list log group for deletion; please delete the log group associated with your cluster via the ec2 console: https://%s.console.aws.amazon.com/cloudwatch/home?#logsV2:log-groups\n", accessConfig.Region)
				errors.PrintError(err)
				fmt.Println()
			} else {
				if !logGroupExists {
					fmt.Println("log group doesn't exist ✓")
				} else {
					err = awsClient.DeleteLogGroup(accessConfig.ClusterName)
					if err != nil {
						errorsList = append(errorsList, err)
						fmt.Print("failed ✗")
						fmt.Printf("\n\nfailed to delete log group %s; please delete the log group associated with your cluster via the ec2 console: https://%s.console.aws.amazon.com/cloudwatch/home?#logsV2:log-groups\n", accessConfig.ClusterName, accessConfig.Region)
						errors.PrintError(err)
						fmt.Println()
					} else {
						fmt.Println("✓")
					}
				}
			}
		}

		// best-effort deletion of cached config
		cachedClusterConfigPath := getCachedClusterConfigPath(accessConfig.ClusterName, accessConfig.Region)
		_ = os.Remove(cachedClusterConfigPath)

		if len(errorsList) > 0 {
			exit.Error(errors.ListOfErrors(ErrClusterDown, false, errorsList...))
		}
		fmt.Printf("\nplease check CloudFormation to ensure that all resources for the %s cluster eventually become successfully deleted: %s\n", accessConfig.ClusterName, clusterstate.CloudFormationURL(accessConfig.ClusterName, accessConfig.Region))
		if !_flagClusterDownKeepAWSResources && bucketExists {
			fmt.Printf("\na lifecycle rule has been applied to the cluster's %s bucket to empty its contents within the next 24 hours; you can delete the %s bucket via the s3 console once it has been emptied (or you can empty and delete it now): https://s3.console.aws.amazon.com/s3/management/%s\n", bucketName, bucketName, bucketName)
		}
		fmt.Println()

		// best-effort deletion of cli environment(s)
		if loadBalancer != nil {
			envNames, isDefaultEnv, _ := getEnvNamesByOperatorEndpoint(*loadBalancer.DNSName)
			if len(envNames) > 0 {
				for _, envName := range envNames {
					err := removeEnvFromCLIConfig(envName)
					if err != nil {
						exit.Error(err)
					}
				}
				fmt.Printf("deleted the %s environment configuration%s\n", s.StrsAnd(envNames), s.SIfPlural(len(envNames)))
				if isDefaultEnv {
					newDefaultEnv, err := getDefaultEnv()
					if err != nil {
						exit.Error(err)
					}
					if newDefaultEnv != nil {
						fmt.Println(fmt.Sprintf("set the default environment to %s", *newDefaultEnv))
					}
				}
			}
		}
	},
}

var _clusterExportCmd = &cobra.Command{
	Use:   "export",
	Short: "download the configurations for all APIs",
	Args:  cobra.NoArgs,
	Run: func(cmd *cobra.Command, args []string) {
		telemetry.Event("cli.cluster.export")

		accessConfig, err := getClusterAccessConfigWithCache(true)
		if err != nil {
			exit.Error(err)
		}

		// Check AWS access
		awsClient, err := newAWSClient(accessConfig.Region, true)
		if err != nil {
			exit.Error(err)
		}
		warnIfNotAdmin(awsClient)

		stacks, err := clusterstate.GetClusterStacks(awsClient, accessConfig)
		if err != nil {
			exit.Error(err)
		}

		state := clusterstate.GetClusterState(stacks)
		if err := clusterstate.AssertClusterState(stacks, state, clusterstate.StateClusterExists); err != nil {
			exit.Error(err)
		}

		loadBalancer, err := getNLBLoadBalancer(accessConfig.ClusterName, OperatorLoadBalancer, awsClient)
		if err != nil {
			exit.Error(err)
		}

		operatorConfig := cluster.OperatorConfig{
			Telemetry:        isTelemetryEnabled(),
			ClientID:         clientID(),
			OperatorEndpoint: "https://" + *loadBalancer.DNSName,
		}

		var apisResponse []schema.APIResponse
		apisResponse, err = cluster.GetAPIs(operatorConfig)
		if err != nil {
			exit.Error(err)
		}
		if len(apisResponse) == 0 {
			fmt.Println(fmt.Sprintf("no apis found in your cluster named %s in %s", accessConfig.ClusterName, accessConfig.Region))
			exit.Ok()
		}

		exportPath := fmt.Sprintf("export-%s-%s", accessConfig.Region, accessConfig.ClusterName)

		err = files.CreateDir(exportPath)
		if err != nil {
			exit.Error(err)
		}

		for _, api := range apisResponse {
			apisWithSpec, err := cluster.GetAPI(operatorConfig, api.Metadata.Name)
			if err != nil {
				exit.Error(err)
			}

			specFilePath := filepath.Join(exportPath, api.Metadata.Name+".yaml")
			fmt.Println(fmt.Sprintf("exporting %s to %s", api.Metadata.Name, specFilePath))

			yamlBytes, err := yaml.Marshal(apisWithSpec[0].Spec.API.SubmittedAPISpec)
			if err != nil {
				exit.Error(err)
			}

			err = files.WriteFile(yamlBytes, specFilePath)
			if err != nil {
				exit.Error(err)
			}
		}
	},
}

var _clusterHealthCmd = &cobra.Command{
	Use:   "health",
	Short: "inspect the health of components in the cluster",
	Args:  cobra.NoArgs,
	Run: func(cmd *cobra.Command, args []string) {
		accessConfig, err := getClusterAccessConfigWithCache(true)
		if err != nil {
			exit.Error(err)
		}

		awsClient, err := awslib.NewForRegion(accessConfig.Region)
		if err != nil {
			exit.Error(err)
		}

		restConfig, err := getClusterRESTConfig(awsClient, accessConfig.ClusterName)
		if err != nil {
			exit.Error(err)
		}

		scheme := runtime.NewScheme()
		if err := clientgoscheme.AddToScheme(scheme); err != nil {
			exit.Error(err)
		}

		k8sClient, err := k8s.New(consts.DefaultNamespace, false, restConfig, scheme)
		if err != nil {
			exit.Error(err)
		}

		clusterHealth, err := health.Check(awsClient, k8sClient, accessConfig.ClusterName)
		if err != nil {
			exit.Error(err)
		}

		clusterWarnings, err := health.GetWarnings(k8sClient)
		if err != nil {
			exit.Error(err)
		}

		if _flagOutput == flags.JSONOutputType {
			fmt.Println(clusterHealth)
			return
		}

		healthTable := table.Table{
			Headers: []table.Header{
				{Title: ""},
				{Title: "live"},
				{Title: "warning", Hidden: !clusterWarnings.HasWarnings()},
			},
			Rows: [][]interface{}{
				{"operator", console.BoolColor(clusterHealth.Operator), ""},
				{"prometheus", console.BoolColor(clusterHealth.Prometheus), clusterWarnings.Prometheus},
				{"autoscaler", console.BoolColor(clusterHealth.Autoscaler), ""},
				{"activator", console.BoolColor(clusterHealth.Activator), ""},
				{"async gateway", console.BoolColor(clusterHealth.AsyncGateway), ""},
				{"grafana", console.BoolColor(clusterHealth.Grafana), ""},
				{"controller manager", console.BoolColor(clusterHealth.ControllerManager), ""},
				{"apis gateway", console.BoolColor(clusterHealth.APIsGateway), ""},
				{"operator gateway", console.BoolColor(clusterHealth.APIsGateway), ""},
				{"cluster autoscaler", console.BoolColor(clusterHealth.ClusterAutoscaler), ""},
				{"operator load balancer", console.BoolColor(clusterHealth.OperatorLoadBalancer), ""},
				{"apis load balancer", console.BoolColor(clusterHealth.APIsLoadBalancer), ""},
				{"fluent bit", console.BoolColor(clusterHealth.FluentBit), ""},
				{"node exporter", console.BoolColor(clusterHealth.NodeExporter), ""},
				{"dcgm exporter", console.BoolColor(clusterHealth.DCGMExporter), ""},
				{"statsd exporter", console.BoolColor(clusterHealth.StatsDExporter), ""},
				{"event exporter", console.BoolColor(clusterHealth.EventExporter), ""},
				{"kube state metrics", console.BoolColor(clusterHealth.KubeStateMetrics), ""},
			},
		}

		fmt.Println(healthTable.MustFormat())
	},
}

func cmdPrintConfig(awsClient *awslib.Client, accessConfig *clusterconfig.AccessConfig, outputType flags.OutputType) {
	clusterConfig := refreshCachedClusterConfig(awsClient, accessConfig, outputType == flags.PrettyOutputType)

	infoInterface := clusterConfig.CoreConfig

	if outputType == flags.JSONOutputType {
		outputBytes, err := libjson.Marshal(infoInterface)
		if err != nil {
			exit.Error(err)
		}
		fmt.Println(string(outputBytes))
	} else {
		outputBytes, err := yaml.Marshal(infoInterface)
		if err != nil {
			exit.Error(err)
		}
		fmt.Println(string(outputBytes))
	}
}

func cmdInfo(awsClient *awslib.Client, accessConfig *clusterconfig.AccessConfig, stacks clusterstate.ClusterStacks, outputType flags.OutputType, disallowPrompt bool) {
	clusterConfig := refreshCachedClusterConfig(awsClient, accessConfig, outputType == flags.PrettyOutputType)

	operatorLoadBalancer, err := getNLBLoadBalancer(accessConfig.ClusterName, OperatorLoadBalancer, awsClient)
	if err != nil {
		exit.Error(err)
	}
	operatorEndpoint := s.EnsurePrefix(*operatorLoadBalancer.DNSName, "https://")

	var apiEndpoint string
	if clusterConfig.APILoadBalancerType == clusterconfig.NLBLoadBalancerType {
		apiLoadBalancer, err := getNLBLoadBalancer(accessConfig.ClusterName, APILoadBalancer, awsClient)
		if err != nil {
			exit.Error(err)
		}
		apiEndpoint = *apiLoadBalancer.DNSName
	}
	if clusterConfig.APILoadBalancerType == clusterconfig.ELBLoadBalancerType {
		apiLoadBalancer, err := getELBLoadBalancer(accessConfig.ClusterName, APILoadBalancer, awsClient)
		if err != nil {
			exit.Error(err)
		}
		apiEndpoint = *apiLoadBalancer.DNSName
	}

	if outputType == flags.JSONOutputType || outputType == flags.YAMLOutputType {
		infoResponse, err := getInfoOperatorResponse(operatorEndpoint)
		if err != nil {
			exit.Error(err)
		}
		infoResponse.ClusterConfig.Config = clusterConfig

		infoInterface := map[string]interface{}{
			"cluster_config":      infoResponse.ClusterConfig.Config,
			"cluster_metadata":    infoResponse.ClusterConfig.OperatorMetadata,
			"worker_node_infos":   infoResponse.WorkerNodeInfos,
			"operator_node_infos": infoResponse.OperatorNodeInfos,
			"endpoint_operator":   operatorEndpoint,
			"endpoint_api":        apiEndpoint,
		}

		var outputBytes []byte
		if outputType == flags.JSONOutputType {
			outputBytes, err = libjson.Marshal(infoInterface)
		} else {
			outputBytes, err = yaml.Marshal(infoInterface)
		}
		if err != nil {
			exit.Error(err)
		}
		fmt.Println(string(outputBytes))
	}
	if outputType == flags.PrettyOutputType {
		fmt.Println(console.Bold("endpoints:"))
		fmt.Println("operator:         ", operatorEndpoint)
		fmt.Println("api load balancer:", apiEndpoint)
		fmt.Println()

		if err := printInfoOperatorResponse(clusterConfig, stacks, operatorEndpoint); err != nil {
			exit.Error(err)
		}
	}

	if _flagClusterInfoEnv != "" {
		if err := updateCLIEnv(_flagClusterInfoEnv, operatorEndpoint, disallowPrompt, outputType == flags.PrettyOutputType); err != nil {
			exit.Error(err)
		}
	}
}

func printInfoOperatorResponse(clusterConfig clusterconfig.Config, stacks clusterstate.ClusterStacks, operatorEndpoint string) error {
	fmt.Print("fetching cluster status ...\n\n")

	fmt.Println(stacks.TableString())

	yamlBytes, err := yaml.Marshal(clusterConfig)
	if err != nil {
		return err
	}
	yamlString := string(yamlBytes)

	infoResponse, err := getInfoOperatorResponse(operatorEndpoint)
	if err != nil {
		fmt.Println(yamlString)
		return err
	}
	infoResponse.ClusterConfig.Config = clusterConfig

	fmt.Println(console.Bold("cluster config:"))
	fmt.Println(fmt.Sprintf("cluster version: %s", infoResponse.ClusterConfig.APIVersion))
	fmt.Print(yamlString)

	printInfoPricing(infoResponse, clusterConfig)
	printInfoNodes(infoResponse)

	return nil
}

func getInfoOperatorResponse(operatorEndpoint string) (*schema.InfoResponse, error) {
	operatorConfig := cluster.OperatorConfig{
		Telemetry:        isTelemetryEnabled(),
		ClientID:         clientID(),
		OperatorEndpoint: operatorEndpoint,
	}
	return cluster.Info(operatorConfig)
}

func printInfoPricing(infoResponse *schema.InfoResponse, clusterConfig clusterconfig.Config) {
	eksPrice := awslib.EKSPrices[clusterConfig.Region]
	operatorInstancePrice := awslib.InstanceMetadatas[clusterConfig.Region]["t3.medium"].Price
	operatorEBSPrice := awslib.EBSMetadatas[clusterConfig.Region]["gp3"].PriceGB * 20 / 30 / 24
	prometheusInstancePrice := awslib.InstanceMetadatas[clusterConfig.Region][clusterConfig.PrometheusInstanceType].Price
	prometheusEBSPrice := awslib.EBSMetadatas[clusterConfig.Region]["gp3"].PriceGB * 20 / 30 / 24
	metricsEBSPrice := awslib.EBSMetadatas[clusterConfig.Region]["gp2"].PriceGB * (40 + 2) / 30 / 24
	nlbPrice := awslib.NLBMetadatas[clusterConfig.Region].Price
	elbPrice := awslib.ELBMetadatas[clusterConfig.Region].Price
	natUnitPrice := awslib.NATMetadatas[clusterConfig.Region].Price

	var loadBalancersPrice float64
	usesELBForAPILoadBalancer := clusterConfig.APILoadBalancerType == clusterconfig.ELBLoadBalancerType
	if usesELBForAPILoadBalancer {
		loadBalancersPrice = nlbPrice + elbPrice
	} else {
		loadBalancersPrice = 2 * nlbPrice
	}

	headers := []table.Header{
		{Title: "aws resource"},
		{Title: "cost per hour"},
	}

	var rows [][]interface{}
	rows = append(rows, []interface{}{"1 eks cluster", s.DollarsMaxPrecision(eksPrice)})

	var totalNodeGroupsPrice float64
	for _, ng := range clusterConfig.NodeGroups {
		var ngNamePrefix string
		if ng.Spot {
			ngNamePrefix = "cx-ws-"
		} else {
			ngNamePrefix = "cx-wd-"
		}
		nodesInfo := infoResponse.GetNodesWithNodeGroupName(ngNamePrefix + ng.Name)
		numInstances := len(nodesInfo)

		ebsPrice := awslib.EBSMetadatas[clusterConfig.Region][ng.InstanceVolumeType.String()].PriceGB * float64(ng.InstanceVolumeSize) / 30 / 24
		if ng.InstanceVolumeType == clusterconfig.IO1VolumeType && ng.InstanceVolumeIOPS != nil {
			ebsPrice += awslib.EBSMetadatas[clusterConfig.Region][ng.InstanceVolumeType.String()].PriceIOPS * float64(*ng.InstanceVolumeIOPS) / 30 / 24
		}
		if ng.InstanceVolumeType == clusterconfig.GP3VolumeType && ng.InstanceVolumeIOPS != nil && ng.InstanceVolumeThroughput != nil {
			ebsPrice += libmath.MaxFloat64(0, (awslib.EBSMetadatas[clusterConfig.Region][ng.InstanceVolumeType.String()].PriceIOPS-3000)*float64(*ng.InstanceVolumeIOPS)/30/24)
			ebsPrice += libmath.MaxFloat64(0, (awslib.EBSMetadatas[clusterConfig.Region][ng.InstanceVolumeType.String()].PriceThroughput-125)*float64(*ng.InstanceVolumeThroughput)/30/24)
		}
		totalEBSPrice := ebsPrice * float64(numInstances)

		totalInstancePrice := float64(0)
		for _, nodeInfo := range nodesInfo {
			totalInstancePrice += nodeInfo.Price
		}

		rows = append(rows, []interface{}{fmt.Sprintf("nodegroup %s: %d (out of %d) %s", ng.Name, numInstances, ng.MaxInstances, s.PluralS("instance", numInstances)), s.DollarsAndTenthsOfCents(totalInstancePrice+totalEBSPrice) + " total"})

		totalNodeGroupsPrice += totalEBSPrice + totalInstancePrice
	}

	operatorNodeGroupPrice := float64(len(infoResponse.OperatorNodeInfos)) * (operatorInstancePrice + operatorEBSPrice)
	prometheusNodeGroupPrice := prometheusInstancePrice + prometheusEBSPrice + metricsEBSPrice

	var natTotalPrice float64
	if clusterConfig.NATGateway == clusterconfig.SingleNATGateway {
		natTotalPrice = natUnitPrice
	} else if clusterConfig.NATGateway == clusterconfig.HighlyAvailableNATGateway {
		natTotalPrice = natUnitPrice * float64(len(clusterConfig.AvailabilityZones))
	}
	totalPrice := eksPrice + totalNodeGroupsPrice + operatorNodeGroupPrice + prometheusNodeGroupPrice + loadBalancersPrice + natTotalPrice
	fmt.Printf(console.Bold("\nyour cluster currently costs %s per hour\n\n"), s.DollarsAndCents(totalPrice))

	rows = append(rows, []interface{}{fmt.Sprintf("%d t3.medium %s (cortex system)", len(infoResponse.OperatorNodeInfos), s.PluralS("instance", len(infoResponse.OperatorNodeInfos))), s.DollarsAndTenthsOfCents(operatorNodeGroupPrice) + " total"})
	rows = append(rows, []interface{}{fmt.Sprintf("1 %s instance (prometheus)", clusterConfig.PrometheusInstanceType), s.DollarsAndTenthsOfCents(prometheusNodeGroupPrice)})
	if usesELBForAPILoadBalancer {
		rows = append(rows, []interface{}{"1 network load balancer", s.DollarsMaxPrecision(nlbPrice)})
		rows = append(rows, []interface{}{"1 classic load balancer", s.DollarsMaxPrecision(elbPrice)})
	} else {
		rows = append(rows, []interface{}{"2 network load balancers", s.DollarsMaxPrecision(loadBalancersPrice) + " total"})
	}

	if clusterConfig.NATGateway == clusterconfig.SingleNATGateway {
		rows = append(rows, []interface{}{"1 nat gateway", s.DollarsMaxPrecision(natUnitPrice)})
	} else if clusterConfig.NATGateway == clusterconfig.HighlyAvailableNATGateway {
		numNATs := len(clusterConfig.AvailabilityZones)
		rows = append(rows, []interface{}{fmt.Sprintf("%d nat gateways", numNATs), s.DollarsMaxPrecision(natUnitPrice*float64(numNATs)) + " total"})
	}

	t := table.Table{
		Headers: headers,
		Rows:    rows,
	}
	t.MustPrint(&table.Opts{Sort: pointer.Bool(false)})
}

func printInfoNodes(infoResponse *schema.InfoResponse) {
	numAPIInstances := len(infoResponse.WorkerNodeInfos)

	var totalReplicas int
	var doesClusterHaveGPUs, doesClusterHaveInfs, doesClusterHaveEnqueuers bool
	for _, nodeInfo := range infoResponse.WorkerNodeInfos {
		totalReplicas += nodeInfo.NumReplicas
		if nodeInfo.ComputeUserCapacity.GPU > 0 {
			doesClusterHaveGPUs = true
		}
		if nodeInfo.ComputeUserCapacity.Inf > 0 {
			doesClusterHaveInfs = true
		}
		if nodeInfo.NumEnqueuerReplicas > 0 {
			doesClusterHaveEnqueuers = true
		}
	}

	var pendingReplicasStr string
	if infoResponse.NumPendingReplicas > 0 {
		pendingReplicasStr = fmt.Sprintf(", and %d unscheduled %s", infoResponse.NumPendingReplicas, s.PluralS("replica", infoResponse.NumPendingReplicas))
	}

	fmt.Printf(console.Bold("\nyour cluster has %d API %s running across %d %s%s\n"), totalReplicas, s.PluralS("replica", totalReplicas), numAPIInstances, s.PluralS("instance", numAPIInstances), pendingReplicasStr)

	if len(infoResponse.WorkerNodeInfos) == 0 {
		return
	}

	headers := []table.Header{
		{Title: "instance type"},
		{Title: "lifecycle"},
		{Title: "replicas"},
		{Title: "batch enqueuer replicas", Hidden: !doesClusterHaveEnqueuers},
		{Title: "CPU (requested / total allocatable)"},
		{Title: "memory (requested / total allocatable)"},
		{Title: "GPU (requested / total allocatable)", Hidden: !doesClusterHaveGPUs},
		{Title: "Inf (requested / total allocatable)", Hidden: !doesClusterHaveInfs},
	}

	var rows [][]interface{}
	for _, nodeInfo := range infoResponse.WorkerNodeInfos {
		lifecycle := "on-demand"
		if nodeInfo.IsSpot {
			lifecycle = "spot"
		}

		cpuStr := nodeInfo.ComputeUserRequested.CPU.MilliString() + " / " + nodeInfo.ComputeUserCapacity.CPU.MilliString()
		memStr := nodeInfo.ComputeUserRequested.Mem.String() + " / " + nodeInfo.ComputeUserCapacity.Mem.String()
		gpuStr := s.Int64(nodeInfo.ComputeUserRequested.GPU) + " / " + s.Int64(nodeInfo.ComputeUserCapacity.GPU)
		infStr := s.Int64(nodeInfo.ComputeUserRequested.Inf) + " / " + s.Int64(nodeInfo.ComputeUserCapacity.Inf)
		rows = append(rows, []interface{}{nodeInfo.InstanceType, lifecycle, nodeInfo.NumReplicas, nodeInfo.NumEnqueuerReplicas, cpuStr, memStr, gpuStr, infStr})
	}

	t := table.Table{
		Headers: headers,
		Rows:    rows,
	}
	fmt.Println()
	t.MustPrint(&table.Opts{Sort: pointer.Bool(false)})
}

func updateCLIEnv(envName string, operatorEndpoint string, disallowPrompt bool, printToStdout bool) error {
	prevEnv, err := readEnv(envName)
	if err != nil {
		return err
	}

	newEnvironment := cliconfig.Environment{
		Name:             envName,
		OperatorEndpoint: operatorEndpoint,
	}

	shouldWriteEnv := false
	envWasUpdated := false
	if prevEnv == nil {
		shouldWriteEnv = true
		if printToStdout {
			fmt.Println()
		}
	} else if prevEnv.OperatorEndpoint != operatorEndpoint {
		envWasUpdated = true
		if printToStdout {
			if disallowPrompt {
				shouldWriteEnv = true
				fmt.Println()
			} else {
				shouldWriteEnv = prompt.YesOrNo(fmt.Sprintf("\nfound an existing environment named \"%s\"; would you like to overwrite it to connect to this cluster?", envName), "", "")
			}
		} else {
			shouldWriteEnv = true
		}
	}

	if shouldWriteEnv {
		err := addEnvToCLIConfig(newEnvironment, true)
		if err != nil {
			return err
		}

		if printToStdout {
			if envWasUpdated {
				fmt.Printf(console.Bold("the environment named \"%s\" has been updated to point to this cluster (and was set as the default environment)\n"), envName)
			} else {
				fmt.Printf(console.Bold("an environment named \"%s\" has been configured to point to this cluster (and was set as the default environment)\n"), envName)
			}
		}
	}

	return nil
}

func cmdDebug(awsClient *awslib.Client, accessConfig *clusterconfig.AccessConfig) {
	// note: if modifying this string, also change it in files.IgnoreCortexDebug()
	debugFileName := fmt.Sprintf("cortex-debug-%s.tgz", time.Now().UTC().Format("2006-01-02-15-04-05"))

	containerDebugPath := "/out/" + debugFileName
	copyFromPaths := []dockerCopyFromPath{
		{
			containerPath: containerDebugPath,
			localDir:      _cwd,
		},
	}

	out, exitCode, err := runManagerAccessCommand("/root/debug.sh "+containerDebugPath, *accessConfig, awsClient, nil, copyFromPaths)
	if err != nil {
		exit.Error(err)
	}
	if exitCode == nil || *exitCode != 0 {
		exit.Error(ErrorClusterDebug(out))
	}

	fmt.Println("saved cluster info to ./" + debugFileName)
	return
}

func refreshCachedClusterConfig(awsClient *awslib.Client, accessConfig *clusterconfig.AccessConfig, printToStdout bool) clusterconfig.Config {
	// add empty file if cached cluster doesn't exist so that the file output by manager container maintains current user permissions
	cachedClusterConfigPath := getCachedClusterConfigPath(accessConfig.ClusterName, accessConfig.Region)
	containerConfigPath := fmt.Sprintf("/out/%s", filepath.Base(cachedClusterConfigPath))

	copyFromPaths := []dockerCopyFromPath{
		{
			containerPath: containerConfigPath,
			localDir:      files.Dir(cachedClusterConfigPath),
		},
	}

	if printToStdout {
		fmt.Print("syncing cluster configuration ...\n\n")
	}
	out, exitCode, err := runManagerAccessCommand("/root/refresh.sh "+containerConfigPath, *accessConfig, awsClient, nil, copyFromPaths)
	if err != nil {
		exit.Error(err)
	}
	if exitCode == nil || *exitCode != 0 {
		exit.Error(ErrorClusterRefresh(out))
	}

	refreshedClusterConfig := &clusterconfig.Config{}
	err = readCachedClusterConfigFile(refreshedClusterConfig, cachedClusterConfigPath)
	if err != nil {
		exit.Error(err)
	}
	return *refreshedClusterConfig
}

func createS3BucketIfNotFound(awsClient *awslib.Client, bucket string, tags map[string]string) error {
	bucketFound, err := awsClient.DoesBucketExist(bucket)
	if err != nil {
		return err
	}
	if !bucketFound {
		fmt.Print("○ creating a new s3 bucket: ", bucket)
		err = awsClient.CreateBucket(bucket)
		if err != nil {
			fmt.Print("\n\n")
			return err
		}
		err = awsClient.EnableBucketEncryption(bucket)
		if err != nil {
			fmt.Print("\n\n")
			return err
		}
	} else {
		fmt.Print("○ using existing s3 bucket: ", bucket)
	}

	// retry since it's possible that it takes some time for the new bucket to be registered by AWS
	for i := 0; i < 10; i++ {
		err = awsClient.TagBucket(bucket, tags)
		if err == nil {
			fmt.Println(" ✓")
			return nil
		}
		if !awslib.IsNoSuchBucketErr(err) {
			break
		}
		time.Sleep(1 * time.Second)
	}

	fmt.Print("\n\n")
	return err
}

func setLifecycleRulesOnClusterUp(awsClient *awslib.Client, bucket, newClusterUID string) error {
	err := awsClient.DeleteLifecycleRules(bucket)
	if err != nil {
		return err
	}

	clusterUIDs, err := awsClient.ListS3TopLevelDirs(bucket)
	if err != nil {
		return err
	}

	if len(clusterUIDs)+1 > consts.MaxBucketLifecycleRules {
		return ErrorClusterUIDsLimitInBucket(bucket)
	}

	expirationDate := libtime.GetCurrentUTCDate().Add(-24 * time.Hour)
	rules := []s3.LifecycleRule{}
	for _, clusterUID := range clusterUIDs {
		rules = append(rules, s3.LifecycleRule{
			Expiration: &s3.LifecycleExpiration{
				Date: &expirationDate,
			},
			ID: pointer.String("cluster-remove-" + clusterUID),
			Filter: &s3.LifecycleRuleFilter{
				Prefix: pointer.String(s.EnsureSuffix(clusterUID, "/")),
			},
			Status: pointer.String("Enabled"),
		})
	}

	rules = append(rules, s3.LifecycleRule{
		Expiration: &s3.LifecycleExpiration{
			Days: pointer.Int64(consts.AsyncWorkloadsExpirationDays),
		},
		ID: pointer.String("async-workloads-expiry-policy"),
		Filter: &s3.LifecycleRuleFilter{
			Prefix: pointer.String(s.EnsureSuffix(filepath.Join(newClusterUID, "workloads"), "/")),
		},
		Status: pointer.String("Enabled"),
	})

	return awsClient.SetLifecycleRules(bucket, rules)
}

func setLifecycleRulesOnClusterDown(awsClient *awslib.Client, bucket string) error {
	err := awsClient.DeleteLifecycleRules(bucket)
	if err != nil {
		return err
	}

	expirationDate := libtime.GetCurrentUTCDate().Add(-24 * time.Hour)
	return awsClient.SetLifecycleRules(bucket, []s3.LifecycleRule{
		{
			Expiration: &s3.LifecycleExpiration{
				Date: &expirationDate,
			},
			ID: pointer.String("bucket-cleaner"),
			Filter: &s3.LifecycleRuleFilter{
				Prefix: pointer.String(""),
			},
			Status: pointer.String("Enabled"),
		},
	})
}

func createLogGroupIfNotFound(awsClient *awslib.Client, logGroup string, tags map[string]string) error {
	logGroupFound, err := awsClient.DoesLogGroupExist(logGroup)
	if err != nil {
		return err
	}
	if !logGroupFound {
		fmt.Print("○ creating a new cloudwatch log group: ", logGroup)
		err = awsClient.CreateLogGroup(logGroup, tags)
		if err != nil {
			fmt.Print("\n\n")
			return err
		}
		fmt.Println(" ✓")
		return nil
	}

	fmt.Print("○ using existing cloudwatch log group: ", logGroup)

	// retry since it's possible that it takes some time for the new log group to be registered by AWS
	err = awsClient.TagLogGroup(logGroup, tags)
	if err != nil {
		fmt.Print("\n\n")
		return err
	}

	fmt.Println(" ✓")

	return nil
}

type LoadBalancer string

var (
	OperatorLoadBalancer LoadBalancer = "operator"
	APILoadBalancer      LoadBalancer = "api"
)

func (lb LoadBalancer) String() string {
	return string(lb)
}

// Will return error if the load balancer can't be found
func getNLBLoadBalancer(clusterName string, whichLB LoadBalancer, awsClient *awslib.Client) (*elbv2.LoadBalancer, error) {
	loadBalancer, err := awsClient.FindLoadBalancerV2(map[string]string{
		clusterconfig.ClusterNameTag: clusterName,
		"cortex.dev/load-balancer":   whichLB.String(),
	})
	if err != nil {
		return nil, errors.Wrap(err, fmt.Sprintf("unable to locate %s load balancer", whichLB.String()))
	}

	if loadBalancer == nil {
		return nil, ErrorNoOperatorLoadBalancer(whichLB.String())
	}

	return loadBalancer, nil
}

// Will return error if the load balancer can't be found
func getELBLoadBalancer(clusterName string, whichLB LoadBalancer, awsClient *awslib.Client) (*elb.LoadBalancerDescription, error) {
	loadBalancer, err := awsClient.FindLoadBalancer(map[string]string{
		clusterconfig.ClusterNameTag: clusterName,
		"cortex.dev/load-balancer":   whichLB.String(),
	})
	if err != nil {
		return nil, errors.Wrap(err, fmt.Sprintf("unable to locate %s load balancer", whichLB.String()))
	}

	if loadBalancer == nil {
		return nil, ErrorNoOperatorLoadBalancer(whichLB.String())
	}

	return loadBalancer, nil
}

func listPVCVolumesForCluster(awsClient *awslib.Client, clusterName string) ([]ec2.Volume, error) {
	return awsClient.ListVolumes(ec2.Tag{
		Key:   pointer.String(fmt.Sprintf("kubernetes.io/cluster/%s", clusterName)),
		Value: nil, // any value should be ok as long as the key is present
	})
}

func filterEKSCTLOutput(out string) string {
	return strings.Join(s.RemoveDuplicates(strings.Split(out, "\n"), _eksctlPrefixRegex), "\n")
}

func getClusterRESTConfig(awsClient *awslib.Client, clusterName string) (*rest.Config, error) {
	clusterOutput, err := awsClient.EKS().DescribeCluster(
		&eks.DescribeClusterInput{
			Name: aws.String(clusterName),
		},
	)
	if err != nil {
		return nil, err
	}

	gen, err := token.NewGenerator(true, false)
	if err != nil {
		return nil, err
	}

	opts := &token.GetTokenOptions{
		ClusterID: aws.StringValue(clusterOutput.Cluster.Name),
	}

	tok, err := gen.GetWithOptions(opts)
	if err != nil {
		return nil, err
	}

	ca, err := base64.StdEncoding.DecodeString(aws.StringValue(clusterOutput.Cluster.CertificateAuthority.Data))
	if err != nil {
		return nil, err
	}

	return &rest.Config{
		Host:        aws.StringValue(clusterOutput.Cluster.Endpoint),
		BearerToken: tok.Token,
		TLSClientConfig: rest.TLSClientConfig{
			CAData: ca,
		},
	}, nil
}


================================================
FILE: cli/cmd/completion.go
================================================
/*
Copyright 2022 Cortex Labs, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package cmd

import (
	"fmt"
	"os"

	"github.com/cortexlabs/cortex/pkg/lib/exit"
	"github.com/spf13/cobra"
)

func completionInit() {
	_completionCmd.Flags().SortFlags = false
}

var _bashAliasText = `
# alias

alias cx='cortex'
if [[ $(type -t compopt) = "builtin" ]]; then
    complete -o default -F __start_cortex cx
else
    complete -o default -o nospace -F __start_cortex cx
fi
`

var _completionCmd = &cobra.Command{
	Use:   "completion SHELL",
	Short: "generate shell completion scripts",
	Long: `generate shell completion scripts

to enable cortex shell completion:
    bash:
        add this to ~/.bash_profile (mac) or ~/.bashrc (linux):
            source <(cortex completion bash)

        note: bash-completion must be installed on your system; example installation instructions:
            mac:
                1) install bash completion:
                   brew install bash-completion
                2) add this to your ~/.bash_profile:
                   source $(brew --prefix)/etc/bash_completion
                3) log out and back in, or close your terminal window and reopen it
            ubuntu:
                1) install bash completion:
                   apt update && apt install -y bash-completion  # you may need sudo
                2) open ~/.bashrc and uncomment the bash completion section, or add this:
                   if [ -f /etc/bash_completion ] && ! shopt -oq posix; then . /etc/bash_completion; fi
                3) log out and back in, or close your terminal window and reopen it

    zsh:
        option 1:
            add this to ~/.zshrc:
                source <(cortex completion zsh)
            if that failed, you can try adding this line (above the source command you just added):
                autoload -Uz compinit && compinit
        option 2:
            create a _cortex file in your fpath, for example:
                cortex completion zsh > /usr/local/share/zsh/site-functions/_cortex

Note: this will also add the "cx" alias for cortex for convenience
`,
	Args:      cobra.ExactArgs(1),
	ValidArgs: []string{"bash", "zsh"},
	Run: func(cmd *cobra.Command, args []string) {
		switch args[0] {
		case "bash":
			_rootCmd.GenBashCompletion(os.Stdout)
			fmt.Print(_bashAliasText)

		case "zsh":
			_rootCmd.GenZshCompletion(os.Stdout)
			fmt.Print("alias cx='cortex'\n\n")

			// https://github.com/spf13/cobra/pull/887
			// https://github.com/corneliusweig/rakkess/blob/master/cmd/completion.go
			// https://github.com/GoogleContainerTools/skaffold/blob/master/cmd/skaffold/app/cmd/completion.go
			// https://github.com/spf13/cobra/issues/881
			// https://github.com/asdf-vm/asdf/issues/266
			fmt.Println("if compquote '' 2>/dev/null; then _cortex; else compdef _cortex cortex; fi")

		default:
			fmt.Println()
			exit.Error(ErrorShellCompletionNotSupported(args[0]))
		}
	},
}


================================================
FILE: cli/cmd/const.go
================================================
/*
Copyright 2022 Cortex Labs, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package cmd

const (
	_timeFormat = "02 Jan 06 15:04:05 MST"
)


================================================
FILE: cli/cmd/delete.go
================================================
/*
Copyright 2022 Cortex Labs, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package cmd

import (
	"fmt"
	"strings"

	"github.com/cortexlabs/cortex/cli/cluster"
	"github.com/cortexlabs/cortex/cli/types/flags"
	"github.com/cortexlabs/cortex/pkg/lib/exit"
	libjson "github.com/cortexlabs/cortex/pkg/lib/json"
	"github.com/cortexlabs/cortex/pkg/lib/print"
	"github.com/cortexlabs/cortex/pkg/lib/telemetry"
	"github.com/cortexlabs/cortex/pkg/operator/schema"
	"github.com/spf13/cobra"
)

var (
	_flagDeleteEnv       string
	_flagDeleteKeepCache bool
	_flagDeleteForce     bool
)

func deleteInit() {
	_deleteCmd.Flags().SortFlags = false
	_deleteCmd.Flags().StringVarP(&_flagDeleteEnv, "env", "e", "", "environment to use")

	_deleteCmd.Flags().BoolVarP(&_flagDeleteForce, "force", "f", false, "delete the api without confirmation")
	_deleteCmd.Flags().BoolVarP(&_flagDeleteKeepCache, "keep-cache", "c", false, "keep cached data for the api")
	_deleteCmd.Flags().VarP(&_flagOutput, "output", "o", fmt.Sprintf("output format: one of %s", strings.Join(flags.OutputTypeStringsExcluding(flags.YAMLOutputType), "|")))
}

var _deleteCmd = &cobra.Command{
	Use:   "delete API_NAME [JOB_ID]",
	Short: "delete an api or stop a job",
	Args:  cobra.RangeArgs(1, 2),
	Run: func(cmd *cobra.Command, args []string) {
		envName, err := getEnvFromFlag(_flagDeleteEnv)
		if err != nil {
			telemetry.Event("cli.delete")
			exit.Error(err)
		}

		env, err := ReadOrConfigureEnv(envName)
		if err != nil {
			telemetry.Event("cli.delete")
			exit.Error(err)
		}
		telemetry.Event("cli.delete", map[string]interface{}{"env_name": env.Name})

		err = printEnvIfNotSpecified(env.Name, cmd)
		if err != nil {
			exit.Error(err)
		}

		var deleteResponse schema.DeleteResponse
		if len(args) == 2 {
			apisRes, err := cluster.GetAPI(MustGetOperatorConfig(env.Name), args[0])
			if err != nil {
				exit.Error(err)
			}

			deleteResponse, err = cluster.StopJob(MustGetOperatorConfig(env.Name), apisRes[0].Spec.Kind, args[0], args[1])
			if err != nil {
				exit.Error(err)
			}
		} else {
			deleteResponse, err = cluster.Delete(MustGetOperatorConfig(env.Name), args[0], _flagDeleteKeepCache, _flagDeleteForce)
			if err != nil {
				exit.Error(err)
			}
		}

		if _flagOutput == flags.JSONOutputType {
			bytes, err := libjson.Marshal(deleteResponse)
			if err != nil {
				exit.Error(err)
			}
			fmt.Print(string(bytes))
			return
		}

		print.BoldFirstLine(deleteResponse.Message)
	},
}


================================================
FILE: cli/cmd/deploy.go
================================================
/*
Copyright 2022 Cortex Labs, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package cmd

import (
	"fmt"
	"strings"

	"github.com/cortexlabs/cortex/cli/cluster"
	"github.com/cortexlabs/cortex/cli/types/flags"
	"github.com/cortexlabs/cortex/pkg/lib/exit"
	"github.com/cortexlabs/cortex/pkg/lib/files"
	libjson "github.com/cortexlabs/cortex/pkg/lib/json"
	"github.com/cortexlabs/cortex/pkg/lib/print"
	"github.com/cortexlabs/cortex/pkg/lib/telemetry"
	"github.com/cortexlabs/cortex/pkg/operator/schema"
	"github.com/spf13/cobra"
)

var (
	_warningFileBytes    = 1024 * 1024 * 10
	_warningProjectBytes = 1024 * 1024 * 10
	_warningFileCount    = 1000

	_maxFileSizeBytes    int64 = 1024 * 1024 * 32 // 32mb
	_maxProjectSizeBytes int64 = 1024 * 1024 * 32 // 32mb

	_flagDeployEnv            string
	_flagDeployForce          bool
	_flagDeployDisallowPrompt bool
)

func deployInit() {
	_deployCmd.Flags().SortFlags = false
	_deployCmd.Flags().StringVarP(&_flagDeployEnv, "env", "e", "", "environment to use")
	_deployCmd.Flags().BoolVarP(&_flagDeployForce, "force", "f", false, "override the in-progress api update")
	_deployCmd.Flags().BoolVarP(&_flagDeployDisallowPrompt, "yes", "y", false, "skip prompts")
	_deployCmd.Flags().VarP(&_flagOutput, "output", "o", fmt.Sprintf("output format: one of %s", strings.Join(flags.OutputTypeStringsExcluding(flags.YAMLOutputType), "|")))
}

var _deployCmd = &cobra.Command{
	Use:   "deploy [CONFIG_FILE]",
	Short: "create or update apis",
	Args:  cobra.RangeArgs(0, 1),
	Run: func(cmd *cobra.Command, args []string) {
		envName, err := getEnvFromFlag(_flagDeployEnv)
		if err != nil {
			telemetry.Event("cli.deploy")
			exit.Error(err)
		}

		env, err := ReadOrConfigureEnv(envName)
		if err != nil {
			telemetry.Event("cli.deploy")
			exit.Error(err)
		}
		telemetry.Event("cli.deploy", map[string]interface{}{"env_name": env.Name})

		err = printEnvIfNotSpecified(env.Name, cmd)
		if err != nil {
			exit.Error(err)
		}

		configPath := getConfigPath(args)

		projectRoot := files.Dir(configPath)
		if projectRoot == _homeDir {
			exit.Error(ErrorDeployFromTopLevelDir("home"))
		}
		if projectRoot == "/" {
			exit.Error(ErrorDeployFromTopLevelDir("root"))
		}

		deploymentBytes, err := getDeploymentBytes(configPath)
		if err != nil {
			exit.Error(err)
		}

		deployResults, err := cluster.Deploy(MustGetOperatorConfig(env.Name), configPath, deploymentBytes, _flagDeployForce)
		if err != nil {
			exit.Error(err)
		}

		switch _flagOutput {
		case flags.JSONOutputType:
			bytes, err := libjson.Marshal(deployResults)
			if err != nil {
				exit.Error(err)
			}
			fmt.Print(string(bytes))
		case flags.PrettyOutputType:
			message := mergeResultMessages(deployResults)
			if didAnyResultsError(deployResults) {
				print.StderrBoldFirstBlock(message)
			} else {
				print.BoldFirstBlock(message)
			}
		}

		if didAnyResultsError(deployResults) {
			exit.Error(nil)
		}
	},
}

// Returns absolute path
func getConfigPath(args []string) string {
	var configPath string

	if len(args) == 0 {
		configPath = "cortex.yaml"
		if !files.IsFile(configPath) {
			exit.Error(ErrorCortexYAMLNotFound())
		}
	} else {
		configPath = args[0]
		if err := files.CheckFile(configPath); err != nil {
			exit.Error(err)
		}
	}

	return files.RelToAbsPath(configPath, _cwd)
}

func getDeploymentBytes(configPath string) (map[string][]byte, error) {
	configBytes, err := files.ReadFileBytes(configPath)
	if err != nil {
		return nil, err
	}

	uploadBytes := map[string][]byte{
		"config": configBytes,
	}

	return uploadBytes, nil
}

func mergeResultMessages(results []schema.DeployResult) string {
	var okMessages []string
	var errMessages []string

	for _, result := range results {
		if result.Error != "" {
			errMessages = append(errMessages, result.Error)
		} else {
			okMessages = append(okMessages, result.Message)
		}
	}

	output := ""

	if len(okMessages) > 0 {
		output += strings.Join(okMessages, "\n")
		if len(errMessages) > 0 {
			output += "\n\n"
		}
	}

	if len(errMessages) > 0 {
		output += strings.Join(errMessages, "\n")
	}

	return output
}

func didAllResultsError(results []schema.DeployResult) bool {
	for _, result := range results {
		if result.Error == "" {
			return false
		}
	}
	return true
}

func didAnyResultsError(results []schema.DeployResult) bool {
	for _, result := range results {
		if result.Error != "" {
			return true
		}
	}
	return false
}


================================================
FILE: cli/cmd/describe.go
================================================
/*
Copyright 2022 Cortex Labs, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package cmd

import (
	"fmt"

	"github.com/cortexlabs/cortex/cli/cluster"
	"github.com/cortexlabs/cortex/cli/types/cliconfig"
	"github.com/cortexlabs/cortex/pkg/lib/errors"
	"github.com/cortexlabs/cortex/pkg/lib/exit"
	"github.com/cortexlabs/cortex/pkg/lib/telemetry"
	"github.com/cortexlabs/cortex/pkg/types/userconfig"
	"github.com/spf13/cobra"
)

const (
	_titleReplicaStatus = "replica status"
	_titleReplicaCount  = "replica count"
)

var (
	_flagDescribeEnv   string
	_flagDescribeWatch bool
)

func describeInit() {
	_describeCmd.Flags().SortFlags = false
	_describeCmd.Flags().StringVarP(&_flagDescribeEnv, "env", "e", "", "environment to use")
	_describeCmd.Flags().BoolVarP(&_flagDescribeWatch, "watch", "w", false, "re-run the command every 2 seconds")
}

var _describeCmd = &cobra.Command{
	Use:   "describe [API_NAME]",
	Short: "describe an api",
	Args:  cobra.ExactArgs(1),
	Run: func(cmd *cobra.Command, args []string) {
		apiName := args[0]

		var envName string
		if wasFlagProvided(cmd, "env") {
			envName = _flagDescribeEnv
		} else {
			var err error
			envName, err = getEnvFromFlag("")
			if err != nil {
				telemetry.Event("cli.describe")
				exit.Error(err)
			}
		}

		env, err := ReadOrConfigureEnv(envName)
		if err != nil {
			telemetry.Event("cli.describe")
			exit.Error(err)
		}
		telemetry.Event("cli.describe", map[string]interface{}{"env_name": env.Name})

		rerun(_flagDescribeWatch, func() (string, error) {
			env, err := ReadOrConfigureEnv(envName)
			if err != nil {
				exit.Error(err)
			}

			out, err := envStringIfNotSpecified(envName, cmd)
			if err != nil {
				return "", err
			}
			apiTable, err := describeAPI(env, apiName)
			if err != nil {
				return "", err
			}

			return out + apiTable, nil
		})
	},
}

func describeAPI(env cliconfig.Environment, apiName string) (string, error) {
	apisRes, err := cluster.DescribeAPI(MustGetOperatorConfig(env.Name), apiName)
	if err != nil {
		return "", err
	}

	if len(apisRes) == 0 {
		exit.Error(errors.ErrorUnexpected(fmt.Sprintf("unable to find api %s", apiName)))
	}

	apiRes := apisRes[0]

	switch apiRes.Metadata.Kind {
	case userconfig.RealtimeAPIKind:
		return realtimeDescribeAPITable(apiRes, env)
	case userconfig.AsyncAPIKind:
		return asyncDescribeAPITable(apiRes, env)
	default:
		return "", errors.ErrorUnexpected(fmt.Sprintf("encountered unexpected kind %s for api %s", apiRes.Metadata.Kind, apiRes.Metadata.Name))
	}
}


================================================
FILE: cli/cmd/env.go
================================================
/*
Copyright 2022 Cortex Labs, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package cmd

import (
	"fmt"
	"strings"

	"github.com/cortexlabs/cortex/cli/types/cliconfig"
	"github.com/cortexlabs/cortex/cli/types/flags"
	"github.com/cortexlabs/cortex/pkg/lib/exit"
	libjson "github.com/cortexlabs/cortex/pkg/lib/json"
	"github.com/cortexlabs/cortex/pkg/lib/print"
	"github.com/cortexlabs/cortex/pkg/lib/telemetry"
	"github.com/spf13/cobra"
)

var (
	_flagEnvOperatorEndpoint string
)

func envInit() {
	_envConfigureCmd.Flags().SortFlags = false
	_envConfigureCmd.Flags().StringVarP(&_flagEnvOperatorEndpoint, "operator-endpoint", "o", "", "set the operator endpoint without prompting")
	_envCmd.AddCommand(_envConfigureCmd)

	_envListCmd.Flags().SortFlags = false
	_envListCmd.Flags().VarP(&_flagOutput, "output", "o", fmt.Sprintf("output format: one of %s", strings.Join(flags.OutputTypeStringsExcluding(flags.YAMLOutputType), "|")))
	_envCmd.AddCommand(_envListCmd)

	_envDefaultCmd.Flags().SortFlags = false
	_envCmd.AddCommand(_envDefaultCmd)

	_envRenameCmd.Flags().SortFlags = false
	_envCmd.AddCommand(_envRenameCmd)

	_envDeleteCmd.Flags().SortFlags = false
	_envCmd.AddCommand(_envDeleteCmd)
}

var _envCmd = &cobra.Command{
	Use:   "env",
	Short: "manage cli environments (contains subcommands)",
}

var _envConfigureCmd = &cobra.Command{
	Use:   "configure [ENVIRONMENT_NAME]",
	Short: "configure an environment",
	Args:  cobra.RangeArgs(0, 1),
	Run: func(cmd *cobra.Command, args []string) {
		telemetry.Event("cli.env.configure")

		var envName string
		if len(args) == 1 {
			envName = args[0]
		}

		fieldsToSkipPrompt := cliconfig.Environment{}
		if _flagEnvOperatorEndpoint != "" {
			operatorEndpoint, err := validateOperatorEndpoint(_flagEnvOperatorEndpoint)
			if err != nil {
				exit.Error(err)
			}
			fieldsToSkipPrompt.OperatorEndpoint = operatorEndpoint
		}

		if _, err := configureEnv(envName, fieldsToSkipPrompt); err != nil {
			exit.Error(err)
		}
	},
}

var _envListCmd = &cobra.Command{
	Use:   "list",
	Short: "list all configured environments",
	Args:  cobra.NoArgs,
	Run: func(cmd *cobra.Command, args []string) {
		telemetry.Event("cli.env.list")

		cliConfig, err := readCLIConfig()
		if err != nil {
			exit.Error(err)
		}

		if _flagOutput == flags.JSONOutputType {
			bytes, err := libjson.Marshal(cliConfig.ConvertToUserFacingCLIConfig())
			if err != nil {
				exit.Error(err)
			}
			fmt.Print(string(bytes))
			return
		}

		if len(cliConfig.Environments) == 0 {
			fmt.Println("no environments are configured")
			return
		}

		defaultEnv, err := getDefaultEnv()
		if err != nil {
			exit.Error(err)
		}

		for i, env := range cliConfig.Environments {
			fmt.Print(env.String(defaultEnv != nil && *defaultEnv == env.Name))
			if i+1 < len(cliConfig.Environments) {
				fmt.Println()
			}
		}
	},
}

var _envDefaultCmd = &cobra.Command{
	Use:   "default [ENVIRONMENT_NAME]",
	Short: "set the default environment",
	Args:  cobra.RangeArgs(0, 1),
	Run: func(cmd *cobra.Command, args []string) {
		telemetry.Event("cli.env.default")

		defaultEnv, err := getDefaultEnv()
		if err != nil {
			exit.Error(err)
		}

		var envName string
		if len(args) == 0 {
			if defaultEnv != nil {
				fmt.Printf("current default environment: %s\n\n", *defaultEnv)
			}
			envName = promptForExistingEnvName("name of environment to set as default")
		} else {
			envName = args[0]
		}

		if defaultEnv != nil && *defaultEnv == envName {
			print.BoldFirstLine(fmt.Sprintf("%s is already the default environment", envName))
			exit.Ok()
		}

		if err := setDefaultEnv(envName); err != nil {
			exit.Error(err)
		}

		print.BoldFirstLine(fmt.Sprintf("set %s as the default environment", envName))
	},
}

var _envRenameCmd = &cobra.Command{
	Use:   "rename EXISTING_NAME NEW_NAME",
	Short: "rename an environment",
	Args:  cobra.ExactArgs(2),
	Run: func(cmd *cobra.Command, args []string) {
		telemetry.Event("cli.env.rename")

		oldEnvName := args[0]
		newEnvName := args[1]

		if err := renameEnv(oldEnvName, newEnvName); err != nil {
			exit.Error(err)
		}

		print.BoldFirstLine(fmt.Sprintf("renamed the %s environment to %s", oldEnvName, newEnvName))
	},
}

var _envDeleteCmd = &cobra.Command{
	Use:   "delete [ENVIRONMENT_NAME]",
	Short: "delete an environment configuration",
	Args:  cobra.RangeArgs(0, 1),
	Run: func(cmd *cobra.Command, args []string) {
		telemetry.Event("cli.env.delete")

		var envName string
		if len(args) == 1 {
			envName = args[0]
		} else {
			envName = promptForExistingEnvName("name of environment to delete")
		}

		prevDefault, err := getDefaultEnv()
		if err != nil {
			exit.Error(err)
		}

		if err := removeEnvFromCLIConfig(envName); err != nil {
			exit.Error(err)
		}

		newDefault, err := getDefaultEnv()
		if err != nil {
			exit.Error(err)
		}

		print.BoldFirstLine(fmt.Sprintf("deleted the %s environment configuration", envName))
		if prevDefault != nil && newDefault == nil {
			print.BoldFirstLine("unset the default environment")
		} else if newDefault != nil && (prevDefault == nil || *prevDefault != *newDefault) {
			print.BoldFirstLine(fmt.Sprintf("set the default environment to %s", *newDefault))
		}
	},
}


================================================
FILE: cli/cmd/errors.go
================================================
/*
Copyright 2022 Cortex Labs, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package cmd

import (
	"fmt"
	"net/url"
	"strings"

	"github.com/cortexlabs/cortex/pkg/consts"
	"github.com/cortexlabs/cortex/pkg/lib/errors"
	s "github.com/cortexlabs/cortex/pkg/lib/strings"
	"github.com/cortexlabs/cortex/pkg/lib/urls"
	"github.com/cortexlabs/cortex/pkg/types/clusterconfig"
)

const (
	_errStrCantMakeRequest = "unable to make request"
	_errStrRead            = "unable to read"
)

func errStrFailedToConnect(u url.URL) string {
	return "failed to connect to " + urls.TrimQueryParamsURL(u)
}

const (
	ErrInvalidProvider                     = "cli.invalid_provider"
	ErrInvalidLegacyProvider               = "cli.invalid_legacy_provider"
	ErrNoAvailableEnvironment              = "cli.no_available_environment"
	ErrEnvironmentNotSet                   = "cli.environment_not_set"
	ErrEnvironmentNotFound                 = "cli.environment_not_found"
	ErrFieldNotFoundInEnvironment          = "cli.field_not_found_in_environment"
	ErrInvalidOperatorEndpoint             = "cli.invalid_operator_endpoint"
	ErrNoOperatorLoadBalancer              = "cli.no_operator_load_balancer"
	ErrCortexYAMLNotFound                  = "cli.cortex_yaml_not_found"
	ErrDockerCtrlC                         = "cli.docker_ctrl_c"
	ErrResponseUnknown                     = "cli.response_unknown"
	ErrMissingAWSCredentials               = "cli.missing_aws_credentials"
	ErrCredentialsInClusterConfig          = "cli.credentials_in_cluster_config"
	ErrClusterUp                           = "cli.cluster_up"
	ErrClusterConfigure                    = "cli.cluster_configure"
	ErrClusterDebug                        = "cli.cluster_debug"
	ErrClusterRefresh                      = "cli.cluster_refresh"
	ErrClusterDown                         = "cli.cluster_down"
	ErrSpecifyAtLeastOneFlag               = "cli.specify_at_least_one_flag"
	ErrMinInstancesLowerThan               = "cli.min_instances_lower_than"
	ErrMaxInstancesLowerThan               = "cli.max_instances_lower_than"
	ErrMinInstancesGreaterThanMaxInstances = "cli.min_instances_greater_than_max_instances"
	ErrNodeGroupNotFound                   = "cli.nodegroup_not_found"
	ErrMutuallyExclusiveFlags              = "cli.mutually_exclusive_flags"
	ErrClusterAccessConfigRequired         = "cli.cluster_access_config_or_prompts_required"
	ErrShellCompletionNotSupported         = "cli.shell_completion_not_supported"
	ErrNoTerminalWidth                     = "cli.no_terminal_width"
	ErrDeployFromTopLevelDir               = "cli.deploy_from_top_level_dir"
	ErrAPINameMustBeProvided               = "cli.api_name_must_be_provided"
	ErrAPINotFoundInConfig                 = "cli.api_not_found_in_config"
	ErrClusterUIDsLimitInBucket            = "cli.cluster_uids_limit_in_bucket"
)

func ErrorInvalidProvider(providerStr, cliConfigPath string) error {
	return errors.WithStack(&errors.Error{
		Kind:    ErrInvalidProvider,
		Message: fmt.Sprintf("\"%s\" is not a supported provider (only aws is supported); remove the environment(s) which use the %s provider from %s, or delete %s (it will be recreated on subsequent CLI commands)", providerStr, providerStr, cliConfigPath, cliConfigPath),
	})
}

func ErrorInvalidLegacyProvider(providerStr, cliConfigPath string) error {
	return errors.WithStack(&errors.Error{
		Kind:    ErrInvalidLegacyProvider,
		Message: fmt.Sprintf("the %s provider is no longer supported on cortex v%s; remove the environment(s) which use the %s provider from %s, or delete %s (it will be recreated on subsequent CLI commands)", providerStr, consts.CortexVersionMinor, providerStr, cliConfigPath, cliConfigPath),
	})
}

func ErrorNoAvailableEnvironment() error {
	return errors.WithStack(&errors.Error{
		Kind:    ErrNoAvailableEnvironment,
		Message: "no environments are configured; run `cortex cluster up` to create a cluster, or run `cortex env configure` to connect to an existing cluster",
	})
}

func ErrorEnvironmentNotSet() error {
	return errors.WithStack(&errors.Error{
		Kind:    ErrEnvironmentNotSet,
		Message: "no environment was provided and the default environment is not set; specify the environment to use via the `-e/--env` flag, or run `cortex env default` to set the default environment",
	})
}

func ErrorEnvironmentNotFound(envName string) error {
	return errors.WithStack(&errors.Error{
		Kind:    ErrEnvironmentNotFound,
		Message: fmt.Sprintf("unable to find environment named \"%s\"", envName),
	})
}

func ErrorFieldNotFoundInEnvironment(fieldName string, envName string) error {
	return errors.WithStack(&errors.Error{
		Kind:    ErrFieldNotFoundInEnvironment,
		Message: fmt.Sprintf("%s was not found in %s environment", fieldName, envName),
	})
}

func ErrorInvalidOperatorEndpoint(endpoint string) error {
	return errors.WithStack(&errors.Error{
		Kind:    ErrInvalidOperatorEndpoint,
		Message: fmt.Sprintf("%s is not a cortex operator endpoint; run `cortex cluster info` to show your operator endpoint or run `cortex cluster up` to spin up a new cluster", endpoint),
	})
}

func ErrorNoOperatorLoadBalancer(whichLB string) error {
	return errors.WithStack(&errors.Error{
		Kind:    ErrNoOperatorLoadBalancer,
		Message: fmt.Sprintf("unable to locate %s load balancer", whichLB),
	})
}

func ErrorCortexYAMLNotFound() error {
	return errors.WithStack(&errors.Error{
		Kind:    ErrCortexYAMLNotFound,
		Message: "no api config file was specified, and ./cortex.yaml does not exist; create cortex.yaml, or reference an existing config file by running `cortex deploy <config_file_path>`",
	})
}

func ErrorDockerCtrlC() error {
	return errors.WithStack(&errors.Error{
		Kind:        ErrDockerCtrlC,
		NoPrint:     true,
		NoTelemetry: true,
	})
}

func ErrorResponseUnknown(body string, statusCode int) error {
	msg := body
	if strings.TrimSpace(body) == "" {
		msg = fmt.Sprintf("empty response (status code %d)", statusCode)
	}

	return errors.WithStack(&errors.Error{
		Kind:    ErrResponseUnknown,
		Message: msg,
	})
}

func ErrorClusterUp(out string) error {
	return errors.WithStack(&errors.Error{
		Kind:    ErrClusterUp,
		Message: out,
		NoPrint: true,
	})
}

func ErrorClusterConfigure(out string) error {
	return errors.WithStack(&errors.Error{
		Kind:    ErrClusterConfigure,
		Message: out,
		NoPrint: true,
	})
}

func ErrorClusterDebug(out string) error {
	return errors.WithStack(&errors.Error{
		Kind:    ErrClusterDebug,
		Message: out,
		NoPrint: true,
	})
}

func ErrorClusterRefresh(out string) error {
	return errors.WithStack(&errors.Error{
		Kind:    ErrClusterRefresh,
		Message: out,
		NoPrint: true,
	})
}

func ErrorClusterDown(out string) error {
	return errors.WithStack(&errors.Error{
		Kind:    ErrClusterDown,
		Message: out,
		NoPrint: true,
	})
}

func ErrorSpecifyAtLeastOneFlag(flagsToSpecify ...string) error {
	return errors.WithStack(&errors.Error{
		Kind:    ErrSpecifyAtLeastOneFlag,
		Message: fmt.Sprintf("must specify at least one of the following flags: %s", s.StrsOr(flagsToSpecify)),
	})
}

func ErrorMinInstancesLowerThan(minValue int64) error {
	return errors.WithStack(&errors.Error{
		Kind:    ErrMinInstancesLowerThan,
		Message: fmt.Sprintf("min instances cannot be set to a value lower than %d", minValue),
	})
}

func ErrorMaxInstancesLowerThan(minValue int64) error {
	return errors.WithStack(&errors.Error{
		Kind:    ErrMaxInstancesLowerThan,
		Message: fmt.Sprintf("max instances cannot be set to a value lower than %d", minValue),
	})
}

func ErrorMinInstancesGreaterThanMaxInstances(minInstances, maxInstances int64) error {
	return errors.WithStack(&errors.Error{
		Kind:    ErrMinInstancesGreaterThanMaxInstances,
		Message: fmt.Sprintf("min instances (%d) cannot be set to a value higher than max instances (%d)", minInstances, maxInstances),
	})
}

func ErrorNodeGroupNotFound(scalingNodeGroupName, clusterName, clusterRegion string, availableNodeGroups []string) error {
	return errors.WithStack(&errors.Error{
		Kind:    ErrNodeGroupNotFound,
		Message: fmt.Sprintf("nodegroup %s couldn't be found in the cluster named %s in region %s; the available nodegroups for this cluster are: %s", scalingNodeGroupName, clusterName, clusterRegion, s.StrsAnd(availableNodeGroups)),
	})
}

func ErrorMutuallyExclusiveFlags(flagA, flagB string) error {
	return errors.WithStack(&errors.Error{
		Kind:    ErrMutuallyExclusiveFlags,
		Message: fmt.Sprintf("flags %s and %s cannot be used at the same time", flagA, flagB),
	})
}

func ErrorClusterAccessConfigRequired(cliFlagsOnly bool) error {
	message := ""
	if cliFlagsOnly {
		message = "please provide the name and region of the cluster using the CLI flags (e.g. via `--name` and `--region`)"
	} else {
		message = fmt.Sprintf("please provide a cluster configuration file which specifies `%s` and `%s` (e.g. via `--config cluster.yaml`) or use the CLI flags to specify the cluster (e.g. via `--name` and `--region`)", clusterconfig.ClusterNameKey, clusterconfig.RegionKey)
	}
	return errors.WithStack(&errors.Error{
		Kind:    ErrClusterAccessConfigRequired,
		Message: message,
	})
}

func ErrorShellCompletionNotSupported(shell string) error {
	return errors.WithStack(&errors.Error{
		Kind:    ErrShellCompletionNotSupported,
		Message: fmt.Sprintf("shell completion for %s is not supported (only bash and zsh are supported)", shell),
	})
}

func ErrorNoTerminalWidth() error {
	return errors.WithStack(&errors.Error{
		Kind:    ErrNoTerminalWidth,
		Message: "unable to determine terminal width; please re-run the command without the `--watch` flag",
	})
}

func ErrorDeployFromTopLevelDir(genericDirName string) error {
	return errors.WithStack(&errors.Error{
		Kind:    ErrDeployFromTopLevelDir,
		Message: fmt.Sprintf("cannot deploy from your %s directory - when deploying your API, cortex sends all files in your project directory (i.e. the directory which contains cortex.yaml) to your cluster (see https://docs.cortexlabs.com/v/%s/); therefore it is recommended to create a subdirectory for your project files", genericDirName, consts.CortexVersionMinor),
	})
}

func ErrorAPINameMustBeProvided() error {
	return errors.WithStack(&errors.Error{
		Kind:    ErrAPINameMustBeProvided,
		Message: fmt.Sprintf("multiple apis listed; please specify the name of an api"),
	})
}

func ErrorAPINotFoundInConfig(apiName string) error {
	return errors.WithStack(&errors.Error{
		Kind:    ErrAPINotFoundInConfig,
		Message: fmt.Sprintf("api '%s' not found in config", apiName),
	})
}

func ErrorClusterUIDsLimitInBucket(bucket string) error {
	return errors.WithStack(&errors.Error{
		Kind:    ErrClusterUIDsLimitInBucket,
		Message: fmt.Sprintf("detected too many top level folders in %s bucket; please empty your bucket and try again", bucket),
	})
}


================================================
FILE: cli/cmd/get.go
================================================
/*
Copyright 2022 Cortex Labs, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package cmd

import (
	"fmt"
	"strings"
	"time"

	"github.com/cortexlabs/cortex/cli/cluster"
	"github.com/cortexlabs/cortex/cli/types/cliconfig"
	"github.com/cortexlabs/cortex/cli/types/flags"
	"github.com/cortexlabs/cortex/pkg/lib/console"
	"github.com/cortexlabs/cortex/pkg/lib/errors"
	"github.com/cortexlabs/cortex/pkg/lib/exit"
	libjson "github.com/cortexlabs/cortex/pkg/lib/json"
	"github.com/cortexlabs/cortex/pkg/lib/pointer"
	s "github.com/cortexlabs/cortex/pkg/lib/strings"
	"github.com/cortexlabs/cortex/pkg/lib/table"
	"github.com/cortexlabs/cortex/pkg/lib/telemetry"
	libtime "github.com/cortexlabs/cortex/pkg/lib/time"
	"github.com/cortexlabs/cortex/pkg/operator/schema"
	"github.com/cortexlabs/cortex/pkg/types/userconfig"
	"github.com/cortexlabs/yaml"
	"github.com/spf13/cobra"
)

const (
	_titleEnvironment = "env"
	_titleRealtimeAPI = "realtime api"
	_titleAsyncAPI    = "async api"
	_titleLive        = "live"
	_titleUpToDate    = "up-to-date"
	_titleLastUpdated = "last update"
)

var (
	_flagGetEnv   string
	_flagGetWatch bool
)

func getInit() {
	_getCmd.Flags().SortFlags = false
	_getCmd.Flags().StringVarP(&_flagGetEnv, "env", "e", "", "environment to use")
	_getCmd.Flags().BoolVarP(&_flagGetWatch, "watch", "w", false, "re-run the command every 2 seconds")
	_getCmd.Flags().VarP(&_flagOutput, "output", "o", fmt.Sprintf("output format: one of %s", strings.Join(flags.OutputTypeStringsExcluding(flags.YAMLOutputType), "|")))
	addVerboseFlag(_getCmd)
}

var _getCmd = &cobra.Command{
	Use:   "get [API_NAME] [JOB_ID]",
	Short: "get information about apis or jobs",
	Args:  cobra.RangeArgs(0, 2),
	Run: func(cmd *cobra.Command, args []string) {
		var envName string
		if wasFlagProvided(cmd, "env") {
			envName = _flagGetEnv
		} else if len(args) > 0 {
			var err error
			envName, err = getEnvFromFlag("")
			if err != nil {
				telemetry.Event("cli.get")
				exit.Error(err)
			}
		}

		if len(args) == 1 || wasFlagProvided(cmd, "env") {
			env, err := ReadOrConfigureEnv(envName)
			if err != nil {
				telemetry.Event("cli.get")
				exit.Error(err)
			}
			telemetry.Event("cli.get", map[string]interface{}{"env_name": env.Name})
		} else {
			telemetry.Event("cli.get")
		}

		rerun(_flagGetWatch, func() (string, error) {
			if len(args) == 1 {
				env, err := ReadOrConfigureEnv(envName)
				if err != nil {
					exit.Error(err)
				}

				out, err := envStringIfNotSpecified(envName, cmd)
				if err != nil {
					return "", err
				}
				apiTable, err := getAPI(env, args[0])
				if err != nil {
					return "", err
				}

				if _flagOutput == flags.JSONOutputType || _flagOutput == flags.YAMLOutputType {
					return apiTable, nil
				}

				return out + apiTable, nil
			} else if len(args) == 2 {
				env, err := ReadOrConfigureEnv(envName)
				if err != nil {
					exit.Error(err)
				}

				out, err := envStringIfNotSpecified(envName, cmd)
				if err != nil {
					return "", err
				}

				apisRes, err := cluster.GetAPI(MustGetOperatorConfig(envName), args[0])
				if err != nil {
					return "", err
				}

				var jobTable string
				if apisRes[0].Metadata.Kind == userconfig.BatchAPIKind {
					jobTable, err = getBatchJob(env, args[0], args[1])
				} else {
					jobTable, err = getTaskJob(env, args[0], args[1])
				}
				if err != nil {
					return "", err
				}
				if _flagOutput == flags.JSONOutputType || _flagOutput == flags.YAMLOutputType {
					return jobTable, nil
				}

				return out + jobTable, nil
			} else {
				envs, err := listConfiguredEnvs()
				if err != nil {
					return "", err
				}
				if len(envs) == 0 {
					return "", ErrorNoAvailableEnvironment()
				}

				if wasFlagProvided(cmd, "env") {
					env, err := ReadOrConfigureEnv(envName)
					if err != nil {
						exit.Error(err)
					}

					out, err := envStringIfNotSpecified(envName, cmd)
					if err != nil {
						return "", err
					}

					apiTable, err := getAPIsByEnv(env)
					if err != nil {
						return "", err
					}

					if _flagOutput == flags.JSONOutputType || _flagOutput == flags.YAMLOutputType {
						return apiTable, nil
					}

					return out + apiTable, nil
				}

				out, err := getAPIsInAllEnvironments()
				if err != nil {
					return "", err
				}

				return out, nil
			}
		})
	},
}

func getAPIsInAllEnvironments() (string, error) {
	cliConfig, err := readCLIConfig()
	if err != nil {
		return "", err
	}

	var allRealtimeAPIs []schema.APIResponse
	var allRealtimeAPIEnvs []string
	var allAsyncAPIs []schema.APIResponse
	var allAsyncAPIEnvs []string
	var allBatchAPIs []schema.APIResponse
	var allBatchAPIEnvs []string
	var allTaskAPIs []schema.APIResponse
	var allTaskAPIEnvs []string
	var allTrafficSplitters []schema.APIResponse
	var allTrafficSplitterEnvs []string

	type getAPIsOutput struct {
		EnvName string               `json:"env_name"`
		APIs    []schema.APIResponse `json:"apis"`
		Error   string               `json:"error"`
	}

	allAPIsOutput := []getAPIsOutput{}

	errorsMap := map[string]error{}
	// get apis from both environments
	for _, env := range cliConfig.Environments {
		apisRes, err := cluster.GetAPIs(MustGetOperatorConfig(env.Name))

		apisOutput := getAPIsOutput{
			EnvName: env.Name,
			APIs:    apisRes,
		}

		if err == nil {
			for _, api := range apisRes {
				switch api.Metadata.Kind {
				case userconfig.BatchAPIKind:
					allBatchAPIEnvs = append(allBatchAPIEnvs, env.Name)
					allBatchAPIs = append(allBatchAPIs, api)
				case userconfig.RealtimeAPIKind:
					allRealtimeAPIEnvs = append(allRealtimeAPIEnvs, env.Name)
					allRealtimeAPIs = append(allRealtimeAPIs, api)
				case userconfig.AsyncAPIKind:
					allAsyncAPIEnvs = append(allAsyncAPIEnvs, env.Name)
					allAsyncAPIs = append(allAsyncAPIs, api)
				case userconfig.TaskAPIKind:
					allTaskAPIEnvs = append(allTaskAPIEnvs, env.Name)
					allTaskAPIs = append(allTaskAPIs, api)
				case userconfig.TrafficSplitterKind:
					allTrafficSplitterEnvs = append(allTrafficSplitterEnvs, env.Name)
					allTrafficSplitters = append(allTrafficSplitters, api)
				}
			}
		} else {
			apisOutput.Error = err.Error()
			errorsMap[env.Name] = err
		}

		allAPIsOutput = append(allAPIsOutput, apisOutput)
	}

	var bytes []byte
	if _flagOutput == flags.JSONOutputType {
		bytes, err = libjson.Marshal(allAPIsOutput)
	} else if _flagOutput == flags.YAMLOutputType {
		bytes, err = yaml.Marshal(allAPIsOutput)
	}
	if err != nil {
		return "", err
	}
	if _flagOutput == flags.JSONOutputType || _flagOutput == flags.YAMLOutputType {
		return string(bytes), nil
	}

	out := ""

	if len(allRealtimeAPIs) == 0 && len(allAsyncAPIs) == 0 && len(allBatchAPIs) == 0 && len(allTrafficSplitters) == 0 && len(allTaskAPIs) == 0 {
		// check if any environments errorred
		if len(errorsMap) != len(cliConfig.Environments) {
			if len(errorsMap) == 0 {
				return console.Bold("no apis are deployed"), nil
			}

			var successfulEnvs []string
			for _, env := range cliConfig.Environments {
				if _, ok := errorsMap[env.Name]; !ok {
					successfulEnvs = append(successfulEnvs, env.Name)
				}
			}
			fmt.Println(console.Bold(fmt.Sprintf("no apis are deployed in %s: %s", s.PluralS("environment", len(successfulEnvs)), s.StrsAnd(successfulEnvs))) + "\n")
		}

		// Print the first error
		for name, err := range errorsMap {
			if err != nil {
				exit.Error(errors.Wrap(err, "env "+name))
			}
		}
	} else {
		if len(allBatchAPIs) > 0 {
			t := batchAPIsTable(allBatchAPIs, allBatchAPIEnvs)
			out += t.MustFormat()
		}

		if len(allTaskAPIs) > 0 {
			t := taskAPIsTable(allTaskAPIs, allTaskAPIEnvs)
			if len(allBatchAPIs) > 0 {
				out += "\n"
			}
			out += t.MustFormat()
		}

		if len(allRealtimeAPIs) > 0 {
			t := realtimeAPIsTable(allRealtimeAPIs, allRealtimeAPIEnvs)
			if len(allBatchAPIs) > 0 || len(allTaskAPIs) > 0 {
				out += "\n"
			}
			out += t.MustFormat()
		}
		if len(allAsyncAPIs) > 0 {
			t := asyncAPIsTable(allAsyncAPIs, allAsyncAPIEnvs)
			if len(allBatchAPIs) > 0 || len(allTaskAPIs) > 0 || len(allRealtimeAPIs) > 0 {
				out += "\n"
			}
			out += t.MustFormat()
		}

		if len(allTrafficSplitters) > 0 {
			t := trafficSplitterListTable(allTrafficSplitters, allTrafficSplitterEnvs)

			if len(allBatchAPIs) > 0 || len(allTaskAPIs) > 0 || len(allRealtimeAPIs) > 0 || len(allAsyncAPIs) > 0 {
				out += "\n"
			}

			out += t.MustFormat()
		}
	}

	if len(errorsMap) == 1 {
		out = s.EnsureBlankLineIfNotEmpty(out)
		out += fmt.Sprintf("unable to detect apis from the %s environment; run `cortex get --env %s` if this is unexpected\n", errors.FirstKeyInErrorMap(errorsMap), errors.FirstKeyInErrorMap(errorsMap))
	} else if len(errorsMap) > 1 {
		out = s.EnsureBlankLineIfNotEmpty(out)
		out += fmt.Sprintf("unable to detect apis from the %s environments; run `cortex get --env ENV_NAME` if this is unexpected\n", s.StrsAnd(errors.NonNilErrorMapKeys(errorsMap)))
	}

	return out, nil
}

func getAPIsByEnv(env cliconfig.Environment) (string, error) {
	apisRes, err := cluster.GetAPIs(MustGetOperatorConfig(env.Name))
	if err != nil {
		return "", err
	}

	var bytes []byte
	if _flagOutput == flags.JSONOutputType {
		bytes, err = libjson.Marshal(apisRes)
	} else if _flagOutput == flags.YAMLOutputType {
		bytes, err = yaml.Marshal(apisRes)
	}
	if err != nil {
		return "", err
	}
	if _flagOutput == flags.JSONOutputType || _flagOutput == flags.YAMLOutputType {
		return string(bytes), nil
	}

	var allRealtimeAPIs []schema.APIResponse
	var allAsyncAPIs []schema.APIResponse
	var allBatchAPIs []schema.APIResponse
	var allTaskAPIs []schema.APIResponse
	var allTrafficSplitters []schema.APIResponse

	for _, api := range apisRes {
		switch api.Metadata.Kind {
		case userconfig.BatchAPIKind:
			allBatchAPIs = append(allBatchAPIs, api)
		case userconfig.TaskAPIKind:
			allTaskAPIs = append(allTaskAPIs, api)
		case user
Download .txt
gitextract_xza_bns1/

├── .circleci/
│   └── config.yml
├── .dockerignore
├── .gitbook.yaml
├── .github/
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug-report.md
│   │   ├── feature-request.md
│   │   └── question.md
│   └── pull_request_template.md
├── .gitignore
├── CONTRIBUTING.md
├── LICENSE
├── Makefile
├── README.md
├── build/
│   ├── amend-image.sh
│   ├── amend-images.sh
│   ├── build-image.sh
│   ├── build-images.sh
│   ├── cli.sh
│   ├── generate_ami_mapping.go
│   ├── images.sh
│   ├── lint-docs.sh
│   ├── lint.sh
│   ├── push-image.sh
│   ├── push-images.sh
│   └── test.sh
├── cli/
│   ├── cluster/
│   │   ├── delete.go
│   │   ├── deploy.go
│   │   ├── errors.go
│   │   ├── get.go
│   │   ├── info.go
│   │   ├── lib_http_client.go
│   │   ├── logs.go
│   │   └── refresh.go
│   ├── cmd/
│   │   ├── cluster.go
│   │   ├── completion.go
│   │   ├── const.go
│   │   ├── delete.go
│   │   ├── deploy.go
│   │   ├── describe.go
│   │   ├── env.go
│   │   ├── errors.go
│   │   ├── get.go
│   │   ├── lib_apis.go
│   │   ├── lib_async_apis.go
│   │   ├── lib_aws_creds.go
│   │   ├── lib_batch_apis.go
│   │   ├── lib_cli_config.go
│   │   ├── lib_client_id.go
│   │   ├── lib_cluster_config.go
│   │   ├── lib_manager.go
│   │   ├── lib_realtime_apis.go
│   │   ├── lib_task_apis.go
│   │   ├── lib_traffic_splitters.go
│   │   ├── lib_watch.go
│   │   ├── logs.go
│   │   ├── refresh.go
│   │   ├── root.go
│   │   └── version.go
│   ├── lib/
│   │   └── routines/
│   │       └── routines.go
│   ├── main.go
│   └── types/
│       ├── cliconfig/
│       │   ├── cli_config.go
│       │   ├── config_key.go
│       │   ├── environment.go
│       │   └── errors.go
│       └── flags/
│           ├── errors.go
│           └── output_type.go
├── cmd/
│   ├── activator/
│   │   └── main.go
│   ├── async-gateway/
│   │   └── main.go
│   ├── autoscaler/
│   │   └── main.go
│   ├── dequeuer/
│   │   └── main.go
│   ├── enqueuer/
│   │   └── main.go
│   ├── operator/
│   │   └── main.go
│   └── proxy/
│       └── main.go
├── dev/
│   ├── build_cli.sh
│   ├── create_user.py
│   ├── delete_ecr_repos.py
│   ├── export_images.sh
│   ├── find_missing_docs_links.py
│   ├── format.sh
│   ├── generate_cli_md.sh
│   ├── generate_python_client_md.sh
│   ├── get_operator_url.py
│   ├── load.go
│   ├── minimum_aws_policy.json
│   ├── operator_local.sh
│   ├── prometheus.md
│   ├── registry.sh
│   ├── update_cli_config.py
│   ├── util.sh
│   └── versions.md
├── docs/
│   ├── README.md
│   ├── clients/
│   │   ├── cli.md
│   │   ├── install.md
│   │   ├── python.md
│   │   └── uninstall.md
│   ├── clusters/
│   │   ├── advanced/
│   │   │   ├── kubectl.md
│   │   │   ├── registry.md
│   │   │   └── self-hosted-images.md
│   │   ├── instances/
│   │   │   ├── multi.md
│   │   │   └── spot.md
│   │   ├── management/
│   │   │   ├── auth.md
│   │   │   ├── create.md
│   │   │   ├── delete.md
│   │   │   ├── environments.md
│   │   │   ├── production.md
│   │   │   └── update.md
│   │   ├── networking/
│   │   │   ├── api-gateway.md
│   │   │   ├── custom-domain.md
│   │   │   ├── https.md
│   │   │   ├── load-balancers.md
│   │   │   └── vpc-peering.md
│   │   └── observability/
│   │       ├── alerting.md
│   │       ├── logging.md
│   │       └── metrics.md
│   ├── overview.md
│   ├── start.md
│   ├── summary.md
│   └── workloads/
│       ├── async/
│       │   ├── async.md
│       │   ├── autoscaling.md
│       │   ├── configuration.md
│       │   ├── containers.md
│       │   ├── example.md
│       │   └── statuses.md
│       ├── batch/
│       │   ├── batch.md
│       │   ├── configuration.md
│       │   ├── containers.md
│       │   ├── example.md
│       │   ├── jobs.md
│       │   └── statuses.md
│       ├── realtime/
│       │   ├── autoscaling.md
│       │   ├── configuration.md
│       │   ├── containers.md
│       │   ├── example.md
│       │   ├── metrics.md
│       │   ├── realtime.md
│       │   ├── statuses.md
│       │   ├── traffic-splitter.md
│       │   └── troubleshooting.md
│       └── task/
│           ├── configuration.md
│           ├── containers.md
│           ├── example.md
│           ├── jobs.md
│           ├── statuses.md
│           └── task.md
├── get-cli.sh
├── go.mod
├── go.sum
├── images/
│   ├── activator/
│   │   └── Dockerfile
│   ├── async-gateway/
│   │   └── Dockerfile
│   ├── autoscaler/
│   │   └── Dockerfile
│   ├── cluster-autoscaler/
│   │   └── Dockerfile
│   ├── controller-manager/
│   │   └── Dockerfile
│   ├── dequeuer/
│   │   └── Dockerfile
│   ├── enqueuer/
│   │   └── Dockerfile
│   ├── event-exporter/
│   │   └── Dockerfile
│   ├── fluent-bit/
│   │   └── Dockerfile
│   ├── grafana/
│   │   └── Dockerfile
│   ├── istio-pilot/
│   │   └── Dockerfile
│   ├── istio-proxy/
│   │   └── Dockerfile
│   ├── kube-rbac-proxy/
│   │   └── Dockerfile
│   ├── kubexit/
│   │   └── Dockerfile
│   ├── manager/
│   │   └── Dockerfile
│   ├── metrics-server/
│   │   └── Dockerfile
│   ├── neuron-device-plugin/
│   │   └── Dockerfile
│   ├── neuron-scheduler/
│   │   └── Dockerfile
│   ├── nvidia-device-plugin/
│   │   └── Dockerfile
│   ├── operator/
│   │   └── Dockerfile
│   ├── prometheus/
│   │   └── Dockerfile
│   ├── prometheus-config-reloader/
│   │   └── Dockerfile
│   ├── prometheus-dcgm-exporter/
│   │   └── Dockerfile
│   ├── prometheus-kube-state-metrics/
│   │   └── Dockerfile
│   ├── prometheus-node-exporter/
│   │   └── Dockerfile
│   ├── prometheus-operator/
│   │   └── Dockerfile
│   ├── prometheus-statsd-exporter/
│   │   └── Dockerfile
│   └── proxy/
│       └── Dockerfile
├── manager/
│   ├── check_cortex_version.sh
│   ├── cluster_config_env.py
│   ├── debug.sh
│   ├── generate_eks.py
│   ├── get_api_load_balancer_state.py
│   ├── get_operator_load_balancer_state.py
│   ├── get_operator_target_group_status.py
│   ├── helpers.py
│   ├── install.sh
│   ├── manifests/
│   │   ├── activator.yaml.j2
│   │   ├── ami.json
│   │   ├── apis.yaml.j2
│   │   ├── async-gateway.yaml.j2
│   │   ├── autoscaler.yaml.j2
│   │   ├── cluster-autoscaler.yaml.j2
│   │   ├── default_cortex_cli_config.yaml
│   │   ├── event-exporter.yaml
│   │   ├── fluent-bit.yaml.j2
│   │   ├── grafana/
│   │   │   ├── grafana-dashboard-async.yaml
│   │   │   ├── grafana-dashboard-batch.yaml
│   │   │   ├── grafana-dashboard-cluster.yaml
│   │   │   ├── grafana-dashboard-control-plane.yaml
│   │   │   ├── grafana-dashboard-nodes.yaml
│   │   │   ├── grafana-dashboard-realtime.yaml
│   │   │   ├── grafana-dashboard-task.yaml
│   │   │   └── grafana.yaml.j2
│   │   ├── inferentia.yaml
│   │   ├── istio.yaml.j2
│   │   ├── kube-proxy.patch.yaml
│   │   ├── metrics-server.yaml
│   │   ├── namespaces.yaml
│   │   ├── nvidia.yaml
│   │   ├── operator.yaml.j2
│   │   ├── prometheus-additional-scrape-configs.yaml.j2
│   │   ├── prometheus-dcgm-exporter.yaml
│   │   ├── prometheus-kube-state-metrics.yaml
│   │   ├── prometheus-kubelet-exporter.yaml
│   │   ├── prometheus-monitoring.yaml
│   │   ├── prometheus-node-exporter.yaml
│   │   ├── prometheus-operator.yaml
│   │   └── prometheus-statsd-exporter.yaml
│   ├── refresh.sh
│   ├── render_template.py
│   ├── requirements.txt
│   ├── uninstall.sh
│   └── upgrade_kube_proxy_mode.py
├── pkg/
│   ├── activator/
│   │   ├── activator.go
│   │   ├── activator_test.go
│   │   ├── api_activator.go
│   │   ├── api_activator_test.go
│   │   ├── handler.go
│   │   ├── handler_test.go
│   │   ├── helpers.go
│   │   └── request_stats.go
│   ├── async-gateway/
│   │   ├── endpoint.go
│   │   ├── queue.go
│   │   ├── service.go
│   │   ├── storage.go
│   │   └── types.go
│   ├── autoscaler/
│   │   ├── async_scaler.go
│   │   ├── autoscaler.go
│   │   ├── autoscaler_test.go
│   │   ├── client.go
│   │   ├── handler.go
│   │   ├── realtime_scaler.go
│   │   ├── recommendations.go
│   │   └── scaler_func.go
│   ├── config/
│   │   └── config.go
│   ├── consts/
│   │   └── consts.go
│   ├── crds/
│   │   ├── Makefile
│   │   ├── PROJECT
│   │   ├── apis/
│   │   │   └── batch/
│   │   │       └── v1alpha1/
│   │   │           ├── batchjob_metrics.go
│   │   │           ├── batchjob_types.go
│   │   │           ├── groupversion_info.go
│   │   │           └── zz_generated.deepcopy.go
│   │   ├── config/
│   │   │   ├── crd/
│   │   │   │   ├── bases/
│   │   │   │   │   └── batch.cortex.dev_batchjobs.yaml
│   │   │   │   ├── kustomization.yaml
│   │   │   │   ├── kustomizeconfig.yaml
│   │   │   │   └── patches/
│   │   │   │       ├── cainjection_in_batchjobs.yaml
│   │   │   │       └── webhook_in_batchjobs.yaml
│   │   │   ├── default/
│   │   │   │   ├── kustomization.yaml
│   │   │   │   ├── manager_auth_proxy_patch.yaml
│   │   │   │   └── manager_config_patch.yaml
│   │   │   ├── manager/
│   │   │   │   ├── controller_manager_config.yaml
│   │   │   │   ├── kustomization.yaml
│   │   │   │   └── manager.yaml
│   │   │   ├── prometheus/
│   │   │   │   ├── kustomization.yaml
│   │   │   │   └── monitor.yaml
│   │   │   ├── rbac/
│   │   │   │   ├── auth_proxy_client_clusterrole.yaml
│   │   │   │   ├── auth_proxy_role.yaml
│   │   │   │   ├── auth_proxy_role_binding.yaml
│   │   │   │   ├── auth_proxy_service.yaml
│   │   │   │   ├── batchjob_editor_role.yaml
│   │   │   │   ├── batchjob_viewer_role.yaml
│   │   │   │   ├── kustomization.yaml
│   │   │   │   ├── leader_election_role.yaml
│   │   │   │   ├── leader_election_role_binding.yaml
│   │   │   │   ├── role.yaml
│   │   │   │   ├── role_binding.yaml
│   │   │   │   └── service_account.yaml
│   │   │   └── samples/
│   │   │       └── batch_v1alpha1_batchjob.yaml
│   │   ├── controllers/
│   │   │   ├── batch/
│   │   │   │   ├── batchjob_controller.go
│   │   │   │   ├── batchjob_controller_config.go
│   │   │   │   ├── batchjob_controller_helpers.go
│   │   │   │   ├── batchjob_controller_test.go
│   │   │   │   └── suite_test.go
│   │   │   └── errors.go
│   │   ├── hack/
│   │   │   ├── boilerplate.go.txt
│   │   │   └── run_manager.sh
│   │   └── main.go
│   ├── dequeuer/
│   │   ├── async_handler.go
│   │   ├── async_handler_test.go
│   │   ├── async_stats.go
│   │   ├── async_stats_test.go
│   │   ├── batch_handler.go
│   │   ├── batch_handler_test.go
│   │   ├── dequeuer.go
│   │   ├── dequeuer_test.go
│   │   ├── errors.go
│   │   ├── http_handler.go
│   │   ├── message_handler.go
│   │   ├── probes.go
│   │   ├── probes_test.go
│   │   ├── queue_attributes.go
│   │   └── request_stats.go
│   ├── enqueuer/
│   │   ├── enqueuer.go
│   │   ├── errors.go
│   │   ├── helpers.go
│   │   └── uploader.go
│   ├── health/
│   │   └── health.go
│   ├── lib/
│   │   ├── archive/
│   │   │   ├── archive_test.go
│   │   │   ├── archiver.go
│   │   │   ├── errors.go
│   │   │   ├── input.go
│   │   │   ├── tar.go
│   │   │   ├── tgz.go
│   │   │   └── zip.go
│   │   ├── aws/
│   │   │   ├── acm.go
│   │   │   ├── apigateway.go
│   │   │   ├── autoscaling.go
│   │   │   ├── aws.go
│   │   │   ├── clients.go
│   │   │   ├── cloudformation.go
│   │   │   ├── cloudwatch.go
│   │   │   ├── credentials.go
│   │   │   ├── ec2.go
│   │   │   ├── ec2_test.go
│   │   │   ├── ecr.go
│   │   │   ├── eks.go
│   │   │   ├── elb.go
│   │   │   ├── elbv2.go
│   │   │   ├── errors.go
│   │   │   ├── gen_resource_metadata.py
│   │   │   ├── iam.go
│   │   │   ├── resource_metadata.go
│   │   │   ├── s3.go
│   │   │   ├── servicequotas.go
│   │   │   ├── sqs.go
│   │   │   └── sts.go
│   │   ├── cast/
│   │   │   ├── interface.go
│   │   │   └── interface_test.go
│   │   ├── configreader/
│   │   │   ├── bool.go
│   │   │   ├── bool_list.go
│   │   │   ├── bool_ptr.go
│   │   │   ├── errors.go
│   │   │   ├── float32.go
│   │   │   ├── float32_list.go
│   │   │   ├── float32_ptr.go
│   │   │   ├── float64.go
│   │   │   ├── float64_list.go
│   │   │   ├── float64_ptr.go
│   │   │   ├── int.go
│   │   │   ├── int32.go
│   │   │   ├── int32_list.go
│   │   │   ├── int32_ptr.go
│   │   │   ├── int64.go
│   │   │   ├── int64_list.go
│   │   │   ├── int64_ptr.go
│   │   │   ├── int_list.go
│   │   │   ├── int_ptr.go
│   │   │   ├── interface.go
│   │   │   ├── interface_map.go
│   │   │   ├── interface_map_list.go
│   │   │   ├── interface_test.go
│   │   │   ├── reader.go
│   │   │   ├── reader_test.go
│   │   │   ├── string.go
│   │   │   ├── string_list.go
│   │   │   ├── string_map.go
│   │   │   ├── string_ptr.go
│   │   │   ├── types.go
│   │   │   └── validators.go
│   │   ├── console/
│   │   │   └── format.go
│   │   ├── cron/
│   │   │   └── cron.go
│   │   ├── debug/
│   │   │   └── debug.go
│   │   ├── docker/
│   │   │   ├── docker.go
│   │   │   └── errors.go
│   │   ├── errors/
│   │   │   ├── error.go
│   │   │   ├── errors.go
│   │   │   ├── message.go
│   │   │   ├── multi.go
│   │   │   └── stack.go
│   │   ├── exit/
│   │   │   └── exit.go
│   │   ├── files/
│   │   │   ├── errors.go
│   │   │   ├── files.go
│   │   │   └── files_test.go
│   │   ├── hash/
│   │   │   └── hash.go
│   │   ├── json/
│   │   │   ├── errors.go
│   │   │   └── json.go
│   │   ├── k8s/
│   │   │   ├── configmap.go
│   │   │   ├── deployment.go
│   │   │   ├── errors.go
│   │   │   ├── hpa.go
│   │   │   ├── ingress.go
│   │   │   ├── job.go
│   │   │   ├── k8s.go
│   │   │   ├── node.go
│   │   │   ├── parsers.go
│   │   │   ├── pod.go
│   │   │   ├── quantity.go
│   │   │   ├── secret.go
│   │   │   ├── service.go
│   │   │   ├── virtual_service.go
│   │   │   └── volume.go
│   │   ├── logging/
│   │   │   ├── errors.go
│   │   │   └── logging.go
│   │   ├── maps/
│   │   │   ├── interface.go
│   │   │   └── string.go
│   │   ├── math/
│   │   │   ├── float32.go
│   │   │   ├── float64.go
│   │   │   ├── int.go
│   │   │   ├── int32.go
│   │   │   └── int64.go
│   │   ├── msgpack/
│   │   │   ├── errors.go
│   │   │   └── msgpack.go
│   │   ├── parallel/
│   │   │   ├── parallel.go
│   │   │   └── parallel_test.go
│   │   ├── pointer/
│   │   │   ├── equal.go
│   │   │   ├── pointer.go
│   │   │   └── pointer_test.go
│   │   ├── print/
│   │   │   └── print.go
│   │   ├── prompt/
│   │   │   ├── errors.go
│   │   │   └── prompt.go
│   │   ├── random/
│   │   │   └── random.go
│   │   ├── regex/
│   │   │   ├── regex.go
│   │   │   └── regex_test.go
│   │   ├── requests/
│   │   │   ├── errors.go
│   │   │   └── requests.go
│   │   ├── sets/
│   │   │   └── strset/
│   │   │       ├── strset.go
│   │   │       ├── strset_test.go
│   │   │       └── threadsafe/
│   │   │           ├── strset.go
│   │   │           └── strset_test.go
│   │   ├── slices/
│   │   │   ├── bool.go
│   │   │   ├── errors.go
│   │   │   ├── float32.go
│   │   │   ├── float64.go
│   │   │   ├── float64_ptr.go
│   │   │   ├── float64_ptr_test.go
│   │   │   ├── int.go
│   │   │   ├── int32.go
│   │   │   ├── int64.go
│   │   │   ├── sort.go
│   │   │   ├── string.go
│   │   │   └── string_test.go
│   │   ├── strings/
│   │   │   ├── operations.go
│   │   │   ├── operations_test.go
│   │   │   ├── parse.go
│   │   │   ├── stringify.go
│   │   │   └── stringify_test.go
│   │   ├── structs/
│   │   │   ├── deepcopy.go
│   │   │   └── deepcopy_test.go
│   │   ├── table/
│   │   │   ├── errors.go
│   │   │   ├── key_value.go
│   │   │   └── table.go
│   │   ├── telemetry/
│   │   │   ├── error_cache.go
│   │   │   ├── errors.go
│   │   │   └── telemetry.go
│   │   ├── time/
│   │   │   └── time.go
│   │   └── urls/
│   │       ├── errors.go
│   │       └── urls.go
│   ├── operator/
│   │   ├── endpoints/
│   │   │   ├── delete.go
│   │   │   ├── deploy.go
│   │   │   ├── describe.go
│   │   │   ├── errors.go
│   │   │   ├── get.go
│   │   │   ├── get_batch_job.go
│   │   │   ├── get_task_job.go
│   │   │   ├── info.go
│   │   │   ├── logs.go
│   │   │   ├── logs_job.go
│   │   │   ├── middleware.go
│   │   │   ├── params.go
│   │   │   ├── refresh.go
│   │   │   ├── respond.go
│   │   │   ├── stop_batch_job.go
│   │   │   ├── stop_task_job.go
│   │   │   ├── submit_batch.go
│   │   │   ├── submit_task.go
│   │   │   └── verify_cortex.go
│   │   ├── lib/
│   │   │   ├── exit/
│   │   │   │   └── exit.go
│   │   │   └── routines/
│   │   │       └── routines.go
│   │   ├── operator/
│   │   │   ├── cron.go
│   │   │   ├── deployed_resource.go
│   │   │   ├── errors.go
│   │   │   ├── k8s.go
│   │   │   ├── logging.go
│   │   │   ├── memory_capacity.go
│   │   │   ├── storage.go
│   │   │   └── workload_logging.go
│   │   ├── resources/
│   │   │   ├── asyncapi/
│   │   │   │   ├── api.go
│   │   │   │   ├── errors.go
│   │   │   │   ├── k8s_specs.go
│   │   │   │   ├── queue.go
│   │   │   │   ├── queue_metrics.go
│   │   │   │   └── status.go
│   │   │   ├── errors.go
│   │   │   ├── job/
│   │   │   │   ├── batchapi/
│   │   │   │   │   ├── api.go
│   │   │   │   │   ├── errors.go
│   │   │   │   │   ├── job.go
│   │   │   │   │   ├── job_status.go
│   │   │   │   │   ├── k8s_specs.go
│   │   │   │   │   ├── queue.go
│   │   │   │   │   ├── s3_iterator.go
│   │   │   │   │   └── validations.go
│   │   │   │   ├── cache.go
│   │   │   │   ├── consts.go
│   │   │   │   ├── errors.go
│   │   │   │   ├── state.go
│   │   │   │   ├── taskapi/
│   │   │   │   │   ├── api.go
│   │   │   │   │   ├── cron.go
│   │   │   │   │   ├── job.go
│   │   │   │   │   ├── job_status.go
│   │   │   │   │   ├── k8s_specs.go
│   │   │   │   │   ├── metrics.go
│   │   │   │   │   └── validations.go
│   │   │   │   └── worker_stats.go
│   │   │   ├── realtimeapi/
│   │   │   │   ├── api.go
│   │   │   │   ├── errors.go
│   │   │   │   ├── k8s_specs.go
│   │   │   │   └── status.go
│   │   │   ├── resources.go
│   │   │   ├── trafficsplitter/
│   │   │   │   ├── api.go
│   │   │   │   └── k8s_specs.go
│   │   │   └── validations.go
│   │   └── schema/
│   │       ├── config_key.go
│   │       ├── job_submission.go
│   │       └── schema.go
│   ├── probe/
│   │   ├── handler.go
│   │   ├── handler_test.go
│   │   ├── probe.go
│   │   └── probe_test.go
│   ├── proxy/
│   │   ├── breaker.go
│   │   ├── breaker_test.go
│   │   ├── handler.go
│   │   ├── handler_test.go
│   │   ├── proxy.go
│   │   ├── proxy_test.go
│   │   └── request_stats.go
│   ├── types/
│   │   ├── async/
│   │   │   ├── s3_paths.go
│   │   │   └── status.go
│   │   ├── clusterconfig/
│   │   │   ├── availability_zones.go
│   │   │   ├── aws_policy.go
│   │   │   ├── cluster_config.go
│   │   │   ├── config_key.go
│   │   │   ├── errors.go
│   │   │   ├── load_balancer_scheme.go
│   │   │   ├── load_balancer_type.go
│   │   │   ├── nat_gateway_type.go
│   │   │   ├── network_validations.go
│   │   │   ├── subnet_visibility.go
│   │   │   └── volume_types.go
│   │   ├── clusterstate/
│   │   │   ├── clusterstate.go
│   │   │   ├── errors.go
│   │   │   └── state.go
│   │   ├── metrics/
│   │   │   ├── batch_metrics.go
│   │   │   ├── metrics_test.go
│   │   │   └── queue_metrics.go
│   │   ├── spec/
│   │   │   ├── api.go
│   │   │   ├── errors.go
│   │   │   ├── id_gen.go
│   │   │   ├── job.go
│   │   │   ├── utils.go
│   │   │   └── validations.go
│   │   ├── status/
│   │   │   ├── job_code.go
│   │   │   ├── job_status.go
│   │   │   └── status.go
│   │   └── userconfig/
│   │       ├── api.go
│   │       ├── config_key.go
│   │       ├── kind.go
│   │       ├── log_level.go
│   │       └── resource.go
│   └── workloads/
│       ├── configmap.go
│       ├── helpers.go
│       ├── init.go
│       └── k8s.go
├── python/
│   └── client/
│       ├── README.md
│       ├── cortex/
│       │   ├── __init__.py
│       │   ├── binary/
│       │   │   └── __init__.py
│       │   ├── client.py
│       │   ├── consts.py
│       │   ├── exceptions.py
│       │   ├── telemetry.py
│       │   └── util.py
│       └── setup.py
└── test/
    ├── README.md
    ├── apis/
    │   ├── async/
    │   │   ├── hello-world/
    │   │   │   ├── app/
    │   │   │   │   ├── main.py
    │   │   │   │   └── requirements.txt
    │   │   │   ├── build-cpu.sh
    │   │   │   ├── cortex_cpu.yaml
    │   │   │   └── cpu.Dockerfile
    │   │   └── text-generator/
    │   │       ├── app/
    │   │       │   ├── main.py
    │   │       │   ├── requirements-cpu.txt
    │   │       │   └── requirements-gpu.txt
    │   │       ├── build-cpu.sh
    │   │       ├── build-gpu.sh
    │   │       ├── cortex_cpu.yaml
    │   │       ├── cortex_gpu.yaml
    │   │       ├── cpu.Dockerfile
    │   │       ├── expectations.yaml
    │   │       ├── gpu.Dockerfile
    │   │       └── sample.json
    │   ├── batch/
    │   │   ├── image-classifier-alexnet/
    │   │   │   ├── app/
    │   │   │   │   ├── main.py
    │   │   │   │   ├── requirements-cpu.txt
    │   │   │   │   └── requirements-gpu.txt
    │   │   │   ├── build-cpu.sh
    │   │   │   ├── build-gpu.sh
    │   │   │   ├── cortex_cpu.yaml
    │   │   │   ├── cortex_gpu.yaml
    │   │   │   ├── cpu.Dockerfile
    │   │   │   ├── gpu.Dockerfile
    │   │   │   ├── sample.json
    │   │   │   └── submit.py
    │   │   └── sum/
    │   │       ├── app/
    │   │       │   ├── main.py
    │   │       │   └── requirements.txt
    │   │       ├── build-cpu.sh
    │   │       ├── cortex_cpu.yaml
    │   │       ├── cpu.Dockerfile
    │   │       ├── sample.json
    │   │       ├── sample_generator.py
    │   │       └── submit.py
    │   ├── realtime/
    │   │   ├── hello-world/
    │   │   │   ├── app/
    │   │   │   │   ├── main.py
    │   │   │   │   └── requirements.txt
    │   │   │   ├── build-cpu.sh
    │   │   │   ├── cortex_cpu.yaml
    │   │   │   ├── cortex_cpu_arm64.yaml
    │   │   │   ├── cortex_scale_to_zero.yaml
    │   │   │   ├── cpu.Dockerfile
    │   │   │   └── sample.json
    │   │   ├── image-classifier-resnet50/
    │   │   │   ├── README.md
    │   │   │   ├── build-cpu.sh
    │   │   │   ├── build-gpu.sh
    │   │   │   ├── build-neuron-rtd.sh
    │   │   │   ├── build-neuron-tf-serving.sh
    │   │   │   ├── client.py
    │   │   │   ├── client_inf.py
    │   │   │   ├── cortex_cpu.yaml
    │   │   │   ├── cortex_gpu.yaml
    │   │   │   ├── cortex_inf.yaml
    │   │   │   ├── cortex_inf_rtd.yaml
    │   │   │   ├── cpu.Dockerfile
    │   │   │   ├── gpu.Dockerfile
    │   │   │   ├── neuron-rtd.Dockerfile
    │   │   │   ├── neuron-tf-serving.Dockerfile
    │   │   │   └── sample.json
    │   │   ├── multi-container/
    │   │   │   ├── app/
    │   │   │   │   ├── main.py
    │   │   │   │   └── requirements.txt
    │   │   │   ├── build-tfs-cpu.sh
    │   │   │   ├── build-web-cpu.sh
    │   │   │   ├── cortex_cpu.yaml
    │   │   │   ├── sample.json
    │   │   │   ├── tfs-cpu.Dockerfile
    │   │   │   └── web-cpu.Dockerfile
    │   │   ├── prime-generator/
    │   │   │   ├── app/
    │   │   │   │   ├── main.py
    │   │   │   │   └── requirements.txt
    │   │   │   ├── build-cpu.sh
    │   │   │   ├── cortex_cpu.yaml
    │   │   │   ├── cpu.Dockerfile
    │   │   │   └── sample.json
    │   │   ├── sleep/
    │   │   │   ├── app/
    │   │   │   │   ├── main.py
    │   │   │   │   └── requirements.txt
    │   │   │   ├── build-cpu.sh
    │   │   │   ├── cortex_cpu.yaml
    │   │   │   └── cpu.Dockerfile
    │   │   └── text-generator/
    │   │       ├── app/
    │   │       │   ├── main.py
    │   │       │   ├── requirements-cpu.txt
    │   │       │   └── requirements-gpu.txt
    │   │       ├── build-cpu.sh
    │   │       ├── build-gpu.sh
    │   │       ├── cortex_cpu.yaml
    │   │       ├── cortex_gpu.yaml
    │   │       ├── cpu.Dockerfile
    │   │       ├── gpu.Dockerfile
    │   │       └── sample.json
    │   ├── task/
    │   │   └── iris-classifier-trainer/
    │   │       ├── app/
    │   │       │   ├── main.py
    │   │       │   └── requirements.txt
    │   │       ├── build-cpu.sh
    │   │       ├── cortex_cpu.yaml
    │   │       ├── cpu.Dockerfile
    │   │       └── submit.py
    │   └── trafficsplitter/
    │       └── hello-world/
    │           ├── .dockerignore
    │           ├── cortex_cpu.yaml
    │           └── sample.json
    ├── e2e/
    │   ├── README.md
    │   ├── e2e/
    │   │   ├── __init__.py
    │   │   ├── cluster.py
    │   │   ├── exceptions.py
    │   │   ├── expectations.py
    │   │   ├── generator.py
    │   │   ├── tests.py
    │   │   └── utils.py
    │   ├── pytest.ini
    │   ├── setup.py
    │   └── tests/
    │       ├── __init__.py
    │       ├── aws/
    │       │   ├── __init__.py
    │       │   ├── conftest.py
    │       │   ├── test_async.py
    │       │   ├── test_autoscaling.py
    │       │   ├── test_batch.py
    │       │   ├── test_load.py
    │       │   ├── test_long_running.py
    │       │   ├── test_realtime.py
    │       │   ├── test_scale_to_zero.py
    │       │   └── test_task.py
    │       └── conftest.py
    └── utils/
        ├── README.md
        ├── build-all.sh
        ├── build.sh
        └── throughput_test.py
Download .txt
Showing preview only (374K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (3806 symbols across 416 files)

FILE: build/generate_ami_mapping.go
  constant eksResourceAccountStandard (line 40) | eksResourceAccountStandard = "602401143452"
  constant eksResourceAccountAPEast1 (line 43) | eksResourceAccountAPEast1 = "800184023465"
  constant eksResourceAccountMESouth1 (line 46) | eksResourceAccountMESouth1 = "558608220178"
  constant eksResourceAccountCNNorthWest1 (line 49) | eksResourceAccountCNNorthWest1 = "961992271922"
  constant eksResourceAccountCNNorth1 (line 52) | eksResourceAccountCNNorth1 = "918309763551"
  constant eksResourceAccountAFSouth1 (line 55) | eksResourceAccountAFSouth1 = "877085696533"
  constant eksResourceAccountEUSouth1 (line 58) | eksResourceAccountEUSouth1 = "590381155156"
  constant eksResourceAccountUSGovWest1 (line 61) | eksResourceAccountUSGovWest1 = "013241004608"
  constant eksResourceAccountUSGovEast1 (line 64) | eksResourceAccountUSGovEast1 = "151742754352"
  constant RegionUSWest1 (line 70) | RegionUSWest1 = "us-west-1"
  constant RegionUSWest2 (line 73) | RegionUSWest2 = "us-west-2"
  constant RegionUSEast1 (line 76) | RegionUSEast1 = "us-east-1"
  constant RegionUSEast2 (line 79) | RegionUSEast2 = "us-east-2"
  constant RegionCACentral1 (line 82) | RegionCACentral1 = "ca-central-1"
  constant RegionEUWest1 (line 85) | RegionEUWest1 = "eu-west-1"
  constant RegionEUWest2 (line 88) | RegionEUWest2 = "eu-west-2"
  constant RegionEUWest3 (line 91) | RegionEUWest3 = "eu-west-3"
  constant RegionEUNorth1 (line 94) | RegionEUNorth1 = "eu-north-1"
  constant RegionEUCentral1 (line 97) | RegionEUCentral1 = "eu-central-1"
  constant RegionEUSouth1 (line 100) | RegionEUSouth1 = "eu-south-1"
  constant RegionAPNorthEast1 (line 103) | RegionAPNorthEast1 = "ap-northeast-1"
  constant RegionAPNorthEast2 (line 106) | RegionAPNorthEast2 = "ap-northeast-2"
  constant RegionAPNorthEast3 (line 109) | RegionAPNorthEast3 = "ap-northeast-3"
  constant RegionAPSouthEast1 (line 112) | RegionAPSouthEast1 = "ap-southeast-1"
  constant RegionAPSouthEast2 (line 115) | RegionAPSouthEast2 = "ap-southeast-2"
  constant RegionAPSouth1 (line 118) | RegionAPSouth1 = "ap-south-1"
  constant RegionAPEast1 (line 121) | RegionAPEast1 = "ap-east-1"
  constant RegionMESouth1 (line 124) | RegionMESouth1 = "me-south-1"
  constant RegionSAEast1 (line 127) | RegionSAEast1 = "sa-east-1"
  constant RegionAFSouth1 (line 130) | RegionAFSouth1 = "af-south-1"
  constant RegionCNNorthwest1 (line 133) | RegionCNNorthwest1 = "cn-northwest-1"
  constant RegionCNNorth1 (line 136) | RegionCNNorth1 = "cn-north-1"
  constant RegionUSGovWest1 (line 139) | RegionUSGovWest1 = "us-gov-west-1"
  constant RegionUSGovEast1 (line 142) | RegionUSGovEast1 = "us-gov-east-1"
  constant DefaultRegion (line 145) | DefaultRegion = RegionUSWest2
  function SupportedRegions (line 149) | func SupportedRegions() []string {
  function EKSResourceAccountID (line 179) | func EKSResourceAccountID(region string) string {
  function main (line 202) | func main() {
  function FindImage (line 275) | func FindImage(ec2api ec2iface.EC2API, ownerAccount, namePattern string)...

FILE: cli/cluster/delete.go
  function Delete (line 32) | func Delete(operatorConfig OperatorConfig, apiName string, keepCache boo...
  function getReadyRealtimeAPIReplicasOrNil (line 59) | func getReadyRealtimeAPIReplicasOrNil(operatorConfig OperatorConfig, api...
  function StopJob (line 77) | func StopJob(operatorConfig OperatorConfig, kind userconfig.Kind, apiNam...

FILE: cli/cluster/deploy.go
  function Deploy (line 28) | func Deploy(operatorConfig OperatorConfig, configPath string, deployment...

FILE: cli/cluster/errors.go
  constant _errStrCantMakeRequest (line 30) | _errStrCantMakeRequest = "unable to make request"
  constant _errStrRead (line 31) | _errStrRead            = "unable to read"
  function errStrFailedToConnect (line 34) | func errStrFailedToConnect(u url.URL) string {
  constant ErrFailedToConnectOperator (line 39) | ErrFailedToConnectOperator       = "cli.failed_to_connect_operator"
  constant ErrOperatorSocketRead (line 40) | ErrOperatorSocketRead            = "cli.operator_socket_read"
  constant ErrResponseUnknown (line 41) | ErrResponseUnknown               = "cli.response_unknown"
  constant ErrOperatorResponseUnknown (line 42) | ErrOperatorResponseUnknown       = "cli.operator_response_unknown"
  constant ErrOperatorStreamResponseUnknown (line 43) | ErrOperatorStreamResponseUnknown = "cli.operator_stream_response_unknown"
  function ErrorFailedToConnectOperator (line 46) | func ErrorFailedToConnectOperator(originalError error, envName string, o...
  function ErrorOperatorSocketRead (line 75) | func ErrorOperatorSocketRead(err error) error {
  function ErrorResponseUnknown (line 83) | func ErrorResponseUnknown(body string, statusCode int) error {
  function ErrorOperatorResponseUnknown (line 95) | func ErrorOperatorResponseUnknown(body string, statusCode int) error {
  function ErrorOperatorStreamResponseUnknown (line 102) | func ErrorOperatorStreamResponseUnknown(body string, statusCode int) err...

FILE: cli/cluster/get.go
  function GetAPIs (line 27) | func GetAPIs(operatorConfig OperatorConfig) ([]schema.APIResponse, error) {
  function GetAPI (line 40) | func GetAPI(operatorConfig OperatorConfig, apiName string) ([]schema.API...
  function DescribeAPI (line 54) | func DescribeAPI(operatorConfig OperatorConfig, apiName string) ([]schem...
  function GetAPIByID (line 68) | func GetAPIByID(operatorConfig OperatorConfig, apiName string, apiID str...
  function GetBatchJob (line 82) | func GetBatchJob(operatorConfig OperatorConfig, apiName string, jobID st...
  function GetTaskJob (line 97) | func GetTaskJob(operatorConfig OperatorConfig, apiName string, jobID str...

FILE: cli/cluster/info.go
  function Info (line 25) | func Info(operatorConfig OperatorConfig) (*schema.InfoResponse, error) {

FILE: cli/cluster/lib_http_client.go
  type OperatorClient (line 37) | type OperatorClient struct
  type OperatorConfig (line 41) | type OperatorConfig struct
  function HTTPGet (line 48) | func HTTPGet(operatorConfig OperatorConfig, endpoint string, qParams ......
  function HTTPPostObjAsJSON (line 56) | func HTTPPostObjAsJSON(operatorConfig OperatorConfig, endpoint string, r...
  function HTTPPostJSON (line 64) | func HTTPPostJSON(operatorConfig OperatorConfig, endpoint string, jsonRe...
  function HTTPPostNoBody (line 74) | func HTTPPostNoBody(operatorConfig OperatorConfig, endpoint string, qPar...
  function HTTPDelete (line 82) | func HTTPDelete(operatorConfig OperatorConfig, endpoint string, qParams ...
  type HTTPUploadInput (line 90) | type HTTPUploadInput struct
  function HTTPUpload (line 95) | func HTTPUpload(operatorConfig OperatorConfig, endpoint string, input *H...
  function addFileToMultipart (line 130) | func addFileToMultipart(fileName string, writer *multipart.Writer, reade...
  function HTTPUploadZip (line 142) | func HTTPUploadZip(operatorConfig OperatorConfig, endpoint string, zipIn...
  function operatorRequest (line 156) | func operatorRequest(operatorConfig OperatorConfig, method string, endpo...
  function makeOperatorRequest (line 173) | func makeOperatorRequest(operatorConfig OperatorConfig, request *http.Re...

FILE: cli/cluster/logs.go
  function GetLogs (line 38) | func GetLogs(operatorConfig OperatorConfig, apiName string) (schema.LogR...
  function GetJobLogs (line 52) | func GetJobLogs(operatorConfig OperatorConfig, apiName string, jobID str...
  function StreamLogs (line 66) | func StreamLogs(operatorConfig OperatorConfig, apiName string) error {
  function StreamJobLogs (line 70) | func StreamJobLogs(operatorConfig OperatorConfig, apiName string, jobID ...
  function streamLogs (line 74) | func streamLogs(operatorConfig OperatorConfig, path string, qParams ...m...
  function handleConnection (line 139) | func handleConnection(connection *websocket.Conn, done chan struct{}) {
  function closeConnection (line 152) | func closeConnection(connection *websocket.Conn, done chan struct{}, int...

FILE: cli/cluster/refresh.go
  function Refresh (line 26) | func Refresh(operatorConfig OperatorConfig, apiName string, force bool) ...

FILE: cli/cmd/cluster.go
  function clusterInit (line 80) | func clusterInit() {
  function addClusterConfigFlag (line 123) | func addClusterConfigFlag(cmd *cobra.Command) {
  function addClusterNameFlag (line 131) | func addClusterNameFlag(cmd *cobra.Command) {
  function addClusterRegionFlag (line 135) | func addClusterRegionFlag(cmd *cobra.Command) {
  function cmdPrintConfig (line 866) | func cmdPrintConfig(awsClient *awslib.Client, accessConfig *clusterconfi...
  function cmdInfo (line 886) | func cmdInfo(awsClient *awslib.Client, accessConfig *clusterconfig.Acces...
  function printInfoOperatorResponse (line 956) | func printInfoOperatorResponse(clusterConfig clusterconfig.Config, stack...
  function getInfoOperatorResponse (line 984) | func getInfoOperatorResponse(operatorEndpoint string) (*schema.InfoRespo...
  function printInfoPricing (line 993) | func printInfoPricing(infoResponse *schema.InfoResponse, clusterConfig c...
  function printInfoNodes (line 1086) | func printInfoNodes(infoResponse *schema.InfoResponse) {
  function updateCLIEnv (line 1148) | func updateCLIEnv(envName string, operatorEndpoint string, disallowPromp...
  function cmdDebug (line 1198) | func cmdDebug(awsClient *awslib.Client, accessConfig *clusterconfig.Acce...
  function refreshCachedClusterConfig (line 1222) | func refreshCachedClusterConfig(awsClient *awslib.Client, accessConfig *...
  function createS3BucketIfNotFound (line 1253) | func createS3BucketIfNotFound(awsClient *awslib.Client, bucket string, t...
  function setLifecycleRulesOnClusterUp (line 1291) | func setLifecycleRulesOnClusterUp(awsClient *awslib.Client, bucket, newC...
  function setLifecycleRulesOnClusterDown (line 1335) | func setLifecycleRulesOnClusterDown(awsClient *awslib.Client, bucket str...
  function createLogGroupIfNotFound (line 1356) | func createLogGroupIfNotFound(awsClient *awslib.Client, logGroup string,...
  type LoadBalancer (line 1386) | type LoadBalancer
    method String (line 1393) | func (lb LoadBalancer) String() string {
  function getNLBLoadBalancer (line 1398) | func getNLBLoadBalancer(clusterName string, whichLB LoadBalancer, awsCli...
  function getELBLoadBalancer (line 1415) | func getELBLoadBalancer(clusterName string, whichLB LoadBalancer, awsCli...
  function listPVCVolumesForCluster (line 1431) | func listPVCVolumesForCluster(awsClient *awslib.Client, clusterName stri...
  function filterEKSCTLOutput (line 1438) | func filterEKSCTLOutput(out string) string {
  function getClusterRESTConfig (line 1442) | func getClusterRESTConfig(awsClient *awslib.Client, clusterName string) ...

FILE: cli/cmd/completion.go
  function completionInit (line 27) | func completionInit() {

FILE: cli/cmd/const.go
  constant _timeFormat (line 20) | _timeFormat = "02 Jan 06 15:04:05 MST"

FILE: cli/cmd/delete.go
  function deleteInit (line 39) | func deleteInit() {

FILE: cli/cmd/deploy.go
  function deployInit (line 47) | func deployInit() {
  function getConfigPath (line 121) | func getConfigPath(args []string) string {
  function getDeploymentBytes (line 139) | func getDeploymentBytes(configPath string) (map[string][]byte, error) {
  function mergeResultMessages (line 152) | func mergeResultMessages(results []schema.DeployResult) string {
  function didAllResultsError (line 180) | func didAllResultsError(results []schema.DeployResult) bool {
  function didAnyResultsError (line 189) | func didAnyResultsError(results []schema.DeployResult) bool {

FILE: cli/cmd/describe.go
  constant _titleReplicaStatus (line 32) | _titleReplicaStatus = "replica status"
  constant _titleReplicaCount (line 33) | _titleReplicaCount  = "replica count"
  function describeInit (line 41) | func describeInit() {
  function describeAPI (line 93) | func describeAPI(env cliconfig.Environment, apiName string) (string, err...

FILE: cli/cmd/env.go
  function envInit (line 36) | func envInit() {

FILE: cli/cmd/errors.go
  constant _errStrCantMakeRequest (line 32) | _errStrCantMakeRequest = "unable to make request"
  constant _errStrRead (line 33) | _errStrRead            = "unable to read"
  function errStrFailedToConnect (line 36) | func errStrFailedToConnect(u url.URL) string {
  constant ErrInvalidProvider (line 41) | ErrInvalidProvider                     = "cli.invalid_provider"
  constant ErrInvalidLegacyProvider (line 42) | ErrInvalidLegacyProvider               = "cli.invalid_legacy_provider"
  constant ErrNoAvailableEnvironment (line 43) | ErrNoAvailableEnvironment              = "cli.no_available_environment"
  constant ErrEnvironmentNotSet (line 44) | ErrEnvironmentNotSet                   = "cli.environment_not_set"
  constant ErrEnvironmentNotFound (line 45) | ErrEnvironmentNotFound                 = "cli.environment_not_found"
  constant ErrFieldNotFoundInEnvironment (line 46) | ErrFieldNotFoundInEnvironment          = "cli.field_not_found_in_environ...
  constant ErrInvalidOperatorEndpoint (line 47) | ErrInvalidOperatorEndpoint             = "cli.invalid_operator_endpoint"
  constant ErrNoOperatorLoadBalancer (line 48) | ErrNoOperatorLoadBalancer              = "cli.no_operator_load_balancer"
  constant ErrCortexYAMLNotFound (line 49) | ErrCortexYAMLNotFound                  = "cli.cortex_yaml_not_found"
  constant ErrDockerCtrlC (line 50) | ErrDockerCtrlC                         = "cli.docker_ctrl_c"
  constant ErrResponseUnknown (line 51) | ErrResponseUnknown                     = "cli.response_unknown"
  constant ErrMissingAWSCredentials (line 52) | ErrMissingAWSCredentials               = "cli.missing_aws_credentials"
  constant ErrCredentialsInClusterConfig (line 53) | ErrCredentialsInClusterConfig          = "cli.credentials_in_cluster_con...
  constant ErrClusterUp (line 54) | ErrClusterUp                           = "cli.cluster_up"
  constant ErrClusterConfigure (line 55) | ErrClusterConfigure                    = "cli.cluster_configure"
  constant ErrClusterDebug (line 56) | ErrClusterDebug                        = "cli.cluster_debug"
  constant ErrClusterRefresh (line 57) | ErrClusterRefresh                      = "cli.cluster_refresh"
  constant ErrClusterDown (line 58) | ErrClusterDown                         = "cli.cluster_down"
  constant ErrSpecifyAtLeastOneFlag (line 59) | ErrSpecifyAtLeastOneFlag               = "cli.specify_at_least_one_flag"
  constant ErrMinInstancesLowerThan (line 60) | ErrMinInstancesLowerThan               = "cli.min_instances_lower_than"
  constant ErrMaxInstancesLowerThan (line 61) | ErrMaxInstancesLowerThan               = "cli.max_instances_lower_than"
  constant ErrMinInstancesGreaterThanMaxInstances (line 62) | ErrMinInstancesGreaterThanMaxInstances = "cli.min_instances_greater_than...
  constant ErrNodeGroupNotFound (line 63) | ErrNodeGroupNotFound                   = "cli.nodegroup_not_found"
  constant ErrMutuallyExclusiveFlags (line 64) | ErrMutuallyExclusiveFlags              = "cli.mutually_exclusive_flags"
  constant ErrClusterAccessConfigRequired (line 65) | ErrClusterAccessConfigRequired         = "cli.cluster_access_config_or_p...
  constant ErrShellCompletionNotSupported (line 66) | ErrShellCompletionNotSupported         = "cli.shell_completion_not_suppo...
  constant ErrNoTerminalWidth (line 67) | ErrNoTerminalWidth                     = "cli.no_terminal_width"
  constant ErrDeployFromTopLevelDir (line 68) | ErrDeployFromTopLevelDir               = "cli.deploy_from_top_level_dir"
  constant ErrAPINameMustBeProvided (line 69) | ErrAPINameMustBeProvided               = "cli.api_name_must_be_provided"
  constant ErrAPINotFoundInConfig (line 70) | ErrAPINotFoundInConfig                 = "cli.api_not_found_in_config"
  constant ErrClusterUIDsLimitInBucket (line 71) | ErrClusterUIDsLimitInBucket            = "cli.cluster_uids_limit_in_bucket"
  function ErrorInvalidProvider (line 74) | func ErrorInvalidProvider(providerStr, cliConfigPath string) error {
  function ErrorInvalidLegacyProvider (line 81) | func ErrorInvalidLegacyProvider(providerStr, cliConfigPath string) error {
  function ErrorNoAvailableEnvironment (line 88) | func ErrorNoAvailableEnvironment() error {
  function ErrorEnvironmentNotSet (line 95) | func ErrorEnvironmentNotSet() error {
  function ErrorEnvironmentNotFound (line 102) | func ErrorEnvironmentNotFound(envName string) error {
  function ErrorFieldNotFoundInEnvironment (line 109) | func ErrorFieldNotFoundInEnvironment(fieldName string, envName string) e...
  function ErrorInvalidOperatorEndpoint (line 116) | func ErrorInvalidOperatorEndpoint(endpoint string) error {
  function ErrorNoOperatorLoadBalancer (line 123) | func ErrorNoOperatorLoadBalancer(whichLB string) error {
  function ErrorCortexYAMLNotFound (line 130) | func ErrorCortexYAMLNotFound() error {
  function ErrorDockerCtrlC (line 137) | func ErrorDockerCtrlC() error {
  function ErrorResponseUnknown (line 145) | func ErrorResponseUnknown(body string, statusCode int) error {
  function ErrorClusterUp (line 157) | func ErrorClusterUp(out string) error {
  function ErrorClusterConfigure (line 165) | func ErrorClusterConfigure(out string) error {
  function ErrorClusterDebug (line 173) | func ErrorClusterDebug(out string) error {
  function ErrorClusterRefresh (line 181) | func ErrorClusterRefresh(out string) error {
  function ErrorClusterDown (line 189) | func ErrorClusterDown(out string) error {
  function ErrorSpecifyAtLeastOneFlag (line 197) | func ErrorSpecifyAtLeastOneFlag(flagsToSpecify ...string) error {
  function ErrorMinInstancesLowerThan (line 204) | func ErrorMinInstancesLowerThan(minValue int64) error {
  function ErrorMaxInstancesLowerThan (line 211) | func ErrorMaxInstancesLowerThan(minValue int64) error {
  function ErrorMinInstancesGreaterThanMaxInstances (line 218) | func ErrorMinInstancesGreaterThanMaxInstances(minInstances, maxInstances...
  function ErrorNodeGroupNotFound (line 225) | func ErrorNodeGroupNotFound(scalingNodeGroupName, clusterName, clusterRe...
  function ErrorMutuallyExclusiveFlags (line 232) | func ErrorMutuallyExclusiveFlags(flagA, flagB string) error {
  function ErrorClusterAccessConfigRequired (line 239) | func ErrorClusterAccessConfigRequired(cliFlagsOnly bool) error {
  function ErrorShellCompletionNotSupported (line 252) | func ErrorShellCompletionNotSupported(shell string) error {
  function ErrorNoTerminalWidth (line 259) | func ErrorNoTerminalWidth() error {
  function ErrorDeployFromTopLevelDir (line 266) | func ErrorDeployFromTopLevelDir(genericDirName string) error {
  function ErrorAPINameMustBeProvided (line 273) | func ErrorAPINameMustBeProvided() error {
  function ErrorAPINotFoundInConfig (line 280) | func ErrorAPINotFoundInConfig(apiName string) error {
  function ErrorClusterUIDsLimitInBucket (line 287) | func ErrorClusterUIDsLimitInBucket(bucket string) error {

FILE: cli/cmd/get.go
  constant _titleEnvironment (line 43) | _titleEnvironment = "env"
  constant _titleRealtimeAPI (line 44) | _titleRealtimeAPI = "realtime api"
  constant _titleAsyncAPI (line 45) | _titleAsyncAPI    = "async api"
  constant _titleLive (line 46) | _titleLive        = "live"
  constant _titleUpToDate (line 47) | _titleUpToDate    = "up-to-date"
  constant _titleLastUpdated (line 48) | _titleLastUpdated = "last update"
  function getInit (line 56) | func getInit() {
  function getAPIsInAllEnvironments (line 186) | func getAPIsInAllEnvironments() (string, error) {
  function getAPIsByEnv (line 337) | func getAPIsByEnv(env cliconfig.Environment) (string, error) {
  function getAPI (line 462) | func getAPI(env cliconfig.Environment, apiName string) (string, error) {
  function apiHistoryTable (line 503) | func apiHistoryTable(apiVersions []schema.APIVersion) string {
  function titleStr (line 520) | func titleStr(title string) string {

FILE: cli/cmd/lib_apis.go
  function replicaCountTable (line 24) | func replicaCountTable(counts *status.ReplicaCounts) table.Table {

FILE: cli/cmd/lib_async_apis.go
  function asyncAPITable (line 32) | func asyncAPITable(asyncAPI schema.APIResponse, env cliconfig.Environmen...
  function asyncDescribeAPITable (line 58) | func asyncDescribeAPITable(asyncAPI schema.APIResponse, env cliconfig.En...
  function asyncAPIsTable (line 84) | func asyncAPIsTable(asyncAPIs []schema.APIResponse, envNames []string) t...

FILE: cli/cmd/lib_aws_creds.go
  function newAWSClient (line 29) | func newAWSClient(region string, printToStdout bool) (*aws.Client, error) {
  function promptIfNotAdmin (line 50) | func promptIfNotAdmin(awsClient *aws.Client, disallowPrompt bool) {
  function warnIfNotAdmin (line 66) | func warnIfNotAdmin(awsClient *aws.Client) {

FILE: cli/cmd/lib_batch_apis.go
  constant _titleBatchAPI (line 38) | _titleBatchAPI    = "batch api"
  constant _titleJobCount (line 39) | _titleJobCount    = "running jobs"
  constant _titleLatestJobID (line 40) | _titleLatestJobID = "latest job id"
  function batchAPIsTable (line 43) | func batchAPIsTable(batchAPIs []schema.APIResponse, envNames []string) t...
  function batchAPITable (line 87) | func batchAPITable(batchAPI schema.APIResponse) string {
  function getBatchJob (line 145) | func getBatchJob(env cliconfig.Environment, apiName string, jobID string...

FILE: cli/cmd/lib_cli_config.go
  function getEnvFromFlag (line 101) | func getEnvFromFlag(envFlag string) (string, error) {
  function promptForExistingEnvName (line 126) | func promptForExistingEnvName(promptMsg string) string {
  function promptEnv (line 159) | func promptEnv(env *cliconfig.Environment, defaults cliconfig.Environmen...
  function validateOperatorEndpoint (line 210) | func validateOperatorEndpoint(endpoint string) (string, error) {
  function getDefaultEnv (line 257) | func getDefaultEnv() (*string, error) {
  function setDefaultEnv (line 279) | func setDefaultEnv(envName string) error {
  function renameEnv (line 302) | func renameEnv(oldEnvName string, newEnvName string) error {
  function readTelemetryConfig (line 336) | func readTelemetryConfig() (bool, error) {
  function isTelemetryEnabled (line 350) | func isTelemetryEnabled() bool {
  function readEnv (line 359) | func readEnv(envName string) (*cliconfig.Environment, error) {
  function ReadOrConfigureEnv (line 374) | func ReadOrConfigureEnv(envName string) (cliconfig.Environment, error) {
  function getEnvConfigDefaults (line 397) | func getEnvConfigDefaults(envName string) cliconfig.Environment {
  function configureEnv (line 413) | func configureEnv(envName string, fieldsToSkipPrompt cliconfig.Environme...
  function MustGetOperatorConfig (line 439) | func MustGetOperatorConfig(envName string) cluster.OperatorConfig {
  function listConfiguredEnvs (line 464) | func listConfiguredEnvs() ([]*cliconfig.Environment, error) {
  function listConfiguredEnvNames (line 473) | func listConfiguredEnvNames() ([]string, error) {
  function isEnvConfigured (line 487) | func isEnvConfigured(envName string) (bool, error) {
  function addEnvToCLIConfig (line 502) | func addEnvToCLIConfig(newEnv cliconfig.Environment, setAsDefault bool) ...
  function removeEnvFromCLIConfig (line 532) | func removeEnvFromCLIConfig(envName string) error {
  function getEnvNamesByOperatorEndpoint (line 574) | func getEnvNamesByOperatorEndpoint(operatorEndpoint string) ([]string, b...
  function readCLIConfig (line 595) | func readCLIConfig() (cliconfig.CLIConfig, error) {
  function writeCLIConfig (line 624) | func writeCLIConfig(cliConfig cliconfig.CLIConfig) error {

FILE: cli/cmd/lib_client_id.go
  function clientID (line 26) | func clientID() string {

FILE: cli/cmd/lib_cluster_config.go
  function getCachedClusterConfigPath (line 43) | func getCachedClusterConfigPath(clusterName string, region string) string {
  function existingCachedClusterConfigPaths (line 47) | func existingCachedClusterConfigPaths() []string {
  function readCachedClusterConfigFile (line 63) | func readCachedClusterConfigFile(clusterConfig *clusterconfig.Config, fi...
  function readUserClusterConfigFile (line 72) | func readUserClusterConfigFile(clusterConfig *clusterconfig.Config, file...
  function getNewClusterAccessConfig (line 81) | func getNewClusterAccessConfig(clusterConfigFile string) (*clusterconfig...
  function getClusterAccessConfigWithCache (line 92) | func getClusterAccessConfigWithCache(hasClusterFlags bool) (*clusterconf...
  function getInstallClusterConfig (line 125) | func getInstallClusterConfig(awsClient *aws.Client, clusterConfigFile st...
  function getConfigureClusterConfig (line 144) | func getConfigureClusterConfig(awsClient *aws.Client, k8sClient *k8s.Cli...
  function confirmInstallClusterConfig (line 164) | func confirmInstallClusterConfig(clusterConfig *clusterconfig.Config, aw...
  function confirmConfigureClusterConfig (line 306) | func confirmConfigureClusterConfig(configureChanges clusterconfig.Config...

FILE: cli/cmd/lib_manager.go
  type dockerCopyFromPath (line 45) | type dockerCopyFromPath struct
  type dockerCopyToPath (line 50) | type dockerCopyToPath struct
  function runManager (line 55) | func runManager(containerConfig *container.Config, addNewLineAfterPull b...
  function runManagerWithClusterConfig (line 163) | func runManagerWithClusterConfig(entrypoint string, clusterConfig *clust...
  function runManagerAccessCommand (line 220) | func runManagerAccessCommand(entrypoint string, accessConfig clusterconf...

FILE: cli/cmd/lib_realtime_apis.go
  function realtimeAPITable (line 32) | func realtimeAPITable(realtimeAPI schema.APIResponse, env cliconfig.Envi...
  function realtimeDescribeAPITable (line 57) | func realtimeDescribeAPITable(realtimeAPI schema.APIResponse, env clicon...
  function realtimeAPIsTable (line 83) | func realtimeAPIsTable(realtimeAPIs []schema.APIResponse, envNames []str...

FILE: cli/cmd/lib_task_apis.go
  constant _titleTaskAPI (line 36) | _titleTaskAPI         = "task api"
  constant _titleTaskJobCount (line 37) | _titleTaskJobCount    = "running jobs"
  constant _titleLatestTaskJobID (line 38) | _titleLatestTaskJobID = "latest job id"
  function taskAPIsTable (line 41) | func taskAPIsTable(taskAPIs []schema.APIResponse, envNames []string) tab...
  function taskAPITable (line 85) | func taskAPITable(taskAPI schema.APIResponse) string {
  function getTaskJob (line 140) | func getTaskJob(env cliconfig.Environment, apiName string, jobID string)...

FILE: cli/cmd/lib_traffic_splitters.go
  constant _titleTrafficSplitter (line 34) | _titleTrafficSplitter   = "traffic splitter"
  constant _trafficSplitterWeights (line 35) | _trafficSplitterWeights = "weights"
  constant _titleAPIs (line 36) | _titleAPIs              = "apis"
  function trafficSplitterTable (line 39) | func trafficSplitterTable(trafficSplitter schema.APIResponse, env clicon...
  function trafficSplitTable (line 68) | func trafficSplitTable(trafficSplitter schema.APIResponse, env cliconfig...
  function trafficSplitterListTable (line 110) | func trafficSplitterListTable(trafficSplitter []schema.APIResponse, envN...

FILE: cli/cmd/lib_watch.go
  function getTerminalWidth (line 32) | func getTerminalWidth() int {
  function watchHeader (line 51) | func watchHeader() string {
  function rerun (line 59) | func rerun(watchFlag bool, f func() (string, error)) {

FILE: cli/cmd/logs.go
  function logsInit (line 40) | func logsInit() {

FILE: cli/cmd/refresh.go
  function refreshInit (line 37) | func refreshInit() {

FILE: cli/cmd/root.go
  function init (line 53) | func init() {
  function initTelemetry (line 124) | func initTelemetry() {
  function Execute (line 151) | func Execute() {
  function updateRootUsage (line 176) | func updateRootUsage() {
  function addVerboseFlag (line 197) | func addVerboseFlag(cmd *cobra.Command) {
  function wasFlagProvided (line 201) | func wasFlagProvided(cmd *cobra.Command, flagName string) bool {
  function printEnvIfNotSpecified (line 212) | func printEnvIfNotSpecified(envName string, cmd *cobra.Command) error {
  function envStringIfNotSpecified (line 225) | func envStringIfNotSpecified(envName string, cmd *cobra.Command) (string...

FILE: cli/cmd/version.go
  function versionInit (line 31) | func versionInit() {

FILE: cli/lib/routines/routines.go
  function RunWithPanicHandler (line 25) | func RunWithPanicHandler(f func(), exitOnPanic bool) {

FILE: cli/main.go
  function main (line 23) | func main() {

FILE: cli/types/cliconfig/cli_config.go
  type CLIConfig (line 24) | type CLIConfig struct
    method Validate (line 35) | func (cliConfig *CLIConfig) Validate() error {
    method ConvertToUserFacingCLIConfig (line 59) | func (cliConfig *CLIConfig) ConvertToUserFacingCLIConfig() UserFacingC...
  type UserFacingCLIConfig (line 30) | type UserFacingCLIConfig struct

FILE: cli/types/cliconfig/config_key.go
  constant EnvironmentsKey (line 20) | EnvironmentsKey       = "environments"
  constant DefaultEnvironmentKey (line 21) | DefaultEnvironmentKey = "default_environment"
  constant NameKey (line 22) | NameKey               = "name"
  constant OperatorEndpointKey (line 23) | OperatorEndpointKey   = "operator_endpoint"

FILE: cli/types/cliconfig/environment.go
  type Environment (line 29) | type Environment struct
    method String (line 34) | func (env Environment) String(isDefault bool) string {
    method Validate (line 64) | func (env *Environment) Validate() error {
  function CortexEndpointValidator (line 48) | func CortexEndpointValidator(val string) (string, error) {

FILE: cli/types/cliconfig/errors.go
  constant ErrEnvironmentNotConfigured (line 27) | ErrEnvironmentNotConfigured     = "cliconfig.environment_not_configured"
  constant ErrEnvironmentAlreadyConfigured (line 28) | ErrEnvironmentAlreadyConfigured = "cliconfig.environment_already_configu...
  constant ErrDuplicateEnvironmentNames (line 29) | ErrDuplicateEnvironmentNames    = "cliconfig.duplicate_environment_names"
  function ErrorEnvironmentNotConfigured (line 32) | func ErrorEnvironmentNotConfigured(envName string) error {
  function ErrorEnvironmentAlreadyConfigured (line 39) | func ErrorEnvironmentAlreadyConfigured(envName string) error {
  function ErrorDuplicateEnvironmentNames (line 46) | func ErrorDuplicateEnvironmentNames(envName string) error {

FILE: cli/types/flags/errors.go
  constant ErrInvalidOutputType (line 27) | ErrInvalidOutputType = "flags.invalid_output_type"
  function ErrorInvalidOutputType (line 30) | func ErrorInvalidOutputType(invalidOutputType string) error {

FILE: cli/types/flags/output_type.go
  type OutputType (line 19) | type OutputType
    method String (line 58) | func (t OutputType) String() string {
    method MarshalText (line 63) | func (t OutputType) MarshalText() ([]byte, error) {
    method UnmarshalText (line 68) | func (t *OutputType) UnmarshalText(text []byte) error {
    method UnmarshalBinary (line 83) | func (t *OutputType) UnmarshalBinary(data []byte) error {
    method MarshalBinary (line 88) | func (t OutputType) MarshalBinary() ([]byte, error) {
    method Set (line 92) | func (t *OutputType) Set(value string) error {
    method Type (line 101) | func (t OutputType) Type() string {
  constant UnknownOutputType (line 22) | UnknownOutputType OutputType = iota
  constant PrettyOutputType (line 23) | PrettyOutputType
  constant JSONOutputType (line 24) | JSONOutputType
  constant YAMLOutputType (line 25) | YAMLOutputType
  function OutputTypeFromString (line 35) | func OutputTypeFromString(s string) OutputType {
  function OutputTypeStrings (line 44) | func OutputTypeStrings() []string {
  function OutputTypeStringsExcluding (line 48) | func OutputTypeStringsExcluding(outputType OutputType) []string {

FILE: cmd/activator/main.go
  function main (line 45) | func main() {
  function informerFilter (line 191) | func informerFilter(listOptions *kmeta.ListOptions) {
  function exit (line 205) | func exit(log *zap.SugaredLogger, err error, wrapStrs ...string) {

FILE: cmd/async-gateway/main.go
  constant _defaultPort (line 37) | _defaultPort = "8080"
  function main (line 41) | func main() {
  function exit (line 122) | func exit(log *zap.SugaredLogger, err error, wrapStrs ...string) {

FILE: cmd/autoscaler/main.go
  function main (line 51) | func main() {
  function apiResourceFromLabels (line 245) | func apiResourceFromLabels(labels map[string]string) (userconfig.Resourc...
  function informerFilter (line 262) | func informerFilter(listOptions *kmeta.ListOptions) {
  function exit (line 277) | func exit(log *zap.SugaredLogger, err error, wrapStrs ...string) {

FILE: cmd/dequeuer/main.go
  function main (line 42) | func main() {
  function exit (line 249) | func exit(log *zap.SugaredLogger, err error, wrapStrs ...string) {

FILE: cmd/enqueuer/main.go
  function createLogger (line 30) | func createLogger() (*zap.Logger, error) {
  function main (line 63) | func main() {

FILE: cmd/operator/main.go
  constant _operatorPortStr (line 41) | _operatorPortStr = "8888"
  function main (line 43) | func main() {

FILE: cmd/proxy/main.go
  constant _reportInterval (line 42) | _reportInterval        = 10 * time.Second
  constant _requestSampleInterval (line 43) | _requestSampleInterval = 1 * time.Second
  function main (line 46) | func main() {
  function exit (line 191) | func exit(log *zap.SugaredLogger, err error, wrapStrs ...string) {
  function readinessTCPHandler (line 207) | func readinessTCPHandler(port int, enableTCPProbe bool, logger *zap.Suga...

FILE: dev/find_missing_docs_links.py
  function main (line 30) | def main():
  function get_docs_file_paths (line 43) | def get_docs_file_paths():
  function get_links_from_file (line 53) | def get_links_from_file(file):
  function check_links (line 84) | def check_links(link_infos):
  function check_all_http_links (line 112) | async def check_all_http_links(http_link_infos, errors):
  function check_http_link (line 130) | async def check_http_link(session, src_file, line_num, link, errors):
  function check_local_link (line 147) | def check_local_link(src_file, line_num, original_link_text, target_file...
  function header_matches (line 166) | def header_matches(text, header):
  function err_str (line 174) | def err_str(src_file, line_num, original_link_text, reason):
  function is_external_link (line 179) | def is_external_link(link):

FILE: dev/get_operator_url.py
  function main (line 19) | def main():
  function get_operator_url (line 26) | def get_operator_url(cluster_name, region):

FILE: dev/load.go
  constant _numConcurrent (line 42) | _numConcurrent        = 3
  constant _requestDelay (line 43) | _requestDelay         = 0 * time.Millisecond
  constant _numRequestsPerThread (line 44) | _numRequestsPerThread = 0
  constant _numMainLoops (line 45) | _numMainLoops         = 1
  constant _requestInterval (line 48) | _requestInterval        = 0 * time.Millisecond
  constant _numRequests (line 49) | _numRequests     uint64 = 0
  constant _maxInFlight (line 50) | _maxInFlight            = 5
  constant _printSuccessDots (line 53) | _printSuccessDots = true
  constant _printBody (line 54) | _printBody        = false
  constant _printHTTPErrors (line 55) | _printHTTPErrors  = true
  constant _printGoErrors (line 56) | _printGoErrors    = true
  type Counter (line 59) | type Counter struct
  function main (line 78) | func main() {
  function runConstantRequestsPerSecond (line 108) | func runConstantRequestsPerSecond(url string, jsonBytes []byte) {
  function runConstantRequestsPerSecondIteration (line 137) | func runConstantRequestsPerSecondIteration(url string, jsonBytes []byte,...
  function runConstantInFlight (line 162) | func runConstantInFlight(url string, jsonBytes []byte) {
  function runConstantInFlightIteration (line 202) | func runConstantInFlightIteration(url string, jsonBytes []byte, loopNum ...
  function makeRequestLoop (line 246) | func makeRequestLoop(url string, jsonBytes []byte) {
  function makeRequest (line 266) | func makeRequest(url string, jsonBytes []byte) {
  function mustReadJSONBytes (line 315) | func mustReadJSONBytes(jsonPath string) []byte {
  function mustExtractArgs (line 325) | func mustExtractArgs() (string, string) {

FILE: dev/update_cli_config.py
  function update_cli_config (line 20) | def update_cli_config(cli_config_file_path, env_name, operator_endpoint):

FILE: manager/cluster_config_env.py
  function export (line 21) | def export(base_key, value):
  function exportTags (line 54) | def exportTags(tags, env_var_name, tag_overrides={}):

FILE: manager/generate_eks.py
  function parse_instance_type (line 29) | def parse_instance_type(instance_type: str) -> ParsedInstanceType:
  function default_nodegroup (line 46) | def default_nodegroup(cluster_config):
  function merge_override (line 89) | def merge_override(a, b):
  function apply_worker_settings (line 104) | def apply_worker_settings(nodegroup, config):
  function apply_clusterconfig (line 125) | def apply_clusterconfig(nodegroup, config):
  function apply_spot_settings (line 143) | def apply_spot_settings(nodegroup, config):
  function apply_gpu_settings (line 162) | def apply_gpu_settings(nodegroup):
  function is_gpu (line 185) | def is_gpu(instance_type):
  function apply_inf_settings (line 190) | def apply_inf_settings(nodegroup, config):
  function is_inf (line 215) | def is_inf(instance_type):
  function get_inf_resources (line 220) | def get_inf_resources(instance_type):
  function is_arm64 (line 232) | def is_arm64(instance_type: str):
  function get_all_worker_nodegroups (line 237) | def get_all_worker_nodegroups(ami_map: dict, cluster_config: dict) -> list:
  function get_worker_nodegroup (line 247) | def get_worker_nodegroup(ami_map: dict, nodegroup_config: dict, cluster_...
  function get_nodegroup_config_by_name (line 269) | def get_nodegroup_config_by_name(cluster_config: dict, ng_name: str) -> ...
  function get_empty_eks_nodegroup (line 278) | def get_empty_eks_nodegroup(name: str) -> dict:
  function get_ami (line 285) | def get_ami(ami_map: dict, instance_type: str) -> str:
  function generate_eks (line 306) | def generate_eks(
  class IgnoreAliases (line 434) | class IgnoreAliases(yaml.Dumper):
    method ignore_aliases (line 440) | def ignore_aliases(self, data):

FILE: manager/get_api_load_balancer_state.py
  function get_api_load_balancer_state (line 21) | def get_api_load_balancer_state():

FILE: manager/get_operator_load_balancer_state.py
  function get_operator_load_balancer_state (line 21) | def get_operator_load_balancer_state():

FILE: manager/get_operator_target_group_status.py
  function get_operator_target_group_status (line 22) | def get_operator_target_group_status():
  function get_load_balancer_https_target_group_arn (line 33) | def get_load_balancer_https_target_group_arn(load_balancer_arn, client_e...
  function get_target_health (line 45) | def get_target_health(target_group_arn, client_elbv2):

FILE: manager/helpers.py
  function get_operator_load_balancer_v2 (line 16) | def get_operator_load_balancer_v2(cluster_name, client_elbv2):
  function get_api_load_balancer_v2 (line 20) | def get_api_load_balancer_v2(cluster_name, client_elbv2):
  function get_api_load_balancer (line 24) | def get_api_load_balancer(cluster_name, client_elb):
  function get_api_load_balancer_health (line 28) | def get_api_load_balancer_health(load_balancer_name, client_elb):
  function _get_load_balancer_v2 (line 38) | def _get_load_balancer_v2(load_balancer_tag, cluster_name, client_elbv2):
  function _get_load_balancer (line 62) | def _get_load_balancer(load_balancer_tag, cluster_name, client_elb):

FILE: manager/upgrade_kube_proxy_mode.py
  function main (line 21) | def main():

FILE: pkg/activator/activator.go
  type ctxValue (line 37) | type ctxValue
  constant APINameCtxKey (line 39) | APINameCtxKey ctxValue = "apiName"
  type StatsReporter (line 41) | type StatsReporter interface
  type Activator (line 46) | type Activator interface
  type activator (line 50) | type activator struct
    method Try (line 101) | func (a *activator) Try(ctx context.Context, fn func() error) error {
    method getOrCreateAPIActivator (line 122) | func (a *activator) getOrCreateAPIActivator(ctx context.Context, apiNa...
    method getOrCreateReadinessTracker (line 148) | func (a *activator) getOrCreateReadinessTracker(apiName string) *readi...
    method addAPI (line 162) | func (a *activator) addAPI(obj interface{}) {
    method updateAPI (line 186) | func (a *activator) updateAPI(oldObj interface{}, newObj interface{}) {
    method removeAPI (line 216) | func (a *activator) removeAPI(obj interface{}) {
    method awakenAPI (line 237) | func (a *activator) awakenAPI(apiName string) {
    method updateReadinessTracker (line 249) | func (a *activator) updateReadinessTracker(obj interface{}) {
    method removeReadinessTracker (line 275) | func (a *activator) removeReadinessTracker(obj interface{}) {
  function New (line 61) | func New(

FILE: pkg/activator/activator_test.go
  type autoscalerClientMock (line 33) | type autoscalerClientMock struct
    method AddAPI (line 35) | func (m autoscalerClientMock) AddAPI(_ userconfig.Resource) error {
    method Awaken (line 39) | func (m autoscalerClientMock) Awaken(_ userconfig.Resource) error {
  function newLogger (line 43) | func newLogger(t *testing.T) *zap.SugaredLogger {
  function TestActivator_Try (line 56) | func TestActivator_Try(t *testing.T) {

FILE: pkg/activator/api_activator.go
  type apiActivator (line 31) | type apiActivator struct
    method try (line 47) | func (a *apiActivator) try(ctx context.Context, fn func() error, track...
    method updateQueueParams (line 75) | func (a *apiActivator) updateQueueParams(maxQueueLength, maxConcurrenc...
    method inFlight (line 81) | func (a *apiActivator) inFlight() int64 {
  function newAPIActivator (line 35) | func newAPIActivator(maxQueueLength, maxConcurrency int) *apiActivator {
  type readinessTracker (line 85) | type readinessTracker struct
    method Update (line 97) | func (t *readinessTracker) Update(deployment *kapps.Deployment) {
    method IsReady (line 109) | func (t *readinessTracker) IsReady() bool {
    method Wait (line 115) | func (t *readinessTracker) Wait() chan bool {
  function newReadinessTracker (line 91) | func newReadinessTracker() *readinessTracker {

FILE: pkg/activator/api_activator_test.go
  function TestApiActivator_Try (line 30) | func TestApiActivator_Try(t *testing.T) {

FILE: pkg/activator/handler.go
  type Handler (line 36) | type Handler struct
    method ServeHTTP (line 48) | func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
    method proxyRequest (line 77) | func (h *Handler) proxyRequest(w http.ResponseWriter, r *http.Request)...
  function NewHandler (line 41) | func NewHandler(act Activator, logger *zap.SugaredLogger) *Handler {
  function hasCortexProbeHeader (line 98) | func hasCortexProbeHeader(r *http.Request) bool {

FILE: pkg/activator/handler_test.go
  function TestActivatorHandler_ServeHTTP (line 30) | func TestActivatorHandler_ServeHTTP(t *testing.T) {

FILE: pkg/activator/helpers.go
  type apiMeta (line 27) | type apiMeta struct
  function getAPIMeta (line 36) | func getAPIMeta(obj interface{}) (apiMeta, error) {

FILE: pkg/activator/request_stats.go
  type PrometheusStatsReporter (line 29) | type PrometheusStatsReporter struct
    method AddAPI (line 46) | func (r *PrometheusStatsReporter) AddAPI(apiName string) {
    method RemoveAPI (line 50) | func (r *PrometheusStatsReporter) RemoveAPI(apiName string) {
    method ServeHTTP (line 54) | func (r *PrometheusStatsReporter) ServeHTTP(w http.ResponseWriter, req...
  function NewPrometheusStatsReporter (line 34) | func NewPrometheusStatsReporter() *PrometheusStatsReporter {

FILE: pkg/async-gateway/endpoint.go
  type Endpoint (line 33) | type Endpoint struct
    method CreateWorkload (line 47) | func (e *Endpoint) CreateWorkload(w http.ResponseWriter, r *http.Reque...
    method GetWorkload (line 89) | func (e *Endpoint) GetWorkload(w http.ResponseWriter, r *http.Request) {
  function NewEndpoint (line 39) | func NewEndpoint(svc Service, logger *zap.SugaredLogger) *Endpoint {
  function respondPlainText (line 124) | func respondPlainText(w http.ResponseWriter, statusCode int, message str...
  function respondJSON (line 130) | func respondJSON(w http.ResponseWriter, statusCode int, s interface{}) e...
  function logErrorWithTelemetry (line 136) | func logErrorWithTelemetry(log *zap.SugaredLogger, err error) {

FILE: pkg/async-gateway/queue.go
  type Queue (line 26) | type Queue interface
  type sqs (line 30) | type sqs struct
    method SendMessage (line 43) | func (q *sqs) SendMessage(message string, uniqueID string) error {
  function NewSQS (line 36) | func NewSQS(queueURL string, sess *session.Session) Queue {

FILE: pkg/async-gateway/service.go
  type Service (line 34) | type Service interface
  type service (line 39) | type service struct
    method CreateWorkload (line 57) | func (s *service) CreateWorkload(id string, apiName string, queueURL s...
    method GetWorkload (line 95) | func (s *service) GetWorkload(id string, apiName string) (GetWorkloadR...
    method getStatus (line 138) | func (s *service) getStatus(id string, apiName string) (async.Status, ...
  function NewService (line 47) | func NewService(clusterUID string, storage Storage, logger *zap.SugaredL...

FILE: pkg/async-gateway/storage.go
  type Storage (line 32) | type Storage interface
  type s3 (line 39) | type s3 struct
    method Upload (line 60) | func (s *s3) Upload(key string, payload io.Reader, contentType string)...
    method Download (line 71) | func (s *s3) Download(key string) ([]byte, error) {
    method List (line 88) | func (s *s3) List(key string) ([]string, error) {
    method GetLastModified (line 111) | func (s *s3) GetLastModified(key string) (time.Time, error) {
  function NewS3 (line 47) | func NewS3(sess *session.Session, bucket string) Storage {

FILE: pkg/async-gateway/types.go
  type CreateWorkloadResponse (line 29) | type CreateWorkloadResponse struct
  type GetWorkloadResponse (line 34) | type GetWorkloadResponse struct

FILE: pkg/autoscaler/async_scaler.go
  type AsyncScaler (line 33) | type AsyncScaler struct
    method Scale (line 45) | func (s *AsyncScaler) Scale(apiName string, request int32) error {
    method GetInFlightRequests (line 68) | func (s *AsyncScaler) GetInFlightRequests(apiName string, window time....
    method GetAutoscalingSpec (line 100) | func (s *AsyncScaler) GetAutoscalingSpec(apiName string) (*userconfig....
    method CurrentRequestedReplicas (line 118) | func (s *AsyncScaler) CurrentRequestedReplicas(apiName string) (int32,...
  function NewAsyncScaler (line 38) | func NewAsyncScaler(k8sClient *k8s.Client, promClient promv1.API) *Async...

FILE: pkg/autoscaler/autoscaler.go
  constant _prometheusQueryTimeoutSeconds (line 36) | _prometheusQueryTimeoutSeconds = 10
  type Scaler (line 39) | type Scaler interface
  type Autoscaler (line 46) | type Autoscaler struct
    method AddScaler (line 62) | func (a *Autoscaler) AddScaler(scaler Scaler, kind userconfig.Kind) {
    method Awaken (line 66) | func (a *Autoscaler) Awaken(api userconfig.Resource) error {
    method AddAPI (line 98) | func (a *Autoscaler) AddAPI(api userconfig.Resource) error {
    method RemoveAPI (line 123) | func (a *Autoscaler) RemoveAPI(api userconfig.Resource) {
    method Stop (line 138) | func (a *Autoscaler) Stop() {
    method autoscaleFn (line 145) | func (a *Autoscaler) autoscaleFn(api userconfig.Resource) (func() erro...
  function New (line 53) | func New(logger *zap.SugaredLogger) *Autoscaler {

FILE: pkg/autoscaler/autoscaler_test.go
  function newLogger (line 31) | func newLogger(t *testing.T) *zap.SugaredLogger {
  function generateRecommendationTimeline (line 44) | func generateRecommendationTimeline(t *testing.T, recs []int32, interval...
  function TestAutoscaler_AutoscaleFn (line 60) | func TestAutoscaler_AutoscaleFn(t *testing.T) {
  function TestAutoscaler_Awake (line 245) | func TestAutoscaler_Awake(t *testing.T) {
  function TestAutoscaler_MinReplicas (line 319) | func TestAutoscaler_MinReplicas(t *testing.T) {
  function TestAutoscaler_MaxReplicas (line 391) | func TestAutoscaler_MaxReplicas(t *testing.T) {

FILE: pkg/autoscaler/client.go
  type Client (line 30) | type Client interface
  type client (line 34) | type client struct
    method Awaken (line 46) | func (c *client) Awaken(api userconfig.Resource) error {
  function NewClient (line 39) | func NewClient(endpoint string) Client {

FILE: pkg/autoscaler/handler.go
  type Handler (line 28) | type Handler struct
    method Awaken (line 36) | func (h *Handler) Awaken(w http.ResponseWriter, r *http.Request) {
  function NewHandler (line 32) | func NewHandler(autoscaler *Autoscaler) *Handler {

FILE: pkg/autoscaler/realtime_scaler.go
  type RealtimeScaler (line 39) | type RealtimeScaler struct
    method Scale (line 53) | func (s *RealtimeScaler) Scale(apiName string, request int32) error {
    method GetInFlightRequests (line 102) | func (s *RealtimeScaler) GetInFlightRequests(apiName string, window ti...
    method GetAutoscalingSpec (line 138) | func (s *RealtimeScaler) GetAutoscalingSpec(apiName string) (*userconf...
    method CurrentRequestedReplicas (line 156) | func (s *RealtimeScaler) CurrentRequestedReplicas(apiName string) (int...
    method routeToService (line 176) | func (s *RealtimeScaler) routeToService(deployment *kapps.Deployment) ...
    method routeToActivator (line 208) | func (s *RealtimeScaler) routeToActivator(deployment *kapps.Deployment...
    method waitForReadyReplicas (line 236) | func (s *RealtimeScaler) waitForReadyReplicas(ctx context.Context, dep...
  function NewRealtimeScaler (line 45) | func NewRealtimeScaler(k8sClient *k8s.Client, promClient promv1.API, log...

FILE: pkg/autoscaler/recommendations.go
  type recommendations (line 25) | type recommendations struct
    method add (line 36) | func (r *recommendations) add(rec int32) {
    method deleteOlderThan (line 43) | func (r *recommendations) deleteOlderThan(period time.Duration) {
    method maxSince (line 55) | func (r *recommendations) maxSince(period time.Duration) *int32 {
    method minSince (line 77) | func (r *recommendations) minSince(period time.Duration) *int32 {
  function newRecommendations (line 30) | func newRecommendations() *recommendations {

FILE: pkg/autoscaler/scaler_func.go
  type ScalerFunc (line 25) | type ScalerFunc struct
    method Scale (line 32) | func (s *ScalerFunc) Scale(apiName string, request int32) error {
    method GetInFlightRequests (line 40) | func (s *ScalerFunc) GetInFlightRequests(apiName string, window time.D...
    method GetAutoscalingSpec (line 48) | func (s *ScalerFunc) GetAutoscalingSpec(apiName string) (*userconfig.A...
    method CurrentRequestedReplicas (line 56) | func (s *ScalerFunc) CurrentRequestedReplicas(apiName string) (int32, ...

FILE: pkg/config/config.go
  function init (line 55) | func init() {
  function InitConfigs (line 60) | func InitConfigs(clusterConfig *clusterconfig.Config, operatorMetadata *...
  function getClusterConfigFromConfigMap (line 65) | func getClusterConfigFromConfigMap() (clusterconfig.Config, error) {
  function Init (line 79) | func Init() error {

FILE: pkg/consts/consts.go
  function DefaultRegistry (line 109) | func DefaultRegistry() string {

FILE: pkg/crds/apis/batch/v1alpha1/batchjob_metrics.go
  constant _metricsRequestTimeoutSeconds (line 33) | _metricsRequestTimeoutSeconds = 10
  function GetMetrics (line 37) | func GetMetrics(promAPIv1 promv1.API, jobKey spec.JobKey, t time.Time) (...
  function getSucceededBatchesForJobMetric (line 72) | func getSucceededBatchesForJobMetric(promAPIv1 promv1.API, jobKey spec.J...
  function getFailedBatchesForJobMetric (line 91) | func getFailedBatchesForJobMetric(promAPIv1 promv1.API, jobKey spec.JobK...
  function getAvgTimePerBatchMetric (line 110) | func getAvgTimePerBatchMetric(promAPIv1 promv1.API, jobKey spec.JobKey, ...
  function queryPrometheusVec (line 130) | func queryPrometheusVec(promAPIv1 promv1.API, query string, t time.Time)...

FILE: pkg/crds/apis/batch/v1alpha1/batchjob_types.go
  type BatchJobSpec (line 26) | type BatchJobSpec struct
  type DeadLetterQueueSpec (line 73) | type DeadLetterQueueSpec struct
  type BatchJobStatus (line 87) | type BatchJobStatus struct
  type EnqueuingStatus (line 109) | type EnqueuingStatus
  constant EnqueuingNotStarted (line 113) | EnqueuingNotStarted EnqueuingStatus = "not_started"
  constant EnqueuingInProgress (line 114) | EnqueuingInProgress EnqueuingStatus = "in_progress"
  constant EnqueuingDone (line 115) | EnqueuingDone       EnqueuingStatus = "done"
  constant EnqueuingFailed (line 116) | EnqueuingFailed     EnqueuingStatus = "failed"
  type BatchJob (line 125) | type BatchJob struct
  type BatchJobList (line 136) | type BatchJobList struct
  function init (line 142) | func init() {

FILE: pkg/crds/apis/batch/v1alpha1/zz_generated.deepcopy.go
  method DeepCopyInto (line 32) | func (in *BatchJob) DeepCopyInto(out *BatchJob) {
  method DeepCopy (line 41) | func (in *BatchJob) DeepCopy() *BatchJob {
  method DeepCopyObject (line 51) | func (in *BatchJob) DeepCopyObject() runtime.Object {
  method DeepCopyInto (line 59) | func (in *BatchJobList) DeepCopyInto(out *BatchJobList) {
  method DeepCopy (line 73) | func (in *BatchJobList) DeepCopy() *BatchJobList {
  method DeepCopyObject (line 83) | func (in *BatchJobList) DeepCopyObject() runtime.Object {
  method DeepCopyInto (line 91) | func (in *BatchJobSpec) DeepCopyInto(out *BatchJobSpec) {
  method DeepCopy (line 133) | func (in *BatchJobSpec) DeepCopy() *BatchJobSpec {
  method DeepCopyInto (line 143) | func (in *BatchJobStatus) DeepCopyInto(out *BatchJobStatus) {
  method DeepCopy (line 157) | func (in *BatchJobStatus) DeepCopy() *BatchJobStatus {
  method DeepCopyInto (line 167) | func (in *DeadLetterQueueSpec) DeepCopyInto(out *DeadLetterQueueSpec) {
  method DeepCopy (line 172) | func (in *DeadLetterQueueSpec) DeepCopy() *DeadLetterQueueSpec {

FILE: pkg/crds/controllers/batch/batchjob_controller.go
  constant _sqsFinalizer (line 39) | _sqsFinalizer                 = "sqs.finalizers.batch.cortex.dev"
  constant _s3Finalizer (line 40) | _s3Finalizer                  = "s3.finalizers.batch.cortex.dev"
  constant _completedTimestampAnnotation (line 41) | _completedTimestampAnnotation = "batch.cortex.dev/completed_timestamp"
  type BatchJobReconciler (line 45) | type BatchJobReconciler struct
    method Reconcile (line 64) | func (r *BatchJobReconciler) Reconcile(ctx context.Context, req ctrl.R...
    method SetupWithManager (line 287) | func (r *BatchJobReconciler) SetupWithManager(mgr ctrl.Manager) error {

FILE: pkg/crds/controllers/batch/batchjob_controller_config.go
  type BatchJobReconcilerConfig (line 25) | type BatchJobReconcilerConfig struct
    method ApplyDefaults (line 33) | func (c BatchJobReconcilerConfig) ApplyDefaults() BatchJobReconcilerCo...

FILE: pkg/crds/controllers/batch/batchjob_controller_helpers.go
  constant _enqueuerContainerName (line 55) | _enqueuerContainerName  = "enqueuer"
  constant _deadlineExceededReason (line 56) | _deadlineExceededReason = "DeadlineExceeded"
  constant _cacheDuration (line 57) | _cacheDuration          = 60 * time.Second
  function init (line 62) | func init() {
  type batchJobStatusInfo (line 67) | type batchJobStatusInfo struct
  method getConfigMap (line 75) | func (r *BatchJobReconciler) getConfigMap(ctx context.Context, batchJob ...
  method checkIfQueueExists (line 91) | func (r *BatchJobReconciler) checkIfQueueExists(batchJob batch.BatchJob)...
  method createQueue (line 108) | func (r *BatchJobReconciler) createQueue(batchJob batch.BatchJob) (strin...
  method getQueueURL (line 150) | func (r *BatchJobReconciler) getQueueURL(batchJob batch.BatchJob) string {
  method getQueueName (line 158) | func (r *BatchJobReconciler) getQueueName(batchJob batch.BatchJob) string {
  method checkEnqueuingStatus (line 165) | func (r *BatchJobReconciler) checkEnqueuingStatus(ctx context.Context, b...
  method enqueuePayload (line 193) | func (r *BatchJobReconciler) enqueuePayload(ctx context.Context, batchJo...
  method createWorkerConfigMap (line 206) | func (r *BatchJobReconciler) createWorkerConfigMap(ctx context.Context, ...
  method createWorkerJob (line 239) | func (r *BatchJobReconciler) createWorkerJob(ctx context.Context, batchJ...
  method desiredEnqueuerJob (line 262) | func (r *BatchJobReconciler) desiredEnqueuerJob(batchJob batch.BatchJob,...
  method desiredWorkerJob (line 324) | func (r *BatchJobReconciler) desiredWorkerJob(batchJob batch.BatchJob, a...
  method desiredConfigMap (line 384) | func (r *BatchJobReconciler) desiredConfigMap(batchJob batch.BatchJob, d...
  method getAPISpec (line 406) | func (r *BatchJobReconciler) getAPISpec(batchJob batch.BatchJob) (*spec....
  method getWorkerJob (line 430) | func (r *BatchJobReconciler) getWorkerJob(ctx context.Context, batchJob ...
  method getWorkerJobPods (line 445) | func (r *BatchJobReconciler) getWorkerJobPods(ctx context.Context, batch...
  method updateStatus (line 461) | func (r *BatchJobReconciler) updateStatus(ctx context.Context, batchJob ...
  method deleteSQSQueue (line 545) | func (r *BatchJobReconciler) deleteSQSQueue(batchJob batch.BatchJob) err...
  method uploadJobSpec (line 559) | func (r *BatchJobReconciler) uploadJobSpec(batchJob batch.BatchJob, api ...
  method ConvertControllerBatchToJobSpec (line 572) | func (r *BatchJobReconciler) ConvertControllerBatchToJobSpec(batchJob ba...
  method jobSpecKey (line 618) | func (r *BatchJobReconciler) jobSpecKey(batchJob batch.BatchJob) string {
  method updateCompletedTimestamp (line 631) | func (r *BatchJobReconciler) updateCompletedTimestamp(ctx context.Contex...
  method persistJobToS3 (line 646) | func (r *BatchJobReconciler) persistJobToS3(batchJob batch.BatchJob) err...
  function getTotalBatchCount (line 657) | func getTotalBatchCount(r *BatchJobReconciler, batchJob batch.BatchJob) ...
  function getMetrics (line 680) | func getMetrics(r *BatchJobReconciler, batchJob batch.BatchJob) (metrics...
  function saveJobMetrics (line 698) | func saveJobMetrics(r *BatchJobReconciler, batchJob batch.BatchJob) error {
  function saveJobStatus (line 712) | func saveJobStatus(r *BatchJobReconciler, batchJob batch.BatchJob) error {
  function getReplicaCounts (line 735) | func getReplicaCounts(workerJobPods []kcore.Pod) status.WorkerCounts {

FILE: pkg/crds/controllers/batch/batchjob_controller_test.go
  function uploadTestAPISpec (line 39) | func uploadTestAPISpec(apiName string, apiID string) error {
  function deleteTestAPISpec (line 70) | func deleteTestAPISpec(apiName string, apiID string) error {

FILE: pkg/crds/controllers/errors.go
  constant _optimisticLockErrorMessage (line 26) | _optimisticLockErrorMessage = "the object has been modified; please appl...
  function IsOptimisticLockError (line 30) | func IsOptimisticLockError(err error) bool {

FILE: pkg/crds/main.go
  function init (line 54) | func init() {
  function main (line 61) | func main() {

FILE: pkg/dequeuer/async_handler.go
  constant CortexRequestIDHeader (line 39) | CortexRequestIDHeader = "X-Cortex-Request-ID"
  type AsyncMessageHandler (line 42) | type AsyncMessageHandler struct
    method Handle (line 69) | func (h *AsyncMessageHandler) Handle(message *sqs.Message) error {
    method handleMessage (line 86) | func (h *AsyncMessageHandler) handleMessage(requestID string) error {
    method updateStatus (line 143) | func (h *AsyncMessageHandler) updateStatus(requestID string, status as...
    method getPayload (line 148) | func (h *AsyncMessageHandler) getPayload(requestID string) (io.ReadClo...
    method deletePayload (line 162) | func (h *AsyncMessageHandler) deletePayload(requestID string) {
    method submitRequest (line 171) | func (h *AsyncMessageHandler) submitRequest(payload io.Reader, headers...
    method uploadResult (line 213) | func (h *AsyncMessageHandler) uploadResult(requestID string, result in...
    method getHeaders (line 218) | func (h *AsyncMessageHandler) getHeaders(requestID string) (http.Heade...
  type AsyncMessageHandlerConfig (line 51) | type AsyncMessageHandlerConfig struct
  function NewAsyncMessageHandler (line 58) | func NewAsyncMessageHandler(config AsyncMessageHandlerConfig, awsClient ...

FILE: pkg/dequeuer/async_handler_test.go
  constant _testBucket (line 35) | _testBucket = "test"
  function TestAsyncMessageHandler_Handle (line 38) | func TestAsyncMessageHandler_Handle(t *testing.T) {
  function TestAsyncMessageHandler_Handle_Errors (line 91) | func TestAsyncMessageHandler_Handle_Errors(t *testing.T) {

FILE: pkg/dequeuer/async_stats.go
  type AsyncStatsReporter (line 28) | type AsyncStatsReporter struct
    method HandleEvent (line 54) | func (r *AsyncStatsReporter) HandleEvent(event RequestEvent) {
    method ServeHTTP (line 63) | func (r *AsyncStatsReporter) ServeHTTP(w http.ResponseWriter, req *htt...
  function NewAsyncPrometheusStatsReporter (line 34) | func NewAsyncPrometheusStatsReporter() *AsyncStatsReporter {

FILE: pkg/dequeuer/async_stats_test.go
  function TestNewAsyncPrometheusStatsReporter (line 31) | func TestNewAsyncPrometheusStatsReporter(t *testing.T) {
  function TestAsyncStatsReporter_HandleEvent (line 52) | func TestAsyncStatsReporter_HandleEvent(t *testing.T) {

FILE: pkg/dequeuer/batch_handler.go
  constant CortexJobIDHeader (line 36) | CortexJobIDHeader        = "X-Cortex-Job-ID"
  constant _jobCompleteMessageDelay (line 37) | _jobCompleteMessageDelay = 10 * time.Second
  type BatchMessageHandler (line 40) | type BatchMessageHandler struct
    method Handle (line 75) | func (h *BatchMessageHandler) Handle(message *sqs.Message) error {
    method recordSuccess (line 90) | func (h *BatchMessageHandler) recordSuccess() error {
    method recordFailure (line 98) | func (h *BatchMessageHandler) recordFailure() error {
    method recordTimePerBatch (line 106) | func (h *BatchMessageHandler) recordTimePerBatch(elapsedTime time.Dura...
    method submitRequest (line 114) | func (h *BatchMessageHandler) submitRequest(messageBody string, isOnJo...
    method handleBatch (line 146) | func (h *BatchMessageHandler) handleBatch(message *sqs.Message) error {
    method onJobComplete (line 175) | func (h *BatchMessageHandler) onJobComplete(message *sqs.Message) error {
  type BatchMessageHandlerConfig (line 50) | type BatchMessageHandlerConfig struct
  function NewBatchMessageHandler (line 58) | func NewBatchMessageHandler(config BatchMessageHandlerConfig, awsClient ...
  function isOnJobCompleteMessage (line 228) | func isOnJobCompleteMessage(message *sqs.Message) bool {

FILE: pkg/dequeuer/batch_handler_test.go
  function TestBatchMessageHandler_Handle (line 30) | func TestBatchMessageHandler_Handle(t *testing.T) {
  function TestBatchMessageHandler_Handle_OnJobComplete (line 61) | func TestBatchMessageHandler_Handle_OnJobComplete(t *testing.T) {

FILE: pkg/dequeuer/dequeuer.go
  type SQSDequeuerConfig (line 40) | type SQSDequeuerConfig struct
  type SQSDequeuer (line 47) | type SQSDequeuer struct
    method ReceiveMessage (line 80) | func (d *SQSDequeuer) ReceiveMessage() (*sqs.Message, error) {
    method Start (line 100) | func (d *SQSDequeuer) Start(messageHandler MessageHandler, readinessPr...
    method worker (line 125) | func (d SQSDequeuer) worker(messageHandler MessageHandler, readinessPr...
    method Shutdown (line 176) | func (d *SQSDequeuer) Shutdown() {
    method handleMessage (line 180) | func (d *SQSDequeuer) handleMessage(message *sqs.Message, messageHandl...
    method StartMessageRenewer (line 220) | func (d *SQSDequeuer) StartMessageRenewer(receiptHandle string) chan s...
  function NewSQSDequeuer (line 60) | func NewSQSDequeuer(config SQSDequeuerConfig, awsClient *awslib.Client, ...

FILE: pkg/dequeuer/dequeuer_test.go
  constant _localStackDefaultRegion (line 43) | _localStackDefaultRegion = "us-east-1"
  function TestMain (line 46) | func TestMain(m *testing.M) {
  function testAWSClient (line 103) | func testAWSClient(t *testing.T) *awslib.Client {
  function newLogger (line 123) | func newLogger(t *testing.T) *zap.SugaredLogger {
  function createQueue (line 136) | func createQueue(t *testing.T, awsClient *awslib.Client) string {
  function TestSQSDequeuer_ReceiveMessage (line 158) | func TestSQSDequeuer_ReceiveMessage(t *testing.T) {
  function TestSQSDequeuer_StartMessageRenewer (line 195) | func TestSQSDequeuer_StartMessageRenewer(t *testing.T) {
  function TestSQSDequeuerTerminationOnEmptyQueue (line 244) | func TestSQSDequeuerTerminationOnEmptyQueue(t *testing.T) {
  function TestSQSDequeuer_Shutdown (line 295) | func TestSQSDequeuer_Shutdown(t *testing.T) {
  function TestSQSDequeuer_Start_HandlerError (line 338) | func TestSQSDequeuer_Start_HandlerError(t *testing.T) {

FILE: pkg/dequeuer/errors.go
  constant ErrUserContainerResponseStatusCode (line 26) | ErrUserContainerResponseStatusCode        = "dequeuer.user_container_res...
  constant ErrUserContainerResponseMissingJSONHeader (line 27) | ErrUserContainerResponseMissingJSONHeader = "dequeuer.user_container_res...
  constant ErrUserContainerResponseNotJSONDecodable (line 28) | ErrUserContainerResponseNotJSONDecodable  = "dequeuer.user_container_res...
  constant ErrUserContainerNotReachable (line 29) | ErrUserContainerNotReachable              = "dequeuer.user_container_not...
  function ErrorUserContainerResponseStatusCode (line 32) | func ErrorUserContainerResponseStatusCode(statusCode int) error {
  function ErrorUserContainerResponseMissingJSONHeader (line 40) | func ErrorUserContainerResponseMissingJSONHeader() error {
  function ErrorUserContainerResponseNotJSONDecodable (line 48) | func ErrorUserContainerResponseNotJSONDecodable() error {
  function ErrorUserContainerNotReachable (line 56) | func ErrorUserContainerNotReachable(err error) error {

FILE: pkg/dequeuer/http_handler.go
  function HealthcheckHandler (line 21) | func HealthcheckHandler(isHealthy func() bool) http.HandlerFunc {

FILE: pkg/dequeuer/message_handler.go
  type MessageHandler (line 21) | type MessageHandler interface
  function NewMessageHandlerFunc (line 25) | func NewMessageHandlerFunc(handleFunc func(*sqs.Message) error) MessageH...
  type messageHandlerFunc (line 29) | type messageHandlerFunc struct
    method Handle (line 33) | func (h *messageHandlerFunc) Handle(msg *sqs.Message) error {

FILE: pkg/dequeuer/probes.go
  function ProbesFromFile (line 27) | func ProbesFromFile(probesPath string, logger *zap.SugaredLogger) ([]*pr...
  function HasTCPProbeTargetingUserPod (line 48) | func HasTCPProbeTargetingUserPod(probes []*probe.Probe, userPort int) bo...

FILE: pkg/dequeuer/probes_test.go
  function TestDefaultTCPProbeNotPresent (line 28) | func TestDefaultTCPProbeNotPresent(t *testing.T) {
  function TestDefaultTCPProbePresent (line 66) | func TestDefaultTCPProbePresent(t *testing.T) {

FILE: pkg/dequeuer/queue_attributes.go
  type QueueAttributes (line 27) | type QueueAttributes struct
    method TotalMessages (line 33) | func (attr QueueAttributes) TotalMessages() int {
  function GetQueueAttributes (line 37) | func GetQueueAttributes(client *awslib.Client, queueURL string) (QueueAt...

FILE: pkg/dequeuer/request_stats.go
  type RequestEvent (line 21) | type RequestEvent struct
  type RequestEventHandler (line 26) | type RequestEventHandler interface
  type requestEventHandlerFunc (line 30) | type requestEventHandlerFunc struct
    method HandleEvent (line 34) | func (h *requestEventHandlerFunc) HandleEvent(event RequestEvent) {
  function NewRequestEventHandlerFunc (line 38) | func NewRequestEventHandlerFunc(handleFunc func(event RequestEvent)) Req...

FILE: pkg/enqueuer/enqueuer.go
  constant _s3DownloadChunkSize (line 39) | _s3DownloadChunkSize = 32 * 1024 * 1024
  type EnvConfig (line 42) | type EnvConfig struct
  type ItemList (line 53) | type ItemList struct
  type S3Lister (line 58) | type S3Lister struct
  type FilePathLister (line 65) | type FilePathLister struct
  type DelimitedFiles (line 70) | type DelimitedFiles struct
  type JobSubmission (line 75) | type JobSubmission struct
  type onJobCompleteRequestBody (line 81) | type onJobCompleteRequestBody struct
  function randomMessageID (line 85) | func randomMessageID() string {
  type Enqueuer (line 89) | type Enqueuer struct
    method Enqueue (line 110) | func (e *Enqueuer) Enqueue() (int, error) {
    method UploadBatchCount (line 173) | func (e *Enqueuer) UploadBatchCount(batchCount int) error {
    method getJobPayload (line 178) | func (e *Enqueuer) getJobPayload() (JobSubmission, error) {
    method deleteJobPayload (line 195) | func (e *Enqueuer) deleteJobPayload() error {
    method enqueueItems (line 203) | func (e *Enqueuer) enqueueItems(itemList *ItemList) (int, error) {
    method enqueueS3Paths (line 255) | func (e *Enqueuer) enqueueS3Paths(s3PathsLister *FilePathLister) (int,...
    method enqueueS3FileContents (line 298) | func (e *Enqueuer) enqueueS3FileContents(delimitedFiles *DelimitedFile...
    method streamJSONToQueue (line 352) | func (e *Enqueuer) streamJSONToQueue(uploader *sqsBatchUploader, bytes...
  function NewEnqueuer (line 96) | func NewEnqueuer(envConfig EnvConfig, queueURL string, logger *zap.Logge...
  function addS3PathsToQueue (line 391) | func addS3PathsToQueue(uploader *sqsBatchUploader, s3PathList []string) ...

FILE: pkg/enqueuer/errors.go
  constant ErrFailedToEnqueueMessages (line 26) | ErrFailedToEnqueueMessages = "batchapi.failed_to_enqueue_messages"
  constant ErrMessageExceedsMaxSize (line 27) | ErrMessageExceedsMaxSize   = "batchapi.message_exceeds_max_size"
  function ErrorFailedToEnqueueMessages (line 30) | func ErrorFailedToEnqueueMessages(message string) error {
  function ErrorMessageExceedsMaxSize (line 37) | func ErrorMessageExceedsMaxSize(messageSize int, messageLimit int) error {

FILE: pkg/enqueuer/helpers.go
  type jsonBuffer (line 29) | type jsonBuffer struct
    method Add (line 41) | func (j *jsonBuffer) Add(jsonMessage json.RawMessage) {
    method Clear (line 45) | func (j *jsonBuffer) Clear() {
    method Length (line 49) | func (j *jsonBuffer) Length() int {
  function newJSONBuffer (line 34) | func newJSONBuffer(batchSize int) *jsonBuffer {
  function addJSONObjectsToQueue (line 53) | func addJSONObjectsToQueue(uploader *sqsBatchUploader, jsonMessageList *...
  function s3IteratorFromLister (line 67) | func s3IteratorFromLister(awsClient *awslib.Client, s3Lister S3Lister, f...

FILE: pkg/enqueuer/uploader.go
  constant _messageSizeLimit (line 28) | _messageSizeLimit    = 250 * 1024
  constant _maxMessagesPerBatch (line 29) | _maxMessagesPerBatch = 10
  type sqsBatchUploader (line 32) | type sqsBatchUploader struct
    method AddToBatch (line 64) | func (uploader *sqsBatchUploader) AddToBatch(id string, body *string) ...
    method Flush (line 91) | func (uploader *sqsBatchUploader) Flush() error {
    method enqueueToSQS (line 110) | func (uploader *sqsBatchUploader) enqueueToSQS() error {
  function newSQSBatchUploader (line 43) | func newSQSBatchUploader(apiName, jobID, queueURL string, client *sqs.SQ...

FILE: pkg/health/health.go
  type ClusterHealth (line 42) | type ClusterHealth struct
    method String (line 63) | func (c ClusterHealth) String() string {
  type ClusterWarnings (line 72) | type ClusterWarnings struct
    method HasWarnings (line 77) | func (w ClusterWarnings) HasWarnings() bool {
  function Check (line 88) | func Check(awsClient *awslib.Client, k8sClient *k8s.Client, clusterName ...
  function GetWarnings (line 227) | func GetWarnings(k8sClient *k8s.Client) (ClusterWarnings, error) {
  function getDeploymentReadiness (line 244) | func getDeploymentReadiness(k8sClient *k8s.Client, name, namespace strin...
  function getStatefulSetReadiness (line 260) | func getStatefulSetReadiness(k8sClient *k8s.Client, name, namespace stri...
  function getDaemonSetReadiness (line 275) | func getDaemonSetReadiness(k8sClient *k8s.Client, name, namespace string...
  function getLoadBalancerHealth (line 290) | func getLoadBalancerHealth(awsClient *awslib.Client, clusterName string,...
  function getPodMemorySaturation (line 326) | func getPodMemorySaturation(k8sClient *k8s.Client, podName, namespace st...

FILE: pkg/lib/archive/archive_test.go
  function TestArchive (line 30) | func TestArchive(t *testing.T) {
  function CheckArchive (line 355) | func CheckArchive(input *Input, expected []string, shouldErr bool, t *te...
  function CheckZip (line 361) | func CheckZip(input *Input, expected []string, shouldErr bool, t *testin...
  function CheckTar (line 392) | func CheckTar(input *Input, expected []string, shouldErr bool, t *testin...
  function CheckTgz (line 423) | func CheckTgz(input *Input, expected []string, shouldErr bool, t *testin...

FILE: pkg/lib/archive/archiver.go
  type archiveType (line 31) | type archiveType
  constant unknownArchiveType (line 34) | unknownArchiveType archiveType = iota
  constant zipArchiveType (line 35) | zipArchiveType
  constant tarArchiveType (line 36) | tarArchiveType
  constant tgzArchiveType (line 37) | tgzArchiveType
  type archiver (line 40) | type archiver interface
  function archive (line 45) | func archive(input *Input, arc archiver) (strset.Set, error) {
  function addBytesToArchive (line 87) | func addBytesToArchive(byteInput *BytesInput, input *Input, arc archiver...
  function addFileToArchive (line 102) | func addFileToArchive(fileInput *FileInput, input *Input, arc archiver, ...
  function addDirToArchive (line 116) | func addDirToArchive(dirInput *DirInput, input *Input, arc archiver, add...
  function addFileListToArchive (line 153) | func addFileListToArchive(fileListInput *FileListInput, input *Input, ar...
  function addEmptyFileToArchive (line 183) | func addEmptyFileToArchive(path string, input *Input, arc archiver, adde...
  function archiveToWriter (line 191) | func archiveToWriter(input *Input, writer io.Writer, arcType archiveType...
  function archiveToMem (line 218) | func archiveToMem(input *Input, arcType archiveType) ([]byte, strset.Set...
  function archiveToFile (line 229) | func archiveToFile(input *Input, destDir string, arcType archiveType) (s...

FILE: pkg/lib/archive/errors.go
  constant _errStrCreateArchive (line 27) | _errStrCreateArchive = "unable to create archive"
  constant _errStrCreateZip (line 28) | _errStrCreateZip     = "unable to create zip file"
  constant _errStrCreateTar (line 29) | _errStrCreateTar     = "unable to create tar file"
  constant _errStrUnzip (line 30) | _errStrUnzip         = "unable to unzip file"
  constant _errStrUntar (line 31) | _errStrUntar         = "unable to extract tar file"
  constant ErrDuplicatePath (line 35) | ErrDuplicatePath = "archive.duplicate_path"
  function ErrorDuplicatePath (line 38) | func ErrorDuplicatePath(path string) error {

FILE: pkg/lib/archive/input.go
  type Input (line 23) | type Input struct
  type FileInput (line 33) | type FileInput struct
  type BytesInput (line 38) | type BytesInput struct
  type DirInput (line 43) | type DirInput struct
  type FileListInput (line 52) | type FileListInput struct

FILE: pkg/lib/archive/tar.go
  type tarArchiver (line 33) | type tarArchiver struct
    method add (line 43) | func (arc *tarArchiver) add(reader io.Reader, dest string, size int64)...
    method close (line 62) | func (arc *tarArchiver) close() error {
  function newTarArchiver (line 37) | func newTarArchiver(writer io.Writer) *tarArchiver {
  function TarToWriter (line 66) | func TarToWriter(input *Input, writer io.Writer) (strset.Set, error) {
  function TarToFile (line 70) | func TarToFile(input *Input, destDir string) (strset.Set, error) {
  function TarToMem (line 74) | func TarToMem(input *Input) ([]byte, strset.Set, error) {
  function UntarReaderToDir (line 79) | func UntarReaderToDir(reader io.Reader, destDir string) (strset.Set, err...
  function UntarFileToDir (line 138) | func UntarFileToDir(src string, destDir string) (strset.Set, error) {
  function UntarReaderToMem (line 148) | func UntarReaderToMem(reader io.Reader) (map[string][]byte, error) {
  function UntarMemToMem (line 179) | func UntarMemToMem(tarBytes []byte) (map[string][]byte, error) {
  function UntarFileToMem (line 183) | func UntarFileToMem(src string) (map[string][]byte, error) {

FILE: pkg/lib/archive/tgz.go
  type tgzArchiver (line 29) | type tgzArchiver struct
    method add (line 42) | func (arc *tgzArchiver) add(reader io.Reader, dest string, size int64)...
    method close (line 46) | func (arc *tgzArchiver) close() error {
  function newTgzArchiver (line 34) | func newTgzArchiver(writer io.Writer) *tgzArchiver {
  function TgzToWriter (line 52) | func TgzToWriter(input *Input, writer io.Writer) (strset.Set, error) {
  function TgzToFile (line 56) | func TgzToFile(input *Input, destDir string) (strset.Set, error) {
  function TgzToMem (line 60) | func TgzToMem(input *Input) ([]byte, strset.Set, error) {
  function UntgzReaderToDir (line 65) | func UntgzReaderToDir(reader io.Reader, destDir string) (strset.Set, err...
  function UntgzFileToDir (line 76) | func UntgzFileToDir(src string, destDir string) (strset.Set, error) {
  function UntgzReaderToMem (line 86) | func UntgzReaderToMem(reader io.Reader) (map[string][]byte, error) {
  function UntgzMemToMem (line 96) | func UntgzMemToMem(tgzBytes []byte) (map[string][]byte, error) {
  function UntgzFileToMem (line 100) | func UntgzFileToMem(src string) (map[string][]byte, error) {

FILE: pkg/lib/archive/zip.go
  type zipArchiver (line 33) | type zipArchiver struct
    method add (line 43) | func (arc *zipArchiver) add(reader io.Reader, dest string, size int64)...
    method close (line 57) | func (arc *zipArchiver) close() error {
  function newZipArchiver (line 37) | func newZipArchiver(writer io.Writer) *zipArchiver {
  function ZipToWriter (line 61) | func ZipToWriter(input *Input, writer io.Writer) (strset.Set, error) {
  function ZipToFile (line 65) | func ZipToFile(input *Input, destDir string) (strset.Set, error) {
  function ZipToMem (line 69) | func ZipToMem(input *Input) ([]byte, strset.Set, error) {
  function UnzipFileToDir (line 74) | func UnzipFileToDir(src string, destDir string) (strset.Set, error) {
  function UnzipMemToMem (line 133) | func UnzipMemToMem(zipBytes []byte) (map[string][]byte, error) {
  function UnzipFileToMem (line 142) | func UnzipFileToMem(src string) (map[string][]byte, error) {
  function unzipZipReaderToMem (line 157) | func unzipZipReaderToMem(zipReader *zip.Reader) (map[string][]byte, erro...

FILE: pkg/lib/aws/acm.go
  method DoesCertificateExist (line 25) | func (c *Client) DoesCertificateExist(sslCertificateARN string) (bool, e...

FILE: pkg/lib/aws/apigateway.go
  method CreateAPIGateway (line 29) | func (c *Client) CreateAPIGateway(name string, tags map[string]string) (...
  method GetVPCLinkByTag (line 57) | func (c *Client) GetVPCLinkByTag(tagName string, tagValue string) (*apig...
  method GetAPIGatewayByTag (line 86) | func (c *Client) GetAPIGatewayByTag(tagName string, tagValue string) (*a...
  method DeleteVPCLinkByTag (line 115) | func (c *Client) DeleteVPCLinkByTag(tagName string, tagValue string) (*a...
  method DeleteAPIGatewayByTag (line 134) | func (c *Client) DeleteAPIGatewayByTag(tagName string, tagValue string) ...
  method DeleteAPIGateway (line 151) | func (c *Client) DeleteAPIGateway(apiGatewayID string) error {
  method DeleteAPIGatewayMappingsForDomainName (line 169) | func (c *Client) DeleteAPIGatewayMappingsForDomainName(apiGatewayID stri...
  method DeleteAPIGatewayMappings (line 205) | func (c *Client) DeleteAPIGatewayMappings(apiGatewayID string) error {
  method GetVPCLinkIntegration (line 233) | func (c *Client) GetVPCLinkIntegration(apiGatewayID string, vpcLinkID st...
  method GetRouteIntegrationID (line 262) | func (c *Client) GetRouteIntegrationID(apiGatewayID string, endpoint str...
  function ExtractRouteIntegrationID (line 275) | func ExtractRouteIntegrationID(route *apigatewayv2.Route) string {
  method GetRoute (line 287) | func (c *Client) GetRoute(apiGatewayID string, endpoint string) (*apigat...
  method CreateRoute (line 316) | func (c *Client) CreateRoute(apiGatewayID string, integrationID string, ...
  method CreateHTTPIntegration (line 329) | func (c *Client) CreateHTTPIntegration(apiGatewayID string, targetEndpoi...
  method DeleteIntegration (line 344) | func (c *Client) DeleteIntegration(apiGatewayID string, integrationID st...
  method DeleteRoute (line 356) | func (c *Client) DeleteRoute(apiGatewayID string, endpoint string) (*api...

FILE: pkg/lib/aws/autoscaling.go
  method AutoscalingGroups (line 26) | func (c *Client) AutoscalingGroups(tags map[string]string) ([]*autoscali...
  method MostRecentASGActivity (line 68) | func (c *Client) MostRecentASGActivity(asgName string) (*autoscaling.Act...

FILE: pkg/lib/aws/aws.go
  type Client (line 29) | type Client struct
    method Session (line 153) | func (c Client) Session() *session.Session {
  function NewForSession (line 38) | func NewForSession(sess *session.Session) (*Client, error) {
  function NewFromClientS3Path (line 49) | func NewFromClientS3Path(s3Path string, awsClient *Client) (*Client, err...
  function NewFromS3Path (line 62) | func NewFromS3Path(s3Path string) (*Client, error) {
  function NewFromS3Bucket (line 70) | func NewFromS3Bucket(bucket string) (*Client, error) {
  function NewForRegion (line 78) | func NewForRegion(region string) (*Client, error) {
  function New (line 109) | func New() (*Client, error) {
  function NewAnonymousClientWithRegion (line 138) | func NewAnonymousClientWithRegion(region string) (*Client, error) {

FILE: pkg/lib/aws/clients.go
  type clients (line 39) | type clients struct
  method S3 (line 60) | func (c *Client) S3() *s3.S3 {
  method S3Uploader (line 67) | func (c *Client) S3Uploader() *s3manager.Uploader {
  method S3Downloader (line 74) | func (c *Client) S3Downloader() *s3manager.Downloader {
  method STS (line 81) | func (c *Client) STS() *sts.STS {
  method SQS (line 88) | func (c *Client) SQS() *sqs.SQS {
  method EC2 (line 95) | func (c *Client) EC2() *ec2.EC2 {
  method ELB (line 102) | func (c *Client) ELB() *elb.ELB {
  method ELBV2 (line 109) | func (c *Client) ELBV2() *elbv2.ELBV2 {
  method EKS (line 116) | func (c *Client) EKS() *eks.EKS {
  method ECR (line 123) | func (c *Client) ECR() *ecr.ECR {
  method CloudFormation (line 130) | func (c *Client) CloudFormation() *cloudformation.CloudFormation {
  method Autoscaling (line 137) | func (c *Client) Autoscaling() *autoscaling.AutoScaling {
  method ACM (line 144) | func (c *Client) ACM() *acm.ACM {
  method CloudWatchLogs (line 151) | func (c *Client) CloudWatchLogs() *cloudwatchlogs.CloudWatchLogs {
  method CloudWatch (line 158) | func (c *Client) CloudWatch() *cloudwatch.CloudWatch {
  method APIGatewayV2 (line 165) | func (c *Client) APIGatewayV2() *apigatewayv2.ApiGatewayV2 {
  method ServiceQuotas (line 172) | func (c *Client) ServiceQuotas() *servicequotas.ServiceQuotas {
  method IAM (line 179) | func (c *Client) IAM() *iam.IAM {

FILE: pkg/lib/aws/cloudformation.go
  method ListEKSStacks (line 25) | func (c *Client) ListEKSStacks(controlPlaneStackName string, nodeGroupSt...
  function getStackSummariesFromMap (line 60) | func getStackSummariesFromMap(stackSummaries map[string]*cloudformation....

FILE: pkg/lib/aws/cloudwatch.go
  type CloudWatchDashboard (line 35) | type CloudWatchDashboard struct
  type CloudWatchWidget (line 63) | type CloudWatchWidget struct
  type CloudWatchWidgetGrid (line 72) | type CloudWatchWidgetGrid struct
    method AddWidget (line 296) | func (grid *CloudWatchWidgetGrid) AddWidget(
  method DoesLogGroupExist (line 82) | func (c *Client) DoesLogGroupExist(logGroup string) (bool, error) {
  method CreateLogGroup (line 96) | func (c *Client) CreateLogGroup(logGroup string, tags map[string]string)...
  method DeleteLogGroup (line 108) | func (c *Client) DeleteLogGroup(logGroup string) error {
  method TagLogGroup (line 119) | func (c *Client) TagLogGroup(logGroup string, tagMap map[string]string) ...
  method NewDashboard (line 138) | func (c *Client) NewDashboard(title string) *CloudWatchDashboard {
  method GetDashboard (line 149) | func (c *Client) GetDashboard(dashboardName string) (*CloudWatchDashboar...
  method GetDashboardOrEmpty (line 169) | func (c *Client) GetDashboardOrEmpty(dashboardName string, title string)...
  method CreateDashboard (line 183) | func (c *Client) CreateDashboard(dashboardName string, title string) err...
  method PutDashboard (line 195) | func (c *Client) PutDashboard(dashboard *CloudWatchDashboard, dashboardN...
  method DeleteDashboard (line 213) | func (c *Client) DeleteDashboard(dashboardName string) error {
  method DoesDashboardExist (line 225) | func (c *Client) DoesDashboardExist(dashboardName string) (bool, error) {
  function TextWidget (line 249) | func TextWidget(x int, y int, width int, height int, markdown string) Cl...
  function NewHorizontalGrid (line 254) | func NewHorizontalGrid(xOrigin, yOrigin, widgetHeight, widgetWidth, numC...
  function NewVerticalGrid (line 275) | func NewVerticalGrid(xOrigin, yOrigin, widgetHeight, widgetWidth, numRow...
  function HighestY (line 344) | func HighestY(dashboard *CloudWatchDashboard) (int, error) {

FILE: pkg/lib/aws/credentials.go
  method AccessKeyID (line 20) | func (c *Client) AccessKeyID() *string {
  method SecretAccessKey (line 37) | func (c *Client) SecretAccessKey() *string {
  method SessionToken (line 54) | func (c *Client) SessionToken() *string {

FILE: pkg/lib/aws/ec2.go
  type ParsedInstanceType (line 38) | type ParsedInstanceType struct
  function IsValidInstanceType (line 46) | func IsValidInstanceType(instanceType string) bool {
  function CheckValidInstanceType (line 51) | func CheckValidInstanceType(instanceType string) error {
  function ParseInstanceType (line 64) | func ParseInstanceType(instanceType string) (ParsedInstanceType, error) {
  function IsARMInstance (line 106) | func IsARMInstance(instanceType string) (bool, error) {
  function IsAMDGPUInstance (line 123) | func IsAMDGPUInstance(instanceType string) (bool, error) {
  function IsNvidiaGPUInstance (line 140) | func IsNvidiaGPUInstance(instanceType string) (bool, error) {
  function IsGPUInstance (line 157) | func IsGPUInstance(instanceType string) (bool, error) {
  function IsInferentiaInstance (line 171) | func IsInferentiaInstance(instanceType string) (bool, error) {
  function IsTrainiumInstance (line 180) | func IsTrainiumInstance(instanceType string) (bool, error) {
  function IsMacInstance (line 189) | func IsMacInstance(instanceType string) (bool, error) {
  function IsFPGAInstance (line 202) | func IsFPGAInstance(instanceType string) (bool, error) {
  function IsAlevoInstance (line 215) | func IsAlevoInstance(instanceType string) (bool, error) {
  function IsGaudiInstance (line 228) | func IsGaudiInstance(instanceType string) (bool, error) {
  method SpotInstancePrice (line 241) | func (c *Client) SpotInstancePrice(instanceType string) (float64, error) {
  method ListAllRegions (line 279) | func (c *Client) ListAllRegions() (strset.Set, error) {
  method ListEnabledRegions (line 298) | func (c *Client) ListEnabledRegions() (strset.Set, error) {
  method ListRegions (line 317) | func (c *Client) ListRegions() (strset.Set, strset.Set, error) {
  method ListAvailabilityZonesInRegion (line 341) | func (c *Client) ListAvailabilityZonesInRegion() (strset.Set, error) {
  method listSupportedAvailabilityZonesSingle (line 370) | func (c *Client) listSupportedAvailabilityZonesSingle(instanceType strin...
  method ListSupportedAvailabilityZones (line 399) | func (c *Client) ListSupportedAvailabilityZones(instanceType string, ins...
  method ListElasticIPs (line 424) | func (c *Client) ListElasticIPs() ([]string, error) {
  method ListInternetGateways (line 442) | func (c *Client) ListInternetGateways() ([]string, error) {
  method DescribeNATGateways (line 463) | func (c *Client) DescribeNATGateways() ([]ec2.NatGateway, error) {
  method DescribeSubnets (line 485) | func (c *Client) DescribeSubnets() ([]ec2.Subnet, error) {
  method DescribeVpcs (line 507) | func (c *Client) DescribeVpcs() ([]ec2.Vpc, error) {
  method DescribeSecurityGroups (line 529) | func (c *Client) DescribeSecurityGroups() ([]ec2.SecurityGroup, error) {
  method ListVolumes (line 551) | func (c *Client) ListVolumes(tags ...ec2.Tag) ([]ec2.Volume, error) {
  method DeleteVolume (line 576) | func (c *Client) DeleteVolume(volumeID string) error {
  function hasAllEC2Tags (line 587) | func hasAllEC2Tags(queryTags []ec2.Tag, allResourceTags []*ec2.Tag) bool {
  function hasEC2Tag (line 597) | func hasEC2Tag(queryTag ec2.Tag, allResourceTags []*ec2.Tag) bool {

FILE: pkg/lib/aws/ec2_test.go
  function TestParseInstanceType (line 27) | func TestParseInstanceType(t *testing.T) {

FILE: pkg/lib/aws/ecr.go
  type ECRAuthConfig (line 29) | type ECRAuthConfig struct
  method GetECRAuthToken (line 37) | func (c *Client) GetECRAuthToken() (*ecr.GetAuthorizationTokenOutput, er...
  method GetECRAuthConfig (line 45) | func (c *Client) GetECRAuthConfig() (ECRAuthConfig, error) {
  function GetAccountIDFromECRURL (line 72) | func GetAccountIDFromECRURL(path string) string {
  function GetRegionFromECRURL (line 79) | func GetRegionFromECRURL(path string) string {

FILE: pkg/lib/aws/eks.go
  function init (line 27) | func init() {
  method EKSClusterOrNil (line 35) | func (c *Client) EKSClusterOrNil(clusterName string) (*eks.Cluster, erro...

FILE: pkg/lib/aws/elb.go
  type ClassicLoadBalancerState (line 25) | type ClassicLoadBalancerState
    method String (line 33) | func (state ClassicLoadBalancerState) String() string {
  constant LoadBalancerStateInService (line 28) | LoadBalancerStateInService    ClassicLoadBalancerState = "InService"
  constant LoadBalancerStateOutOfService (line 29) | LoadBalancerStateOutOfService ClassicLoadBalancerState = "OutOfService"
  constant LoadBalancerStateUnknown (line 30) | LoadBalancerStateUnknown      ClassicLoadBalancerState = "Unknown"
  method FindLoadBalancer (line 38) | func (c *Client) FindLoadBalancer(tags map[string]string) (*elb.LoadBala...
  method IsLoadBalancerHealthy (line 99) | func (c *Client) IsLoadBalancerHealthy(loadBalancerName string) (bool, e...

FILE: pkg/lib/aws/elbv2.go
  function IsInstanceSupportedByNLB (line 31) | func IsInstanceSupportedByNLB(instanceType string) (bool, error) {
  method FindLoadBalancerV2 (line 46) | func (c *Client) FindLoadBalancerV2(tags map[string]string) (*elbv2.Load...
  function IsLoadBalancerV2Healthy (line 107) | func IsLoadBalancerV2Healthy(loadBalancer elbv2.LoadBalancer) bool {

FILE: pkg/lib/aws/errors.go
  constant ErrInvalidInstanceType (line 31) | ErrInvalidInstanceType          = "aws.invalid_instance_type"
  constant ErrInvalidAWSCredentials (line 32) | ErrInvalidAWSCredentials        = "aws.invalid_aws_credentials"
  constant ErrInvalidS3aPath (line 33) | ErrInvalidS3aPath               = "aws.invalid_s3a_path"
  constant ErrInvalidS3Path (line 34) | ErrInvalidS3Path                = "aws.invalid_s3_path"
  constant ErrUnexpectedMissingCredentials (line 35) | ErrUnexpectedMissingCredentials = "aws.unexpected_missing_credentials"
  constant ErrAuth (line 36) | ErrAuth                         = "aws.auth"
  constant ErrBucketInaccessible (line 37) | ErrBucketInaccessible           = "aws.bucket_inaccessible"
  constant ErrBucketNotFound (line 38) | ErrBucketNotFound               = "aws.bucket_not_found"
  constant ErrInsufficientInstanceQuota (line 39) | ErrInsufficientInstanceQuota    = "aws.insufficient_instance_quota"
  constant ErrNoValidSpotPrices (line 40) | ErrNoValidSpotPrices            = "aws.no_valid_spot_prices"
  constant ErrECRExtractingCredentials (line 41) | ErrECRExtractingCredentials     = "aws.ecr_failed_credentials"
  constant ErrDashboardWidthOutOfRange (line 42) | ErrDashboardWidthOutOfRange     = "aws.dashboard_width_ouf_of_range"
  constant ErrDashboardHeightOutOfRange (line 43) | ErrDashboardHeightOutOfRange    = "aws.dashboard_height_out_of_range"
  constant ErrRegionNotConfigured (line 44) | ErrRegionNotConfigured          = "aws.region_not_configured"
  constant ErrUnableToFindCredentials (line 45) | ErrUnableToFindCredentials      = "aws.unable_to_find_credentials"
  constant ErrNATGatewayLimitExceeded (line 46) | ErrNATGatewayLimitExceeded      = "aws.nat_gateway_limit_exceeded"
  constant ErrEIPLimitExceeded (line 47) | ErrEIPLimitExceeded             = "aws.eip_limit_exceeded"
  constant ErrInternetGatewayLimitExceeded (line 48) | ErrInternetGatewayLimitExceeded = "aws.internet_gateway_limit_exceeded"
  constant ErrVPCLimitExceeded (line 49) | ErrVPCLimitExceeded             = "aws.vpc_limit_exceeded"
  constant ErrSecurityGroupRulesExceeded (line 50) | ErrSecurityGroupRulesExceeded   = "aws.security_group_rules_exceeded"
  constant ErrSecurityGroupLimitExceeded (line 51) | ErrSecurityGroupLimitExceeded   = "aws.security_group_limit_exceeded"
  function IsAWSError (line 54) | func IsAWSError(err error) bool {
  function IsNotFoundErr (line 61) | func IsNotFoundErr(err error) bool {
  function IsNoSuchKeyErr (line 65) | func IsNoSuchKeyErr(err error) bool {
  function IsNoSuchEntityErr (line 69) | func IsNoSuchEntityErr(err error) bool {
  function IsNoSuchBucketErr (line 73) | func IsNoSuchBucketErr(err error) bool {
  function IsNonExistentQueueErr (line 77) | func IsNonExistentQueueErr(err error) bool {
  function IsGenericNotFoundErr (line 81) | func IsGenericNotFoundErr(err error) bool {
  function IsErrCode (line 85) | func IsErrCode(err error, errorCode string) bool {
  function ErrorInvalidInstanceType (line 96) | func ErrorInvalidInstanceType(instanceType string) error {
  function ErrorInvalidAWSCredentials (line 103) | func ErrorInvalidAWSCredentials(awsErr error) error {
  function ErrorInvalidS3aPath (line 112) | func ErrorInvalidS3aPath(provided string) error {
  function ErrorInvalidS3Path (line 119) | func ErrorInvalidS3Path(provided string) error {
  function ErrorUnexpectedMissingCredentials (line 126) | func ErrorUnexpectedMissingCredentials(awsAccessKeyID string, awsSecretA...
  function ErrorAuth (line 142) | func ErrorAuth() error {
  function ErrorBucketInaccessible (line 149) | func ErrorBucketInaccessible(bucket string) error {
  function ErrorBucketNotFound (line 156) | func ErrorBucketNotFound(bucket string) error {
  function ErrorInsufficientInstanceQuota (line 163) | func ErrorInsufficientInstanceQuota(instanceTypes []string, lifecycle st...
  function ErrorNoValidSpotPrices (line 172) | func ErrorNoValidSpotPrices(instanceType string, region string) error {
  function ErrorECRExtractingCredentials (line 179) | func ErrorECRExtractingCredentials() error {
  function ErrorDashboardWidthOutOfRange (line 186) | func ErrorDashboardWidthOutOfRange(width int) error {
  function ErrorDashboardHeightOutOfRange (line 193) | func ErrorDashboardHeightOutOfRange(height int) error {
  function ErrorRegionNotConfigured (line 200) | func ErrorRegionNotConfigured() error {
  function ErrorUnableToFindCredentials (line 207) | func ErrorUnableToFindCredentials() error {
  function ErrorNATGatewayLimitExceeded (line 214) | func ErrorNATGatewayLimitExceeded(currentLimit, additionalQuotaRequired ...
  function ErrorEIPLimitExceeded (line 222) | func ErrorEIPLimitExceeded(currentLimit, additionalQuotaRequired int, re...
  function ErrorInternetGatewayLimitExceeded (line 230) | func ErrorInternetGatewayLimitExceeded(currentLimit, additionalQuotaRequ...
  function ErrorVPCLimitExceeded (line 238) | func ErrorVPCLimitExceeded(currentLimit, additionalQuotaRequired int, re...
  function ErrorSecurityGroupRulesExceeded (line 246) | func ErrorSecurityGroupRulesExceeded(currentLimit, additionalQuotaRequir...
  function ErrorSecurityGroupLimitExceeded (line 254) | func ErrorSecurityGroupLimitExceeded(currentLimit, additionalQuotaRequir...

FILE: pkg/lib/aws/gen_resource_metadata.py
  function get_instance_metadatas (line 65) | def get_instance_metadatas(pricing):
  function get_nlb_metadata (line 110) | def get_nlb_metadata(pricing):
  function get_elb_metadata (line 130) | def get_elb_metadata(pricing):
  function get_nat_metadata (line 150) | def get_nat_metadata(pricing):
  function get_ebs_metadata (line 170) | def get_ebs_metadata(pricing):
  function get_eks_price (line 259) | def get_eks_price(region):
  function instanceTypeSorter (line 438) | def instanceTypeSorter(instanceType):
  function main (line 467) | def main():

FILE: pkg/lib/aws/iam.go
  function PartitionFromRegion (line 29) | func PartitionFromRegion(region string) string {
  function administratorAccessARN (line 36) | func administratorAccessARN(region string) string {
  method GetUser (line 40) | func (c *Client) GetUser() (iam.User, error) {
  method GetGroupsForUser (line 48) | func (c *Client) GetGroupsForUser(userName string) ([]iam.Group, error) {
  method GetManagedPoliciesForUser (line 70) | func (c *Client) GetManagedPoliciesForUser(userName string) ([]iam.Attac...
  method isAdminUser (line 103) | func (c *Client) isAdminUser(user iam.User) bool {
  method isRoleAdmin (line 128) | func (c *Client) isRoleAdmin() bool {
  method IsAdmin (line 166) | func (c *Client) IsAdmin() bool {
  method DeletePolicy (line 184) | func (c *Client) DeletePolicy(policyARN string) error {
  method GetPolicyOrNil (line 213) | func (c *Client) GetPolicyOrNil(policyARN string) (*iam.Policy, error) {

FILE: pkg/lib/aws/resource_metadata.go
  type InstanceMetadata (line 26) | type InstanceMetadata struct
  type NLBMetadata (line 36) | type NLBMetadata struct
  type ELBMetadata (line 41) | type ELBMetadata struct
  type NATMetadata (line 46) | type NATMetadata struct
  type EBSMetadata (line 51) | type EBSMetadata struct

FILE: pkg/lib/aws/s3.go
  constant DefaultS3Region (line 44) | DefaultS3Region string = endpoints.UsWest2RegionID
  function init (line 48) | func init() {
  function S3Path (line 63) | func S3Path(bucket string, key string) string {
  function JoinS3Path (line 67) | func JoinS3Path(paths ...string) string {
  function SplitS3Path (line 75) | func SplitS3Path(s3Path string) (string, string, error) {
  function SplitS3aPath (line 90) | func SplitS3aPath(s3aPath string) (string, string, error) {
  function IsValidS3Path (line 102) | func IsValidS3Path(s3Path string) bool {
  function IsValidS3aPath (line 116) | func IsValidS3aPath(s3aPath string) bool {
  method GetNLevelsDeepFromS3Path (line 135) | func (c *Client) GetNLevelsDeepFromS3Path(s3Path string, depth int, incl...
  method ListS3TopLevelDirs (line 164) | func (c *Client) ListS3TopLevelDirs(bucket string) ([]string, error) {
  function ConvertS3ObjectsToKeys (line 202) | func ConvertS3ObjectsToKeys(s3Objects ...*s3.Object) []string {
  function GetBucketRegionFromS3Path (line 212) | func GetBucketRegionFromS3Path(s3Path string) (string, error) {
  function GetBucketRegion (line 221) | func GetBucketRegion(bucket string) (string, error) {
  method IsS3PathFile (line 230) | func (c *Client) IsS3PathFile(s3Path string, s3Paths ...string) (bool, e...
  method IsS3File (line 251) | func (c *Client) IsS3File(bucket string, fileKey string, fileKeys ...str...
  method IsS3PathPrefix (line 270) | func (c *Client) IsS3PathPrefix(s3Path string, s3Paths ...string) (bool,...
  method IsS3Prefix (line 291) | func (c *Client) IsS3Prefix(bucket string, prefix string, prefixes ...st...
  method IsS3PathDir (line 312) | func (c *Client) IsS3PathDir(s3Path string, s3Paths ...string) (bool, er...
  method IsS3Dir (line 333) | func (c *Client) IsS3Dir(bucket string, dirPath string, dirPaths ...stri...
  method DoesBucketExist (line 343) | func (c *Client) DoesBucketExist(bucket string) (bool, error) {
  method CreateBucket (line 362) | func (c *Client) CreateBucket(bucket string) error {
  method EnableBucketEncryption (line 379) | func (c *Client) EnableBucketEncryption(bucket string) error {
  method UploadReaderToS3 (line 398) | func (c *Client) UploadReaderToS3(data io.Reader, bucket string, key str...
  method UploadFileToS3 (line 414) | func (c *Client) UploadFileToS3(path string, bucket string, key string) ...
  method UploadBytesToS3 (line 423) | func (c *Client) UploadBytesToS3(data []byte, bucket string, key string)...
  method UploadStringToS3 (line 427) | func (c *Client) UploadStringToS3(str string, bucket string, key string)...
  method UploadJSONToS3 (line 431) | func (c *Client) UploadJSONToS3(obj interface{}, bucket string, key stri...
  method UploadMsgpackToS3 (line 439) | func (c *Client) UploadMsgpackToS3(obj interface{}, bucket string, key s...
  method CreateEmptyS3File (line 447) | func (c *Client) CreateEmptyS3File(bucket string, key string) error {
  method UploadDirToS3 (line 451) | func (c *Client) UploadDirToS3(localDirPath string, bucket string, s3Dir...
  method ReadReaderFromS3 (line 469) | func (c *Client) ReadReaderFromS3(bucket string, key string) (io.ReadClo...
  method ReadBufferFromS3 (line 483) | func (c *Client) ReadBufferFromS3(bucket string, key string) (*bytes.Buf...
  method ReadBytesFromS3 (line 496) | func (c *Client) ReadBytesFromS3(bucket string, key string) ([]byte, err...
  method ReadStringFromS3 (line 504) | func (c *Client) ReadStringFromS3(bucket string, key string) (string, er...
  method ReadJSONFromS3 (line 512) | func (c *Client) ReadJSONFromS3(objPtr interface{}, bucket string, key s...
  method ReadMsgpackFromS3 (line 520) | func (c *Client) ReadMsgpackFromS3(objPtr interface{}, bucket string, ke...
  method ReadStringFromS3Path (line 528) | func (c *Client) ReadStringFromS3Path(s3Path string) (string, error) {
  method ReadBytesFromS3Path (line 536) | func (c *Client) ReadBytesFromS3Path(s3Path string) ([]byte, error) {
  method ReadMsgpackFromS3Path (line 544) | func (c *Client) ReadMsgpackFromS3Path(objPtr interface{}, s3Path string...
  method DownloadFileFromS3 (line 554) | func (c *Client) DownloadFileFromS3(bucket string, key string, localPath...
  method DownloadDirFromS3 (line 574) | func (c *Client) DownloadDirFromS3(bucket string, s3Dir string, localDir...
  method DownloadPrefixFromS3 (line 598) | func (c *Client) DownloadPrefixFromS3(bucket string, prefix string, loca...
  method S3FileIterator (line 655) | func (c *Client) S3FileIterator(bucket string, s3Obj *s3.Object, partSiz...
  method ListS3Dir (line 695) | func (c *Client) ListS3Dir(bucket string, s3Dir string, includeDirObject...
  method ListS3PathDir (line 700) | func (c *Client) ListS3PathDir(s3DirPath string, includeDirObjects bool,...
  method ListS3DirOneLevel (line 707) | func (c *Client) ListS3DirOneLevel(bucket string, s3Dir string, maxResul...
  method ListS3Prefix (line 730) | func (c *Client) ListS3Prefix(bucket string, prefix string, includeDirOb...
  method ListS3PathPrefix (line 745) | func (c *Client) ListS3PathPrefix(s3Path string, includeDirObjects bool,...
  method DeleteS3File (line 753) | func (c *Client) DeleteS3File(bucket string, key string) error {
  method DeleteS3Dir (line 767) | func (c *Client) DeleteS3Dir(bucket string, s3Dir string, continueIfFail...
  method DeleteS3Prefix (line 772) | func (c *Client) DeleteS3Prefix(bucket string, prefix string, continueIf...
  method HashS3Dir (line 806) | func (c *Client) HashS3Dir(bucket string, prefix string, maxResults *int...
  method S3Iterator (line 825) | func (c *Client) S3Iterator(bucket string, prefix string, includeDirObje...
  method S3BatchIterator (line 849) | func (c *Client) S3BatchIterator(bucket string, prefix string, includeDi...
  method TagBucket (line 914) | func (c *Client) TagBucket(bucket string, tagMap map[string]string) error {
  method SetLifecycleRules (line 939) | func (c *Client) SetLifecycleRules(bucket string, rules []s3.LifecycleRu...
  method GetLifecycleRules (line 954) | func (c *Client) GetLifecycleRules(bucket string) ([]s3.LifecycleRule, e...
  method DeleteLifecycleRules (line 975) | func (c *Client) DeleteLifecycleRules(bucket string) error {

FILE: pkg/lib/aws/servicequotas.go
  constant _baseInboundRulesForNodeGroup (line 34) | _baseInboundRulesForNodeGroup = 11
  constant _inboundRulesPerAZ (line 35) | _inboundRulesPerAZ            = 8
  constant _baseNumberOfSecurityGroups (line 37) | _baseNumberOfSecurityGroups = 4
  type InstanceTypeRequests (line 40) | type InstanceTypeRequests struct
  type instanceClassRequest (line 46) | type instanceClassRequest struct
  method VerifyInstanceQuota (line 61) | func (c *Client) VerifyInstanceQuota(instances []InstanceTypeRequests) e...
  method ListServiceQuotas (line 155) | func (c *Client) ListServiceQuotas(quotaCodes []string, serviceCodes []s...
  method VerifyInternetGatewayQuota (line 187) | func (c *Client) VerifyInternetGatewayQuota(internetGatewayQuota int, re...
  method VerifyNATGatewayQuota (line 201) | func (c *Client) VerifyNATGatewayQuota(natGatewayQuota int, availability...
  method VerifyEIPQuota (line 246) | func (c *Client) VerifyEIPQuota(eipQuota int, availabilityZones strset.S...
  method VerifyVPCQuota (line 267) | func (c *Client) VerifyVPCQuota(vpcQuota int, requiredVPCs int) error {
  method VerifySecurityGroupQuota (line 281) | func (c *Client) VerifySecurityGroupQuota(securifyGroupsQuota int, numNo...
  method VerifySecurityGroupRulesQuota (line 297) | func (c *Client) VerifySecurityGroupRulesQuota(
  function requiredRulesForNodeGroupSecurityGroup (line 319) | func requiredRulesForNodeGroupSecurityGroup(numAZs, whitelistLength int)...
  function requiredRulesForControlPlaneSecurityGroup (line 330) | func requiredRulesForControlPlaneSecurityGroup(numNodeGroups int) int {
  function requiredSecurityGroups (line 336) | func requiredSecurityGroups(numNodeGroups int, clusterAlreadyExists bool...

FILE: pkg/lib/aws/sqs.go
  method GetAllQueueAttributes (line 25) | func (c *Client) GetAllQueueAttributes(queueURL string) (map[string]stri...
  method ListQueuesByQueueNamePrefix (line 37) | func (c *Client) ListQueuesByQueueNamePrefix(queueNamePrefix string) ([]...
  method DoesQueueExist (line 53) | func (c *Client) DoesQueueExist(queueName string) (bool, error) {
  method DeleteQueuesWithPrefix (line 67) | func (c *Client) DeleteQueuesWithPrefix(queueNamePrefix string) (int, er...

FILE: pkg/lib/aws/sts.go
  method CheckCredentials (line 40) | func (c *Client) CheckCredentials() (string, string, error) {
  method GetCachedAccountID (line 53) | func (c *Client) GetCachedAccountID() (string, string, error) {
  type awsRequest (line 62) | type awsRequest struct
  method IdentityRequestAsHeader (line 71) | func (c *Client) IdentityRequestAsHeader() (string, error) {
  function ExecuteIdentityRequestFromHeader (line 101) | func ExecuteIdentityRequestFromHeader(indentityRequestheader string) (st...

FILE: pkg/lib/cast/interface.go
  function InterfaceToInt8 (line 24) | func InterfaceToInt8(in interface{}) (int8, bool) {
  function InterfaceToInt8Downcast (line 53) | func InterfaceToInt8Downcast(in interface{}) (int8, bool) {
  function InterfaceToInt16 (line 90) | func InterfaceToInt16(in interface{}) (int16, bool) {
  function InterfaceToInt16Downcast (line 117) | func InterfaceToInt16Downcast(in interface{}) (int16, bool) {
  function InterfaceToInt32 (line 152) | func InterfaceToInt32(in interface{}) (int32, bool) {
  function InterfaceToInt32Downcast (line 177) | func InterfaceToInt32Downcast(in interface{}) (int32, bool) {
  function InterfaceToInt (line 210) | func InterfaceToInt(in interface{}) (int, bool) {
  function InterfaceToIntDowncast (line 233) | func InterfaceToIntDowncast(in interface{}) (int, bool) {
  function InterfaceToInt64 (line 264) | func InterfaceToInt64(in interface{}) (int64, bool) {
  function InterfaceToInt64Downcast (line 285) | func InterfaceToInt64Downcast(in interface{}) (int64, bool) {
  function InterfaceToFloat32 (line 315) | func InterfaceToFloat32(in interface{}) (float32, bool) {
  function InterfaceToFloat64 (line 341) | func InterfaceToFloat64(in interface{}) (float64, bool) {
  function JSONNumberToInt (line 366) | func JSONNumberToInt(in interface{}) (interface{}, bool) {
  function JSONNumberToIntOrFloat (line 378) | func JSONNumberToIntOrFloat(in interface{}) (interface{}, bool) {
  function JSONNumber (line 394) | func JSONNumber(in interface{}) interface{} {
  function JSONNumbers (line 410) | func JSONNumbers(in []interface{}) []interface{} {
  function InterfaceToInterfaceSlice (line 418) | func InterfaceToInterfaceSlice(in interface{}) ([]interface{}, bool) {
  function InterfaceToIntSlice (line 443) | func InterfaceToIntSlice(in interface{}) ([]int, bool) {
  function InterfaceToInt32Slice (line 468) | func InterfaceToInt32Slice(in interface{}) ([]int32, bool) {
  function InterfaceToInt64Slice (line 493) | func InterfaceToInt64Slice(in interface{}) ([]int64, bool) {
  function InterfaceToFloat32Slice (line 518) | func InterfaceToFloat32Slice(in interface{}) ([]float32, bool) {
  function InterfaceToFloat64Slice (line 543) | func InterfaceToFloat64Slice(in interface{}) ([]float64, bool) {
  function InterfaceToStrSlice (line 568) | func InterfaceToStrSlice(in interface{}) ([]string, bool) {
  function InterfaceToBoolSlice (line 594) | func InterfaceToBoolSlice(in interface{}) ([]bool, bool) {
  function InterfaceToStrInterfaceMapSlice (line 620) | func InterfaceToStrInterfaceMapSlice(in interface{}) ([]map[string]inter...
  function InterfaceToInterfaceInterfaceMap (line 646) | func InterfaceToInterfaceInterfaceMap(in interface{}) (map[interface{}]i...
  function InterfaceToStrInterfaceMap (line 671) | func InterfaceToStrInterfaceMap(in interface{}) (map[string]interface{},...
  function JSONMarshallable (line 698) | func JSONMarshallable(in interface{}) (interface{}, bool) {
  function InterfaceToStrStrMap (line 731) | func InterfaceToStrStrMap(in interface{}) (map[string]string, bool) {
  function StrMapToStrInterfaceMap (line 761) | func StrMapToStrInterfaceMap(in map[string]string) map[string]interface{} {
  function IsIntType (line 774) | func IsIntType(in interface{}) bool {
  function IsFloatType (line 793) | func IsFloatType(in interface{}) bool {
  function IsNumericType (line 807) | func IsNumericType(in interface{}) bool {
  function IsScalarType (line 811) | func IsScalarType(in interface{}) bool {
  function FlattenInterfaceSlices (line 826) | func FlattenInterfaceSlices(in ...interface{}) []interface{} {

FILE: pkg/lib/cast/interface_test.go
  function TestInterfaceToInterfaceSlice (line 26) | func TestInterfaceToInterfaceSlice(t *testing.T) {
  function TestInterfaceToFloat64 (line 44) | func TestInterfaceToFloat64(t *testing.T) {
  function TestInterfaceToIntDowncast (line 64) | func TestInterfaceToIntDowncast(t *testing.T) {
  function TestInterfaceToInt (line 98) | func TestInterfaceToInt(t *testing.T) {
  function TestInterfaceToInt8Downcast (line 113) | func TestInterfaceToInt8Downcast(t *testing.T) {
  function TestInterfaceToInt8 (line 150) | func TestInterfaceToInt8(t *testing.T) {
  function TestInterfaceToInterfaceInterfaceMap (line 165) | func TestInterfaceToInterfaceInterfaceMap(t *testing.T) {
  function TestJSONMarshallable (line 190) | func TestJSONMarshallable(t *testing.T) {
  function TestFlattenInterfaceSlices (line 242) | func TestFlattenInterfaceSlices(t *testing.T) {

FILE: pkg/lib/configreader/bool.go
  type BoolValidation (line 29) | type BoolValidation struct
  function Bool (line 37) | func Bool(inter interface{}, v *BoolValidation) (bool, error) {
  function BoolFromInterfaceMap (line 51) | func BoolFromInterfaceMap(key string, iMap map[string]interface{}, v *Bo...
  function BoolFromStrMap (line 67) | func BoolFromStrMap(key string, sMap map[string]string, v *BoolValidatio...
  function BoolFromStr (line 83) | func BoolFromStr(valStr string, v *BoolValidation) (bool, error) {
  function BoolFromEnv (line 108) | func BoolFromEnv(envVarName string, v *BoolValidation) (bool, error) {
  function BoolFromFile (line 124) | func BoolFromFile(filePath string, v *BoolValidation) (bool, error) {
  function BoolFromEnvOrFile (line 152) | func BoolFromEnvOrFile(envVarName string, filePath string, v *BoolValida...
  function BoolFromPrompt (line 160) | func BoolFromPrompt(promptOpts *prompt.Options, v *BoolValidation) (bool...
  function ValidateBoolMissing (line 169) | func ValidateBoolMissing(v *BoolValidation) (bool, error) {
  function ValidateBoolProvided (line 176) | func ValidateBoolProvided(val bool, v *BoolValidation) (bool, error) {
  function validateBool (line 183) | func validateBool(val bool, v *BoolValidation) (bool, error) {
  function MustBoolFromEnv (line 191) | func MustBoolFromEnv(envVarName string, v *BoolValidation) bool {
  function MustBoolFromFile (line 199) | func MustBoolFromFile(filePath string, v *BoolValidation) bool {
  function MustBoolFromEnvOrFile (line 207) | func MustBoolFromEnvOrFile(envVarName string, filePath string, v *BoolVa...

FILE: pkg/lib/configreader/bool_list.go
  type BoolListValidation (line 24) | type BoolListValidation struct
  function BoolList (line 37) | func BoolList(inter interface{}, v *BoolListValidation) ([]bool, error) {
  function BoolListFromInterfaceMap (line 53) | func BoolListFromInterfaceMap(key string, iMap map[string]interface{}, v...
  function ValidateBoolListMissing (line 69) | func ValidateBoolListMissing(v *BoolListValidation) ([]bool, error) {
  function ValidateBoolListProvided (line 76) | func ValidateBoolListProvided(val []bool, v *BoolListValidation) ([]bool...
  function validateBoolList (line 87) | func validateBoolList(val []bool, v *BoolListValidation) ([]bool, error) {

FILE: pkg/lib/configreader/bool_ptr.go
  type BoolPtrValidation (line 28) | type BoolPtrValidation struct
  function BoolPtr (line 36) | func BoolPtr(inter interface{}, v *BoolPtrValidation) (*bool, error) {
  function BoolPtrFromInterfaceMap (line 47) | func BoolPtrFromInterfaceMap(key string, iMap map[string]interface{}, v ...
  function BoolPtrFromStrMap (line 63) | func BoolPtrFromStrMap(key string, sMap map[string]string, v *BoolPtrVal...
  function BoolPtrFromStr (line 79) | func BoolPtrFromStr(valStr string, v *BoolPtrValidation) (*bool, error) {
  function BoolPtrFromEnv (line 105) | func BoolPtrFromEnv(envVarName string, v *BoolPtrValidation) (*bool, err...
  function BoolPtrFromFile (line 121) | func BoolPtrFromFile(filePath string, v *BoolPtrValidation) (*bool, erro...
  function BoolPtrFromEnvOrFile (line 149) | func BoolPtrFromEnvOrFile(envVarName string, filePath string, v *BoolPtr...
  function BoolPtrFromPrompt (line 157) | func BoolPtrFromPrompt(promptOpts *prompt.Options, v *BoolPtrValidation)...
  function ValidateBoolPtrMissing (line 168) | func ValidateBoolPtrMissing(v *BoolPtrValidation) (*bool, error) {
  function ValidateBoolPtrProvided (line 175) | func ValidateBoolPtrProvided(val *bool, v *BoolPtrValidation) (*bool, er...

FILE: pkg/lib/configreader/errors.go
  constant ErrParseConfig (line 29) | ErrParseConfig                   = "configreader.parse_config"
  constant ErrUnsupportedFieldValidation (line 30) | ErrUnsupportedFieldValidation    = "configreader.unsupported_field_valid...
  constant ErrUnsupportedKey (line 31) | ErrUnsupportedKey                = "configreader.unsupported_key"
  constant ErrInvalidYAML (line 32) | ErrInvalidYAML                   = "configreader.invalid_yaml"
  constant ErrTooLong (line 33) | ErrTooLong                       = "configreader.too_long"
  constant ErrTooShort (line 34) | ErrTooShort                      = "configreader.too_short"
  constant ErrLeadingWhitespace (line 35) | ErrLeadingWhitespace             = "configreader.leading_whitespace"
  constant ErrTrailingWhitespace (line 36) | ErrTrailingWhitespace            = "configreader.trailing_whitespace"
  constant ErrAlphaNumericDashUnderscore (line 37) | ErrAlphaNumericDashUnderscore    = "configreader.alpha_numeric_dash_unde...
  constant ErrAlphaNumericDash (line 38) | ErrAlphaNumericDash              = "configreader.alpha_numeric_dash"
  constant ErrAlphaNumericDotUnderscore (line 39) | ErrAlphaNumericDotUnderscore     = "configreader.alpha_numeric_dot_under...
  constant ErrAlphaNumericDashDotUnderscore (line 40) | ErrAlphaNumericDashDotUnderscore = "configreader.alpha_numeric_dash_dot_...
  constant ErrInvalidAWSTag (line 41) | ErrInvalidAWSTag                 = "configreader.invalid_aws_tag"
  constant ErrInvalidDockerImage (line 42) | ErrInvalidDockerImage            = "configreader.invalid_docker_image"
  constant ErrMustHavePrefix (line 43) | ErrMustHavePrefix                = "configreader.must_have_prefix"
  constant ErrMustHaveSuffix (line 44) | ErrMustHaveSuffix                = "configreader.must_have_suffix"
  constant ErrCantHavePrefix (line 45) | ErrCantHavePrefix                = "configreader.cant_have_prefix"
  constant ErrCantHaveSuffix (line 46) | ErrCantHaveSuffix                = "configreader.cant_have_suffix"
  constant ErrInvalidInterface (line 47) | ErrInvalidInterface              = "configreader.invalid_interface"
  constant ErrInvalidFloat64 (line 48) | ErrInvalidFloat64                = "configreader.invalid_float64"
  constant ErrInvalidFloat32 (line 49) | ErrInvalidFloat32                = "configreader.invalid_float32"
  constant ErrInvalidInt64 (line 50) | ErrInvalidInt64                  = "configreader.invalid_int64"
  constant ErrInvalidInt32 (line 51) | ErrInvalidInt32                  = "configreader.invalid_int32"
  constant ErrInvalidInt (line 52) | ErrInvalidInt                    = "configreader.invalid_int"
  constant ErrInvalidStr (line 53) | ErrInvalidStr                    = "configreader.invalid_str"
  constant ErrDisallowedValue (line 54) | ErrDisallowedValue               = "configreader.disallowed_value"
  constant ErrMustBeLessThanOrEqualTo (line 55) | ErrMustBeLessThanOrEqualTo       = "configreader.must_be_less_than_or_eq...
  constant ErrMustBeLessThan (line 56) | ErrMustBeLessThan                = "configreader.must_be_less_than"
  constant ErrMustBeGreaterThanOrEqualTo (line 57) | ErrMustBeGreaterThanOrEqualTo    = "configreader.must_be_greater_than_or...
  constant ErrMustBeGreaterThan (line 58) | ErrMustBeGreaterThan             = "configreader.must_be_greater_than"
  constant ErrIsNotMultiple (line 59) | ErrIsNotMultiple                 = "configreader.is_not_multiple"
  constant ErrNonStringKeyFound (line 60) | ErrNonStringKeyFound             = "configreader.non_string_key_found"
  constant ErrInvalidPrimitiveType (line 61) | ErrInvalidPrimitiveType          = "configreader.invalid_primitive_type"
  constant ErrDuplicatedValue (line 62) | ErrDuplicatedValue               = "configreader.duplicated_value"
  constant ErrTooFewElements (line 63) | ErrTooFewElements                = "configreader.too_few_elements"
  constant ErrTooManyElements (line 64) | ErrTooManyElements               = "configreader.too_many_elements"
  constant ErrWrongNumberOfElements (line 65) | ErrWrongNumberOfElements         = "configreader.wrong_number_of_elements"
  constant ErrCannotSetStructField (line 66) | ErrCannotSetStructField          = "configreader.cannot_set_struct_field"
  constant ErrCannotBeNull (line 67) | ErrCannotBeNull                  = "configreader.cannot_be_null"
  constant ErrCannotBeEmptyOrNull (line 68) | ErrCannotBeEmptyOrNull           = "configreader.cannot_be_empty_or_null"
  constant ErrCannotBeEmpty (line 69) | ErrCannotBeEmpty                 = "configreader.cannot_be_empty"
  constant ErrMustBeDefined (line 70) | ErrMustBeDefined                 = "configreader.must_be_defined"
  constant ErrMapMustBeDefined (line 71) | ErrMapMustBeDefined              = "configreader.map_must_be_defined"
  constant ErrMustBeEmpty (line 72) | ErrMustBeEmpty                   = "configreader.must_be_empty"
  constant ErrEmailTooLong (line 73) | ErrEmailTooLong                  = "configreader.email_too_long"
  constant ErrEmailInvalid (line 74) | ErrEmailInvalid                  = "configreader.email_invalid"
  constant ErrCortexResourceOnlyAllowed (line 75) | ErrCortexResourceOnlyAllowed     = "configreader.cortex_resource_only_al...
  constant ErrCortexResourceNotAllowed (line 76) | ErrCortexResourceNotAllowed      = "configreader.cortex_resource_not_all...
  constant ErrImageVersionMismatch (line 77) | ErrImageVersionMismatch          = "configreader.image_version_mismatch"
  constant ErrFieldCantBeSpecified (line 78) | ErrFieldCantBeSpecified          = "configreader.field_cant_be_specified"
  function ErrorParseConfig (line 81) | func ErrorParseConfig() error {
  function ErrorUnsupportedFieldValidation (line 88) | func ErrorUnsupportedFieldValidation() error {
  function ErrorUnsupportedKey (line 95) | func ErrorUnsupportedKey(key interface{}) error {
  function ErrorInvalidYAML (line 102) | func ErrorInvalidYAML(err error) error {
  function ErrorTooLong (line 110) | func ErrorTooLong(provided string, maxLen int) error {
  function ErrorTooShort (line 117) | func ErrorTooShort(provided string, minLen int) error {
  function ErrorLeadingWhitespace (line 124) | func ErrorLeadingWhitespace(provided string) error {
  function ErrorTrailingWhitespace (line 131) | func ErrorTrailingWhitespace(provided string) error {
  function ErrorAlphaNumericDashUnderscore (line 138) | func ErrorAlphaNumericDashUnderscore(provided string) error {
  function ErrorAlphaNumericDash (line 145) | func ErrorAlphaNumericDash(provided string) error {
  function ErrorAlphaNumericDotUnderscore (line 152) | func ErrorAlphaNumericDotUnderscore(provided string) error {
  function ErrorAlphaNumericDashDotUnderscore (line 159) | func ErrorAlphaNumericDashDotUnderscore(provided string) error {
  function ErrorInvalidAWSTag (line 166) | func ErrorInvalidAWSTag(provided string) error {
  function ErrorInvalidDockerImage (line 173) | func ErrorInvalidDockerImage(provided string) error {
  function ErrorMustHavePrefix (line 180) | func ErrorMustHavePrefix(provided string, prefix string, prefixes ...str...
  function ErrorMustHaveSuffix (line 188) | func ErrorMustHaveSuffix(provided string, suffix string, suffixes ...str...
  function ErrorCantHavePrefix (line 196) | func ErrorCantHavePrefix(provided string, prefix string) error {
  function ErrorCantHaveSuffix (line 203) | func ErrorCantHaveSuffix(provided string, suffix string) error {
  function ErrorInvalidInterface (line 210) | func ErrorInvalidInterface(provided interface{}, allowed interface{}, al...
  function ErrorInvalidFloat64 (line 218) | func ErrorInvalidFloat64(provided float64, allowed float64, allowedVals ...
  function ErrorInvalidFloat32 (line 226) | func ErrorInvalidFloat32(provided float32, allowed float32, allowedVals ...
  function ErrorInvalidInt64 (line 234) | func ErrorInvalidInt64(provided int64, allowed int64, allowedVals ...int...
  function ErrorInvalidInt32 (line 242) | func ErrorInvalidInt32(provided int32, allowed int32, allowedVals ...int...
  function ErrorInvalidInt (line 250) | func ErrorInvalidInt(provided int, allowed int, allowedVals ...int) error {
  function ErrorInvalidStr (line 258) | func ErrorInvalidStr(provided string, allowed string, allowedVals ...str...
  function ErrorDisallowedValue (line 266) | func ErrorDisallowedValue(provided interface{}) error {
  function ErrorMustBeLessThanOrEqualTo (line 273) | func ErrorMustBeLessThanOrEqualTo(provided interface{}, boundary interfa...
  function ErrorMustBeLessThan (line 280) | func ErrorMustBeLessThan(provided interface{}, boundary interface{}) err...
  function ErrorMustBeGreaterThanOrEqualTo (line 287) | func ErrorMustBeGreaterThanOrEqualTo(provided interface{}, boundary inte...
  function ErrorMustBeGreaterThan (line 294) | func ErrorMustBeGreaterThan(provided interface{}, boundary interface{}) ...
  function ErrorIsNotMultiple (line 301) | func ErrorIsNotMultiple(provided interface{}, multiple interface{}) error {
  function ErrorNonStringKeyFound (line 308) | func ErrorNonStringKeyFound(key interface{}) error {
  function ErrorInvalidPrimitiveType (line 315) | func ErrorInvalidPrimitiveType(provided interface{}, allowedType Primiti...
  function ErrorDuplicatedValue (line 323) | func ErrorDuplicatedValue(val interface{}) error {
  function ErrorTooFewElements (line 330) | func ErrorTooFewElements(minLength int) error {
  function ErrorTooManyElements (line 337) | func ErrorTooManyElements(maxLength int) error {
  function ErrorWrongNumberOfElements (line 344) | func ErrorWrongNumberOfElements(invalidLengths []int) error {
  function ErrorCannotSetStructField (line 361) | func ErrorCannotSetStructField() error {
  function ErrorCannotBeNull (line 368) | func ErrorCannotBeNull(isRequired bool) error {
  function ErrorCannotBeEmptyOrNull (line 379) | func ErrorCannotBeEmptyOrNull(isRequired bool) error {
  function ErrorCannotBeEmpty (line 390) | func ErrorCannotBeEmpty() error {
  function ErrorMustBeDefined (line 397) | func ErrorMustBeDefined(validValues ...interface{}) error {
  function ErrorMapMustBeDefined (line 409) | func ErrorMapMustBeDefined(keys ...string) error {
  function ErrorMustBeEmpty (line 420) | func ErrorMustBeEmpty() error {
  function ErrorEmailTooLong (line 427) | func ErrorEmailTooLong() error {
  function ErrorEmailInvalid (line 434) | func ErrorEmailInvalid() error {
  function ErrorCortexResourceOnlyAllowed (line 441) | func ErrorCortexResourceOnlyAllowed(invalidStr string) error {
  function ErrorCortexResourceNotAllowed (line 448) | func ErrorCortexResourceNotAllowed(resourceName string) error {
  function ErrorImageVersionMismatch (line 455) | func ErrorImageVersionMismatch(image, tag, cortexVersion string) error {
  function ErrorFieldCantBeSpecified (line 462) | func ErrorFieldCantBeSpecified(errMsg string) error {

FILE: pkg/lib/configreader/float32.go
  type Float32Validation (line 29) | type Float32Validation struct
  function Float32 (line 44) | func Float32(inter interface{}, v *Float32Validation) (float32, error) {
  function Float32FromInterfaceMap (line 58) | func Float32FromInterfaceMap(key string, iMap map[string]interface{}, v ...
  function Float32FromStrMap (line 74) | func Float32FromStrMap(key string, sMap map[string]string, v *Float32Val...
  function Float32FromStr (line 90) | func Float32FromStr(valStr string, v *Float32Validation) (float32, error) {
  function Float32FromEnv (line 101) | func Float32FromEnv(envVarName string, v *Float32Validation) (float32, e...
  function Float32FromFile (line 117) | func Float32FromFile(filePath string, v *Float32Validation) (float32, er...
  function Float32FromEnvOrFile (line 145) | func Float32FromEnvOrFile(envVarName string, filePath string, v *Float32...
  function Float32FromPrompt (line 153) | func Float32FromPrompt(promptOpts *prompt.Options, v *Float32Validation)...
  function ValidateFloat32Missing (line 162) | func ValidateFloat32Missing(v *Float32Validation) (float32, error) {
  function ValidateFloat32Provided (line 169) | func ValidateFloat32Provided(val float32, v *Float32Validation) (float32...
  function validateFloat32 (line 176) | func validateFloat32(val float32, v *Float32Validation) (float32, error) {
  function ValidateFloat32Val (line 188) | func ValidateFloat32Val(val float32, v *Float32Validation) error {
  function MustFloat32FromEnv (line 229) | func MustFloat32FromEnv(envVarName string, v *Float32Validation) float32 {
  function MustFloat32FromFile (line 237) | func MustFloat32FromFile(filePath string, v *Float32Validation) float32 {
  function MustFloat32FromEnvOrFile (line 245) | func MustFloat32FromEnvOrFile(envVarName string, filePath string, v *Flo...

FILE: pkg/lib/configreader/float32_list.go
  type Float32ListValidation (line 24) | type Float32ListValidation struct
  function Float32List (line 37) | func Float32List(inter interface{}, v *Float32ListValidation) ([]float32...
  function Float32ListFromInterfaceMap (line 53) | func Float32ListFromInterfaceMap(key string, iMap map[string]interface{}...
  function ValidateFloat32ListMissing (line 69) | func ValidateFloat32ListMissing(v *Float32ListValidation) ([]float32, er...
  function ValidateFloat32ListProvided (line 76) | func ValidateFloat32ListProvided(val []float32, v *Float32ListValidation...
  function validateFloat32List (line 87) | func validateFloat32List(val []float32, v *Float32ListValidation) ([]flo...

FILE: pkg/lib/configreader/float32_ptr.go
  type Float32PtrValidation (line 27) | type Float32PtrValidation struct
  function makeFloat32ValValidation (line 42) | func makeFloat32ValValidation(v *Float32PtrValidation) *Float32Validation {
  function Float32Ptr (line 54) | func Float32Ptr(inter interface{}, v *Float32PtrValidation) (*float32, e...
  function Float32PtrFromInterfaceMap (line 65) | func Float32PtrFromInterfaceMap(key string, iMap map[string]interface{},...
  function Float32PtrFromStrMap (line 81) | func Float32PtrFromStrMap(key string, sMap map[string]string, v *Float32...
  function Float32PtrFromStr (line 97) | func Float32PtrFromStr(valStr string, v *Float32PtrValidation) (*float32...
  function Float32PtrFromEnv (line 108) | func Float32PtrFromEnv(envVarName string, v *Float32PtrValidation) (*flo...
  function Float32PtrFromFile (line 124) | func Float32PtrFromFile(filePath string, v *Float32PtrValidation) (*floa...
  function Float32PtrFromEnvOrFile (line 152) | func Float32PtrFromEnvOrFile(envVarName string, filePath string, v *Floa...
  function Float32PtrFromPrompt (line 160) | func Float32PtrFromPrompt(promptOpts *prompt.Options, v *Float32PtrValid...
  function ValidateFloat32PtrMissing (line 171) | func ValidateFloat32PtrMissing(v *Float32PtrValidation) (*float32, error) {
  function ValidateFloat32PtrProvided (line 178) | func ValidateFloat32PtrProvided(val *float32, v *Float32PtrValidation) (...
  function validateFloat32Ptr (line 189) | func validateFloat32Ptr(val *float32, v *Float32PtrValidation) (*float32...

FILE: pkg/lib/configreader/float64.go
  type Float64Validation (line 29) | type Float64Validation struct
  function Float64 (line 44) | func Float64(inter interface{}, v *Float64Validation) (float64, error) {
  function Float64FromInterfaceMap (line 58) | func Float64FromInterfaceMap(key string, iMap map[string]interface{}, v ...
  function Float64FromStrMap (line 74) | func Float64FromStrMap(key string, sMap map[string]string, v *Float64Val...
  function Float64FromStr (line 90) | func Float64FromStr(valStr string, v *Float64Validation) (float64, error) {
  function Float64FromEnv (line 101) | func Float64FromEnv(envVarName string, v *Float64Validation) (float64, e...
  function Float64FromFile (line 117) | func Float64FromFile(filePath string, v *Float64Validation) (float64, er...
  function Float64FromEnvOrFile (line 145) | func Float64FromEnvOrFile(envVarName string, filePath string, v *Float64...
  function Float64FromPrompt (line 153) | func Float64FromPrompt(promptOpts *prompt.Options, v *Float64Validation)...
  function ValidateFloat64Missing (line 162) | func ValidateFloat64Missing(v *Float64Validation) (float64, error) {
  function ValidateFloat64Provided (line 169) | func ValidateFloat64Provided(val float64, v *Float64Validation) (float64...
  function validateFloat64 (line 176) | func validateFloat64(val float64, v *Float64Validation) (float64, error) {
  function ValidateFloat64Val (line 188) | func ValidateFloat64Val(val float64, v *Float64Validation) error {
  function MustFloat64FromEnv (line 229) | func MustFloat64FromEnv(envVarName string, v *Float64Validation) float64 {
  function MustFloat64FromFile (line 237) | func MustFloat64FromFile(filePath string, v *Float64Validation) float64 {
  function MustFloat64FromEnvOrFile (line 245) | func MustFloat64FromEnvOrFile(envVarName string, filePath string, v *Flo...

FILE: pkg/lib/configreader/float64_list.go
  type Float64ListValidation (line 24) | type Float64ListValidation struct
  function Float64List (line 37) | func Float64List(inter interface{}, v *Float64ListValidation) ([]float64...
  function Float64ListFromInterfaceMap (line 53) | func Float64ListFromInterfaceMap(key string, iMap map[string]interface{}...
  function ValidateFloat64ListMissing (line 69) | func ValidateFloat64ListMissing(v *Float64ListValidation) ([]float64, er...
  function ValidateFloat64ListProvided (line 76) | func ValidateFloat64ListProvided(val []float64, v *Float64ListValidation...
  function validateFloat64List (line 87) | func validateFloat64List(val []float64, v *Float64ListValidation) ([]flo...

FILE: pkg/lib/configreader/float64_ptr.go
  type Float64PtrValidation (line 27) | type Float64PtrValidation struct
  function makeFloat64ValValidation (line 42) | func makeFloat64ValValidation(v *Float64PtrValidation) *Float64Validation {
  function Float64Ptr (line 54) | func Float64Ptr(inter interface{}, v *Float64PtrValidation) (*float64, e...
  function Float64PtrFromInterfaceMap (line 65) | func Float64PtrFromInterfaceMap(key string, iMap map[string]interface{},...
  function Float64PtrFromStrMap (line 81) | func Float64PtrFromStrMap(key string, sMap map[string]string, v *Float64...
  function Float64PtrFromStr (line 97) | func Float64PtrFromStr(valStr string, v *Float64PtrValidation) (*float64...
  function Float64PtrFromEnv (line 108) | func Float64PtrFromEnv(envVarName string, v *Float64PtrValidation) (*flo...
  function Float64PtrFromFile (line 124) | func Float64PtrFromFile(filePath string, v *Float64PtrValidation) (*floa...
  function Float64PtrFromEnvOrFile (line 152) | func Float64PtrFromEnvOrFile(envVarName string, filePath string, v *Floa...
  function Float64PtrFromPrompt (line 160) | func Float64PtrFromPrompt(promptOpts *prompt.Options, v *Float64PtrValid...
  function ValidateFloat64PtrMissing (line 171) | func ValidateFloat64PtrMissing(v *Float64PtrValidation) (*float64, error) {
  function ValidateFloat64PtrProvided (line 178) | func ValidateFloat64PtrProvided(val *float64, v *Float64PtrValidation) (...
  function validateFloat64Ptr (line 189) | func validateFloat64Ptr(val *float64, v *Float64PtrValidation) (*float64...

FILE: pkg/lib/configreader/int.go
  type IntValidation (line 29) | type IntValidation struct
  function Int (line 44) | func Int(inter interface{}, v *IntValidation) (int, error) {
  function IntFromInterfaceMap (line 58) | func IntFromInterfaceMap(key string, iMap map[string]interface{}, v *Int...
  function IntFromStrMap (line 74) | func IntFromStrMap(key string, sMap map[string]string, v *IntValidation)...
  function IntFromStr (line 90) | func IntFromStr(valStr string, v *IntValidation) (int, error) {
  function IntFromEnv (line 101) | func IntFromEnv(envVarName string, v *IntValidation) (int, error) {
  function IntFromFile (line 117) | func IntFromFile(filePath string, v *IntValidation) (int, error) {
  function IntFromEnvOrFile (line 145) | func IntFromEnvOrFile(envVarName string, filePath string, v *IntValidati...
  function IntFromPrompt (line 153) | func IntFromPrompt(promptOpts *prompt.Options, v *IntValidation) (int, e...
  function ValidateIntMissing (line 162) | func ValidateIntMissing(v *IntValidation) (int, error) {
  function ValidateIntProvided (line 169) | func ValidateIntProvided(val int, v *IntValidation) (int, error) {
  function validateInt (line 176) | func validateInt(val int, v *IntValidation) (int, error) {
  function ValidateIntVal (line 188) | func ValidateIntVal(val int, v *IntValidation) error {
  function MustIntFromEnv (line 229) | func MustIntFromEnv(envVarName string, v *IntValidation) int {
  function MustIntFromFile (line 237) | func MustIntFromFile(filePath string, v *IntValidation) int {
  function MustIntFromEnvOrFile (line 245) | func MustIntFromEnvOrFile(envVarName string, filePath string, v *IntVali...

FILE: pkg/lib/configreader/int32.go
  type Int32Validation (line 29) | type Int32Validation struct
  function Int32 (line 44) | func Int32(inter interface{}, v *Int32Validation) (int32, error) {
  function Int32FromInterfaceMap (line 58) | func Int32FromInterfaceMap(key string, iMap map[string]interface{}, v *I...
  function Int32FromStrMap (line 74) | func Int32FromStrMap(key string, sMap map[string]string, v *Int32Validat...
  function Int32FromStr (line 90) | func Int32FromStr(valStr string, v *Int32Validation) (int32, error) {
  function Int32FromEnv (line 101) | func Int32FromEnv(envVarName string, v *Int32Validation) (int32, error) {
  function Int32FromFile (line 117) | func Int32FromFile(filePath string, v *Int32Validation) (int32, error) {
  function Int32FromEnvOrFile (line 145) | func Int32FromEnvOrFile(envVarName string, filePath string, v *Int32Vali...
  function Int32FromPrompt (line 153) | func Int32FromPrompt(promptOpts *prompt.Options, v *Int32Validation) (in...
  function ValidateInt32Missing (line 162) | func ValidateInt32Missing(v *Int32Validation) (int32, error) {
  function ValidateInt32Provided (line 169) | func ValidateInt32Provided(val int32, v *Int32Validation) (int32, error) {
  function validateInt32 (line 176) | func validateInt32(val int32, v *Int32Validation) (int32, error) {
  function ValidateInt32Val (line 188) | func ValidateInt32Val(val int32, v *Int32Validation) error {
  function MustInt32FromEnv (line 229) | func MustInt32FromEnv(envVarName string, v *Int32Validation) int32 {
  function MustInt32FromFile (line 237) | func MustInt32FromFile(filePath string, v *Int32Validation) int32 {
  function MustInt32FromEnvOrFile (line 245) | func MustInt32FromEnvOrFile(envVarName string, filePath string, v *Int32...

FILE: pkg/lib/configreader/int32_list.go
  type Int32ListValidation (line 24) | type Int32ListValidation struct
  function Int32List (line 37) | func Int32List(inter interface{}, v *Int32ListValidation) ([]int32, erro...
  function Int32ListFromInterfaceMap (line 53) | func Int32ListFromInterfaceMap(key string, iMap map[string]interface{}, ...
  function ValidateInt32ListMissing (line 69) | func ValidateInt32ListMissing(v *Int32ListValidation) ([]int32, error) {
  function ValidateInt32ListProvided (line 76) | func ValidateInt32ListProvided(val []int32, v *Int32ListValidation) ([]i...
  function validateInt32List (line 87) | func validateInt32List(val []int32, v *Int32ListValidation) ([]int32, er...

FILE: pkg/lib/configreader/int32_ptr.go
  type Int32PtrValidation (line 27) | type Int32PtrValidation struct
  function makeInt32ValValidation (line 42) | func makeInt32ValValidation(v *Int32PtrValidation) *Int32Validation {
  function Int32Ptr (line 54) | func Int32Ptr(inter interface{}, v *Int32PtrValidation) (*int32, error) {
  function Int32PtrFromInterfaceMap (line 65) | func Int32PtrFromInterfaceMap(key string, iMap map[string]interface{}, v...
  function Int32PtrFromStrMap (line 81) | func Int32PtrFromStrMap(key string, sMap map[string]string, v *Int32PtrV...
  function Int32PtrFromStr (line 97) | func Int32PtrFromStr(valStr string, v *Int32PtrValidation) (*int32, erro...
  function Int32PtrFromEnv (line 108) | func Int32PtrFromEnv(envVarName string, v *Int32PtrValidation) (*int32, ...
  function Int32PtrFromFile (line 124) | func Int32PtrFromFile(filePath string, v *Int32PtrValidation) (*int32, e...
  function Int32PtrFromEnvOrFile (line 152) | func Int32PtrFromEnvOrFile(envVarName string, filePath string, v *Int32P...
  function Int32PtrFromPrompt (line 160) | func Int32PtrFromPrompt(promptOpts *prompt.Options, v *Int32PtrValidatio...
  function ValidateInt32PtrMissing (line 171) | func ValidateInt32PtrMissing(v *Int32PtrValidation) (*int32, error) {
  function ValidateInt32PtrProvided (line 178) | func ValidateInt32PtrProvided(val *int32, v *Int32PtrValidation) (*int32...
  function validateInt32Ptr (line 189) | func validateInt32Ptr(val *int32, v *Int32PtrValidation) (*int32, error) {

FILE: pkg/lib/configreader/int64.go
  type Int64Validation (line 29) | type Int64Validation struct
  function Int64 (line 44) | func Int64(inter interface{}, v *Int64Validation) (int64, error) {
  function Int64FromInterfaceMap (line 58) | func Int64FromInterfaceMap(key string, iMap map[string]interface{}, v *I...
  function Int64FromStrMap (line 74) | func Int64FromStrMap(key string, sMap map[string]string, v *Int64Validat...
  function Int64FromStr (line 90) | func Int64FromStr(valStr string, v *Int64Validation) (int64, error) {
  function Int64FromEnv (line 101) | func Int64FromEnv(envVarName string, v *Int64Validation) (int64, error) {
  function Int64FromFile (line 117) | func Int64FromFile(filePath string, v *Int64Validation) (int64, error) {
  function Int64FromEnvOrFile (line 145) | func Int64FromEnvOrFile(envVarName string, filePath string, v *Int64Vali...
  function Int64FromPrompt (line 153) | func Int64FromPrompt(promptOpts *prompt.Options, v *Int64Validation) (in...
  function ValidateInt64Missing (line 162) | func ValidateInt64Missing(v *Int64Validation) (int64, error) {
  function ValidateInt64Provided (line 169) | func ValidateInt64Provided(val int64, v *Int64Validation) (int64, error) {
  function validateInt64 (line 176) | func validateInt64(val int64, v *Int64Validation) (int64, error) {
  function ValidateInt64Val (line 188) | func ValidateInt64Val(val int64, v *Int64Validation) error {
  function MustInt64FromEnv (line 229) | func MustInt64FromEnv(envVarName string, v *Int64Validation) int64 {
  function MustInt64FromFile (line 237) | func MustInt64FromFile(filePath string, v *Int64Validation) int64 {
  function MustInt64FromEnvOrFile (line 245) | func MustInt64FromEnvOrFile(envVarName string, filePath string, v *Int64...

FILE: pkg/lib/configreader/int64_list.go
  type Int64ListValidation (line 24) | type Int64ListValidation struct
  function Int64List (line 37) | func Int64List(inter interface{}, v *Int64ListValidation) ([]int64, erro...
  function Int64ListFromInterfaceMap (line 53) | func Int64ListFromInterfaceMap(key string, iMap map[string]interface{}, ...
  function ValidateInt64ListMissing (line 69) | func ValidateInt64ListMissing(v *Int64ListValidation) ([]int64, error) {
  function ValidateInt64ListProvided (line 76) | func ValidateInt64ListProvided(val []int64, v *Int64ListValidation) ([]i...
  function validateInt64List (line 87) | func validateInt64List(val []int64, v *Int64ListValidation) ([]int64, er...

FILE: pkg/lib/configreader/int64_ptr.go
  type Int64PtrValidation (line 27) | type Int64PtrValidation struct
  function makeInt64ValValidation (line 42) | func makeInt64ValValidation(v *Int64PtrValidation) *Int64Validation {
  function Int64Ptr (line 54) | func Int64Ptr(inter interface{}, v *Int64PtrValidation) (*int64, error) {
  function Int64PtrFromInterfaceMap (line 65) | func Int64PtrFromInterfaceMap(key string, iMap map[string]interface{}, v...
  function Int64PtrFromStrMap (line 81) | func Int64PtrFromStrMap(key string, sMap map[string]string, v *Int64PtrV...
  function Int64PtrFromStr (line 97) | func Int64PtrFromStr(valStr string, v *Int64PtrValidation) (*int64, erro...
  function Int64PtrFromEnv (line 108) | func Int64PtrFromEnv(envVarName string, v *Int64PtrValidation) (*int64, ...
  function Int64PtrFromFile (line 124) | func Int64PtrFromFile(filePath string, v *Int64PtrValidation) (*int64, e...
  function Int64PtrFromEnvOrFile (line 152) | func Int64PtrFromEnvOrFile(envVarName string, filePath string, v *Int64P...
  function Int64PtrFromPrompt (line 160) | func Int64PtrFromPrompt(promptOpts *prompt.Options, v *Int64PtrValidatio...
  function ValidateInt64PtrMissing (line 171) | func ValidateInt64PtrMissing(v *Int64PtrValidation) (*int64, error) {
  function ValidateInt64PtrProvided (line 178) | func ValidateInt64PtrProvided(val *int64, v *Int64PtrValidation) (*int64...
  function validateInt64Ptr (line 189) | func validateInt64Ptr(val *int64, v *Int64PtrValidation) (*int64, error) {

FILE: pkg/lib/configreader/int_list.go
  type IntListValidation (line 24) | type IntListValidation struct
  function IntList (line 37) | func IntList(inter interface{}, v *IntListValidation) ([]int, error) {
  function IntListFromInterfaceMap (line 53) | func IntListFromInterfaceMap(key string, iMap map[string]interface{}, v ...
  function ValidateIntListMissing (line 69) | func ValidateIntListMissing(v *IntListValidation) ([]int, error) {
  function ValidateIntListProvided (line 76) | func ValidateIntListProvided(val []int, v *IntListValidation) ([]int, er...
  function validateIntList (line 87) | func validateIntList(val []int, v *IntListValidation) ([]int, error) {

FILE: pkg/lib/configreader/int_ptr.go
  type IntPtrValidation (line 27) | type IntPtrValidation struct
  function makeIntValValidation (line 42) | func makeIntValValidation(v *IntPtrValidation) *IntValidation {
  function IntPtr (line 54) | func IntPtr(inter interface{}, v *IntPtrValidation) (*int, error) {
  function IntPtrFromInterfaceMap (line 65) | func IntPtrFromInterfaceMap(key string, iMap map[string]interface{}, v *...
  function IntPtrFromStrMap (line 81) | func IntPtrFromStrMap(key string, sMap map[string]string, v *IntPtrValid...
  function IntPtrFromStr (line 97) | func IntPtrFromStr(valStr string, v *IntPtrValidation) (*int, error) {
  function IntPtrFromEnv (line 108) | func IntPtrFromEnv(envVarName string, v *IntPtrValidation) (*int, error) {
  function IntPtrFromFile (line 124) | func IntPtrFromFile(filePath string, v *IntPtrValidation) (*int, error) {
  function IntPtrFromEnvOrFile (line 152) | func IntPtrFromEnvOrFile(envVarName string, filePath string, v *IntPtrVa...
  function IntPtrFromPrompt (line 160) | func IntPtrFromPrompt(promptOpts *prompt.Options, v *IntPtrValidation) (...
  function ValidateIntPtrMissing (line 171) | func ValidateIntPtrMissing(v *IntPtrValidation) (*int, error) {
  function ValidateIntPtrProvided (line 178) | func ValidateIntPtrProvided(val *int, v *IntPtrValidation) (*int, error) {
  function validateIntPtr (line 189) | func validateIntPtr(val *int, v *IntPtrValidation) (*int, error) {

FILE: pkg/lib/configreader/interface.go
  type InterfaceValidation (line 29) | type InterfaceValidation struct
  function Interface (line 39) | func Interface(inter interface{}, v *InterfaceValidation) (interface{}, ...
  function InterfaceFromInterfaceMap (line 43) | func InterfaceFromInterfaceMap(key string, iMap map[string]interface{}, ...
  function ValidateInterfaceMissing (line 59) | func ValidateInterfaceMissing(v *InterfaceValidation) (interface{}, erro...
  function ValidateInterfaceProvided (line 66) | func ValidateInterfaceProvided(val interface{}, v *InterfaceValidation) ...
  function validateInterface (line 77) | func validateInterface(val interface{}, v *InterfaceValidation) (interfa...
  function checkNoCortexResources (line 94) | func checkNoCortexResources(obj interface{}) error {
  function checkOnlyCortexResources (line 123) | func checkOnlyCortexResources(obj interface{}) error {
  function FlattenAllStrValues (line 153) | func FlattenAllStrValues(obj interface{}) ([]string, error) {
  function FlattenAllStrValuesAsSet (line 186) | func FlattenAllStrValuesAsSet(obj interface{}) (strset.Set, error) {

FILE: pkg/lib/configreader/interface_map.go
  type InterfaceMapValidation (line 25) | type InterfaceMapValidation struct
  function InterfaceMap (line 41) | func InterfaceMap(inter interface{}, v *InterfaceMapValidation) (map[str...
  function InterfaceMapFromInterfaceMap (line 49) | func InterfaceMapFromInterfaceMap(key string, iMap map[string]interface{...
  function ValidateInterfaceMapMissing (line 65) | func ValidateInterfaceMapMissing(v *InterfaceMapValidation) (map[string]...
  function ValidateInterfaceMapProvided (line 72) | func ValidateInterfaceMapProvided(val map[string]interface{}, v *Interfa...
  function validateInterfaceMap (line 83) | func validateInterfaceMap(val map[string]interface{}, v *InterfaceMapVal...

FILE: pkg/lib/configreader/interface_map_list.go
  type InterfaceMapListValidation (line 24) | type InterfaceMapListValidation struct
  function InterfaceMapList (line 39) | func InterfaceMapList(inter interface{}, v *InterfaceMapListValidation) ...
  function InterfaceMapListFromInterfaceMap (line 55) | func InterfaceMapListFromInterfaceMap(key string, iMap map[string]interf...
  function ValidateInterfaceMapListMissing (line 71) | func ValidateInterfaceMapListMissing(v *InterfaceMapListValidation) ([]m...
  function ValidateInterfaceMapListProvided (line 78) | func ValidateInterfaceMapListProvided(val []map[string]interface{}, v *I...
  function validateInterfaceMapList (line 89) | func validateInterfaceMapList(val []map[string]interface{}, v *Interface...

FILE: pkg/lib/configreader/interface_test.go
  function TestFlattenAllStrValues (line 25) | func TestFlattenAllStrValues(t *testing.T) {
  function CheckFlattenAllStrValues (line 88) | func CheckFlattenAllStrValues(obj interface{}, expected []string, t *tes...

FILE: pkg/lib/configreader/reader.go
  type StructFieldValidation (line 39) | type StructFieldValidation struct
  type StructValidation (line 82) | type StructValidation struct
  type StructListValidation (line 93) | type StructListValidation struct
  type InterfaceStructValidation (line 105) | type InterfaceStructValidation struct
  type InterfaceStructType (line 119) | type InterfaceStructType struct
  type InterfaceStructListValidation (line 124) | type InterfaceStructListValidation struct
  function Struct (line 133) | func Struct(dest interface{}, inter interface{}, v *StructValidation) []...
  function StructList (line 391) | func StructList(dest interface{}, inter interface{}, v *StructListValida...
  function InterfaceStruct (line 444) | func InterfaceStruct(inter interface{}, v *InterfaceStructValidation) (i...
  function InterfaceStructList (line 527) | func InterfaceStructList(dest interface{}, inter interface{}, v *Interfa...
  function updateValidation (line 560) | func updateValidation(validation interface{}, dest interface{}, structFi...
  function ReadInterfaceMapValue (line 574) | func ReadInterfaceMapValue(name string, interMap map[string]interface{})...
  type PromptItemValidation (line 590) | type PromptItemValidation struct
  type PromptValidation (line 614) | type PromptValidation struct
  function ReadPrompt (line 621) | func ReadPrompt(dest interface{}, promptValidation *PromptValidation) er...
  function StructFromStringMap (line 791) | func StructFromStringMap(dest interface{}, strMap map[string]string, v *...
  function StructFromFiles (line 992) | func StructFromFiles(dest interface{}, dirPath string, v *StructValidati...
  function ReadEnvVar (line 1015) | func ReadEnvVar(envVarName string) *string {
  function ParseYAMLFile (line 1027) | func ParseYAMLFile(dest interface{}, validation *StructValidation, fileP...
  function ParseYAMLBytes (line 1041) | func ParseYAMLBytes(dest interface{}, validation *StructValidation, data...
  function ReadYAMLFile (line 1055) | func ReadYAMLFile(filePath string) (interface{}, error) {
  function ReadYAMLFileStrMap (line 1069) | func ReadYAMLFileStrMap(filePath string) (map[string]interface{}, error) {
  function ReadYAMLBytes (line 1081) | func ReadYAMLBytes(yamlBytes []byte) (interface{}, error) {
  function ReadJSONBytes (line 1093) | func ReadJSONBytes(jsonBytes []byte) (interface{}, error) {
  function MustReadYAMLStr (line 1105) | func MustReadYAMLStr(yamlStr string) interface{} {
  function MustReadYAMLStrMap (line 1113) | func MustReadYAMLStrMap(yamlStr string) map[string]interface{} {
  function MustReadJSONStr (line 1125) | func MustReadJSONStr(jsonStr string) interface{} {
  function appendVal (line 1137) | func appendVal(slice interface{}, val interface{}) interface{} {
  function setField (line 1142) | func setField(val interface{}, destStruct interface{}, fieldName string)...
  function setFirstField (line 1172) | func setFirstField(val interface{}, destStruct interface{}) error {
  function setFieldNil (line 1184) | func setFieldNil(destStruct interface{}, fieldName string) error {
  function setFieldIfExists (line 1195) | func setFieldIfExists(val interface{}, destStruct interface{}, fieldName...
  function structHasKey (line 1204) | func structHasKey(val interface{}, fieldName string) bool {
  function inferKey (line 1212) | func inferKey(structType reflect.Type, typeStructField string, typeKey s...
  function inferPromptFieldName (line 1224) | func inferPromptFieldName(structType reflect.Type, typeStructField strin...
  function getTagFieldName (line 1233) | func getTagFieldName(field reflect.StructField) (string, bool) {

FILE: pkg/lib/configreader/reader_test.go
  type SimpleConfig (line 28) | type SimpleConfig struct
  function TestSimple (line 33) | func TestSimple(t *testing.T) {
  type NestedConfig (line 68) | type NestedConfig struct
  type Nested1 (line 73) | type Nested1 struct
  type Nested2 (line 76) | type Nested2 struct
  type Nested3 (line 80) | type Nested3 struct
  function TestNested (line 84) | func TestNested(t *testing.T) {
  type NestedListConfig (line 169) | type NestedListConfig struct
  type NestedList1 (line 173) | type NestedList1 struct
  type NestedList2 (line 176) | type NestedList2 struct
  type NestedList3 (line 182) | type NestedList3 struct
  function TestNestedList (line 187) | func TestNestedList(t *testing.T) {
  type Typed (line 304) | type Typed interface
  type Typed1 (line 308) | type Typed1 struct
    method GetType (line 319) | func (t *Typed1) GetType() string {
  type Typed1WithType (line 313) | type Typed1WithType struct
    method GetType (line 323) | func (t *Typed1WithType) GetType() string {
  type Typed2 (line 327) | type Typed2 struct
    method GetType (line 338) | func (t *Typed2) GetType() string {
  type Typed2WithType (line 332) | type Typed2WithType struct
    method GetType (line 342) | func (t *Typed2WithType) GetType() string {
  type TypedConfig (line 346) | type TypedConfig struct
  function TestInterface (line 423) | func TestInterface(t *testing.T) {
  type TypedListConfig (line 497) | type TypedListConfig struct
  function TestInterfaceList (line 501) | func TestInterfaceList(t *testing.T) {
  type NullableConfig (line 597) | type NullableConfig struct
  type NullableParentConfig (line 603) | type NullableParentConfig struct
  function TestDefaultNull (line 607) | func TestDefaultNull(t *testing.T) {
  type DefaultConfig (line 854) | type DefaultConfig struct
  function TestDefaultField (line 860) | func TestDefaultField(t *testing.T) {
  function testConfig (line 1022) | func testConfig(structValidation *StructValidation, configData interface...
  function testConfigError (line 1037) | func testConfigError(structValidation *StructValidation, configData inte...

FILE: pkg/lib/configreader/string.go
  type StringValidation (line 34) | type StringValidation struct
  function EnvVar (line 72) | func EnvVar(envVarName string) string {
  function String (line 76) | func String(inter interface{}, v *StringValidation) (string, error) {
  function StringFromInterfaceMap (line 107) | func StringFromInterfaceMap(key string, iMap map[string]interface{}, v *...
  function StringFromStrMap (line 123) | func StringFromStrMap(key string, sMap map[string]string, v *StringValid...
  function StringFromStr (line 139) | func StringFromStr(valStr string, v *StringValidation) (string, error) {
  function StringFromEnv (line 143) | func StringFromEnv(envVarName string, v *StringValidation) (string, erro...
  function StringFromFile (line 159) | func StringFromFile(filePath string, v *StringValidation) (string, error) {
  function StringFromEnvOrFile (line 187) | func StringFromEnvOrFile(envVarName string, filePath string, v *StringVa...
  function StringFromPrompt (line 195) | func StringFromPrompt(promptOpts *prompt.Options, v *StringValidation) (...
  function ValidateStringMissing (line 204) | func ValidateStringMissing(v *StringValidation) (string, error) {
  function ValidateStringProvided (line 211) | func ValidateStringProvided(val string, v *StringValidation) (string, er...
  function validateString (line 218) | func validateString(val string, v *StringValidation) (string, error) {
  function ValidateStringVal (line 230) | func ValidateStringVal(val string, v *StringValidation) error {
  function MustStringFromEnv (line 400) | func MustStringFromEnv(envVarName string, v *StringValidation) string {
  function MustStringFromFile (line 408) | func MustStringFromFile(filePath string, v *StringValidation) string {
  function MustStringFromEnvOrFile (line 416) | func MustStringFromEnvOrFile(envVarName string, filePath string, v *Stri...

FILE: pkg/lib/configreader/string_list.go
  type StringListValidation (line 26) | type StringListValidation struct
  function StringList (line 43) | func StringList(inter interface{}, v *StringListValidation) ([]string, e...
  function StringListFromInterfaceMap (line 59) | func StringListFromInterfaceMap(key string, iMap map[string]interface{},...
  function ValidateStringListMissing (line 75) | func ValidateStringListMissing(v *StringListValidation) ([]string, error) {
  function ValidateStringListProvided (line 82) | func ValidateStringListProvided(val []string, v *StringListValidation) (...
  function validateStringList (line 93) | func validateStringList(val []string, v *StringListValidation) ([]string...

FILE: pkg/lib/configreader/string_map.go
  type StringMapValidation (line 24) | type StringMapValidation struct
  function StringMap (line 36) | func StringMap(inter interface{}, v *StringMapValidation) (map[string]st...
  function StringMapFromInterfaceMap (line 44) | func StringMapFromInterfaceMap(key string, iMap map[string]interface{}, ...
  function ValidateStringMapMissing (line 60) | func ValidateStringMapMissing(v *StringMapValidation) (map[string]string...
  function ValidateStringMapProvided (line 67) | func ValidateStringMapProvided(val map[string]string, v *StringMapValida...
  function validateStringMap (line 78) | func validateStringMap(val map[string]string, v *StringMapValidation) (m...

FILE: pkg/lib/configreader/string_ptr.go
  type StringPtrValidation (line 27) | type StringPtrValidation struct
  function makeStringValValidation (line 63) | func makeStringValValidation(v *StringPtrValidation) *StringValidation {
  function StringPtr (line 96) | func StringPtr(inter interface{}, v *StringPtrValidation) (*string, erro...
  function StringPtrFromInterfaceMap (line 125) | func StringPtrFromInterfaceMap(key string, iMap map[string]interface{}, ...
  function StringPtrFromStrMap (line 141) | func StringPtrFromStrMap(key string, sMap map[string]string, v *StringPt...
  function StringPtrFromStr (line 157) | func StringPtrFromStr(str string, v *StringPtrValidation) (*string, erro...
  function StringPtrFromEnv (line 161) | func StringPtrFromEnv(envVarName string, v *StringPtrValidation) (*strin...
  function StringPtrFromFile (line 177) | func StringPtrFromFile(filePath string, v *StringPtrValidation) (*string...
  function StringPtrFromEnvOrFile (line 205) | func StringPtrFromEnvOrFile(envVarName string, filePath string, v *Strin...
  function StringPtrFromPrompt (line 213) | func StringPtrFromPrompt(promptOpts *prompt.Options, v *StringPtrValidat...
  function ValidateStringPtrMissing (line 224) | func ValidateStringPtrMissing(v *StringPtrValidation) (*string, error) {
  function ValidateStringPtrProvided (line 231) | func ValidateStringPtrProvided(val *string, v *StringPtrValidation) (*st...
  function validateStringPtr (line 242) | func validateStringPtr(val *string, v *StringPtrValidation) (*string, er...

FILE: pkg/lib/configreader/types.go
  type TypePlaceholder (line 19) | type TypePlaceholder struct
  type PrimitiveType (line 23) | type PrimitiveType
  type PrimitiveTypes (line 24) | type PrimitiveTypes
    method StringList (line 45) | func (ts PrimitiveTypes) StringList() []string {

FILE: pkg/lib/configreader/validators.go
  function init (line 31) | func init() {
  function GetFilePathValidator (line 35) | func GetFilePathValidator(baseDir string) func(string) (string, error) {
  function S3aPathValidator (line 45) | func S3aPathValidator(val string) (string, error) {
  function S3PathValidator (line 52) | func S3PathValidator(val string) (string, error) {
  function EmailValidator (line 59) | func EmailValidator(val string) (string, error) {
  type DurationValidation (line 71) | type DurationValidation struct
  function DurationParser (line 79) | func DurationParser(v *DurationValidation) func(string) (interface{}, er...
  function ValidateImageVersion (line 124) | func ValidateImageVersion(image, cortexVersion string) (string, error) {

FILE: pkg/lib/console/format.go
  function Bold (line 26) | func Bold(a ...interface{}) string {
  function BoolColor (line 31) | func BoolColor(b bool) string {

FILE: pkg/lib/cron/cron.go
  type Cron (line 25) | type Cron struct
    method RunNow (line 64) | func (c *Cron) RunNow() {
    method Cancel (line 68) | func (c *Cron) Cancel() {
  function Run (line 30) | func Run(f func() error, errHandler func(error), delay time.Duration) Cr...
  function Recoverer (line 72) | func Recoverer(errHandler func(error)) {

FILE: pkg/lib/debug/debug.go
  function Pp (line 29) | func Pp(obj interface{}) {
  function Ppg (line 33) | func Ppg(obj interface{}) {
  function Sppg (line 37) | func Sppg(obj interface{}) string {
  function Ppj (line 47) | func Ppj(obj interface{}) {
  function Ppy (line 55) | func Ppy(obj interface{}) {

FILE: pkg/lib/docker/docker.go
  function init (line 50) | func init() {
  type Client (line 54) | type Client struct
  function GetDockerClient (line 59) | func GetDockerClient() (*Client, error) {
  function MustDockerClient (line 84) | func MustDockerClient() *Client {
  function AWSAuthConfig (line 93) | func AWSAuthConfig(awsClient *aws.Client) (string, error) {
  function WrapDockerError (line 123) | func WrapDockerError(err error) error {
  type PullVerbosity (line 135) | type PullVerbosity
  constant NoPrint (line 138) | NoPrint PullVerbosity = iota
  constant PrintDots (line 139) | PrintDots
  constant PrintProgressBars (line 140) | PrintProgressBars
  function PullImage (line 143) | func PullImage(image string, encodedAuthConfig string, pullVerbosity Pul...
  function StreamDockerLogs (line 207) | func StreamDockerLogs(containerID string, containerIDs ...string) error {
  function StreamDockerLogsFn (line 229) | func StreamDockerLogsFn(containerID string, dockerClient *Client) func()...
  function CopyToContainer (line 251) | func CopyToContainer(containerID string, input *archive.Input, container...
  function CopyFromContainer (line 284) | func CopyFromContainer(containerID string, containerPath string, localDi...
  function EncodeAuthConfig (line 308) | func EncodeAuthConfig(authConfig dockertypes.AuthConfig) (string, error) {
  function CheckImageAccessible (line 317) | func CheckImageAccessible(dockerClient *Client, dockerImage, authConfig ...
  function CheckImageExistsLocally (line 324) | func CheckImageExistsLocally(dockerClient *Client, dockerImage string) e...
  function ExtractImageTag (line 344) | func ExtractImageTag(dockerImage string) string {

FILE: pkg/lib/docker/errors.go
  constant ErrConnectToDockerDaemon (line 29) | ErrConnectToDockerDaemon   = "docker.connect_to_docker_daemon"
  constant ErrDockerPermissions (line 30) | ErrDockerPermissions       = "docker.docker_permissions"
  constant ErrImageDoesntExistLocally (line 31) | ErrImageDoesntExistLocally = "docker.image_doesnt_exist_locally"
  constant ErrImageInaccessible (line 32) | ErrImageInaccessible       = "docker.image_inaccessible"
  function ErrorConnectToDockerDaemon (line 35) | func ErrorConnectToDockerDaemon() error {
  function ErrorDockerPermissions (line 47) | func ErrorDockerPermissions(err error) error {
  function ErrorImageDoesntExistLocally (line 61) | func ErrorImageDoesntExistLocally(image string) error {
  function ErrorImageInaccessible (line 68) | func ErrorImageInaccessible(image string, cause error) error {

FILE: pkg/lib/errors/error.go
  constant ErrNotCortexError (line 27) | ErrNotCortexError = "error"
  type Error (line 29) | type Error struct
    method Error (line 39) | func (cortexError *Error) Error() string {
    method StackTrace (line 43) | func (cortexError *Error) StackTrace() pkgerrors.StackTrace {
    method Format (line 171) | func (cortexError *Error) Format(s fmt.State, verb rune) {
  function WithStack (line 51) | func WithStack(err error) error {
  function Wrap (line 73) | func Wrap(err error, strs ...string) error {
  function Wrapf (line 87) | func Wrapf(err error, template string, params ...string) error {
  function Append (line 92) | func Append(err error, str string) error {
  function getCortexError (line 102) | func getCortexError(err error) *Error {
  function GetKind (line 109) | func GetKind(err error) string {
  function GetMetadata (line 116) | func GetMetadata(err error) interface{} {
  function IsNoTelemetry (line 123) | func IsNoTelemetry(err error) bool {
  function SetNoTelemetry (line 130) | func SetNoTelemetry(err error) error {
  function IsNoPrint (line 136) | func IsNoPrint(err error) bool {
  function SetNoPrint (line 143) | func SetNoPrint(err error) error {
  function Cause (line 150) | func Cause(err error) error {
  function CauseOrSelf (line 157) | func CauseOrSelf(err error) error {
  function PrintStacktrace (line 167) | func PrintStacktrace(err error) {
  function CastRecoverError (line 187) | func CastRecoverError(errInterface interface{}, strs ...string) error {
  function removeEmptyStrs (line 200) | func removeEmptyStrs(strs []string) []string {

FILE: pkg/lib/errors/errors.go
  constant ErrUnexpected (line 27) | ErrUnexpected = "errors.unexpected"
  function ErrorUnexpected (line 30) | func ErrorUnexpected(msgs ...interface{}) error {
  function ListOfErrors (line 42) | func ListOfErrors(errKind string, shouldPrint bool, errors ...error) err...

FILE: pkg/lib/errors/message.go
  function PrintError (line 26) | func PrintError(err error, strs ...string) {
  function PrintErrorForUser (line 31) | func PrintErrorForUser(err error, strs ...string) {
  function ErrorStr (line 36) | func ErrorStr(err error, strs ...string) string {
  function Message (line 41) | func Message(err error, strs ...string) string {
  function MessageFirstLine (line 47) | func MessageFirstLine(err error, strs ...string) string {

FILE: pkg/lib/errors/multi.go
  function AddError (line 19) | func AddError(errs []error, err error, strs ...string) ([]error, bool) {
  function AddErrors (line 28) | func AddErrors(errs []error, newErrs []error, strs ...string) ([]error, ...
  function WrapAll (line 39) | func WrapAll(errs []error, strs ...string) []error {
  function HasError (line 50) | func HasError(errs []error) bool {
  function AreAllErrors (line 59) | func AreAllErrors(errs []error) bool {
  function FirstError (line 68) | func FirstError(errs ...error) error {
  function MapHasError (line 77) | func MapHasError(errs map[string]error) bool {
  function FirstErrorInMap (line 86) | func FirstErrorInMap(errs map[string]error) error {
  function FirstKeyInErrorMap (line 95) | func FirstKeyInErrorMap(errs map[string]error) string {
  function NonNilErrorMapKeys (line 104) | func NonNilErrorMapKeys(errs map[string]error) []string {

FILE: pkg/lib/errors/stack.go
  type stack (line 26) | type stack
    method Format (line 36) | func (s *stack) Format(st fmt.State, verb rune) {
  function callers (line 28) | func callers() *stack {

FILE: pkg/lib/exit/exit.go
  function Ok (line 26) | func Ok() {
  function Error (line 31) | func Error(err error, wrapStrs ...string) {
  function Panic (line 49) | func Panic(err error, wrapStrs ...string) {
  function RecoverAndExit (line 63) | func RecoverAndExit(strs ...string) {

FILE: pkg/lib/files/errors.go
  constant ErrCreateDir (line 27) | ErrCreateDir                    = "files.create_dir"
  constant ErrDeleteDir (line 28) | ErrDeleteDir                    = "files.delete_dir"
  constant ErrReadFormFile (line 29) | ErrReadFormFile                 = "files.read_form_file"
  constant ErrCreateFile (line 30) | ErrCreateFile                   = "files.create_file"
  constant ErrReadDir (line 31) | ErrReadDir                      = "files.read_dir"
  constant ErrReadFile (line 32) | ErrReadFile                     = "files.read_file"
  constant ErrFileAlreadyExists (line 33) | ErrFileAlreadyExists            = "files.file_already_exists"
  constant ErrInsufficientMemoryToReadFile (line 34) | ErrInsufficientMemoryToReadFile = "files.insufficient_memory_to_read_file"
  constant ErrFileSizeLimit (line 35) | ErrFileSizeLimit                = "files.file_size_limit"
  constant ErrProjectSizeLimit (line 36) | ErrProjectSizeLimit             = "files.project_size_limit"
  constant ErrUnexpected (line 37) | ErrUnexpected                   = "files.unexpected"
  constant ErrFileDoesNotExist (line 38) | ErrFileDoesNotExist             = "files.file_does_not_exist"
  constant ErrDirDoesNotExist (line 39) | ErrDirDoesNotExist              = "files.dir_does_not_exist"
  constant ErrNotAFile (line 40) | ErrNotAFile                     = "files.not_a_file"
  constant ErrNotADir (line 41) | ErrNotADir                      = "files.not_a_dir"
  function ErrorCreateDir (line 44) | func ErrorCreateDir(path string) error {
  function ErrorDeleteDir (line 51) | func ErrorDeleteDir(path string) error {
  function ErrorReadFormFile (line 58) | func ErrorReadFormFile(fileName string) error {
  function ErrorCreateFile (line 65) | func ErrorCreateFile(path string) error {
  function ErrorReadDir (line 72) | func ErrorReadDir(path string) error {
  function ErrorReadFile (line 79) | func ErrorReadFile(path string) error {
  function ErrorFileAlreadyExists (line 86) | func ErrorFileAlreadyExists(path string) error {
  function ErrorInsufficientMemoryToReadFile (line 93) | func ErrorInsufficientMemoryToReadFile(fileSizeBytes, availableMemBytes ...
  function ErrorFileSizeLimit (line 100) | func ErrorFileSizeLimit(maxFileSizeBytes int64) error {
  function ErrorProjectSizeLimit (line 107) | func ErrorProjectSizeLimit(maxProjectSizeBytes int64) error {
  function ErrorUnexpected (line 114) | func ErrorUnexpected() error {
  function ErrorFileDoesNotExist (line 121) | func ErrorFileDoesNotExist(path string) error {
  function ErrorDirDoesNotExist (line 128) | func ErrorDirDoesNotExist(path string) error {
  function ErrorNotAFile (line 135) | func ErrorNotAFile(path string) error {
  function ErrorNotADir (line 142) | func ErrorNotADir(path string) error {

FILE: pkg/lib/files/files.go
  function Open (line 50) | func Open(path string) (*os.File, error) {
  function OpenFile (line 65) | func OpenFile(path string, flag int, perm os.FileMode) (*os.File, error) {
  function Create (line 80) | func Create(path string) (*os.File, error) {
  function ReadFile (line 94) | func ReadFile(path string) (string, error) {
  function ReadFileBytes (line 103) | func ReadFileBytes(path string) ([]byte, error) {
  function ReadFileBytesErrPath (line 107) | func ReadFileBytesErrPath(path string, errMsgPath string) ([]byte, error) {
  function CreateFile (line 125) | func CreateFile(path string) error {
  function WriteFileFromReader (line 140) | func WriteFileFromReader(reader io.Reader, path string) error {
  function WriteFile (line 160) | func WriteFile(data []byte, path string) error {
  function IsAbsOrTildePrefixed (line 173) | func IsAbsOrTildePrefixed(path string) bool {
  function EscapeTilde (line 179) | func EscapeTilde(path string) (string, error) {
  function Clean (line 205) | func Clean(path string) (string, error) {
  function ReplacePathWithTilde (line 215) | func ReplacePathWithTilde(absPath string) string {
  function GetTopLevelDirectory (line 239) | func GetTopLevelDirectory(path string) string {
  function TrimDirPrefix (line 256) | func TrimDirPrefix(fullPath string, dirPath string) string {
  function RelToAbsPath (line 263) | func RelToAbsPath(relativePath string, baseDir string) string {
  function UserRelToAbsPath (line 271) | func UserRelToAbsPath(relativePath string) string {
  function PathRelativeToCWD (line 279) | func PathRelativeToCWD(absPath string) string {
  function PathRelativeToDir (line 287) | func PathRelativeToDir(absPath string, dir string) string {
  function DirPathRelativeToCWD (line 297) | func DirPathRelativeToCWD(absPath string) string {
  function DirPathRelativeToDir (line 301) | func DirPathRelativeToDir(absPath string, dir string) string {
  function IsFileOrDir (line 305) | func IsFileOrDir(path string) bool {
  function IsDir (line 311) | func IsDir(path string) bool {
  function CheckDir (line 319) | func CheckDir(dirPath string) error {
  function CheckDirErrPath (line 324) | func CheckDirErrPath(dirPath string, errMsgPath string) error {
  function IsFile (line 342) | func IsFile(path string) bool {
  function CheckFile (line 350) | func CheckFile(path string) error {
  function CheckFileErrPath (line 355) | func CheckFileErrPath(path string, errMsgPath string) error {
  function CreateDir (line 372) | func CreateDir(path string) error {
  function CreateDirIfMissing (line 385) | func CreateDirIfMissing(path string) (bool, error) {
  function DeleteDir (line 402) | func DeleteDir(path string) error {
  function DeleteDirIfPresent (line 415) | func DeleteDirIfPresent(path string) (bool, error) {
  function TmpDir (line 432) | func TmpDir() (string, error) {
  function ParentDir (line 440) | func ParentDir(dir string) string {
  function SearchForFile (line 444) | func SearchForFile(filename string, dir string) (string, error) {
  function MakeEmptyFile (line 472) | func MakeEmptyFile(path string) error {
  function MakeEmptyFiles (line 490) | func MakeEmptyFiles(path string, paths ...string) error {
  function MakeEmptyFilesInDir (line 500) | func MakeEmptyFilesInDir(dir string, path string, paths ...string) error {
  function IsFilePathYAML (line 511) | func IsFilePathYAML(path string) bool {
  function IsFilePathPython (line 516) | func IsFilePathPython(path string) bool {
  type IgnoreFn (line 522) | type IgnoreFn
  function IgnoreHiddenFiles (line 524) | func IgnoreHiddenFiles(path string, fi os.FileInfo) (bool, error) {
  function IgnoreCortexYAML (line 531) | func IgnoreCortexYAML(path string, fi os.FileInfo) (bool, error) {
  function IgnoreCortexDebug (line 538) | func IgnoreCortexDebug(path string, fi os.FileInfo) (bool, error) {
  function IgnoreHiddenFolders (line 545) | func IgnoreHiddenFolders(path string, fi os.FileInfo) (bool, error) {
  function IgnorePythonGeneratedFiles (line 552) | func IgnorePythonGeneratedFiles(path string, fi os.FileInfo) (bool, erro...
  function IgnoreNonPython (line 563) | func IgnoreNonPython(path string, fi os.FileInfo) (bool, error) {
  function IgnoreNonYAML (line 570) | func IgnoreNonYAML(path string, fi os.FileInfo) (bool, error) {
  function IgnoreSpecificFiles (line 577) | func IgnoreSpecificFiles(absPaths ...string) IgnoreFn {
  function GitIgnoreFn (line 584) | func GitIgnoreFn(gitIgnorePath string) (IgnoreFn, error) {
  function PromptForFilesAboveSize (line 602) | func PromptForFilesAboveSize(size int, promptMsgTemplate string) IgnoreFn {
  function ErrorOnBigFilesFn (line 616) | func ErrorOnBigFilesFn(maxFileSizeBytes int64) IgnoreFn {
  function ErrorOnProjectSizeLimit (line 636) | func ErrorOnProjectSizeLimit(maxProjectSizeBytes int64) IgnoreFn {
  function LongestCommonPath (line 650) | func LongestCommonPath(paths ...string) string {
  function FilterPathsWithDirPrefix (line 710) | func FilterPathsWithDirPrefix(paths []string, prefix string) []string {
  type DirsOrder (line 723) | type DirsOrder
  function SortFilePaths (line 729) | func SortFilePaths(paths []string, dirsOrder DirsOrder) []string {
  function FileTree (line 759) | func FileTree(paths []string, cwd string, dirsOrder DirsOrder) string {
  function getTreeBranch (line 808) | func getTreeBranch(dir string, cachedTrees map[string]treeprint.Tree) tr...
  function Dir (line 832) | func Dir(path string) string {
  function DirPaths (line 836) | func DirPaths(paths []string, addTrailingSlash bool) []string {
  function ListDirRecursive (line 848) | func ListDirRecursive(dir string, relative bool, ignoreFns ...IgnoreFn) ...
  function ListDir (line 894) | func ListDir(dir string, relative bool) ([]string, error) {
  function CopyFileOverwrite (line 920) | func CopyFileOverwrite(src string, dest string) error {
  function CopyDirOverwrite (line 940) | func CopyDirOverwrite(src string, dest string, ignoreFns ...IgnoreFn) er...
  function CopyRecursiveShell (line 971) | func CopyRecursiveShell(src string, dest string) error {
  function HashFile (line 993) | func HashFile(path string, paths ...string) (string, error) {
  function HashDirectory (line 1026) | func HashDirectory(dir string, ignoreFns ...IgnoreFn) (string, error) {
  function CloseSilent (line 1070) | func CloseSilent(closer io.Closer, closers ...io.Closer) {
  function ReadReqFile (line 1078) | func ReadReqFile(r *http.Request, fileName string) ([]byte, error) {

FILE: pkg/lib/files/files_test.go
  function IgnoreDir3 (line 27) | func IgnoreDir3(path string, fi os.FileInfo) (bool, error) {
  function TestPrintFileTree (line 34) | func TestPrintFileTree(t *testing.T) {
  function TestListDirRecursive (line 166) | func TestListDirRecursive(t *testing.T) {

FILE: pkg/lib/hash/hash.go
  function Bytes (line 29) | func Bytes(bytes []byte) string {
  function String (line 36) | func String(str string) string {
  function Strings (line 40) | func Strings(strs ...string) string {
  function Any (line 44) | func Any(obj interface{}) string {
  function File (line 48) | func File(path string) (string, error) {

FILE: pkg/lib/json/errors.go
  constant errStrMarshalJSON (line 20) | errStrMarshalJSON   = "invalid json"
  constant errStrUnmarshalJSON (line 21) | errStrUnmarshalJSON = "invalid json cannot be serialized"

FILE: pkg/lib/json/json.go
  function MarshalIndent (line 28) | func MarshalIndent(obj interface{}) ([]byte, error) {
  function Marshal (line 36) | func Marshal(obj interface{}) ([]byte, error) {
  function Unmarshal (line 44) | func Unmarshal(jsonBytes []byte, dst interface{}) error {
  function DecodeWithNumber (line 51) | func DecodeWithNumber(jsonBytes []byte, dst interface{}) error {
  function MarshalJSONStr (line 61) | func MarshalJSONStr(obj interface{}) (string, error) {
  function WriteJSON (line 69) | func WriteJSON(obj interface{}, outPath string) error {
  function Pretty (line 84) | func Pretty(obj interface{}) (string, error) {

FILE: pkg/lib/k8s/configmap.go
  type ConfigMapSpec (line 34) | type ConfigMapSpec struct
  function ConfigMap (line 42) | func ConfigMap(spec *ConfigMapSpec) *kcore.ConfigMap {
  method CreateConfigMap (line 56) | func (c *Client) CreateConfigMap(configMap *kcore.ConfigMap) (*kcore.Con...
  method UpdateConfigMap (line 65) | func (c *Client) UpdateConfigMap(configMap *kcore.ConfigMap) (*kcore.Con...
  method ApplyConfigMap (line 74) | func (c *Client) ApplyConfigMap(configMap *kcore.ConfigMap) (*kcore.Conf...
  method GetConfigMap (line 85) | func (c *Client) GetConfigMap(name string) (*kcore.ConfigMap, error) {
  method GetConfigMapData (line 97) | func (c *Client) GetConfigMapData(name string) (map[string]string, map[s...
  method DeleteConfigMap (line 108) | func (c *Client) DeleteConfigMap(name string) (bool, error) {
  method ListConfigMaps (line 119) | func (c *Client) ListConfigMaps(opts *kmeta.ListOptions) ([]kcore.Config...
  method ListConfigMapsByLabels (line 133) | func (c *Client) ListConfigMapsByLabels(labels map[string]string) ([]kco...
  method ListConfigMapsByLabel (line 140) | func (c *Client) ListConfigMapsByLabel(labelKey string, labelValue strin...
  method ListConfigMapsWithLabelKeys (line 144) | func (c *Client) ListConfigMapsWithLabelKeys(labelKeys ...string) ([]kco...
  function ConfigMapMap (line 151) | func ConfigMapMap(configMaps []kcore.ConfigMap) map[string]kcore.ConfigM...

FILE: pkg/lib/k8s/deployment.go
  type DeploymentSpec (line 37) | type DeploymentSpec struct
  function Deployment (line 48) | func Deployment(spec *DeploymentSpec) *kapps.Deployment {
  method CreateDeployment (line 100) | func (c *Client) CreateDeployment(deployment *kapps.Deployment) (*kapps....
  method UpdateDeployment (line 109) | func (c *Client) UpdateDeployment(deployment *kapps.Deployment) (*kapps....
  method ApplyDeployment (line 118) | func (c *Client) ApplyDeployment(deployment *kapps.Deployment) (*kapps.D...
  method GetDeployment (line 129) | func (c *Client) GetDeployment(name string) (*kapps.Deployment, error) {
  method DeleteDeployment (line 141) | func (c *Client) DeleteDeployment(name string) (bool, error) {
  method ListDeployments (line 152) | func (c *Client) ListDeployments(opts *kmeta.ListOptions) ([]kapps.Deplo...
  method ListDeploymentsByLabels (line 166) | func (c *Client) ListDeploymentsByLabels(labels map[string]string) ([]ka...
  method ListDeploymentsByLabel (line 173) | func (c *Client) ListDeploymentsByLabel(labelKey string, labelValue stri...
  method ListDeploymentsWithLabelKeys (line 177) | func (c *Client) ListDeploymentsWithLabelKeys(labelKeys ...string) ([]ka...
  function DeploymentMap (line 184) | func DeploymentMap(deployments []kapps.Deployment) map[string]kapps.Depl...
  function DeploymentStartTime (line 192) | func DeploymentStartTime(deployment *kapps.Deployment) *time.Time {
  function DeploymentStrategiesMatch (line 203) | func DeploymentStrategiesMatch(s1, s2 kapps.DeploymentStrategy) bool {
  function intOrStrPtrsMatch (line 222) | func intOrStrPtrsMatch(intStr1, intStr2 *intstr.IntOrString) bool {

FILE: pkg/lib/k8s/errors.go
  constant ErrLabelNotFound (line 28) | ErrLabelNotFound      = "k8s.label_not_found"
  constant ErrAnnotationNotFound (line 29) | ErrAnnotationNotFound = "k8s.annotation_not_found"
  constant ErrParseLabel (line 30) | ErrParseLabel         = "k8s.parse_label"
  constant ErrParseAnnotation (line 31) | ErrParseAnnotation    = "k8s.parse_annotation"
  constant ErrParseQuantity (line 32) | ErrParseQuantity      = "k8s.parse_quantity"
  constant ErrMissingMetrics (line 33) | ErrMissingMetrics     = "k8s.missing_metrics"
  constant ErrServiceNotFound (line 34) | ErrServiceNotFound    = "k8s.service_not_found"
  function ErrorLabelNotFound (line 37) | func ErrorLabelNotFound(labelName string) error {
  function ErrorAnnotationNotFound (line 44) | func ErrorAnnotationNotFound(annotationName string) error {
  function ErrorParseLabel (line 51) | func ErrorParseLabel(labelName string, labelVal string, desiredType stri...
  function ErrorParseAnnotation (line 58) | func ErrorParseAnnotation(annotationName string, annotationVal string, d...
  function ErrorParseQuantity (line 65) | func ErrorParseQuantity(qtyStr string) error {
  function ErrorMissingMetrics (line 72) | func ErrorMissingMetrics() error {
  function ErrorServiceNotFound (line 79) | func ErrorServiceNotFound(serviceName string) error {

FILE: pkg/lib/k8s/hpa.go
  type HPASpec (line 35) | type HPASpec struct
  function HPA (line 45) | func HPA(spec *HPASpec) (*kautoscaling.HorizontalPodAutoscaler, error) {
  method CreateHPA (line 97) | func (c *Client) CreateHPA(hpa *kautoscaling.HorizontalPodAutoscaler) (*...
  method UpdateHPA (line 106) | func (c *Client) UpdateHPA(hpa *kautoscaling.HorizontalPodAutoscaler) (*...
  method ApplyHPA (line 115) | func (c *Client) ApplyHPA(hpa *kautoscaling.HorizontalPodAutoscaler) (*k...
  method GetHPA (line 126) | func (c *Client) GetHPA(name string) (*kautoscaling.HorizontalPodAutosca...
  method DeleteHPA (line 138) | func (c *Client) DeleteHPA(name string) (bool, error) {
  method ListHPAs (line 149) | func (c *Client) ListHPAs(opts *kmeta.ListOptions) ([]kautoscaling.Horiz...
  method ListHPAsByLabels (line 163) | func (c *Client) ListHPAsByLabels(labels map[string]string) ([]kautoscal...
  method ListHPAsByLabel (line 170) | func (c *Client) ListHPAsByLabel(labelKey string, labelValue string) ([]...
  method ListHPAsWithLabelKeys (line 174) | func (c *Client) ListHPAsWithLabelKeys(labelKeys ...string) ([]kautoscal...
  function HPAMap (line 181) | func HPAMap(hpas []kautoscaling.HorizontalPodAutoscaler) map[string]kaut...
  function IsHPAUpToDate (line 189) | func IsHPAUpToDate(hpa *kautoscaling.HorizontalPodAutoscaler, minReplica...

FILE: pkg/lib/k8s/ingress.go
  type IngressSpec (line 35) | type IngressSpec struct
  function Ingress (line 45) | func Ingress(spec *IngressSpec) *kextensions.Ingress {
  method CreateIngress (line 83) | func (c *Client) CreateIngress(ingress *kextensions.Ingress) (*kextensio...
  method UpdateIngress (line 92) | func (c *Client) UpdateIngress(ingress *kextensions.Ingress) (*kextensio...
  method ApplyIngress (line 101) | func (c *Client) ApplyIngress(ingress *kextensions.Ingress) (*kextension...
  method GetIngress (line 112) | func (c *Client) GetIngress(name string) (*kextensions.Ingress, error) {
  method DeleteIngress (line 124) | func (c *Client) DeleteIngress(name string) (bool, error) {
  method ListIngresses (line 135) | func (c *Client) ListIngresses(opts *kmeta.ListOptions) ([]kextensions.I...
  method ListIngressesByLabels (line 149) | func (c *Client) ListIngressesByLabels(labels map[string]string) ([]kext...
  method ListIngressesByLabel (line 156) | func (c *Client) ListIngressesByLabel(labelKey string, labelValue string...
  method ListIngressesWithLabelKeys (line 160) | func (c *Client) ListIngressesWithLabelKeys(labelKeys ...string) ([]kext...
  function IngressMap (line 167) | func IngressMap(ingresses []kextensions.Ingress) map[string]kextensions....

FILE: pkg/lib/k8s/job.go
  type JobSpec (line 35) | type JobSpec struct
  function Job (line 45) | func Job(spec *JobSpec) *kbatch.Job {
  method CreateJob (line 74) | func (c *Client) CreateJob(job *kbatch.Job) (*kbatch.Job, error) {
  method UpdateJob (line 83) | func (c *Client) UpdateJob(job *kbatch.Job) (*kbatch.Job, error) {
  method ApplyJob (line 92) | func (c *Client) ApplyJob(job *kbatch.Job) (*kbatch.Job, error) {
  method GetJob (line 103) | func (c *Client) GetJob(name string) (*kbatch.Job, error) {
  method DeleteJob (line 115) | func (c *Client) DeleteJob(name string) (bool, error) {
  method DeleteJobs (line 126) | func (c *Client) DeleteJobs(opts *kmeta.ListOptions) (bool, error) {
  method ListJobs (line 139) | func (c *Client) ListJobs(opts *kmeta.ListOptions) ([]kbatch.Job, error) {
  method ListJobsByLabels (line 153) | func (c *Client) ListJobsByLabels(labels map[string]string) ([]kbatch.Jo...
  method ListJobsByLabel (line 160) | func (c *Client) ListJobsByLabel(labelKey string, labelValue string) ([]...
  method ListJobsWithLabelKeys (line 164) | func (c *Client) ListJobsWithLabelKeys(labelKeys ...string) ([]kbatch.Jo...
  function JobMap (line 171) | func JobMap(jobs []kbatch.Job) map[string]kbatch.Job {
  method IsJobRunning (line 179) | func (c *Client) IsJobRunning(name string) (bool, error) {

FILE: pkg/lib/k8s/k8s.go
  type Client (line 53) | type Client struct
    method ClientSet (line 123) | func (c *Client) ClientSet() *kclientset.Clientset {
    method IstioClientSet (line 127) | func (c *Client) IstioClientSet() *istioclient.Clientset {
  function New (line 72) | func New(namespace string, inCluster bool, restConfig *kclientrest.Confi...
  function RandomName (line 132) | func RandomName() string {
  function ValidName (line 137) | func ValidName(name string) string {
  function ValidNameContainer (line 145) | func ValidNameContainer(name string) string {
  function CPU (line 164) | func CPU(cpu string) kresource.Quantity {
  function Mem (line 168) | func Mem(mem string) kresource.Quantity {
  function LabelExistsSelector (line 172) | func LabelExistsSelector(labelKeys ...string) string {
  function FieldSelectorNotIn (line 180) | func FieldSelectorNotIn(key string, values []string) string {

FILE: pkg/lib/k8s/node.go
  method ListNodes (line 35) | func (c *Client) ListNodes(opts *kmeta.ListOptions) ([]kcore.Node, error) {
  method ListNodesByLabels (line 49) | func (c *Client) ListNodesByLabels(labels map[string]string) ([]kcore.No...
  method ListNodesByLabel (line 56) | func (c *Client) ListNodesByLabel(labelKey string, labelValue string) ([...
  method ListNodesWithLabelKeys (line 60) | func (c *Client) ListNodesWithLabelKeys(labelKeys ...string) ([]kcore.No...
  function HowManyPodsFitOnNode (line 67) | func HowManyPodsFitOnNode(podSpec kcore.PodSpec, node kcore.Node, cpuRes...

FILE: pkg/lib/k8s/parsers.go
  function GetLabel (line 27) | func GetLabel(obj kmeta.Object, key string) (string, error) {
  function GetAnnotation (line 39) | func GetAnnotation(obj kmeta.Object, key string) (string, error) {
  function ParseBoolLabel (line 51) | func ParseBoolLabel(obj kmeta.Object, key string) (bool, error) {
  function ParseBoolAnnotation (line 63) | func ParseBoolAnnotation(obj kmeta.Object, key string) (bool, error) {
  function ParseIntLabel (line 75) | func ParseIntLabel(obj kmeta.Object, key string) (int, error) {
  function ParseIntAnnotation (line 87) | func ParseIntAnnotation(obj kmeta.Object, key string) (int, error) {
  function ParseInt32Label (line 99) | func ParseInt32Label(obj kmeta.Object, key string) (int32, error) {
  function ParseInt32Annotation (line 111) | func ParseInt32Annotation(obj kmeta.Object, key string) (int32, error) {
  function ParseInt64Label (line 123) | func ParseInt64Label(obj kmeta.Object, key string) (int64, error) {
  function ParseInt64Annotation (line 135) | func ParseInt64Annotation(obj kmeta.Object, key string) (int64, error) {
  function ParseFloat32Label (line 147) | func ParseFloat32Label(obj kmeta.Object, key string) (float32, error) {
  function ParseFloat32Annotation (line 159) | func ParseFloat32Annotation(obj kmeta.Object, key string) (float32, erro...
  function ParseFloat64Label (line 171) | func ParseFloat64Label(obj kmeta.Object, key string) (float64, error) {
  function ParseFloat64Annotation (line 183) | func ParseFloat64Annotation(obj kmeta.Object, key string) (float64, erro...
  function ParseDurationLabel (line 195) | func ParseDurationLabel(obj kmeta.Object, key string) (time.Duration, er...
  function ParseDurationAnnotation (line 206) | func ParseDurationAnnotation(obj kmeta.Object, key string) (time.Duratio...

FILE: pkg/lib/k8s/pod.go
  constant ReasonEvicted (line 44) | ReasonEvicted   = "Evicted"
  constant ReasonOOMKilled (line 45) | ReasonOOMKilled = "OOMKilled"
  constant ReasonCompleted (line 46) | ReasonCompleted = "Completed"
  type PodSpec (line 49) | type PodSpec struct
  type PodStatus (line 56) | type PodStatus
  constant PodStatusPending (line 59) | PodStatusPending      PodStatus = "Pending"
  constant PodStatusCreating (line 60) | PodStatusCreating     PodStatus = "Creating"
  constant PodStatusNotReady (line 61) | PodStatusNotReady     PodStatus = "NotReady"
  constant PodStatusReady (line 62) | PodStatusReady        PodStatus = "Ready"
  constant PodStatusErrImagePull (line 63) | PodStatusErrImagePull PodStatus = "ErrImagePull"
  constant PodStatusTerminating (line 64) | PodStatusTerminating  PodStatus = "Terminating"
  constant PodStatusFailed (line 65) | PodStatusFailed       PodStatus = "Failed"
  constant PodStatusKilled (line 66) | PodStatusKilled       PodStatus = "Killed"
  constant PodStatusKilledOOM (line 67) | PodStatusKilledOOM    PodStatus = "KilledOOM"
  constant PodStatusStalled (line 68) | PodStatusStalled      PodStatus = "Stalled"
  constant PodStatusSucceeded (line 69) | PodStatusSucceeded    PodStatus = "Succeeded"
  constant PodStatusUnknown (line 70) | PodStatusUnknown      PodStatus = "Unknown"
  function Pod (line 92) | func Pod(spec *PodSpec) *kcore.Pod {
  function GetPodConditionOf (line 105) | func GetPodConditionOf(pod *kcore.Pod, podType kcore.PodConditionType) (...
  method CreatePod (line 127) | func (c *Client) CreatePod(pod *kcore.Pod) (*kcore.Pod, error) {
  method UpdatePod (line 136) | func (c *Client) UpdatePod(pod *kcore.Pod) (*kcore.Pod, error) {
  method ApplyPod (line 145) | func (c *Client) ApplyPod(pod *kcore.Pod) (*kcore.Pod, error) {
  function IsPodReady (line 156) | func IsPodReady(pod *kcore.Pod) bool {
  function IsPodStalled (line 169) | func IsPodStalled(pod *kcore.Pod) bool {
  function GetPodReadyTime (line 182) | func GetPodReadyTime(pod *kcore.Pod) *time.Time {
  function WasPodOOMKilled (line 197) | func WasPodOOMKilled(pod *kcore.Pod) bool {
  function GetPodStatus (line 216) | func GetPodStatus(pod *kcore.Pod) PodStatus {
  function PodStatusFromContainerStatuses (line 274) | func PodStatusFromContainerStatuses(containerStatuses []kcore.ContainerS...
  method WaitForPodRunning (line 345) | func (c *Client) WaitForPodRunning(name string, numSeconds int) error {
  method GetPod (line 359) | func (c *Client) GetPod(name string) (*kcore.Pod, error) {
  method DeletePod (line 371) | func (c *Client) DeletePod(name string) (bool, error) {
  method ListPods (line 382) | func (c *Client) ListPods(opts *kmeta.ListOptions) ([]kcore.Pod, error) {
  method ListPodsByLabels (line 396) | func (c *Client) ListPodsByLabels(labels map[string]string) ([]kcore.Pod...
  method ListPodsByLabel (line 403) | func (c *Client) ListPodsByLabel(labelKey string, labelValue string) ([]...
  method ListPodsWithLabelKeys (line 407) | func (c *Client) ListPodsWithLabelKeys(labelKeys ...string) ([]kcore.Pod...
  function PodMap (line 414) | func PodMap(pods []kcore.Pod) map[string]kcore.Pod {
  function PodComputesEqual (line 422) | func PodComputesEqual(podSpec1, podSpec2 *kcore.PodSpec) bool {
  function TotalPodCompute (line 428) | func TotalPodCompute(podSpec *kcore.PodSpec) (Quantity, Quantity, int64,...
  method Exec (line 456) | func (c *Client) Exec(podName string, containerName string, command []st...

FILE: pkg/lib/k8s/quantity.go
  type Quantity (line 28) | type Quantity struct
    method MilliString (line 114) | func (quantity *Quantity) MilliString() string {
    method ToFloat32 (line 118) | func (quantity *Quantity) ToFloat32() float32 {
    method ToKiRounded (line 129) | func (quantity *Quantity) ToKiRounded() int64 {
    method ToKiRoundedStr (line 132) | func (quantity *Quantity) ToKiRoundedStr() string {
    method ToKiCeil (line 143) | func (quantity *Quantity) ToKiCeil() int64 {
    method ToKiCeilStr (line 146) | func (quantity *Quantity) ToKiCeilStr() string {
    method ToKiFloor (line 157) | func (quantity *Quantity) ToKiFloor() int64 {
    method ToKiFloorStr (line 160) | func (quantity *Quantity) ToKiFloorStr() string {
    method ToMiRounded (line 171) | func (quantity *Quantity) ToMiRounded() int64 {
    method ToMiRoundedStr (line 174) | func (quantity *Quantity) ToMiRoundedStr() string {
    method ToMiCeil (line 185) | func (quantity *Quantity) ToMiCeil() int64 {
    method ToMiCeilStr (line 188) | func (quantity *Quantity) ToMiCeilStr() string {
    method ToMiFloor (line 199) | func (quantity *Quantity) ToMiFloor() int64 {
    method ToMiFloorStr (line 202) | func (quantity *Quantity) ToMiFloorStr() string {
    method Sub (line 206) | func (quantity *Quantity) Sub(q2 kresource.Quantity) {
    method SubQty (line 211) | func (quantity *Quantity) SubQty(q2 Quantity) {
    method Add (line 216) | func (quantity *Quantity) Add(q2 kresource.Quantity) {
    method AddQty (line 221) | func (quantity *Quantity) AddQty(q2 Quantity) {
    method String (line 226) | func (quantity *Quantity) String() string {
    method Equal (line 236) | func (quantity *Quantity) Equal(quantity2 Quantity) bool {
    method ID (line 240) | func (quantity *Quantity) ID() string {
    method DeepCopy (line 244) | func (quantity *Quantity) DeepCopy() Quantity {
    method MarshalYAML (line 277) | func (quantity Quantity) MarshalYAML() (interface{}, error) {
    method UnmarshalYAML (line 281) | func (quantity *Quantity) UnmarshalYAML(unmarshal func(interface{}) er...
    method MarshalJSON (line 294) | func (quantity Quantity) MarshalJSON() ([]byte, error) {
    method UnmarshalJSON (line 298) | func (quantity *Quantity) UnmarshalJSON(data []byte) error {
    method MarshalBinary (line 313) | func (quantity Quantity) MarshalBinary() ([]byte, error) {
    method UnmarshalBinary (line 317) | func (quantity *Quantity) UnmarshalBinary(data []byte) error {
    method MarshalText (line 321) | func (quantity Quantity) MarshalText() ([]byte, error) {
    method UnmarshalText (line 325) | func (quantity *Quantity) UnmarshalText(data []byte) error {
  type QuantityValidation (line 33) | type QuantityValidation struct
  function QuantityParser (line 40) | func QuantityParser(v *QuantityValidation) func(string) (interface{}, er...
  function WrapQuantity (line 75) | func WrapQuantity(k8sQuantity kresource.Quantity) *Quantity {
  function NewQuantity (line 81) | func NewQuantity(value int64) *Quantity {
  function NewMilliQuantity (line 89) | func NewMilliQuantity(milliValue int64) *Quantity {
  function NewSummed (line 99) | func NewSummed(quantities ...kresource.Quantity) *Quantity {
  function ToKiRounded (line 122) | func ToKiRounded(k8sQuantity kresource.Quantity) int64 {
  function ToKiRoundedStr (line 126) | func ToKiRoundedStr(k8sQuantity kresource.Quantity) string {
  function ToKiCeil (line 136) | func ToKiCeil(k8sQuantity kresource.Quantity) int64 {
  function ToKiCeilStr (line 140) | func ToKiCeilStr(k8sQuantity kresource.Quantity) string {
  function ToKiFloor (line 150) | func ToKiFloor(k8sQuantity kresource.Quantity) int64 {
  function ToKiFloorStr (line 154) | func ToKiFloorStr(k8sQuantity kresource.Quantity) string {
  function ToMiRounded (line 164) | func ToMiRounded(k8sQuantity kresource.Quantity) int64 {
  function ToMiRoundedStr (line 168) | func ToMiRoundedStr(k8sQuantity kresource.Quantity) string {
  function ToMiCeil (line 178) | func ToMiCeil(k8sQuantity kresource.Quantity) int64 {
  function ToMiCeilStr (line 182) | func ToMiCeilStr(k8sQuantity kresource.Quantity) string {
  function ToMiFloor (line 192) | func ToMiFloor(k8sQuantity kresource.Quantity) int64 {
  function ToMiFloorStr (line 196) | func ToMiFloorStr(k8sQuantity kresource.Quantity) string {
  function QuantityPtr (line 251) | func QuantityPtr(k8sQuantity kresource.Quantity) *kresource.Quantity {
  function QuantityPtrID (line 255) | func QuantityPtrID(quantity *Quantity) string {
  function QuantityPtrsEqual (line 262) | func QuantityPtrsEqual(quantity *Quantity, quantity2 *Quantity) bool {
  type quantityMarshalable (line 272) | type quantityMarshalable struct

FILE: pkg/lib/k8s/secret.go
  type SecretSpec (line 34) | type SecretSpec struct
  function Secret (line 41) | func Secret(spec *SecretSpec) *kcore.Secret {
  method CreateSecret (line 54) | func (c *Client) CreateSecret(secret *kcore.Secret) (*kcore.Secret, erro...
  method UpdateSecret (line 63) | func (c *Client) UpdateSecret(secret *kcore.Secret) (*kcore.Secret, erro...
  method ApplySecret (line 72) | func (c *Client) ApplySecret(secret *kcore.Secret) (*kcore.Secret, error) {
  method GetSecret (line 83) | func (c *Client) GetSecret(name string) (*kcore.Secret, error) {
  method GetSecretData (line 95) | func (c *Client) GetSecretData(name string) (map[string][]byte, error) {
  method DeleteSecret (line 106) | func (c *Client) DeleteSecret(name string) (bool, error) {
  method ListSecrets (line 117) | func (c *Client) ListSecrets(opts *kme
Condensed preview — 702 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (5,890K chars).
[
  {
    "path": ".circleci/config.yml",
    "chars": 10779,
    "preview": "version: 2.1\n\norbs:\n  slack: circleci/slack@4.2.0\n\ncommands:\n  install-go:\n    steps:\n      - run:\n          name: Insta"
  },
  {
    "path": ".dockerignore",
    "chars": 146,
    "preview": "/vendor/\n/bin/\n/testbin/\n/dev/\n/docs/\n/test/\n\n**/.*\n**/*.md\n**/*.zip\n\n**/*.pyc\n**/*.pyo\n**/*.pyd\n**/__pycache__/\n\n**/hac"
  },
  {
    "path": ".gitbook.yaml",
    "chars": 69,
    "preview": "root: ./docs/\n\nstructure:\n  readme: ./start.md\n  summary: summary.md\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug-report.md",
    "chars": 679,
    "preview": "---\nname: Bug report\nabout: Report a bug\ntitle: ''\nlabels: bug\nassignees: ''\n\n---\n\n### Version\n\n(use `cortex version` to"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature-request.md",
    "chars": 284,
    "preview": "---\nname: Feature request\nabout: Request a feature\ntitle: ''\nlabels: enhancement\nassignees: ''\n\n---\n\n### Description\n\n(d"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/question.md",
    "chars": 87,
    "preview": "---\nname: Question\nabout: Ask a question\ntitle: ''\nlabels: question\nassignees: ''\n\n---\n"
  },
  {
    "path": ".github/pull_request_template.md",
    "chars": 446,
    "preview": "closes #<issue ID>\n\n---\n\nchecklist:\n\n- [ ] run `make test` and `make lint`\n- [ ] test manually (i.e. build/push all imag"
  },
  {
    "path": ".gitignore",
    "chars": 464,
    "preview": "/vendor/\n/bin/\n/testbin/\n/dev/config/\n\n# PYTHON\n__pycache__/\n*.py[cod]\n*$py.class\n.python-version\n.env\n.venv\n*.egg-info\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 6717,
    "preview": "# Contributing\n\n## Remote development\n\nWe recommend that you run your development environment on an EC2 instance due to "
  },
  {
    "path": "LICENSE",
    "chars": 11357,
    "preview": "                                 Apache License\n                           Version 2.0, January 2004\n                   "
  },
  {
    "path": "Makefile",
    "chars": 9661,
    "preview": "#!make\n\n# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may"
  },
  {
    "path": "README.md",
    "chars": 1564,
    "preview": "**[Docs](https://docs.cortexlabs.com)** • **[Slack](https://community.cortexlabs.com)**\n\n<br>\n\n<img src='https://cortex-"
  },
  {
    "path": "build/amend-image.sh",
    "chars": 1126,
    "preview": "#!/bin/bash\n\n# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# yo"
  },
  {
    "path": "build/amend-images.sh",
    "chars": 883,
    "preview": "#!/bin/bash\n\n# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# yo"
  },
  {
    "path": "build/build-image.sh",
    "chars": 1103,
    "preview": "#!/bin/bash\n\n# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# yo"
  },
  {
    "path": "build/build-images.sh",
    "chars": 1139,
    "preview": "#!/bin/bash\n\n# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# yo"
  },
  {
    "path": "build/cli.sh",
    "chars": 1921,
    "preview": "#!/bin/bash\n\n# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# yo"
  },
  {
    "path": "build/generate_ami_mapping.go",
    "chars": 9645,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "build/images.sh",
    "chars": 1554,
    "preview": "#!/bin/bash\n\n# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# yo"
  },
  {
    "path": "build/lint-docs.sh",
    "chars": 1882,
    "preview": "#!/bin/bash\n\n# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# yo"
  },
  {
    "path": "build/lint.sh",
    "chars": 6376,
    "preview": "#!/bin/bash\n\n# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# yo"
  },
  {
    "path": "build/push-image.sh",
    "chars": 1070,
    "preview": "#!/bin/bash\n\n# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# yo"
  },
  {
    "path": "build/push-images.sh",
    "chars": 1137,
    "preview": "#!/bin/bash\n\n# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# yo"
  },
  {
    "path": "build/test.sh",
    "chars": 2216,
    "preview": "#!/bin/bash\n\n# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# yo"
  },
  {
    "path": "cli/cluster/delete.go",
    "chars": 2859,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cli/cluster/deploy.go",
    "chars": 1449,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cli/cluster/errors.go",
    "chars": 4222,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cli/cluster/get.go",
    "chars": 3247,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cli/cluster/info.go",
    "chars": 1161,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cli/cluster/lib_http_client.go",
    "chars": 6718,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cli/cluster/logs.go",
    "chars": 4735,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cli/cluster/refresh.go",
    "chars": 1302,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cli/cmd/cluster.go",
    "chars": 54682,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cli/cmd/completion.go",
    "chars": 3416,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cli/cmd/const.go",
    "chars": 628,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cli/cmd/delete.go",
    "chars": 2952,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cli/cmd/deploy.go",
    "chars": 4903,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cli/cmd/describe.go",
    "chars": 2997,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cli/cmd/env.go",
    "chars": 5675,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cli/cmd/errors.go",
    "chars": 11234,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cli/cmd/get.go",
    "chars": 14238,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cli/cmd/lib_apis.go",
    "chars": 1627,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cli/cmd/lib_async_apis.go",
    "chars": 3144,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cli/cmd/lib_aws_creds.go",
    "chars": 2541,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cli/cmd/lib_batch_apis.go",
    "chars": 7560,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cli/cmd/lib_cli_config.go",
    "chars": 14922,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cli/cmd/lib_client_id.go",
    "chars": 1011,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cli/cmd/lib_cluster_config.go",
    "chars": 15753,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cli/cmd/lib_manager.go",
    "chars": 8158,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cli/cmd/lib_realtime_apis.go",
    "chars": 3254,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cli/cmd/lib_task_apis.go",
    "chars": 6486,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cli/cmd/lib_traffic_splitters.go",
    "chars": 3582,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cli/cmd/lib_watch.go",
    "chars": 2757,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cli/cmd/logs.go",
    "chars": 2737,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cli/cmd/refresh.go",
    "chars": 2401,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cli/cmd/root.go",
    "chars": 5698,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cli/cmd/version.go",
    "chars": 1859,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cli/lib/routines/routines.go",
    "chars": 1022,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cli/main.go",
    "chars": 662,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cli/types/cliconfig/cli_config.go",
    "chars": 2049,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cli/types/cliconfig/config_key.go",
    "chars": 758,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cli/types/cliconfig/environment.go",
    "chars": 1827,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cli/types/cliconfig/errors.go",
    "chars": 1638,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cli/types/flags/errors.go",
    "chars": 1047,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cli/types/flags/output_type.go",
    "chars": 2295,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cmd/activator/main.go",
    "chars": 6131,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cmd/async-gateway/main.go",
    "chars": 3734,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cmd/autoscaler/main.go",
    "chars": 8048,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cmd/dequeuer/main.go",
    "chars": 7448,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cmd/enqueuer/main.go",
    "chars": 3610,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cmd/operator/main.go",
    "chars": 5108,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "cmd/proxy/main.go",
    "chars": 6138,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "dev/build_cli.sh",
    "chars": 709,
    "preview": "#!/bin/bash\n\n# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# yo"
  },
  {
    "path": "dev/create_user.py",
    "chars": 3506,
    "preview": "#!/bin/bash\n\n# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# yo"
  },
  {
    "path": "dev/delete_ecr_repos.py",
    "chars": 916,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "dev/export_images.sh",
    "chars": 2250,
    "preview": "#!/bin/bash\n\n# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# yo"
  },
  {
    "path": "dev/find_missing_docs_links.py",
    "chars": 5790,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "dev/format.sh",
    "chars": 2358,
    "preview": "#!/bin/bash\n\n# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# yo"
  },
  {
    "path": "dev/generate_cli_md.sh",
    "chars": 1605,
    "preview": "#!/bin/bash\n\n# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# yo"
  },
  {
    "path": "dev/generate_python_client_md.sh",
    "chars": 2255,
    "preview": "#!/bin/bash\n\n# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# yo"
  },
  {
    "path": "dev/get_operator_url.py",
    "chars": 2084,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "dev/load.go",
    "chars": 8158,
    "preview": "/*\nCopyright 2022 Cortex Labs, Inc.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use thi"
  },
  {
    "path": "dev/minimum_aws_policy.json",
    "chars": 5334,
    "preview": "{\n    \"Version\": \"2012-10-17\",\n    \"Statement\": [\n        {\n            \"Effect\": \"Allow\",\n            \"Action\": \"iam:Cr"
  },
  {
    "path": "dev/operator_local.sh",
    "chars": 3442,
    "preview": "#!/bin/bash\n\n# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# yo"
  },
  {
    "path": "dev/prometheus.md",
    "chars": 8883,
    "preview": "# Metrics\n\n## Updating metrics\n\nWhen new metrics/labels/exporters are added to be scraped by prometheus, make sure the f"
  },
  {
    "path": "dev/registry.sh",
    "chars": 6165,
    "preview": "#!/bin/bash\n\n# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# yo"
  },
  {
    "path": "dev/update_cli_config.py",
    "chars": 1979,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "dev/util.sh",
    "chars": 778,
    "preview": "#!/bin/bash\n\n# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# yo"
  },
  {
    "path": "dev/versions.md",
    "chars": 17091,
    "preview": "# Upgrade notes\n\n## eksctl\n\n1. Find the latest release on [GitHub](https://github.com/weaveworks/eksctl/releases) and ch"
  },
  {
    "path": "docs/README.md",
    "chars": 88,
    "preview": "**Please read our documentation at [docs.cortexlabs.com](https://docs.cortexlabs.com)**\n"
  },
  {
    "path": "docs/clients/cli.md",
    "chars": 7114,
    "preview": "# CLI commands\n\n## deploy\n\n```text\ncreate or update apis\n\nUsage:\n  cortex deploy [CONFIG_FILE] [flags]\n\nFlags:\n  -e, --e"
  },
  {
    "path": "docs/clients/install.md",
    "chars": 1045,
    "preview": "# Install\n\n## Install the CLI\n\n<!-- CORTEX_VERSION_README x2 -->\n```bash\n# download CLI version 0.42.1 (Note the \"v\"):\nb"
  },
  {
    "path": "docs/clients/python.md",
    "chars": 4084,
    "preview": "# Python client\n\n* [cortex](#cortex)\n  * [client](#client)\n  * [new\\_client](#new_client)\n  * [env\\_list](#env_list)\n  *"
  },
  {
    "path": "docs/clients/uninstall.md",
    "chars": 197,
    "preview": "# Uninstall\n\n## Uninstall (if installed with pip)\n\n```bash\npip uninstall cortex\nrm -rf ~/.cortex\n```\n\n## Uninstall (if i"
  },
  {
    "path": "docs/clusters/advanced/kubectl.md",
    "chars": 498,
    "preview": "# Setting up `kubectl`\n\n## Install `kubectl`\n\nFollow these [instructions](https://kubernetes.io/docs/tasks/tools/install"
  },
  {
    "path": "docs/clusters/advanced/registry.md",
    "chars": 671,
    "preview": "# Private Docker registry\n\n## Configuring `kubectl`\n\nFollow the instructions [here](kubectl.md).\n\n## Setting credentials"
  },
  {
    "path": "docs/clusters/advanced/self-hosted-images.md",
    "chars": 1994,
    "preview": "# Self-hosted Docker images\n\nSelf-hosting the Cortex cluster's system Docker images can be useful for reducing the ingre"
  },
  {
    "path": "docs/clusters/instances/multi.md",
    "chars": 2567,
    "preview": "# Multi-instance type clusters\n\nCortex can be configured to provision different instance types to improve workload perfo"
  },
  {
    "path": "docs/clusters/instances/spot.md",
    "chars": 4961,
    "preview": "# Spot instances\n\n```yaml\n# cluster.yaml\n\nnode_groups:\n  - name: node-group-1\n\n    # whether to use spot instances for t"
  },
  {
    "path": "docs/clusters/management/auth.md",
    "chars": 10015,
    "preview": "# Auth\n\n## Client\n\nThe Cortex CLI and Python client use the default credential provider chain to get credentials for clu"
  },
  {
    "path": "docs/clusters/management/create.md",
    "chars": 6101,
    "preview": "# Install\n\n## Prerequisites\n\n1. Install and run [Docker](https://docs.docker.com/install) on your machine.\n1. Subscribe "
  },
  {
    "path": "docs/clusters/management/delete.md",
    "chars": 2828,
    "preview": "# Uninstall\n\n```bash\ncortex cluster down\n```\n\n## Bucket Contents\n\nWhen a Cortex cluster is created, an S3 bucket is crea"
  },
  {
    "path": "docs/clusters/management/environments.md",
    "chars": 1892,
    "preview": "# Environments\n\nWhen you create a cluster with `cortex cluster up`, an environment with the same name as your cluster is"
  },
  {
    "path": "docs/clusters/management/production.md",
    "chars": 5113,
    "preview": "# Production guide\n\nAs you take Cortex from development to production, here are a few pointers that might be useful.\n\n##"
  },
  {
    "path": "docs/clusters/management/update.md",
    "chars": 5221,
    "preview": "# Update\n\n## Modify existing cluster\n\nYou can add or remove node groups, resize existing node groups, and update some co"
  },
  {
    "path": "docs/clusters/networking/api-gateway.md",
    "chars": 10054,
    "preview": "# API Gateway\n\nThis guide shows how set up AWS API Gateway for your Cortex APIs, which is the simplest way to enable HTT"
  },
  {
    "path": "docs/clusters/networking/custom-domain.md",
    "chars": 4007,
    "preview": "# Custom domain\n\nYou can set up DNS to use a custom domain for your Cortex APIs. For example, you can make your API acce"
  },
  {
    "path": "docs/clusters/networking/https.md",
    "chars": 3686,
    "preview": "# Setting up HTTPS\n\nThis guide shows how to support HTTPS traffic to Cortex APIs via a custom domain. It is also possibl"
  },
  {
    "path": "docs/clusters/networking/load-balancers.md",
    "chars": 2259,
    "preview": "# Load balancers\n\n![api architecture diagram](https://user-images.githubusercontent.com/808475/103417256-dd6e9700-4b3e-1"
  },
  {
    "path": "docs/clusters/networking/vpc-peering.md",
    "chars": 4592,
    "preview": "# VPC peering\n\nIf you are using an internal operator load balancer (i.e. you set `operator_load_balancer_scheme: interna"
  },
  {
    "path": "docs/clusters/observability/alerting.md",
    "chars": 7557,
    "preview": "# Alerting\n\nCortex supports setting alerts for your APIs out-of-the-box. Alerts are an effective way of identifying prob"
  },
  {
    "path": "docs/clusters/observability/logging.md",
    "chars": 3782,
    "preview": "# Logging\n\nLogs are collected with Fluent Bit and are exported to CloudWatch.\n\n## Logs on AWS\n\nLogs will automatically b"
  },
  {
    "path": "docs/clusters/observability/metrics.md",
    "chars": 6267,
    "preview": "# Metrics\n\nCortex includes Prometheus for metrics collection and Grafana for visualization. You can monitor your APIs wi"
  },
  {
    "path": "docs/overview.md",
    "chars": 1969,
    "preview": "# Overview\n\n## Cluster\n\nThe Cortex cluster runs on an EKS (Kubernetes) cluster in a dedicated VPC on your AWS account.\n\n"
  },
  {
    "path": "docs/start.md",
    "chars": 953,
    "preview": "# Get started\n\n## Create a cluster on your AWS account\n\n<!-- CORTEX_VERSION_README -->\n```bash\n# install the CLI\nbash -c"
  },
  {
    "path": "docs/summary.md",
    "chars": 2556,
    "preview": "# Summary\n\n* [Get started](start.md)\n* [Overview](overview.md)\n\n## Clusters\n\n* Management\n  * [Auth](clusters/management"
  },
  {
    "path": "docs/workloads/async/async.md",
    "chars": 1764,
    "preview": "# Async\n\nAsync APIs are designed for asynchronous workloads in which the user submits an asynchronous request and retrie"
  },
  {
    "path": "docs/workloads/async/autoscaling.md",
    "chars": 7462,
    "preview": "# Autoscaling\n\nCortex auto-scales AsyncAPIs on a per-API basis based on your configuration.\n\n## Autoscaling replicas\n\n##"
  },
  {
    "path": "docs/workloads/async/configuration.md",
    "chars": 7964,
    "preview": "# Configuration\n\n```yaml\n- name: <string>  # name of the API (required)\n  kind: AsyncAPI  # must be \"AsyncAPI\" for async"
  },
  {
    "path": "docs/workloads/async/containers.md",
    "chars": 3979,
    "preview": "# Containers\n\n## Handling requests\n\nIn order to handle requests to your Async API, one of your containers must run a web"
  },
  {
    "path": "docs/workloads/async/example.md",
    "chars": 1802,
    "preview": "# AsyncAPI\n\n### Define an API\n\n```python\n# main.py\n\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel\n\napp = Fa"
  },
  {
    "path": "docs/workloads/async/statuses.md",
    "chars": 1993,
    "preview": "# Request statuses\n\n| Status            | Meaning                                                               |\n| :---"
  },
  {
    "path": "docs/workloads/batch/batch.md",
    "chars": 1610,
    "preview": "# Batch\n\nBatch APIs run distributed and fault-tolerant batch processing jobs on demand.\n\nBatch APIs are a good fit for u"
  },
  {
    "path": "docs/workloads/batch/configuration.md",
    "chars": 4986,
    "preview": "# Configuration\n\n```yaml\n- name: <string>  # name of the API (required)\n  kind: BatchAPI  # must be \"BatchAPI\" for batch"
  },
  {
    "path": "docs/workloads/batch/containers.md",
    "chars": 4276,
    "preview": "# Containers\n\n## Handling requests\n\nIn order to receive batches in your Batch API, one of your containers must run a web"
  },
  {
    "path": "docs/workloads/batch/example.md",
    "chars": 1856,
    "preview": "# BatchAPI\n\n### Define an API\n\n```python\n# main.py\n\nfrom fastapi import FastAPI\nfrom typing import List\n\napp = FastAPI()"
  },
  {
    "path": "docs/workloads/batch/jobs.md",
    "chars": 11918,
    "preview": "# BatchAPI jobs\n\n## Get the Batch API's endpoint\n\n```bash\ncortex get <batch_api_name>\n```\n\n## Submit a Job\n\nThere are th"
  },
  {
    "path": "docs/workloads/batch/statuses.md",
    "chars": 1078,
    "preview": "# Job statuses\n\n| Status                   | Meaning |\n| :--- | :--- |\n| enqueuing                | Job is being split i"
  },
  {
    "path": "docs/workloads/realtime/autoscaling.md",
    "chars": 7992,
    "preview": "# Autoscaling\n\nCortex autoscales each API independently based on its configuration.\n\n## Autoscaling replicas\n\n### Releva"
  },
  {
    "path": "docs/workloads/realtime/configuration.md",
    "chars": 8474,
    "preview": "# Configuration\n\n```yaml\n- name: <string>  # name of the API (required)\n  kind: RealtimeAPI  # must be \"RealtimeAPI\" for"
  },
  {
    "path": "docs/workloads/realtime/containers.md",
    "chars": 3889,
    "preview": "# Containers\n\n## Handling requests\n\nIn order to handle requests to your Realtime API, one of your containers must run a "
  },
  {
    "path": "docs/workloads/realtime/example.md",
    "chars": 1718,
    "preview": "# RealtimeAPI\n\n### Define an API\n\n```python\n# main.py\n\nfrom fastapi import FastAPI\nfrom pydantic import BaseModel\n\napp ="
  },
  {
    "path": "docs/workloads/realtime/metrics.md",
    "chars": 3361,
    "preview": "# Metrics\n\nThe `cortex get` and `cortex get API_NAME` commands display the request time (averaged over the past 2 weeks)"
  },
  {
    "path": "docs/workloads/realtime/realtime.md",
    "chars": 1024,
    "preview": "# Realtime\n\nRealtime APIs respond to requests synchronously and autoscale based on in-flight request volumes.\n\nRealtime "
  },
  {
    "path": "docs/workloads/realtime/statuses.md",
    "chars": 1408,
    "preview": "# Replica states\n\nThe replica states of an API can be inspected by running `cortex describe <api-name>`. Here are the po"
  },
  {
    "path": "docs/workloads/realtime/traffic-splitter.md",
    "chars": 1983,
    "preview": "# Traffic Splitter\n\nTraffic Splitters can be used to expose multiple RealtimeAPIs as a single endpoint for A/B tests, mu"
  },
  {
    "path": "docs/workloads/realtime/troubleshooting.md",
    "chars": 6484,
    "preview": "# Troubleshooting\n\n## 503 error responses from API requests\n\nWhen making requests to your API, it's possible to get a `n"
  },
  {
    "path": "docs/workloads/task/configuration.md",
    "chars": 3572,
    "preview": "# Configuration\n\n```yaml\n- name: <string>  # name of the API (required)\n  kind: TaskAPI  # must be \"TaskAPI\" for task AP"
  },
  {
    "path": "docs/workloads/task/containers.md",
    "chars": 2035,
    "preview": "# Containers\n\n## Job specification\n\nIf you need access to any parameters in the job submission (e.g. `config`), the enti"
  },
  {
    "path": "docs/workloads/task/example.md",
    "chars": 1372,
    "preview": "# TaskAPI\n\n### Define an API\n\n```python\n# main.py\n\nprint(\"hello world\")\n```\n\n### Create a `Dockerfile`\n\n```Dockerfile\nFR"
  },
  {
    "path": "docs/workloads/task/jobs.md",
    "chars": 1496,
    "preview": "# TaskAPI jobs\n\n## Get the Task API's endpoint\n\n```bash\ncortex get <task_api_name>\n```\n\n## Submit a Job\n\n```yaml\nPOST <t"
  },
  {
    "path": "docs/workloads/task/statuses.md",
    "chars": 616,
    "preview": "# Job statuses\n\n| Status                   | Meaning |\n| :--- | :--- |\n| running                  | Task is running |\n| "
  },
  {
    "path": "docs/workloads/task/task.md",
    "chars": 1073,
    "preview": "# Task\n\nTask APIs provide a lambda-style execution of containers. They are useful for running your containers on demand."
  },
  {
    "path": "get-cli.sh",
    "chars": 5515,
    "preview": "#!/bin/bash\n\n# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# yo"
  },
  {
    "path": "go.mod",
    "chars": 6699,
    "preview": "module github.com/cortexlabs/cortex\n\ngo 1.17\n\nrequire (\n\tgithub.com/DataDog/datadog-go v4.8.0+incompatible\n\tgithub.com/a"
  },
  {
    "path": "go.sum",
    "chars": 168808,
    "preview": "bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8=\ncloud.google.co"
  },
  {
    "path": "images/activator/Dockerfile",
    "chars": 1016,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "images/async-gateway/Dockerfile",
    "chars": 1185,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "images/autoscaler/Dockerfile",
    "chars": 1022,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "images/cluster-autoscaler/Dockerfile",
    "chars": 1136,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "images/controller-manager/Dockerfile",
    "chars": 1116,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "images/dequeuer/Dockerfile",
    "chars": 1199,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "images/enqueuer/Dockerfile",
    "chars": 1174,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "images/event-exporter/Dockerfile",
    "chars": 636,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "images/fluent-bit/Dockerfile",
    "chars": 620,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "images/grafana/Dockerfile",
    "chars": 609,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "images/istio-pilot/Dockerfile",
    "chars": 616,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "images/istio-proxy/Dockerfile",
    "chars": 618,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "images/kube-rbac-proxy/Dockerfile",
    "chars": 1259,
    "preview": "# Copyright 2021 Kube RBAC Proxy Authors rights reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"Licen"
  },
  {
    "path": "images/kubexit/Dockerfile",
    "chars": 1087,
    "preview": "# Copyright 2020 Karl Isenberg (https://github.com/karlkfi/kubexit)\n#\n# Licensed under the Apache License, Version 2.0 ("
  },
  {
    "path": "images/manager/Dockerfile",
    "chars": 1925,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "images/metrics-server/Dockerfile",
    "chars": 635,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "images/neuron-device-plugin/Dockerfile",
    "chars": 638,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "images/neuron-scheduler/Dockerfile",
    "chars": 634,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "images/nvidia-device-plugin/Dockerfile",
    "chars": 620,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "images/operator/Dockerfile",
    "chars": 1417,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "images/prometheus/Dockerfile",
    "chars": 625,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "images/prometheus-config-reloader/Dockerfile",
    "chars": 650,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "images/prometheus-dcgm-exporter/Dockerfile",
    "chars": 769,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "images/prometheus-kube-state-metrics/Dockerfile",
    "chars": 643,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "images/prometheus-node-exporter/Dockerfile",
    "chars": 627,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "images/prometheus-operator/Dockerfile",
    "chars": 643,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "images/prometheus-statsd-exporter/Dockerfile",
    "chars": 616,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "images/proxy/Dockerfile",
    "chars": 1033,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "manager/check_cortex_version.sh",
    "chars": 927,
    "preview": "#!/bin/bash\n\n# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# yo"
  },
  {
    "path": "manager/cluster_config_env.py",
    "chars": 2333,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "manager/debug.sh",
    "chars": 5635,
    "preview": "#!/bin/bash\n\n# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# yo"
  },
  {
    "path": "manager/generate_eks.py",
    "chars": 15922,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "manager/get_api_load_balancer_state.py",
    "chars": 1441,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "manager/get_operator_load_balancer_state.py",
    "chars": 1058,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "manager/get_operator_target_group_status.py",
    "chars": 2088,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "manager/helpers.py",
    "chars": 3736,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "manager/install.sh",
    "chars": 27867,
    "preview": "#!/bin/bash\n\n# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# yo"
  },
  {
    "path": "manager/manifests/activator.yaml.j2",
    "chars": 3191,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "manager/manifests/ami.json",
    "chars": 3557,
    "preview": "{\n\t\"1.22\": {\n\t\t\"af-south-1\": {\n\t\t\t\"accelerated_amd64\": \"ami-060db0c99048ca916\",\n\t\t\t\"cpu_amd64\": \"ami-05b1996f962e1a840\","
  },
  {
    "path": "manager/manifests/apis.yaml.j2",
    "chars": 1298,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "manager/manifests/async-gateway.yaml.j2",
    "chars": 2567,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "manager/manifests/autoscaler.yaml.j2",
    "chars": 2395,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "manager/manifests/cluster-autoscaler.yaml.j2",
    "chars": 6451,
    "preview": "# Copyright 2016 The Kubernetes Authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may n"
  },
  {
    "path": "manager/manifests/default_cortex_cli_config.yaml",
    "chars": 713,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "manager/manifests/event-exporter.yaml",
    "chars": 2101,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "manager/manifests/fluent-bit.yaml.j2",
    "chars": 7381,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "manager/manifests/grafana/grafana-dashboard-async.yaml",
    "chars": 54742,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "manager/manifests/grafana/grafana-dashboard-batch.yaml",
    "chars": 39749,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "manager/manifests/grafana/grafana-dashboard-cluster.yaml",
    "chars": 44415,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "manager/manifests/grafana/grafana-dashboard-control-plane.yaml",
    "chars": 32373,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "manager/manifests/grafana/grafana-dashboard-nodes.yaml",
    "chars": 26863,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "manager/manifests/grafana/grafana-dashboard-realtime.yaml",
    "chars": 58395,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "manager/manifests/grafana/grafana-dashboard-task.yaml",
    "chars": 39319,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  },
  {
    "path": "manager/manifests/grafana/grafana.yaml.j2",
    "chars": 6729,
    "preview": "# Copyright 2022 Cortex Labs, Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use"
  }
]

// ... and 502 more files (download for full content)

About this extraction

This page contains the full source code of the cortexlabs/cortex GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 702 files (5.2 MB), approximately 1.4M tokens, and a symbol index with 3806 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!