diff --git a/acceptance.bats b/acceptance.bats index 455c99b..b046d01 100755 --- a/acceptance.bats +++ b/acceptance.bats @@ -12,6 +12,18 @@ [ "$output" = "Summary: 7 resources found in 2 files - Valid: 7, Invalid: 0, Errors: 0 Skipped: 0" ] } +@test "Pass when parsing a valid Kubernetes config file with int_to_string vars" { + run bin/kubeconform -verbose fixtures/int_or_string.yaml + [ "$status" -eq 0 ] + [ "$output" = "fixtures/int_or_string.yaml - Service heapster is valid" ] +} + +@test "Pass when parsing a valid Kubernetes config YAML file with generate name" { + run bin/kubeconform fixtures/generate_name.yaml + [ "$status" -eq 0 ] + [ "$output" = "fixtures/generate_name.yaml - Job pi-{{ generateName }} is valid" ] +} + @test "Pass when parsing a Kubernetes file with string and integer quantities" { run bin/kubeconform -verbose fixtures/quantity.yaml [ "$status" -eq 0 ] diff --git a/fixtures/generate_name.yaml b/fixtures/generate_name.yaml new file mode 100644 index 0000000..d960ee2 --- /dev/null +++ b/fixtures/generate_name.yaml @@ -0,0 +1,13 @@ +apiVersion: batch/v1 +kind: Job +metadata: + generateName: pi- +spec: + template: + spec: + containers: + - name: pi + image: perl + command: ["perl", "-Mbignum=bpi", "-wle", "print bpi(2000)"] + restartPolicy: Never + backoffLimit: 4 \ No newline at end of file diff --git a/fixtures/null_array.yaml b/fixtures/null_array.yaml index befe9fb..ae9ff61 100644 --- a/fixtures/null_array.yaml +++ b/fixtures/null_array.yaml @@ -1,5 +1,5 @@ kind: Deployment -apiVersion: extensions/v1beta1 +apiVersion: apps/v1 metadata: labels: k8s-app: kubernetes-dashboard diff --git a/fixtures/registry/sagemaker.aws.amazon.com_trainingjobs.yaml b/fixtures/registry/sagemaker.aws.amazon.com_trainingjobs.yaml new file mode 100644 index 0000000..7178b32 --- /dev/null +++ b/fixtures/registry/sagemaker.aws.amazon.com_trainingjobs.yaml @@ -0,0 +1,418 @@ + +--- +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.3.0 + creationTimestamp: null + name: trainingjobs.sagemaker.aws.amazon.com +spec: + additionalPrinterColumns: + - JSONPath: .status.trainingJobStatus + name: Status + type: string + - JSONPath: .status.secondaryStatus + name: Secondary-Status + type: string + - JSONPath: .metadata.creationTimestamp + format: date + name: Creation-Time + type: string + - JSONPath: .status.sageMakerTrainingJobName + name: Sagemaker-Job-Name + type: string + group: sagemaker.aws.amazon.com + names: + kind: TrainingJob + listKind: TrainingJobList + plural: trainingjobs + singular: trainingjob + scope: Namespaced + subresources: + status: {} + validation: + openAPIV3Schema: + description: TrainingJob is the Schema for the trainingjobs API + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: TrainingJobSpec defines the desired state of TrainingJob + properties: + algorithmSpecification: + properties: + algorithmName: + minLength: 1 + type: string + metricDefinitions: + items: + properties: + name: + minLength: 1 + type: string + regex: + minLength: 1 + type: string + required: + - name + - regex + type: object + type: array + trainingImage: + minLength: 1 + type: string + trainingInputMode: + enum: + - File + - Pipe + type: string + required: + - trainingInputMode + type: object + checkpointConfig: + properties: + localPath: + type: string + s3Uri: + pattern: ^(https|s3)://([^/]+)/?(.*)$ + type: string + required: + - s3Uri + type: object + debugHookConfig: + description: DebugHookConfig https://docs.aws.amazon.com/sagemaker/latest/dg/API_DebugHookConfig.html + properties: + collectionConfigurations: + items: + description: CollectionConfiguration https://docs.aws.amazon.com/sagemaker/latest/dg/API_CollectionConfiguration.html + properties: + collectionName: + type: string + collectionParameters: + items: + description: Used in describing maps in Kubernetes. + properties: + name: + type: string + value: + type: string + type: object + type: array + type: object + type: array + localPath: + type: string + ruleParameters: + items: + description: Used in describing maps in Kubernetes. + properties: + name: + type: string + value: + type: string + type: object + type: array + s3OutputPath: + pattern: ^(https|s3)://([^/]+)/?(.*)$ + type: string + required: + - s3OutputPath + type: object + debugRuleConfigurations: + items: + description: DebugRuleConfiguration https://docs.aws.amazon.com/sagemaker/latest/dg/API_DebugRuleConfiguration.html + properties: + instanceType: + type: string + localPath: + type: string + ruleConfigurationName: + type: string + ruleEvaluatorImage: + type: string + ruleParameters: + items: + description: Used in describing maps in Kubernetes. + properties: + name: + type: string + value: + type: string + type: object + type: array + s3OutputPath: + pattern: ^(https|s3)://([^/]+)/?(.*)$ + type: string + volumeSizeInGB: + format: int64 + minimum: 1 + type: integer + required: + - ruleConfigurationName + - ruleEvaluatorImage + type: object + type: array + enableInterContainerTrafficEncryption: + type: boolean + enableManagedSpotTraining: + type: boolean + enableNetworkIsolation: + type: boolean + hyperParameters: + items: + description: Used in describing maps in Kubernetes. + properties: + name: + type: string + value: + type: string + type: object + type: array + inputDataConfig: + items: + properties: + channelName: + minLength: 1 + pattern: '[A-Za-z0-9\.\-_]+' + type: string + compressionType: + enum: + - None + - Gzip + type: string + contentType: + type: string + dataSource: + properties: + fileSystemDataSource: + properties: + directoryPath: + type: string + fileSystemAccessMode: + type: string + fileSystemId: + type: string + fileSystemType: + type: string + required: + - directoryPath + - fileSystemAccessMode + - fileSystemId + - fileSystemType + type: object + s3DataSource: + properties: + attributeNames: + items: + type: string + type: array + s3DataDistributionType: + enum: + - FullyReplicated + - ShardedByS3Key + type: string + s3DataType: + enum: + - S3Prefix + - ManifestFile + - AugmentedManifestFile + type: string + s3Uri: + pattern: ^(https|s3)://([^/]+)/?(.*)$ + type: string + required: + - s3DataType + - s3Uri + type: object + type: object + inputMode: + enum: + - Pipe + - File + type: string + recordWrapperType: + type: string + shuffleConfig: + properties: + seed: + format: int64 + type: integer + required: + - seed + type: object + required: + - channelName + - dataSource + type: object + minItems: 1 + type: array + outputDataConfig: + properties: + kmsKeyId: + type: string + s3OutputPath: + pattern: ^(https|s3)://([^/]+)/?(.*)$ + type: string + required: + - s3OutputPath + type: object + region: + minLength: 1 + type: string + resourceConfig: + properties: + instanceCount: + format: int64 + minimum: 1 + type: integer + instanceType: + minLength: 1 + type: string + volumeKmsKeyId: + type: string + volumeSizeInGB: + format: int64 + minimum: 1 + type: integer + required: + - instanceCount + - instanceType + - volumeSizeInGB + type: object + roleArn: + minLength: 20 + type: string + sageMakerEndpoint: + description: A custom SageMaker endpoint to use when communicating with SageMaker. + pattern: ^(https|http)://.*$ + type: string + stoppingCondition: + properties: + maxRuntimeInSeconds: + format: int64 + minimum: 1 + type: integer + maxWaitTimeInSeconds: + format: int64 + minimum: 1 + type: integer + type: object + tags: + items: + properties: + key: + minLength: 1 + type: string + value: + type: string + required: + - key + - value + type: object + type: array + tensorBoardOutputConfig: + description: TensorBoardOutputConfig https://docs.aws.amazon.com/sagemaker/latest/dg/API_TensorBoardOutputConfig.html + properties: + localPath: + type: string + s3OutputPath: + pattern: ^(https|s3)://([^/]+)/?(.*)$ + type: string + required: + - s3OutputPath + type: object + trainingJobName: + description: The SageMaker training job name. This is optional for the SageMaker K8s operator. If it is empty, the operator will populate it with a generated name. + maxLength: 63 + type: string + vpcConfig: + properties: + securityGroupIds: + items: + type: string + maxItems: 5 + minItems: 1 + type: array + subnets: + items: + type: string + maxItems: 16 + minItems: 1 + type: array + required: + - securityGroupIds + - subnets + type: object + required: + - algorithmSpecification + - outputDataConfig + - region + - resourceConfig + - roleArn + - stoppingCondition + type: object + status: + description: TrainingJobStatus defines the observed state of TrainingJob + properties: + additional: + description: Field to store additional information, for example if we are unable to check the status we update this. + type: string + cloudWatchLogUrl: + description: Cloud Watch url for training log + type: string + debugRuleEvaluationStatuses: + description: Status of rule evaluation jobs, obtained from DebugRuleEvaluationStatuses. https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_DescribeTrainingJob.html#sagemaker-DescribeTrainingJob-response-DebugRuleEvaluationStatuses + items: + description: DebugRuleEvaluationStatus https://docs.aws.amazon.com/sagemaker/latest/dg/API_DebugRuleEvaluationStatus.html + properties: + lastModifiedTime: + format: date-time + type: string + ruleConfigurationName: + type: string + ruleEvaluationJobArn: + type: string + ruleEvaluationStatus: + type: string + statusDetail: + type: string + type: object + type: array + lastCheckTime: + description: The last time that we checked the status of the SageMaker job. + format: date-time + type: string + modelPath: + description: Full path to the training artifact (model) + type: string + sageMakerTrainingJobName: + description: SageMaker training job name + type: string + secondaryStatus: + description: The secondary, more granular status of the training job. https://docs.aws.amazon.com/sagemaker/latest/dg/API_DescribeTrainingJob.html#SageMaker-DescribeTrainingJob-response-SecondaryStatus + type: string + trainingJobStatus: + description: The status of the training job. https://docs.aws.amazon.com/sagemaker/latest/dg/API_DescribeTrainingJob.html#SageMaker-DescribeTrainingJob-response-TrainingJobStatus + type: string + type: object + required: + - spec + type: object + version: v1 + versions: + - name: v1 + served: true + storage: true +status: + acceptedNames: + kind: "" + plural: "" + conditions: [] + storedVersions: [] diff --git a/pkg/resource/signature.go b/pkg/resource/signature.go index 299c733..fab315b 100644 --- a/pkg/resource/signature.go +++ b/pkg/resource/signature.go @@ -14,11 +14,17 @@ func SignatureFromBytes(res []byte) (Signature, error) { APIVersion string `yaml:"apiVersion"` Kind string `yaml:"kind"` Metadata struct { - Name string `yaml:"Name"` - Namespace string `yaml:"Namespace"` + Name string `yaml:"name"` + Namespace string `yaml:"namespace"` + GenerateName string `yaml:"generateName"` } `yaml:"Metadata"` }{} err := yaml.Unmarshal(res, &resource) - return Signature{Kind: resource.Kind, Version: resource.APIVersion, Namespace: resource.Metadata.Namespace, Name: resource.Metadata.Name}, err + name := resource.Metadata.Name + if resource.Metadata.GenerateName != "" { + name = resource.Metadata.GenerateName + "{{ generateName }}" + } + + return Signature{Kind: resource.Kind, Version: resource.APIVersion, Namespace: resource.Metadata.Namespace, Name: name}, err }