internal/handlersettings/types.go (110 lines of code) (raw):

package handlersettings import ( "github.com/pkg/errors" ) // handlerSettings holds the configuration of the extension handler. type HandlerSettings struct { PublicSettings ProtectedSettings } // Gets the InstallAsService field from the RunCommand's properties func (s HandlerSettings) InstallAsService() bool { return s.PublicSettings.InstallAsService } func (s HandlerSettings) Script() string { return s.PublicSettings.Source.Script } func (s HandlerSettings) ScriptURI() string { return s.PublicSettings.Source.ScriptURI } func (s HandlerSettings) ScriptSAS() string { return s.ProtectedSettings.SourceSASToken } func (s HandlerSettings) ReadArtifacts() ([]UnifiedArtifact, error) { if s.ProtectedSettings.Artifacts == nil && s.PublicSettings.Artifacts == nil { return nil, nil } if len(s.ProtectedSettings.Artifacts) != len(s.PublicSettings.Artifacts) { return nil, errors.New(("RunCommand artifact download failed. Reason: Invalid artifact specification. This is a product bug.")) } artifacts := make([]UnifiedArtifact, len(s.PublicSettings.Artifacts)) for i := 0; i < len(s.PublicSettings.Artifacts); i++ { publicArtifact := s.PublicSettings.Artifacts[i] found := false for k := 0; k < len(s.ProtectedSettings.Artifacts); k++ { protectedArtifact := s.ProtectedSettings.Artifacts[k] if publicArtifact.ArtifactId == protectedArtifact.ArtifactId { found = true artifacts[i] = UnifiedArtifact{ ArtifactId: publicArtifact.ArtifactId, ArtifactUri: publicArtifact.ArtifactUri, ArtifactSasToken: protectedArtifact.ArtifactSasToken, FileName: publicArtifact.FileName, ArtifactManagedIdentity: protectedArtifact.ArtifactManagedIdentity, } } } if !found { return nil, errors.New(("RunCommand artifact download failed. Reason: Invalid artifact specification. This is a product bug.")) } } return artifacts, nil } // validate makes logical validation on the handlerSettings which already passed // the schema validation. func (s HandlerSettings) validate() error { // If installAsService is false, then the source has to be specified if !s.PublicSettings.InstallAsService { if s.PublicSettings.Source == nil || (s.PublicSettings.Source.Script == "") == (s.PublicSettings.Source.ScriptURI == "") { return errSourceNotSpecified } } return nil } // PublicSettings is the type deserialized from public configuration section of // the extension handler. This should be in sync with publicSettingsSchema. type PublicSettings struct { Source *ScriptSource `json:"source"` Parameters []ParameterDefinition `json:"parameters"` RunAsUser string `json:"runAsUser"` OutputBlobURI string `json:"outputBlobUri"` ErrorBlobURI string `json:"errorBlobUri"` TimeoutInSeconds int `json:"timeoutInSeconds,int"` AsyncExecution bool `json:"asyncExecution,bool"` TreatFailureAsDeploymentFailure bool `json:"treatFailureAsDeploymentFailure,bool"` // List of artifacts to download before running the script Artifacts []PublicArtifactSource `json:"artifacts"` // When the RunCommand extension sees the installAsService == true, it will apply the operations on the service as well. InstallAsService bool `json:"installAsService,bool"` } // ProtectedSettings is the type decoded and deserialized from protected // configuration section. This should be in sync with protectedSettingsSchema. type ProtectedSettings struct { RunAsPassword string `json:"runAsPassword"` SourceSASToken string `json:"sourceSASToken"` OutputBlobSASToken string `json:"outputBlobSASToken"` ErrorBlobSASToken string `json:"errorBlobSASToken"` ProtectedParameters []ParameterDefinition `json:"protectedParameters"` // List of artifacts to download before running the script Artifacts []ProtectedArtifactSource `json:"artifacts"` // Managed identity to use for reading the script if its not a SAS and if the VM doesn't have a system managed identity SourceManagedIdentity *RunCommandManagedIdentity `json:"sourceManagedIdentity"` // Managed identity to use for writing the output blob if the VM doesn't have a system managed identity OutputBlobManagedIdentity *RunCommandManagedIdentity `json:"outputBlobManagedIdentity"` // Managed identity to use for writing the error blob if the VM doesn't have a system managed identity ErrorBlobManagedIdentity *RunCommandManagedIdentity `json:"errorBlobManagedIdentity"` } // Contains the public and protected information for the artifact to download // This structure is only kept in memory. It is neither read nor persisted type UnifiedArtifact struct { ArtifactId int ArtifactUri string FileName string ArtifactSasToken string ArtifactManagedIdentity *RunCommandManagedIdentity } // Contains all public information for the artifact. Any sas token will be removed from the uri and added to the ArtifactSource // in the protected settings. The public and protected artifact settings are keyed by the artifactId. type PublicArtifactSource struct { ArtifactId int `json:"id"` ArtifactUri string `json:"uri"` FileName string `json:"fileName"` } // Contains secret information about an artifact to download to the VM. This includes the sas token for the uri (located in public settings) // and the managed identity. The public and protected artifact sources are keyed by the artifactId. type ProtectedArtifactSource struct { ArtifactId int `json:"id"` ArtifactSasToken string `json:"sasToken"` ArtifactManagedIdentity *RunCommandManagedIdentity `json:"artifactManagedIdentity"` } type RunCommandManagedIdentity struct { ObjectId string `json:"objectId"` ClientId string `json:"clientId"` } type ScriptSource struct { Script string `json:"script"` ScriptURI string `json:"scriptUri"` } type ParameterDefinition struct { Name string `json:"name"` Value string `json:"value"` }