-
Notifications
You must be signed in to change notification settings - Fork 323
/
compatibility.go
105 lines (86 loc) · 4.61 KB
/
compatibility.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
// Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"). You may not
// use this file except in compliance with the License. A copy of the
// License is located at
//
// http://aws.amazon.com/apache2.0/
//
// or in the "license" file accompanying this file. This file 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 contracts provides model definitions for document state
package contracts
import (
"strings"
"github.com/aws/amazon-ssm-agent/agent/appconfig"
"github.com/aws/amazon-ssm-agent/agent/context"
"github.com/aws/amazon-ssm-agent/agent/jsonutil"
)
// TODO deprecate this functionality once we update the windows update document
type managedInstanceDocumentProperties struct {
RunCommand []string
ID string
}
type documentListType map[string]bool
var managedInstanceIncompatibleAWSSSMDocuments documentListType
func init() {
var documentList = documentListType{}
documentList["AWS-ConfigureWindowsUpdate"] = true
documentList["AWS-FindWindowsUpdates"] = true
documentList["AWS-InstallMissingWindowsUpdates"] = true
documentList["AWS-InstallSpecificWindowsUpdates"] = true
documentList["AWS-ListWindowsInventory"] = true
managedInstanceIncompatibleAWSSSMDocuments = documentList
}
// RemoveDependencyOnInstanceMetadata looks for array of commands which will be executed as a part of this document and replace the incompatible code.
func RemoveDependencyOnInstanceMetadata(context context.T, docState *DocumentState) error {
log := context.Log()
var properties []interface{}
var parsedDocumentProperties managedInstanceDocumentProperties
for index, pluginState := range docState.InstancePluginsInformation {
if pluginState.Name == appconfig.PluginNameAwsRunPowerShellScript {
err := jsonutil.Remarshal(pluginState.Configuration.Properties, &properties)
if err != nil {
log.Debugf("properties format unmatch in %v document. error: %v", docState.DocumentInformation.DocumentName, err)
return nil
}
// Since 'Properties' is an array and we use only one property block for the above documents, array location '0' of 'Properties' is used.
err = jsonutil.Remarshal(properties[0], &parsedDocumentProperties)
if err != nil {
log.Debugf("property format unmatch in %v document. error: %v", docState.DocumentInformation.DocumentName, err)
return nil
}
region, err := context.Identity().Region()
if err != nil {
log.Errorf("Error retrieving agent region. error: %v", err)
return err
}
// Comment or replace the incompatible code from this document.
log.Info("Replacing managed instance incompatible code for AWS SSM Document.")
for i, command := range parsedDocumentProperties.RunCommand {
// remove the call to metadata service to retrieve the region for onprem instances
if strings.Contains(command, "$metadataLocation = 'http://169.254.169.254/latest/dynamic/instance-identity/document/region'") {
parsedDocumentProperties.RunCommand[i] = strings.Replace(command, "$metadataLocation = 'http://169.254.169.254/latest/dynamic/instance-identity/document/region'", "# $metadataLocation = 'http://169.254.169.254/latest/dynamic/instance-identity/document/region' (This is done to make it managed instance compatible)", 1)
}
if strings.Contains(command, "$metadata = (New-Object Net.WebClient).DownloadString($metadataLocation)") {
parsedDocumentProperties.RunCommand[i] = strings.Replace(command, "$metadata = (New-Object Net.WebClient).DownloadString($metadataLocation)", "# $metadata = (New-Object Net.WebClient).DownloadString($metadataLocation) (This is done to make it managed instance compatible)", 1)
}
if strings.Contains(command, "$region = (ConvertFrom-JSON $metadata).region") {
parsedDocumentProperties.RunCommand[i] = strings.Replace(command, "$region = (ConvertFrom-JSON $metadata).region", "$region = '"+region+"'", 1)
}
}
// Plug-in the compatible 'Properties' block back to the document.
properties[0] = parsedDocumentProperties
var documentProperties interface{} = properties
pluginState.Configuration.Properties = documentProperties
docState.InstancePluginsInformation[index] = pluginState
}
}
return nil
}
// IsManagedInstanceIncompatibleAWSSSMDocument checks if doc could contain incompatible code for managed instance
func IsManagedInstanceIncompatibleAWSSSMDocument(documentName string) bool {
return managedInstanceIncompatibleAWSSSMDocuments[documentName]
}