github.com/jenkins-x/jx/v2@v2.1.155/pkg/kube/jenkins.go (about) 1 package kube 2 3 import ( 4 "strings" 5 6 "github.com/beevik/etree" 7 "github.com/jenkins-x/jx/v2/pkg/auth" 8 "github.com/jenkins-x/jx/v2/pkg/gits" 9 corev1 "k8s.io/api/core/v1" 10 ) 11 12 const ( 13 BitbucketConfigMapKey = "com.cloudbees.jenkins.plugins.bitbucket.endpoints.BitbucketEndpointConfiguration.xml" 14 GiteaConfigMapKey = "org.jenkinsci.plugin.gitea.servers.GiteaServers.xml" 15 GithubConfigMapKey = "org.jenkinsci.plugins.github_branch_source.GitHubConfiguration.xml" 16 17 bitbucketCloudElementName = "com.cloudbees.jenkins.plugins.bitbucket.endpoints.BitbucketCloudEndpoint" 18 bitbucketServerElementName = "com.cloudbees.jenkins.plugins.bitbucket.endpoints.BitbucketServerEndpoint" 19 20 defaultBitbucketXml = `<?xml version='1.1' encoding='UTF-8'?> 21 <com.cloudbees.jenkins.plugins.bitbucket.endpoints.BitbucketEndpointConfiguration plugin="cloudbees-bitbucket-branch-source@2.2.10"/>` 22 ) 23 24 // UpdateJenkinsGitServers update the Jenkins ConfigMap with any missing Git server configurations for the given server and token 25 func UpdateJenkinsGitServers(cm *corev1.ConfigMap, server *auth.AuthServer, userAuth *auth.UserAuth, credentials string) (bool, error) { 26 if gits.IsGitHubServerURL(server.URL) { 27 return false, nil 28 } 29 var key, v1, v2 string 30 var err error 31 32 switch server.Kind { 33 case gits.KindBitBucketCloud: 34 key = BitbucketConfigMapKey 35 v1 = cm.Data[key] 36 v2, err = createBitbucketCloudConfig(v1, server, userAuth, credentials) 37 case gits.KindBitBucketServer: 38 key = BitbucketConfigMapKey 39 v1 = cm.Data[key] 40 v2, err = createBitbucketServerConfig(v1, server, userAuth, credentials) 41 case gits.KindGitHub: 42 key = GithubConfigMapKey 43 v1 = cm.Data[key] 44 v2, err = createGitHubConfig(v1, server, userAuth, credentials) 45 case gits.KindGitea: 46 key = GiteaConfigMapKey 47 v1 = cm.Data[key] 48 v2, err = createGiteaConfig(v1, server, userAuth, credentials) 49 } 50 if err != nil { 51 return false, err 52 } 53 if v1 == v2 { 54 return false, nil 55 } 56 cm.Data[key] = v2 57 return true, nil 58 } 59 60 // ParseXml parses XML 61 func ParseXml(xml string) (*etree.Document, string, error) { 62 prefix := "" 63 doc := etree.NewDocument() 64 parseXml := xml 65 idx := strings.Index(xml, "?>") 66 if idx > 0 { 67 prefix = xml[0:idx+2] + "\n" 68 parseXml = strings.TrimSpace(xml[idx+2:]) 69 } 70 err := doc.ReadFromString(parseXml) 71 return doc, prefix, err 72 } 73 74 func createGitHubConfig(xml string, server *auth.AuthServer, userAuth *auth.UserAuth, credentials string) (string, error) { 75 u := gits.GitHubEnterpriseApiEndpointURL(server.URL) 76 if strings.TrimSpace(xml) == "" { 77 xml = `<?xml version='1.1' encoding='UTF-8'?> 78 <org.jenkinsci.plugins.github__branch__source.GitHubConfiguration plugin="github-branch-source@2.3.2"/>` 79 } 80 answer := xml 81 doc, prefix, err := ParseXml(xml) 82 if err != nil { 83 return answer, err 84 } 85 root := doc.Root() 86 servers := getChild(root, "endpoints") 87 if servers == nil { 88 servers = root.CreateElement("endpoints") 89 root.AddChild(servers) 90 } 91 92 found := false 93 updated := false 94 for _, n := range servers.ChildElements() { 95 if getChildText(n, "apiUri") == u { 96 found = true 97 break 98 } 99 } 100 if !found { 101 // lets add a new element 102 s := servers.CreateElement("org.jenkinsci.plugins.github__branch__source.Endpoint") 103 servers.AddChild(s) 104 setChildText(s, "name", server.Name) 105 setChildText(s, "apiUri", u) 106 updated = true 107 } 108 if updated { 109 doc.Indent(2) 110 xml2, err := doc.WriteToString() 111 return prefix + xml2, err 112 } 113 return xml, nil 114 115 } 116 117 func createGiteaConfig(xml string, server *auth.AuthServer, userAuth *auth.UserAuth, credentials string) (string, error) { 118 u := server.URL 119 if strings.TrimSpace(xml) == "" { 120 xml = `<?xml version='1.1' encoding='UTF-8'?> 121 <org.jenkinsci.plugin.gitea.servers.GiteaServers plugin="gitea@1.0.5"/>` 122 } 123 answer := xml 124 doc, prefix, err := ParseXml(xml) 125 if err != nil { 126 return answer, err 127 } 128 root := doc.Root() 129 servers := getChild(root, "servers") 130 if servers == nil { 131 servers = root.CreateElement("servers") 132 root.AddChild(servers) 133 } 134 135 found := false 136 updated := false 137 for _, n := range servers.ChildElements() { 138 if getChildText(n, "serverUrl") == u { 139 if setChildText(n, "credentialsId", credentials) { 140 updated = true 141 } 142 found = true 143 break 144 } 145 } 146 if !found { 147 // lets add a new element 148 s := servers.CreateElement("org.jenkinsci.plugin.gitea.servers.GiteaServer") 149 servers.AddChild(s) 150 setChildText(s, "displayName", server.Name) 151 setChildText(s, "serverUrl", u) 152 setChildText(s, "credentialsId", credentials) 153 setChildText(s, "manageHooks", "true") 154 updated = true 155 } 156 if updated { 157 doc.Indent(2) 158 xml2, err := doc.WriteToString() 159 return prefix + xml2, err 160 } 161 return xml, nil 162 } 163 164 func createBitbucketCloudConfig(xml string, server *auth.AuthServer, userAuth *auth.UserAuth, credentials string) (string, error) { 165 elementName := bitbucketCloudElementName 166 if strings.TrimSpace(xml) == "" { 167 xml = defaultBitbucketXml 168 } 169 answer := xml 170 doc, prefix, err := ParseXml(xml) 171 if err != nil { 172 return answer, err 173 } 174 root := doc.Root() 175 servers := getChild(root, "endpoints") 176 if servers == nil { 177 servers = root.CreateElement("endpoints") 178 root.AddChild(servers) 179 } 180 181 found := false 182 updated := false 183 for _, n := range servers.ChildElements() { 184 if setChildText(n, "credentialsId", credentials) { 185 updated = true 186 } 187 if setChildText(n, "manageHooks", "true") { 188 updated = true 189 } 190 found = true 191 break 192 } 193 if !found { 194 // lets add a new element 195 s := servers.CreateElement(elementName) 196 servers.AddChild(s) 197 setChildText(s, "credentialsId", credentials) 198 setChildText(s, "manageHooks", "true") 199 updated = true 200 } 201 if updated { 202 doc.Indent(2) 203 xml2, err := doc.WriteToString() 204 return prefix + xml2, err 205 } 206 return xml, nil 207 } 208 209 func createBitbucketServerConfig(xml string, server *auth.AuthServer, userAuth *auth.UserAuth, credentials string) (string, error) { 210 elementName := bitbucketServerElementName 211 u := server.URL 212 if strings.TrimSpace(xml) == "" { 213 xml = defaultBitbucketXml 214 } 215 answer := xml 216 doc, prefix, err := ParseXml(xml) 217 if err != nil { 218 return answer, err 219 } 220 root := doc.Root() 221 servers := getChild(root, "endpoints") 222 if servers == nil { 223 servers = root.CreateElement("endpoints") 224 root.AddChild(servers) 225 } 226 227 found := false 228 updated := false 229 for _, n := range servers.ChildElements() { 230 if getChildText(n, "serverUrl") == u { 231 if setChildText(n, "credentialsId", credentials) { 232 updated = true 233 } 234 found = true 235 break 236 } 237 } 238 if !found { 239 // lets add a new element 240 s := servers.CreateElement(elementName) 241 servers.AddChild(s) 242 setChildText(s, "displayName", server.Name) 243 setChildText(s, "serverUrl", u) 244 setChildText(s, "credentialsId", credentials) 245 setChildText(s, "manageHooks", "true") 246 updated = true 247 } 248 if updated { 249 doc.Indent(2) 250 xml2, err := doc.WriteToString() 251 return prefix + xml2, err 252 } 253 return xml, nil 254 255 } 256 257 func setChildText(node *etree.Element, childName string, value string) bool { 258 answer := false 259 child := getChild(node, childName) 260 if child == nil { 261 child = node.CreateElement(childName) 262 answer = true 263 node.AddChild(child) 264 } 265 if child.Text() != value { 266 child.SetText(value) 267 answer = true 268 } 269 return answer 270 } 271 272 func getChild(node *etree.Element, childName string) *etree.Element { 273 children := node.ChildElements() 274 for _, child := range children { 275 if child != nil && child.Tag == childName { 276 return child 277 } 278 } 279 return nil 280 } 281 282 func getChildText(node *etree.Element, childName string) string { 283 child := getChild(node, childName) 284 if child != nil { 285 return child.Text() 286 } 287 return "" 288 }